Gate the deploy before validation, and match the bundle's directory mode - #21
Merged
Conversation
The ref assertion ran beside validation rather than before it, so a mis-dispatched production deploy installed a toolchain and built a site before refusing. The upload cleared the setgid bit the bundle is assembled with, so the group would stop propagating below the first directory the transfer creates. A relative environment file is refused rather than resolved when it traverses, since a relative name is meant to reach the secrets directory. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This pull request tightens the deploy pipeline by enforcing an early ref gate, aligns remote upload permissions with the release bundle’s intended directory mode, and hardens environment-file selection to prevent relative-path traversal.
Changes:
- Reorders the deploy workflow so
assert-refruns first andvalidatedepends on it, preventing unnecessary installs/builds on mis-dispatched production deploys. - Updates the deployment rsync upload flags to preserve the intended setgid directory mode (
D2755) and avoid group preservation (--no-g), matching bundle assembly expectations. - Rejects relative
ENV_FILEvalues that include traversal (..) while still allowing absolute paths.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
deploy/make-release.sh |
Refuses traversal in relative ENV_FILE values before anchoring under the repo. |
.github/workflows/deploy-site.yml |
Runs assert-ref first and makes validate depend on it; deploy depends on validate. |
.github/workflows/deploy-site-task.yml |
Aligns rsync upload permissions (--no-g --chmod=D2755,F644) with the bundle’s directory-mode contract. |
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.
Three findings from the promotion review, all valid.
Job ordering contradicted its own comment
assert-refwas documented as running before Hugo is installed, and ran besidevalidate, which installs Hugo and builds the site. A production deploy dispatched from the wrong ref therefore paid for a full validation before refusing. The gate now runs first andvalidateneeds it.The upload cleared setgid
make-release.shassembles with--chmod=D2755deliberately, so the group propagates below the first directory rsync creates. The upload usedD755, which strips that bit on the remote tree and makes the on-host permission model diverge from the one the bundle was built and tested against. Confirmed on a real assembled release:The upload now uses
--no-g --chmod=D2755,F644, matching assembly.A relative environment file could traverse
The resolution claimed to anchor a relative
ENV_FILEunder the repo and did not, so../other.envreached outside it. A relative name exists to reachsecrets/, so traversal is refused rather than resolved. An absolute path is still honoured, which is how a file outside the repo is named deliberately.Verification
Both mirrors pass
1245 URLs honored. actionlint, shellcheck, and shfmt clean.🤖 Generated with Claude Code