ci: check the five publishing credentials without publishing anything - #381
Merged
Conversation
publish.yml pushes to each registry the moment that job succeeds and AUR has no review step, so its own concurrency note warns that a run dying halfway "leaves some registries on the new version and some on the old, with no record of which". A credential that expired quietly between releases is the likeliest way to get there: these secrets were last set 2026-05-03, GitHub PATs commonly carry a 90-day expiry, and releases here are months apart. 3 of the last 5 publish runs failed. New workflow_dispatch workflow, no inputs, contents: read. Every request is a read: /api/v1/me for crates.io, /user plus a permissions.push check on the tap and the bucket, /user for winget (nobody has push on winget-pkgs, the action forks), and AUR's own read-only `list-repos` over SSH. Nothing is created, forked, pushed or tagged. No secret value is echoed -- the report carries HTTP status codes and exit codes only. One step rather than five, and `set -uo pipefail` without `-e`, so a bad credential does not stop the rest from being checked. Finding out in one run which of the five are fine is the point. The AUR check needed hardening after testing. With a deliberately invalid key it PASSED, listing two repos: ssh had fallen through to the agent and to ~/.ssh/config and authenticated with an ambient key. `-F /dev/null`, `IdentitiesOnly=yes` and `IdentityAgent=none` are what make it depend on the key it was given. A credential check that can succeed without the credential is worse than none, because it reports green. Verified in both directions rather than only the happy one: - invalid values for all five: five failure rows, exit 1, no check skipped - real AUR key: lists netscli-bin and netscli-gui-bin, exit 0 - real GitHub token: /user 200 and permissions.push true on both repos, so the extraction is right (jq is preinstalled on ubuntu-latest) PUBLISHING.md's checklist now opens with it, since credentials are the slowest thing to fix and the only ones that fail mid-release.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
publish.ymlpushes to each registry the moment that job succeeds and AUR has no review step — its own concurrency note warns that a run dying halfway "leaves some registries on the new version and some on the old, with no record of which".A credential that expired quietly between releases is the likeliest way to get there. These secrets were last set 2026-05-03, GitHub PATs commonly carry a 90-day expiry, and releases here are months apart. 3 of the last 5 publish runs failed.
What it does
workflow_dispatch, no inputs,contents: read. Every request is a read:CARGO_REGISTRY_TOKENGET /api/v1/meHOMEBREW_TAP_TOKENGET /user+permissions.pushon the tapSCOOP_BUCKET_TOKENGET /user+permissions.pushon the bucketWINGET_TOKENGET /user(nobody has push on winget-pkgs; the action forks)AUR_SSH_PRIVATE_KEYlist-reposover SSHNothing is created, forked, pushed or tagged. No secret value is echoed — the report carries HTTP status codes and exit codes only.
One step rather than five, and
set -uo pipefailwithout-e, so a bad credential doesn't stop the rest from being checked. Learning in one run which of the five are fine is the point.The AUR check needed hardening
Tested with a deliberately invalid key, it passed, listing two repos — ssh had fallen through to the agent and
~/.ssh/configand authenticated with an ambient key.-F /dev/null,IdentitiesOnly=yesandIdentityAgent=noneare what make it depend on the key it was actually given.A credential check that can succeed without the credential is worse than none, because it reports green.
Verification, both directions
netscli-binandnetscli-gui-bin, exit 0/user200 andpermissions.pushtrue on both repos, so the extraction is right (jqis preinstalled onubuntu-latest)PUBLISHING.md's checklist now opens with it, since credentials are the slowest thing to fix and the only ones that fail mid-release.