Ten fixes from a review pass with fresh eyes. The ones that mattered:
rebuild-yum-repo.sh signed repomd.xml with no -u, so it used whatever
the keyring's default key resolved to. That is the packaging key today
only because there is one secret key in it. A repository whose metadata
is signed by the wrong key is one every client with gpgcheck=1 rejects,
produced by a run that exits 0.
The snapshot publish gate required only deb and rpm, whilst its comment
justified exactly one exception. A failed docs, tarball or wheel job
published a snapshot missing those files, and a failed repo-rpm job was
worse: install-repo-readme.py then fails after the packages are uploaded
and signed, leaving half a snapshot on the download server.
The location input was interpolated into shell on the runner holding both
publishing keys. It now travels through the environment, and is validated
against the shape of a datestamp before anything downstream sees it, so a
bad one fails in five seconds rather than after an hour of building.
Make.bat tested %ERRORLEVEL% inside a parenthesised block, where it is
expanded at parse time, so a failed Authenticode signature on
pgAdmin4.exe was undetectable; the handler was PAUSE, which on a headless
signing host either returns at once or blocks until the job times out.
Both sites now fail the build.
A called workflow inherits the caller's ref, so once this is on master an
ordinary push would have shared a concurrency group with the nightly
snapshot's builds and cancelled them.
And PULL_KEY named a file that does not exist on the download server,
which would have failed the first release promotion.
The rest: if-no-files-found on every build artefact, so a build that
produces nothing fails rather than silently shipping a snapshot without
it; pinned syft and helm installers, which were piping a default branch
into a shell as root in the container that builds signed packages; the
Helm chart no longer built and discarded; and the comments that had
stopped describing the code.
The self-test grows from 56 cases to 70, covering the verbs that delete
things, arguments that look like options, and the SSH_ORIGINAL_COMMAND
entry point rather than only the dry-run path.