Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
@@ -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
23 changes: 22 additions & 1 deletion .github/workflows/pr-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,33 @@ 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 = '<!-- pr-preview-bot-comment -->';
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) {
await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body });
} 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 = '<!-- pr-preview-bot-comment -->';
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 });
}
4 changes: 2 additions & 2 deletions .github/workflows/stage-progression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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`;
Expand Down
43 changes: 37 additions & 6 deletions planning/01-repo-implementation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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`;
Expand Down Expand Up @@ -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`
Expand Down
Loading
Loading