Skip to content

ci: notify majorcontext.com when docs change on main#52

Closed
andybons wants to merge 3 commits into
mainfrom
notify-site-docs
Closed

ci: notify majorcontext.com when docs change on main#52
andybons wants to merge 3 commits into
mainfrom
notify-site-docs

Conversation

@andybons

Copy link
Copy Markdown
Contributor

What

Adds .github/workflows/notify-site.yml — on push to main touching docs/content/** or docs/README.md, it sends a repository_dispatch (event_type: docs-updated) to majorcontext/majorcontext.com, which redeploys the docs site immediately instead of waiting for its daily rebuild cron.

Fail-soft: if the SITE_DISPATCH_TOKEN secret is unset or the dispatch call fails, the job logs a notice and exits 0 — a red check on every docs push would be worse than a missed dispatch, and the site's daily cron remains the fallback.

Operator action required to activate

Create a fine-grained PAT owned by an account with write access to majorcontext/majorcontext.com, scoped to only that repo, with Contents: Read and write (this is what POST /repos/{owner}/{repo}/dispatches requires for fine-grained PATs; Metadata: Read-only is auto-added). Store it as the SITE_DISPATCH_TOKEN Actions secret in this repo. Until then the workflow no-ops cleanly.

Pairs with majorcontext.com's repository_dispatch trigger (separate PR).

@claude

claude Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor
📦 Previous Review (superseded by newer review)

Claude finished @andybons's task in 1m 0s —— View job


Review: notify-site.yml

  • Gather context (PR diff, AGENTS.md)
  • Read .github/workflows/notify-site.yml
  • Review for security, correctness, fail-soft behavior
  • Post findings

This is a small, well-scoped CI addition — a single 40-line workflow with no uses: steps (no third-party action supply-chain surface) and no untrusted-input interpolation into run: blocks (the classic script-injection pattern in Actions). Findings:

No blocking issues. The workflow does what it says:

  • Secret (SITE_DISPATCH_TOKEN) is only read into an env var and passed to gh, never echoed or interpolated into a command string — no leak risk.
  • Fail-soft logic is correct: unset token → notice + exit 0; failed gh api call (expired/misscoped token, network blip, rate limit) → notice + exit 0. Either way the job stays green and the daily cron fallback covers it, matching the PR description.
  • Trigger (push to main, path-filtered to docs/content/** and docs/README.md) is scoped correctly — no risk of firing on unrelated pushes or forked-PR contexts (it's push-only, not pull_request_target, so there's no risk of a fork supplying the token or event data).

One nit (left inline, non-blocking): the job has no explicit permissions: block. It never touches GITHUB_TOKEN, so this isn't currently exploitable, but adding permissions: contents: read (or permissions: {}) is a cheap defense-in-depth step per GitHub's Actions hardening guidance, so the job's implicit token scope doesn't silently change if repo/org defaults ever do.

Comment thread .github/workflows/notify-site.yml
@claude

claude Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor
📦 Previous Review (superseded by newer review)

Claude finished @andybons's task in 1m 22s —— View job


Tasks

  • Gather context (PR diff, AGENTS.md)
  • Run code review on .github/workflows/notify-site.yml
  • Post findings

Review: notify-site.yml

Commit 841b9d9 addresses the one nit from the earlier review by pinning the job's default token to permissions: contents: read. Re-reviewed the full file against origin/main.

No blocking issues. This is a well-scoped 44-line CI-only addition:

  • Secret handlingSITE_DISPATCH_TOKEN flows only through the GH_TOKEN env var, consumed by gh api; it's never interpolated into a run: string or echoed, so there's no injection or leak surface. gh api picks up GH_TOKEN automatically for auth.
  • No script injection — no untrusted input (PR title, branch name, etc.) is interpolated into the shell; the only dynamic value is the static event_type=docs-updated field.
  • Fail-soft logic is correct — empty token → ::notice:: + exit 0; failed gh api call → ::notice:: + exit 0. Either path keeps the job green, matching the PR's stated fallback-to-daily-cron behavior.
  • permissions: contents: read is now explicit (the earlier nit). Note the job doesn't even check out the repo, so it doesn't strictly need contents: readpermissions: {} would be marginally tighter — but contents: read is still a clear improvement over an unpinned default and is a reasonable, conventional choice. Not worth blocking on.
  • Trigger scopingpush to main only, path-filtered to docs/content/** and docs/README.md. Not pull_request_target, so forked PRs can't reach this workflow or its secret.
  • gh api ... -f event_type=docs-updated correctly issues a POST (passing -f switches gh api from GET to POST), matching the repository_dispatch endpoint's requirement.

Nothing further to flag — no inline comments needed this round.

@claude

claude Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Claude finished @andybons's task in 58s —— View job


Reviewing PR #52

  • Gather context (PR diff, AGENTS.md, prior review comments)
  • Run code review on .github/workflows/notify-site.yml
  • Post findings

Review: notify-site.yml

Re-reviewed the file at its current HEAD (commit 9f33f42), which now sets permissions: {} per the discussion in the earlier review thread.

No blocking issues. This is a small, well-scoped 44-line CI-only addition:

  • Secret handlingSITE_DISPATCH_TOKEN only flows into the GH_TOKEN env var, consumed by gh api; never echoed or interpolated into a run: string, so there's no leak/injection surface.
  • No script injection — no untrusted input (branch name, commit message, etc.) is interpolated into the shell; the only dynamic value is the static event_type=docs-updated field.
  • Fail-soft logic is correct — empty token → ::notice:: + exit 0; failed gh api call → ::notice:: + exit 0. Either path keeps the job green, matching the PR's stated daily-cron fallback.
  • permissions: {} is now fully locked down — correct, since the job never checks out the repo and only uses the separate SITE_DISPATCH_TOKEN secret, not GITHUB_TOKEN. This closes out the defense-in-depth nit from the earlier review round.
  • Trigger scopingpush to main only, path-filtered to docs/content/** and docs/README.md. Not pull_request_target, so forked PRs can't reach this workflow or its secret.
  • gh api ... -f event_type=docs-updated correctly issues a POST (-f switches gh api from GET to POST), matching what the repository_dispatch endpoint requires.

Nothing further to flag — no new inline comments this round. The earlier permissions: nit is fully resolved.

@andybons

Copy link
Copy Markdown
Contributor Author

Closing — the daily rebuild cron on the site (majorcontext.com) already fixes the staleness problem this was built for. Event-driven dispatch would only cut propagation from ~24h to ~1min for non-urgent docs, at the cost of maintaining a write-scoped PAT that expires and needs rotation. Not worth the standing credential liability. Branch preserved in history if we ever want instant propagation.

@andybons andybons closed this Jul 15, 2026
@andybons andybons deleted the notify-site-docs branch July 15, 2026 14:03
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