Stop the login step interpolating a comment I wrote in it
ci / build and test (push) Successful in 1m40s
ci / android head (push) Failing after 5s
ci / api image (push) Successful in 40s

The secrets were never the problem. The log shows both arriving masked, which is what a
runner does with a value it holds — so the repository secrets were configured correctly the
whole time, and the guidance about Actions Variables was wrong.

What broke was the guard added to diagnose them. Its comment contained an expression
delimiter written out literally to explain what an unset secret renders as, and a shell
comment is not a comment yet at that point: the runner substitutes the whole script before
any shell sees it, so it tried to evaluate an empty expression and failed the step with a
parse error carrying no line number. The step never ran, and push then reached the registry
with nothing to authenticate as — "no basic auth credentials", which looks precisely like
the missing-secret problem the guard was added to rule out.

The comment now describes the delimiter instead of containing one, and warns the next
person, since the failure is invisible to review and to every local check: the file is
valid YAML and the script is valid shell.

Verified with a scan for empty expressions across every run block in the file — one before,
none after — and by running the step's script with credentials set, which passes the guard
and gets a 401 from the real registry. That is the right answer for an invented password,
and it means the endpoint is reachable and the path through this step is sound.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-01 17:01:06 +02:00
co-authored by Claude Opus 5
parent 2bc0d4d89f
commit 08a820adcf
+10 -3
View File
@@ -488,9 +488,16 @@ jobs:
set -eu set -eu
# Checked before use, because an unset secret is not an error anywhere upstream of # Checked before use, because an unset secret is not an error anywhere upstream of
# here: ${{ }} renders a missing value as the empty string, so docker is handed # here: an expression that resolves to nothing renders as the empty string, so
# --username "" and answers with something about credentials, which sends people # docker is handed --username "" and answers with something about credentials,
# to the registry to debug a value that never left the settings page. # which sends people to the registry to debug a value that never left the
# settings page.
#
# Note for anyone editing this comment: an expression delimiter written literally
# here is interpolated even though this is a shell comment. The runner substitutes
# the whole script before any shell sees it, so an empty one fails the step with a
# parse error and no line number — which is how this very block broke the release
# it was added to protect.
# #
# Reported by length, and never by value. Gitea masks known secret values in logs, # Reported by length, and never by value. Gitea masks known secret values in logs,
# but a mask is only as good as the runner's bookkeeping and a length answers the # but a mask is only as good as the runner's bookkeeping and a length answers the