Skip to content

fix(ci): make Pages deployment actually work — injection-safe commit, correct permissions, one publisher - #612

Merged
gHashTag merged 1 commit into
mainfrom
fix/pages-deploy-hardening
Aug 8, 2026
Merged

fix(ci): make Pages deployment actually work — injection-safe commit, correct permissions, one publisher#612
gHashTag merged 1 commit into
mainfrom
fix/pages-deploy-hardening

Conversation

@gHashTag

@gHashTag gHashTag commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Follow-up to #611. That PR fixed the MDX error that aborted the docs build; with the build passing, three further defects surfaced — the site still never reached the web.

1. Shell injection / breakage in the deploy step 🔴

git commit -m 'Deploy: ${{ github.event.head_commit.message }}'

The commit message is pasted verbatim into a single-quoted shell string. A message containing ), a quote or a newline breaks the script:

/home/runner/work/_temp/….sh: line 16: syntax error near unexpected token `)'
##[error]Process completed with exit code 2

That is exactly what happened on the last run. The same hole is a command-injection vector — commit messages are attacker-controllable in fork/PR flows.

Fix: pass it through an env: variable, use a deterministic subject (Deploy <sha>) with the original message quoted in the body, add set -euo pipefail, and exit 0 cleanly when there is nothing to publish.

2. deploy-pages.yml missing OIDC permissions

actions/deploy-pages@v4 authenticates via OIDC and failed every run:

Error: Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable
##[error]Ensure GITHUB_TOKEN has permission "id-token: write".

Fix: added pages: write + id-token: write and the github-pages environment.

3. Two workflows racing for one Pages target

Both deploy-docs.yml and deploy-pages.yml triggered on push to main. deploy-docs.yml is the real publisher — it builds apps/website and docs and pushes the combined output — while deploy-pages.yml only ever uploaded docs/build.

Fix: deploy-pages.yml is now workflow_dispatch only. Kept, not deleted, with a comment explaining the decision so it can be revived deliberately.

4. Pages source pointed at the wrong branch (repo setting, outside this diff)

Pages was configured as main / while the workflow publishes to the gh-pages branch — so even a successful deploy served nothing. This is why https://t27.ai/trinity/ returned 404. Repointed to gh-pages /.

Verification

Note

Other red checks in this repo (e.g. zig build author-guard reporting "no build.zig file found") are pre-existing on main and unrelated to Pages.

🤖 Generated with Claude Code

… correct permissions, one publisher

Three defects kept the site from ever publishing:

1. deploy-docs.yml interpolated the head commit message straight into a shell
   single-quoted string:

       git commit -m 'Deploy: ${{ github.event.head_commit.message }}'

   Any message containing parentheses, quotes or newlines broke the script
   ("syntax error near unexpected token `)`", exit 2) — and the same hole is a
   command-injection vector, since a commit message is attacker-controllable in
   a fork/PR flow. Now passed via an environment variable, with a deterministic
   subject line ("Deploy <sha>") and the original message quoted in the body.
   Also adds `set -euo pipefail` and exits cleanly when there is nothing new.

2. deploy-pages.yml used actions/deploy-pages@v4 without `pages: write` and
   `id-token: write`, so it failed every run with "Unable to get
   ACTIONS_ID_TOKEN_REQUEST_URL env variable". Permissions and the github-pages
   environment added.

3. Both workflows fired on push and raced for the same Pages target.
   deploy-docs.yml is the real publisher (it builds apps/website AND docs and
   pushes the combined output), so deploy-pages.yml is now manual-only. Kept
   rather than deleted, with a comment explaining why.

Separately (repo setting, not in this diff): Pages source was pointing at
`main /` while the workflow deploys to the `gh-pages` branch, so published
output was never served — that is why https://t27.ai/trinity/ returned 404.
Repointed to gh-pages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gHashTag
gHashTag merged commit d44e19c into main Aug 8, 2026
9 of 18 checks passed
@gHashTag
gHashTag deleted the fix/pages-deploy-hardening branch August 8, 2026 07:59
github-actions Bot added a commit that referenced this pull request Aug 8, 2026
fix(ci): make Pages deployment actually work — injection-safe commit, correct permissions, one publisher (#612)

Three defects kept the site from ever publishing:

1. deploy-docs.yml interpolated the head commit message straight into a shell
   single-quoted string:

       git commit -m 'Deploy: ${{ github.event.head_commit.message }}'

   Any message containing parentheses, quotes or newlines broke the script
   ("syntax error near unexpected token `)`", exit 2) — and the same hole is a
   command-injection vector, since a commit message is attacker-controllable in
   a fork/PR flow. Now passed via an environment variable, with a deterministic
   subject line ("Deploy <sha>") and the original message quoted in the body.
   Also adds `set -euo pipefail` and exits cleanly when there is nothing new.

2. deploy-pages.yml used actions/deploy-pages@v4 without `pages: write` and
   `id-token: write`, so it failed every run with "Unable to get
   ACTIONS_ID_TOKEN_REQUEST_URL env variable". Permissions and the github-pages
   environment added.

3. Both workflows fired on push and raced for the same Pages target.
   deploy-docs.yml is the real publisher (it builds apps/website AND docs and
   pushes the combined output), so deploy-pages.yml is now manual-only. Kept
   rather than deleted, with a comment explaining why.

Separately (repo setting, not in this diff): Pages source was pointing at
`main /` while the workflow deploys to the `gh-pages` branch, so published
output was never served — that is why https://t27.ai/trinity/ returned 404.
Repointed to gh-pages.

Co-authored-by: Dmitrii Vasilev <admin@t27.dev>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant