Repository navigation
ci: run signing, Store and Pages deploys in environment-gated jobs. Principle XII. - #6571
Merged
Merged
Conversation
The build job now only builds: it installs with --ignore-scripts, checks out without persisted credentials, and uploads the finished site. A new deploy job (main push or dispatch only) downloads that artifact and runs the pinned wrangler-action under the cloudflare-pages environment, with no checkout. The deploy gate reads a boolean of whether the token is configured. The release PDF job runs under the release environment, keeps the signing key in a keyring of its own under RUNNER_TEMP that is removed at the end, reads the passphrase from stdin, and scopes GH_TOKEN to the upload step. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa
build-dmg builds with a read-only token and no signing material, then hands sign-dmg a tar of the unsigned bundle, DAX driver root, symbols and entitlements. sign-dmg runs under the release environment on v* tags and main, checks out nothing and compiles nothing. Its keychain lives under RUNNER_TEMP with a random, masked password and a six-hour lock, is prepended to the search list rather than made the default, and is deleted when the job ends. Both identities are imported non-exportable (-x), each allowed to its one tool. The .p12 files are removed by trap. notarytool reads a keychain profile stored in that keychain, so later calls no longer pass the app password. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa
…le XII. The draft Store submission moves out of release-windows into its own stage-store-draft job under the release environment; release-windows only attaches assets. The developer-flight job runs under store-flight. Both remove the Store CLI's stored credential and settings when they finish, and the checkouts in all three jobs no longer persist credentials. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa
The tag is read from the environment and must match a release-tag pattern before anything uses it; the checkout targets refs/tags/<tag> and the run stops unless the triggering build was of that tag's commit. workflow_run runs are accepted only from this repository's push or dispatch builds. The job runs under the release environment with contents: write, the workflow default drops to read, the key sits in a keyring of its own that is removed at the end, and the passphrase is read from stdin. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa
…ple VII. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa
wrangler-action installs the newest wrangler 4.x unless told otherwise; both deploy steps now name 4.147.0. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa
ten9876
marked this pull request as ready for review
October 18, 2026 19:23
ten9876
commented
Oct 18, 2026
ten9876
left a comment
Collaborator
Author
There was a problem hiding this comment.
Reviewed revision 313b3dffa6554916f7ce87c84df32cafaac91f24.
Follow-up changes are requested. The detailed report is being supplied directly to the maintainer.
…XII. release-pdf renders the tag's manual with a read-only token and no environment, for v* releases only, and uploads the PDF. A new sign-release-pdf job, under the release environment, checks the tag, downloads the artifact, requires it to be exactly the one expected regular file, then signs, verifies and attaches it. It checks out and runs nothing from the repository. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa
… on its own. Principle XII. sign-dmg unpacks the unsigned bundle into input/ and accepts only the four directories build-dmg stages, with no symlink resolving outside them. Every step runs in input/; the DMG and symbol archive are written to out/, checked to be the expected regular files, and only out/ is uploaded and attached. The DAX PKG version must be a version number. sign-dmg runs unless cancelled, so a failed build leg no longer skips the other leg's signing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa
NF0T
added a commit
to NF0T/AetherSDR
that referenced
this pull request
Oct 18, 2026
…. Principle XII. Addresses the review on aethersdr#6558, and restores what the rebase onto aethersdr#6571 dropped from the deploy job. - resolve-target (read-only token, no checkout) accepts only an empty ref, main, or a published non-pre-release v* release tag, and pins it to a commit SHA. Any other branch or tag is refused. - build-site builds that SHA with a read-only token, no secrets and npm ci --ignore-scripts, writes the PDF redirect, checks the 25 MiB limit and uploads the site. - deploy runs in the cloudflare-pages environment with no permissions and no checkout, and passes the token only to the pinned wrangler-action, with wrangler pinned to 4.147.0 again. A missing token or account ID fails the job instead of skipping it. - A release deploys after sign-release-pdf, the job that now attaches the PDF, not after release-pdf. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 18, 2026
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.
Summary
The release and docs workflows now run their signing, publishing and Store steps in their own jobs, under GitHub Environments, and pass tags and inputs to scripts through
env:.npm ciruns with--ignore-scripts. A newdeployjob (main push/dispatch only, environmentcloudflare-pages) downloads the built site and runs the pinnedwrangler-actionwith an exact wrangler version, with no checkout. For av*release,release-pdfrenders the manual with a read-only token. A newsign-release-pdfjob (environmentrelease, no checkout) checks that the artifact is exactly the expected PDF, then signs it with a temporary GPG keyring (passphrase on stdin) and attaches it.build-dmgbuilds with a read-only token and uploads the unsigned bundle as a tar. A newsign-dmgjob (environmentrelease, v* tags and main; each leg runs even if the other leg's build failed) unpacks it intoinput/. It accepts only the staged directories, with no symlinks pointing outside them, then signs, builds the DAX PKG and DMG, notarizes, and publishes only the regular files it wrote toout/. It checks out nothing and builds nothing. The keychain is per-run with a random, masked password, both identities are imported non-exportable, and the keychain is deleted when the job ends. notarytool uses a keychain profile.stage-store-draftjob (environmentrelease), and the developer-flight job runs understore-flight. Both jobs remove the Store CLI's stored credential and settings at the end. Checkouts in these jobs don't persist credentials.env:and must match a release-tag pattern. Checkout isrefs/tags/<tag>, and the run stops unless the triggering build was of that tag's commit. workflow_run runs are accepted only from this repository's push/dispatch builds. The job runs underrelease, the workflow default token drops tocontents: read, the keyring is temporary and the passphrase comes in on stdin.base_refreach scripts throughenv:.GitHub creates the
release,cloudflare-pagesandstore-flightenvironments on first use. They need their deployment rules and secrets configured before the next tag.Constitution principle honored
Principle XII: each job gets only the credentials it uses, and the scoping is enforced by infrastructure. Principle VII: tag and input values are validated or passed as data at the boundary.
Test plan
actionlint: no new findings on any workflow (one existing shellcheck note fixed)npm ci --ignore-scripts && npm run build; this PR's own Docs run builds it again and skipsdeployChecklist
docs/COMMIT-SIGNING.md)🤖 Generated with Claude Code
https://claude.ai/code/session_012U8wmr3AQGVrmQLp2zNBwa