diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml new file mode 100644 index 000000000..756ef854b --- /dev/null +++ b/.github/workflows/ci-build.yml @@ -0,0 +1,21 @@ +name: CI Build + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + +jobs: + build: + name: CI Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + - run: npm ci + - run: npm run build diff --git a/.github/workflows/pr-preview.yml b/.github/workflows/pr-preview.yml index a10b14fd5..bc9d893eb 100644 --- a/.github/workflows/pr-preview.yml +++ b/.github/workflows/pr-preview.yml @@ -50,8 +50,9 @@ jobs: script: | const prNumber = context.issue.number; const url = `https://usace-rmc.github.io/RMC-Software-Documentation-Previews/pr-${prNumber}/`; + const sha = context.payload.pull_request.head.sha.substring(0, 7); const marker = ''; - const body = `${marker}\n\nšŸ“„ **Preview deployed**\n\n${url}\n\n_This preview updates automatically when new commits are pushed. Deleted when the PR closes._`; + const body = `${marker}\n\nšŸ“„ **Preview deployed** for commit \`${sha}\`\n\n${url}\n\n_This preview updates automatically when new commits are pushed. Deleted when the PR closes._`; const comments = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber }); const existing = comments.data.find(c => c.user.type === 'Bot' && c.body.includes(marker)); if (existing) { @@ -59,3 +60,23 @@ jobs: } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body }); } + - name: Mark preview as stale on failure + if: failure() + uses: actions/github-script@v7 + with: + script: | + const prNumber = context.issue.number; + const sha = context.payload.pull_request.head.sha.substring(0, 7); + const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + const marker = ''; + const comments = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber }); + const existing = comments.data.find(c => c.user.type === 'Bot' && c.body.includes(marker)); + if (existing) { + // Strip any prior stale warning before appending a fresh one + const cleanBody = existing.body.split('\n\nāš ļø')[0]; + const newBody = `${cleanBody}\n\nāš ļø **Preview build failed on commit \`${sha}\`** — the preview URL above is **stale** and reflects an earlier successful build. Do not rely on it as an accurate representation of this PR's current state. [View workflow logs](${runUrl}).`; + await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body: newBody }); + } else { + const body = `${marker}\n\nāŒ **Preview build failed** on commit \`${sha}\`\n\nThe site failed to build for this PR, so there is no preview to view. [View workflow logs](${runUrl}).`; + await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body }); + } diff --git a/.github/workflows/stage-progression.yml b/.github/workflows/stage-progression.yml index 72edaec11..34b43730d 100644 --- a/.github/workflows/stage-progression.yml +++ b/.github/workflows/stage-progression.yml @@ -98,7 +98,7 @@ jobs: if (checkboxChecked) { await removeLabel('stage:ai-editor-review'); await addLabels(['stage:director-review']); - await postComment(`āœ… **Technical edit marked complete** by the author.\n\nAdvancing to **Director review**.\n\n@usace-rmc/docs-admin please:\n1. If revisions were pushed during the technical edit, trigger a fresh checkpoint deploy of this branch\n2. Assign a member of @usace-rmc/docs-director via the Reviewers sidebar\n\nThe Director will review at the live URL.`); + await postComment(`āœ… **Technical edit marked complete** by the author.\n\nAdvancing to **Director review**.\n\n@usace-rmc/docs-admin next steps:\n1. Trigger a checkpoint deploy of branch \`${branch}\` via Actions → Deploy to GitHub Pages → Run workflow (this is the first deploy of this PR to the live site, with the DRAFT watermark)\n2. Approve the deploy at the production environment gate\n3. Post the live URL in a comment on this PR\n4. Assign a member of @usace-rmc/docs-director via the Reviewers sidebar\n\nThe Director will review at the live URL. If the Director requests changes and the author pushes fixes, re-trigger the checkpoint deploy to refresh the live URL.`); } } return; @@ -116,7 +116,7 @@ jobs: comment = `āœ… **Peer review approved** by @${reviewer}.\n\nAdvancing to **RMC Lead Civil review**.\n\n@usace-rmc/docs-admin please assign the appropriate Lead Civil via the Reviewers sidebar. The Lead Civil reviews on the preview URL.`; } else if (existingStage === 'stage:lead-civil-review') { nextStage = 'stage:ai-editor-review'; - comment = `āœ… **Lead Civil review approved** by @${reviewer}.\n\nThe document is ready to be **deployed to the live site** (watermarked) for the technical edit and Director review phases.\n\n@usace-rmc/docs-admin next steps:\n1. Trigger a checkpoint deploy of branch \`${branch}\` via Actions → Deploy to GitHub Pages → Run workflow\n2. Approve the deploy at the production environment gate\n3. Post the live URL in a comment on this PR\n4. Run the \`/technical-edit\` Claude Code skill against this PR (or assign a human technical editor)\n\nAfter the author addresses the technical edit comments and checks the completion checkbox, the document will advance to Director review.`; + comment = `āœ… **Lead Civil review approved** by @${reviewer}.\n\nAdvancing to **technical edit**.\n\n@usace-rmc/docs-admin please run the \`/technical-edit\` Claude Code skill against this PR (or assign a human technical editor). The technical edit reviews the document source MDX directly and posts inline comments on the PR — **no live deploy is needed at this stage**.\n\nAfter the author addresses the technical edit comments and checks the completion checkbox in the PR description, the document will advance to Director review and the site admin will deploy it to the live site (watermarked) at that point.`; } else if (existingStage === 'stage:director-review') { nextStage = 'stage:ready-to-merge'; comment = `āœ… **Director review approved** by @${reviewer}.\n\nThis PR is **ready for final merge and publication**.\n\n@usace-rmc/docs-admin next steps:\n1. Check out this branch (locally or via github.dev)\n2. Flip the document's \`draft\` flag to \`false\`\n3. Update \`00-version-history.mdx\` with reviewer and approver names\n4. Commit and push\n5. Merge this PR to \`main\`\n6. Approve the final production deploy in the Actions tab`; diff --git a/planning/01-repo-implementation.md b/planning/01-repo-implementation.md index 737ca8b7c..c98818279 100644 --- a/planning/01-repo-implementation.md +++ b/planning/01-repo-implementation.md @@ -9,8 +9,8 @@ This document describes every structural change to the `usace-rmc/rmc-software-d 1. Author opens PR with branch prefix `docs/new/`. Preview workflow publishes to unadvertised preview URL. 2. Peer reviewer reviews on **preview URL**, approves. 3. RMC Lead Civil reviews on **preview URL**, approves. -4. Site admin triggers checkpoint deploy of PR branch to **production URL** (watermarked). -5. AI technical edit: someone with Claude Code runs `/technical-edit`, which posts inline review comments on the PR. Author addresses comments, checks a checkbox in the PR description to confirm completion. +4. AI technical edit: someone with Claude Code runs `/technical-edit`, which reads the source MDX and posts inline review comments on the PR. Author addresses comments, checks a checkbox in the PR description to confirm completion. **No live deploy at this stage** — the technical edit works on source files. +5. Site admin triggers checkpoint deploy of PR branch to **production URL** (watermarked). This is the first time the document appears on the live site. 6. Director reviews on **live URL**, approves with one click. 7. Site admin flips draft flag to `false`, merges PR to `main`, approves final deploy (watermark removed). @@ -31,6 +31,7 @@ This document describes every structural change to the `usace-rmc/rmc-software-d - The AI technical edit stage advances when the author checks a task list checkbox in the PR description, not when a reviewer clicks approve. - The stage progression workflow only auto-processes PRs whose branch name starts with `docs/`. PRs from any other branch (infrastructure, tooling, dependency bumps, etc.) are silently ignored — no labels, no comments, no review-process noise. A site admin can still pull any PR into the review process by manually applying a `lane:*` label, which is the escape hatch for mis-named branches or one-off cases. - The PR preview workflow (`pr-preview.yml`) uses a broader path-based trigger and will build a preview for any PR that touches doc-relevant files, regardless of branch prefix. This is intentional: previews are useful for verifying non-doc changes (e.g., a config tweak) even when no formal review is required. +- The required-status-checks list on `main` should contain only checks that always run on PRs. The right checks to require are `CI Build` (from `ci-build.yml`, runs on every PR) and `Manage review stage` (from `stage-progression.yml`, runs on every PR and silent-exits on non-`docs/` branches). **Do not add `Build site` (from `deploy.yml`) or `Build and deploy preview` (from `pr-preview.yml`) as required checks** — the former never runs on PRs and the latter only runs on path-matching PRs, so requiring them blocks PRs forever waiting for results that aren't coming. ## Scope @@ -316,7 +317,35 @@ jobs: fi ``` -### 3.6 `.github/workflows/stage-progression.yml` +### 3.6 `.github/workflows/ci-build.yml` + +Required-status-check workflow that runs on every PR. Builds the site with `npm run build` to catch broken builds before merge. Unlike `deploy.yml` (which only runs on push to main and therefore can't be a meaningful PR check) and `pr-preview.yml` (which is path-conditional and skips non-content PRs), this workflow always runs and is therefore safe to mark as a required check on `main`. + +```yaml +name: CI Build + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + +jobs: + build: + name: CI Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + - run: npm ci + - run: npm run build +``` + +### 3.7 `.github/workflows/stage-progression.yml` ```yaml name: Stage Progression @@ -419,7 +448,7 @@ jobs: if (checkboxChecked) { await removeLabel('stage:ai-editor-review'); await addLabels(['stage:director-review']); - await postComment(`āœ… **Technical edit marked complete** by the author.\n\nAdvancing to **Director review**.\n\n@usace-rmc/docs-admin please:\n1. If revisions were pushed during the technical edit, trigger a fresh checkpoint deploy of this branch\n2. Assign a member of @usace-rmc/docs-director via the Reviewers sidebar\n\nThe Director will review at the live URL.`); + await postComment(`āœ… **Technical edit marked complete** by the author.\n\nAdvancing to **Director review**.\n\n@usace-rmc/docs-admin next steps:\n1. Trigger a checkpoint deploy of branch \`${branch}\` via Actions → Deploy to GitHub Pages → Run workflow (this is the first deploy of this PR to the live site, with the DRAFT watermark)\n2. Approve the deploy at the production environment gate\n3. Post the live URL in a comment on this PR\n4. Assign a member of @usace-rmc/docs-director via the Reviewers sidebar\n\nThe Director will review at the live URL. If the Director requests changes and the author pushes fixes, re-trigger the checkpoint deploy to refresh the live URL.`); } } return; @@ -437,7 +466,7 @@ jobs: comment = `āœ… **Peer review approved** by @${reviewer}.\n\nAdvancing to **RMC Lead Civil review**.\n\n@usace-rmc/docs-admin please assign the appropriate Lead Civil via the Reviewers sidebar. The Lead Civil reviews on the preview URL.`; } else if (existingStage === 'stage:lead-civil-review') { nextStage = 'stage:ai-editor-review'; - comment = `āœ… **Lead Civil review approved** by @${reviewer}.\n\nThe document is ready to be **deployed to the live site** (watermarked) for the technical edit and Director review phases.\n\n@usace-rmc/docs-admin next steps:\n1. Trigger a checkpoint deploy of branch \`${branch}\` via Actions → Deploy to GitHub Pages → Run workflow\n2. Approve the deploy at the production environment gate\n3. Post the live URL in a comment on this PR\n4. Run the \`/technical-edit\` Claude Code skill against this PR (or assign a human technical editor)\n\nAfter the author addresses the technical edit comments and checks the completion checkbox, the document will advance to Director review.`; + comment = `āœ… **Lead Civil review approved** by @${reviewer}.\n\nAdvancing to **technical edit**.\n\n@usace-rmc/docs-admin please run the \`/technical-edit\` Claude Code skill against this PR (or assign a human technical editor). The technical edit reviews the document source MDX directly and posts inline comments on the PR — **no live deploy is needed at this stage**.\n\nAfter the author addresses the technical edit comments and checks the completion checkbox in the PR description, the document will advance to Director review and the site admin will deploy it to the live site (watermarked) at that point.`; } else if (existingStage === 'stage:director-review') { nextStage = 'stage:ready-to-merge'; comment = `āœ… **Director review approved** by @${reviewer}.\n\nThis PR is **ready for final merge and publication**.\n\n@usace-rmc/docs-admin next steps:\n1. Check out this branch (locally or via github.dev)\n2. Flip the document's \`draft\` flag to \`false\`\n3. Update \`00-version-history.mdx\` with reviewer and approver names\n4. Commit and push\n5. Merge this PR to \`main\`\n6. Approve the final production deploy in the Actions tab`; @@ -631,9 +660,11 @@ For each finding, produce: - [ ] `.github/CODEOWNERS` - [ ] `.github/pull_request_template.md` — includes technical edit checkbox - [ ] `.github/workflows/deploy.yml` — with `workflow_dispatch` + `ref` input -- [ ] `.github/workflows/pr-preview.yml` +- [ ] `.github/workflows/pr-preview.yml` — with stale-marker on build failure - [ ] `.github/workflows/pr-preview-cleanup.yml` +- [ ] `.github/workflows/ci-build.yml` — always-runs PR build check - [ ] `.github/workflows/stage-progression.yml` — Lead Civil + AI editor + checkbox detection +- [ ] Branch protection on `main` requires `CI Build` and `Manage review stage` (not `Build site` or `Build and deploy preview` — those are not appropriate as required PR checks) - [ ] `.github/ai-review/technical-editor-prompt.md` - [ ] `.claude/skills/new-revision/SKILL.md` - [ ] `.claude/skills/technical-edit/SKILL.md` diff --git a/planning/02-documentation-guide-implementation.md b/planning/02-documentation-guide-implementation.md index cb2b19d65..0b2955c93 100644 --- a/planning/02-documentation-guide-implementation.md +++ b/planning/02-documentation-guide-implementation.md @@ -82,7 +82,7 @@ This chapter and the six that follow describe the review and approval process fo Every change falls into one of four lanes based on its scope: -**Lane 1: New document.** Peer review → Lead Civil review → Technical edit → Director approval. The document is deployed to the live site (watermarked) after Lead Civil approval so the technical edit and Director review happen at the document's final URL. +**Lane 1: New document.** Peer review → Lead Civil review → Technical edit → Director approval. The peer review, Lead Civil review, and technical edit all happen against the preview URL or the source files. Only after the technical edit completes does the site admin deploy the document to the live site (watermarked) for Director review at the document's final URL. **Lane 2: Major revision.** Peer review → Lead Civil review. Entire review happens on the preview site. Site admin deploys the final version after Lead Civil approval. @@ -92,7 +92,7 @@ Every change falls into one of four lanes based on its scope: ## The draft watermark -Documents flagged as drafts display a large diagonal "DRAFT" watermark. For Lane 1, the watermark appears on the live site during the technical edit and Director review phases, signaling to any reader that the content is not yet authoritative. The watermark is removed when the site admin flips the draft flag after Director approval. +Documents flagged as drafts display a large diagonal "DRAFT" watermark. For Lane 1, the watermark appears on the live site during the Director review phase only — the document is not deployed to the live site until the technical edit is complete. The watermark signals to any reader who happens to find the live URL that the content is not yet authoritative. The watermark is removed when the site admin flips the draft flag after Director approval. For Lanes 2 and 3, the document under revision only exists on the preview site during review. The currently-published version on the live site is never watermarked. @@ -141,7 +141,7 @@ If a document revision was accidentally pushed to a branch that doesn't start wi **Required reviews.** Peer review → RMC Lead Civil review → Technical edit (AI-assisted) → Director approval. -**What happens.** The document is first visible only on the unadvertised PR preview URL, where peer review and Lead Civil review happen. After Lead Civil approval, the site admin deploys the PR branch to the live production site with the DRAFT watermark. The technical edit and Director review both happen on the live URL. After Director approval, the site admin flips the draft flag, merges the PR, and deploys the final version — removing the watermark. +**What happens.** The document is first visible only on the unadvertised PR preview URL, where peer review, Lead Civil review, and the technical edit all happen (the technical edit reads the source MDX directly via `/technical-edit` and posts inline comments — it does not need a deployed version). Only after the author marks the technical edit complete does the site admin deploy the PR branch to the live production site with the DRAFT watermark. The Director then reviews on the live URL. After Director approval, the site admin flips the draft flag, merges the PR, and deploys the final version — removing the watermark. **Example branches:** `docs/new/totalrisk-applications-guide`, `docs/new/lifesim-validation-oroville` @@ -229,7 +229,7 @@ For suggested changes (pre-filled code blocks), you can click "Commit suggestion ## The technical edit (Lane 1) -After Lead Civil approval and the checkpoint deploy, the technical edit stage begins. A team member runs the `/technical-edit` Claude Code skill, which posts inline review comments on the PR. These comments cover grammar, tense, clarity, terminology, and Section 508 compliance. +After Lead Civil approval, the technical edit stage begins. A team member runs the `/technical-edit` Claude Code skill, which reads the source MDX files directly and posts inline review comments on the PR. These comments cover grammar, tense, clarity, terminology, and Section 508 compliance. **The document is not yet deployed to the live site at this stage** — the technical edit works on source files, so the live deploy is deferred until the technical edit is complete. Address each comment the same way you address human reviewer comments — push fixes, reply, and the site admin or you can resolve threads as they're addressed. @@ -241,7 +241,7 @@ Checking this box is what advances the document to Director review. Don't check ## Where reviewers read your document -For Lane 1: peer review and Lead Civil review happen on the **preview URL**. After Lead Civil approval, the site admin deploys the document to the **live production site** (watermarked). The technical edit and Director review happen at the live URL. If you push revisions during these phases, the site admin re-deploys so the live URL stays current. +For Lane 1: peer review and Lead Civil review happen on the **preview URL**. The technical edit reads the source MDX directly via `/technical-edit` and posts inline comments on the PR — no deploy is involved. Only after you mark the technical edit complete does the site admin deploy the document to the **live production site** (watermarked) for **Director review**. If you push revisions during Director review, the site admin re-deploys so the live URL stays current. For Lanes 2, 3, and 4: all review happens on the preview URL only. @@ -331,7 +331,7 @@ The technical edit is an AI-assisted editorial review that checks the document f ## When it happens -The technical edit occurs after the RMC Lead Civil approves a Lane 1 PR and after the site admin has deployed the document to the live site (watermarked). At this point, the document has already been reviewed for technical accuracy by the peer reviewer and for technical quality by the Lead Civil. The technical edit focuses exclusively on editorial quality and accessibility compliance. +The technical edit occurs after the RMC Lead Civil approves a Lane 1 PR. At this point, the document has already been reviewed for technical accuracy by the peer reviewer and for technical quality by the Lead Civil. The technical edit focuses exclusively on editorial quality and accessibility compliance, and reads the source MDX files directly — **no live deploy is needed at this stage**. The document is only deployed to the live site after the technical edit is complete, and that deploy is for the Director review phase. ## How it works @@ -366,7 +366,7 @@ The review prompt is a versioned file in the repository at `.github/ai-review/te ## Fallback to a human editor -A site admin can route any document to a human technical editor instead of (or in addition to) the AI review. The human editor follows the same workflow as peer reviewers and Lead Civils: they're assigned to the PR, review the document (on the live URL for Lane 1), post comments, and submit their review. The author addresses comments the same way. The only difference is that advancement to Director review requires the human editor to click Approve rather than the author checking the checkbox. +A site admin can route any document to a human technical editor instead of (or in addition to) the AI review. The human editor follows the same workflow as peer reviewers and Lead Civils: they're assigned to the PR, review the document on the **preview URL** (the technical edit happens before any live deploy), post comments, and submit their review. The author addresses comments the same way. The only difference is that advancement to Director review requires the human editor to click Approve rather than the author checking the checkbox. ## Who can run the skill @@ -467,7 +467,7 @@ For Lane 1, you assign up to three people across the lifecycle: the peer reviewe ## Running a checkpoint deploy (Lane 1) -After Lead Civil approval, deploy the PR branch to the live site (watermarked): +After the author marks the technical edit complete (the PR advances to `stage:director-review`), deploy the PR branch to the live site (watermarked) for the Director's review: 1. Repo → **Actions** tab → click **Deploy to GitHub Pages** in the sidebar 2. Click **Run workflow** dropdown (upper right) @@ -475,15 +475,17 @@ After Lead Civil approval, deploy the PR branch to the live site (watermarked): 4. Click **Run workflow** 5. When the build completes, click **Review deployments** → check `production` → **Approve and deploy** 6. Verify the document on the live URL with the watermark -7. Post a comment on the PR with the live URL so the technical editor and Director know where to read +7. Post a comment on the PR with the live URL so the Director knows where to read -Re-deploy whenever the author pushes revisions during the technical edit or Director review. Post a comment noting the update. +This is the **first** time the document appears on the live site. The peer review, Lead Civil review, and technical edit all happened earlier on the preview URL or against source files; the live deploy is deferred until the document has passed editorial review. + +Re-deploy whenever the author pushes revisions during Director review. Post a comment noting the update. ## Running the technical edit -After the checkpoint deploy, run `/technical-edit` from Claude Code while on the PR branch. If you don't have Claude Code access, coordinate with a team member who does. +After Lead Civil approval (the PR advances to `stage:ai-editor-review`), run `/technical-edit` from Claude Code while on the PR branch. If you don't have Claude Code access, coordinate with a team member who does. **No deploy is required at this stage** — the technical edit reads the source MDX directly. -The AI posts inline review comments. The author addresses them and checks the PR description checkbox to advance. +The AI posts inline review comments. The author addresses them and checks the PR description checkbox to advance the PR to Director review, at which point you'll run the checkpoint deploy. ## Preparing the final merge @@ -504,7 +506,7 @@ Lane 4: no version history update needed. Every deploy pauses at the production environment gate. You receive an email. Navigate to Actions → the workflow run → Review deployments → check `production` → Approve and deploy. -A Lane 1 document may involve multiple deploys: one checkpoint after Lead Civil approval, re-deploys during technical edit/Director review, and one final deploy after merge. +A Lane 1 document may involve multiple deploys: one checkpoint after the technical edit completes (for Director review), optional re-deploys during Director review if the author pushes fixes, and one final deploy after merge. ## Handling Lane 4 PRs