ci: add release preflight to verify deploy credentials before the build#641
Conversation
Objective: A release only touches its deploy credentials in the very last steps, after a ~30-40 min build. So an expired npm token, a revoked GitHub PAT, or a mis-scoped Maven login is not discovered until the build has already finished — wasting the wait and risking a half-published release where some registries got the artifact and others did not. Approach: Add a preflight that actually authenticates each credential up front and gates the release on it. It makes a real authenticated call per target (npm whoami, Maven Central Portal, a GPG sign+verify, a GitHub repo push-permission check, and a PyPI OIDC token mint) and collects all results before failing, so one run tells you every credential that is broken — not just the first. It lives in its own reusable workflow (preflight.yml) so it both gates release.yml via `needs` AND can be run on its own from the Actions tab to check credentials in ~1 min without triggering a build. Secrets are handled defensively: read only from the environment, fed to curl via a stdin config (never argv, so nothing leaks through /proc/<pid>/cmdline), derived values are ::add-mask::'d, and the GPG private key is imported into an ephemeral keyring that is killed and wiped on exit. Credentials are passed to the reusable workflow explicitly (not `secrets: inherit`) so preflight only ever sees the six secrets it uses. Evidence: Ran the script locally against the live endpoints with deliberately wrong credentials, and scanned all output for secret material. Before: credential failures surfaced only after the full build, at deploy time. After: preflight fails in ~1 min and names every broken credential; release does not start. | Scenario | Expected | Actual | |----------|----------|--------| | No secrets set | all FAIL, clean exit 1 | 5/5 FAIL, exit 1, no crash | | Wrong Maven creds (live call) | HTTP 401, labeled bad creds | "HTTP 401 - bad credentials" | | Maven pass with " \ : and spaces | credential sent intact | decoded credential byte-identical | | Wrong GitHub PAT (live call) | no push access | "no push access to .../opendataloader.org" | | Bad GPG key | import fails, not a false pass | "GPG signing (import)" FAIL | | CI + RUNNER_TEMP unset | refuse (do not write key to /tmp) | hard-fail before import | | Leak scan (stdout+stderr+summary) | zero secret material | no raw or base64 credential found | shellcheck and actionlint both report clean on all three files. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughAdds a reusable release preflight workflow and script that authenticate deployment credentials before release execution. The release workflow now waits for preflight completion, while the script aggregates npm, Maven, GPG, GitHub, and PyPI authentication results. ChangesRelease preflight gate
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ReleaseWorkflow
participant PreflightWorkflow
participant PreflightScript
participant CredentialServices
ReleaseWorkflow->>PreflightWorkflow: invoke with selected secrets
PreflightWorkflow->>PreflightScript: run preflight checks
PreflightScript->>CredentialServices: authenticate npm, Maven, GPG, GitHub, and PyPI
CredentialServices-->>PreflightScript: return authentication results
PreflightScript-->>PreflightWorkflow: return aggregated status
PreflightWorkflow-->>ReleaseWorkflow: allow or block release job
Suggested reviewers: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Objective
A release only touches its deploy credentials in the very last steps, after a ~30-40 min build. So an expired npm token, a revoked GitHub PAT, or a mis-scoped Maven login isn't discovered until the build has already finished — wasting the wait and risking a half-published release where some registries got the artifact and others didn't.
Approach
Add a preflight that actually authenticates each credential up front and gates the release on it.
npm whoami, Maven Central Portal, a GPG sign+verify, a GitHub repo push-permission check, and a PyPI OIDC token mint.preflight.yml,workflow_call+workflow_dispatch), so it both gatesrelease.ymlvianeedsand can be run on its own from the Actions tab to check credentials in ~1 min without triggering a build.Secrets are handled defensively — read only from the environment; fed to curl via a stdin config (never argv, so nothing leaks through
/proc/<pid>/cmdline); derived values are::add-mask::'d; the GPG private key is imported into an ephemeral keyring killed and wiped on exit; and credentials are passed to the reusable workflow explicitly (notsecrets: inherit), so preflight only ever sees the six secrets it uses.Evidence
Ran the script locally against the live endpoints with deliberately wrong credentials, and scanned all output for secret material.
Before: credential failures surfaced only after the full build, at deploy time.
After: preflight fails in ~1 min and names every broken credential; release does not start.
HTTP 401 — bad credentials" \ :and spacesno push access to …/opendataloader.orgGPG signing (import)FAILRUNNER_TEMPunset/tmp)shellcheckandactionlintboth report clean on all three files.Known limitations (by design)
id-token: write), not trusted-publisher registration (not checkable without a publish).🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes