Public Access
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>