Skip to content

Commit 7714617

Browse files
authored
Merge pull request #108 from USACE-RMC/feature/review-workflow-infrastructure
Defer Lane 1 checkpoint deploy until after technical edit
2 parents e56aae0 + 5772edb commit 7714617

5 files changed

Lines changed: 97 additions & 22 deletions

File tree

.github/workflows/ci-build.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: CI Build
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
build:
12+
name: CI Build
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: '20'
19+
cache: 'npm'
20+
- run: npm ci
21+
- run: npm run build

.github/workflows/pr-preview.yml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,33 @@ jobs:
5050
script: |
5151
const prNumber = context.issue.number;
5252
const url = `https://usace-rmc.github.io/RMC-Software-Documentation-Previews/pr-${prNumber}/`;
53+
const sha = context.payload.pull_request.head.sha.substring(0, 7);
5354
const marker = '<!-- pr-preview-bot-comment -->';
54-
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._`;
55+
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._`;
5556
const comments = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber });
5657
const existing = comments.data.find(c => c.user.type === 'Bot' && c.body.includes(marker));
5758
if (existing) {
5859
await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body });
5960
} else {
6061
await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body });
6162
}
63+
- name: Mark preview as stale on failure
64+
if: failure()
65+
uses: actions/github-script@v7
66+
with:
67+
script: |
68+
const prNumber = context.issue.number;
69+
const sha = context.payload.pull_request.head.sha.substring(0, 7);
70+
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
71+
const marker = '<!-- pr-preview-bot-comment -->';
72+
const comments = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber });
73+
const existing = comments.data.find(c => c.user.type === 'Bot' && c.body.includes(marker));
74+
if (existing) {
75+
// Strip any prior stale warning before appending a fresh one
76+
const cleanBody = existing.body.split('\n\n⚠️')[0];
77+
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}).`;
78+
await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body: newBody });
79+
} else {
80+
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}).`;
81+
await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, body });
82+
}

.github/workflows/stage-progression.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ jobs:
9898
if (checkboxChecked) {
9999
await removeLabel('stage:ai-editor-review');
100100
await addLabels(['stage:director-review']);
101-
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.`);
101+
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.`);
102102
}
103103
}
104104
return;
@@ -116,7 +116,7 @@ jobs:
116116
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.`;
117117
} else if (existingStage === 'stage:lead-civil-review') {
118118
nextStage = 'stage:ai-editor-review';
119-
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.`;
119+
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.`;
120120
} else if (existingStage === 'stage:director-review') {
121121
nextStage = 'stage:ready-to-merge';
122122
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`;

planning/01-repo-implementation.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ This document describes every structural change to the `usace-rmc/rmc-software-d
99
1. Author opens PR with branch prefix `docs/new/`. Preview workflow publishes to unadvertised preview URL.
1010
2. Peer reviewer reviews on **preview URL**, approves.
1111
3. RMC Lead Civil reviews on **preview URL**, approves.
12-
4. Site admin triggers checkpoint deploy of PR branch to **production URL** (watermarked).
13-
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.
12+
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.
13+
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.
1414
6. Director reviews on **live URL**, approves with one click.
1515
7. Site admin flips draft flag to `false`, merges PR to `main`, approves final deploy (watermark removed).
1616

@@ -31,6 +31,7 @@ This document describes every structural change to the `usace-rmc/rmc-software-d
3131
- The AI technical edit stage advances when the author checks a task list checkbox in the PR description, not when a reviewer clicks approve.
3232
- 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.
3333
- 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.
34+
- 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.
3435

3536
## Scope
3637

@@ -316,7 +317,35 @@ jobs:
316317
fi
317318
```
318319
319-
### 3.6 `.github/workflows/stage-progression.yml`
320+
### 3.6 `.github/workflows/ci-build.yml`
321+
322+
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`.
323+
324+
```yaml
325+
name: CI Build
326+
327+
on:
328+
pull_request:
329+
types: [opened, synchronize, reopened]
330+
331+
permissions:
332+
contents: read
333+
334+
jobs:
335+
build:
336+
name: CI Build
337+
runs-on: ubuntu-latest
338+
steps:
339+
- uses: actions/checkout@v4
340+
- uses: actions/setup-node@v4
341+
with:
342+
node-version: '20'
343+
cache: 'npm'
344+
- run: npm ci
345+
- run: npm run build
346+
```
347+
348+
### 3.7 `.github/workflows/stage-progression.yml`
320349

321350
```yaml
322351
name: Stage Progression
@@ -419,7 +448,7 @@ jobs:
419448
if (checkboxChecked) {
420449
await removeLabel('stage:ai-editor-review');
421450
await addLabels(['stage:director-review']);
422-
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.`);
451+
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.`);
423452
}
424453
}
425454
return;
@@ -437,7 +466,7 @@ jobs:
437466
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.`;
438467
} else if (existingStage === 'stage:lead-civil-review') {
439468
nextStage = 'stage:ai-editor-review';
440-
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.`;
469+
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.`;
441470
} else if (existingStage === 'stage:director-review') {
442471
nextStage = 'stage:ready-to-merge';
443472
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:
631660
- [ ] `.github/CODEOWNERS`
632661
- [ ] `.github/pull_request_template.md` — includes technical edit checkbox
633662
- [ ] `.github/workflows/deploy.yml` — with `workflow_dispatch` + `ref` input
634-
- [ ] `.github/workflows/pr-preview.yml`
663+
- [ ] `.github/workflows/pr-preview.yml` — with stale-marker on build failure
635664
- [ ] `.github/workflows/pr-preview-cleanup.yml`
665+
- [ ] `.github/workflows/ci-build.yml` — always-runs PR build check
636666
- [ ] `.github/workflows/stage-progression.yml` — Lead Civil + AI editor + checkbox detection
667+
- [ ] 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)
637668
- [ ] `.github/ai-review/technical-editor-prompt.md`
638669
- [ ] `.claude/skills/new-revision/SKILL.md`
639670
- [ ] `.claude/skills/technical-edit/SKILL.md`

0 commit comments

Comments
 (0)