Skip to content

mirror-reusable: a missing GITEA_HOST reddens the default branch instead of printing a skip notice (exit 1 in ssh-keyscan) #1264

Open

Description

@hyperpolymath

Summary

mirror-reusable.yml handles a missing secret gracefully and a missing variable fatally, and the failure costs a red default branch with no diagnostic.

Every forge job is gated on vars.<FORGE>_MIRROR_ENABLED == 'true' and skips itself with a ::notice:: when its key secret is empty — a deliberate, documented design ("the vars gate answers 'is Radicle mirror desired here?'; the secret gate answers 'are we configured to actually do it?'").

The gitea leg adds a third input, vars.GITEA_HOST, and uses it where a missing value cannot be tolerated:

      - name: Mirror to Gitea
        if: ${{ env.GITEA_KEY != '' }}
        run: |
          ssh-keyscan -t ed25519 ${{ vars.GITEA_HOST }} >> ~/.ssh/known_hosts
          git remote add gitea git@${{ vars.GITEA_HOST }}:hyperpolymath/... || true
          git push --force gitea main

With GITEA_MIRROR_ENABLED=true, a non-empty GITEA_SSH_KEY and an empty GITEA_HOST, the job starts (unlike the missing-secret case), ssh-keyscan is called with no host argument, prints its usage message and exits 1 — before any push is attempted.

Evidence

hyperpolymath/rpa-elysium, main, run https://github.com/hyperpolymath/rpa-elysium/actions/runs/38608642035:

job conclusion exit code
mirror / mirror-codeberg success —
mirror / mirror-gitlab success —
mirror / mirror-bitbucket success —
mirror / mirror-sourcehut success —
mirror / mirror-radicle success —
mirror / mirror-gitea failure 1
mirror / mirror-disroot failure 128

The exit codes distinguish the two causes exactly: 1 is ssh-keyscan's usage error (the host variable is empty), 128 is git's fatal code (the push was refused — a different, repo-side problem). Job annotations carry only "Process completed with exit code 1." — the run says nothing about which variable is missing, and the job log is the only place the cause exists. On rpa-elysium this leg has been red since 2026-09-15 (last success 2026-09-08).

Why it matters estate-wide

Any repo with GITEA_MIRROR_ENABLED=true and no GITEA_HOST set (repo- or org-level) reddens its default branch on every push with a failure that cannot be diagnosed from the run, the job name or the annotation. It is the same class as the missing-secret case the workflow already handles with a notice.

Suggested fix (owner's call)

  1. Gate the step the way the secret is gated — if: ${{ env.GITEA_KEY != '' && env.GITEA_HOST != '' }} — and extend the existing "Skipped (... not configured)" step's notice to name vars.GITEA_HOST rather than leaving the job to die inside ssh-keyscan.
  2. Or give GITEA_HOST a default when unset, if there is a canonical host.
  3. Or make the leg fail fast with a one-line ::error:: naming the variable, if a red is wanted — but then the diagnosis should be in the annotation, not only in the log.

Any of the three is better than the current state, where a configuration gap is indistinguishable from a forge outage.

Found while triaging hyperpolymath/rpa-elysium#138 / #147 (pre-existing reds surfaced by the actions.lock cure, #1070).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions