-
Notifications
You must be signed in to change notification settings - Fork 0
201 lines (175 loc) · 8.5 KB
/
Copy pathgenerate.yaml
File metadata and controls
201 lines (175 loc) · 8.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
name: Generate Rules from Docs
# Regenerates docs-driven skill rules and opens a sync PR. Triggered when the
# documentation repo deploys (repository_dispatch), on a weekly safety-net
# cron, or manually. See docs/plans-archive/docs-driven-skills.md (Phase 2).
#
# Offline-first: the docs repo is checked out and built in-job; the generator
# reads the local build output and never fetches docs over the network.
on:
repository_dispatch:
types: [docs-updated]
schedule:
# Mondays 09:17 UTC — safety net in case a dispatch is missed.
- cron: '17 9 * * 1'
workflow_dispatch:
inputs:
docs_ref:
description: 'Docs ref to build (branch, tag, or commit SHA)'
required: false
default: 'main'
permissions:
contents: write
pull-requests: write
issues: write
concurrency:
group: generate-rules
cancel-in-progress: false
jobs:
generate:
name: Generate and open sync PR
runs-on: ubuntu-latest
steps:
- name: Mint app token
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.SKILLS_SYNC_APP_ID }}
private-key: ${{ secrets.SKILLS_SYNC_APP_PRIVATE_KEY }}
- name: Checkout skills
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: skills
fetch-depth: 0
# Use the App token so the branch push (and thus the auto-PR) is
# attributed to the App and triggers the validate workflow.
token: ${{ steps.app-token.outputs.token }}
- name: Resolve docs ref
id: docsref
run: |
REF="${{ github.event.client_payload.sha || github.event.inputs.docs_ref || 'main' }}"
echo "ref=$REF" >> "$GITHUB_OUTPUT"
echo "Docs ref: $REF"
- name: Checkout documentation
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: HarperFast/documentation
ref: ${{ steps.docsref.outputs.ref }}
path: documentation
# documentation is a public repo, so the default job token reads it.
# Full history (fetch-depth: 0) so the sync PR body can resolve the
# docs commit range since each rule's recorded baseline.
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: skills/.nvmrc
- name: Build documentation (produces flat-markdown under build/)
working-directory: documentation
run: |
npm ci
npm run build
- name: Install skills dependencies
working-directory: skills
run: npm ci
- name: Capture pre-sync provenance
working-directory: skills
# Snapshot each rule's recorded baseline (sourceCommit/inputHash) and
# which rules are stale, BEFORE generation overwrites the frontmatter.
# The PR step reads this snapshot to explain why each rule changed.
# Non-strict: this never blocks the sync — the generator is the gate.
run: npm run sync:report -- --docs-path ../documentation --out ../sync-provenance.json
- name: Generate rules
working-directory: skills
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: npm run generate -- --docs-path ../documentation
- name: Validate
working-directory: skills
run: |
npm run format:check
npm run build
node scripts/validate-skills.mjs
node scripts/generation/validate-generated.mjs --docs-path ../documentation
- name: Report generation failure
if: failure()
working-directory: skills
env:
GH_TOKEN: ${{ steps.app-token.outputs.token || github.token }}
run: |
set -euo pipefail
# Resolve the actual docs commit SHA (falls back to the ref if the
# documentation checkout failed before we could read HEAD).
DOCS_SHA=$(git -C ../documentation rev-parse HEAD 2>/dev/null || echo "${{ steps.docsref.outputs.ref }}")
SHORT="${DOCS_SHA:0:7}"
TITLE="Auto-sync generation failure (${SHORT})"
# Idempotent by docs SHA: if an open issue for this SHA already
# exists, add a comment rather than opening a duplicate.
EXISTING=$(gh issue list --state open --json number,title \
--jq ".[] | select(.title == \"${TITLE}\") | .number" 2>/dev/null | head -1 || echo "")
if [ -n "$EXISTING" ]; then
echo "Existing failure issue #${EXISTING} — appending comment."
gh issue comment "$EXISTING" --body \
"Generation failed again for \`${DOCS_SHA}\` at $(date -u +%Y-%m-%dT%H:%M:%SZ). Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details."
else
NEW_ISSUE_URL=$(gh issue create \
--title "${TITLE}" \
--body "Auto-sync generation failed for docs SHA \`${DOCS_SHA}\`.
Opened automatically by \`.github/workflows/generate.yaml\`. Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for the full error.
**Common causes and fixes (Story 4 in docs/plans-archive/docs-driven-skills.md):**
- Source file renamed or moved — update \`sources[].path\` in \`rules.manifest.yaml\`.
- Section heading renamed or removed — update \`sources[].section\`.
- Must-cover assertion no longer in source — update \`must_cover\` or the section changed.
After fixing, regenerate locally (\`npm run generate -- --docs-path <docs>\`) and open a fix PR.")
echo "Opened failure issue ${NEW_ISSUE_URL}"
# Set the org-level "Bug" issue type (replaces the retired `bug` label).
NEW_ISSUE_NUM=$(printf '%s' "$NEW_ISSUE_URL" | grep -oE '[0-9]+$')
if [ -n "$NEW_ISSUE_NUM" ]; then
gh api -X PATCH "/repos/${{ github.repository }}/issues/${NEW_ISSUE_NUM}" \
-f type="Bug" || echo "Could not set issue type (non-fatal)."
fi
fi
- name: Open or update sync PR
working-directory: skills
env:
# The App token (not the default job token) ensures the auto-PR
# triggers the validate workflow — PRs opened by the job token do
# not trigger other workflows.
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
set -euo pipefail
# The generator only writes rule bodies + AGENTS.md under this path.
if git diff --quiet -- harper-best-practices; then
echo "No changes — skills are already in sync with docs."
exit 0
fi
DOCS_SHA=$(git -C ../documentation rev-parse HEAD)
SHORT=${DOCS_SHA:0:7}
BRANCH="auto/docs-sync"
git config user.name "${{ steps.app-token.outputs.app-slug }}[bot]"
git config user.email "${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com"
# Single rolling branch: at most one open auto-sync PR at a time. If
# docs change again before it merges, the same PR is force-updated.
git checkout -B "$BRANCH"
git add harper-best-practices
git commit -m "docs: regenerate rules from documentation@${SHORT}"
# Force is intentional: each run replaces the rolling branch's prior
# commit in place so the open sync PR always reflects the latest docs.
git push --force origin "$BRANCH"
# Compose a provenance-rich body from the pre-sync snapshot: which
# rules changed, the docs commit each was last synced from, and the
# full docs commit range since the oldest such baseline.
BODY="$(npm run --silent sync:report -- \
--docs-path ../documentation \
--format pr-body \
--from ../sync-provenance.json)"
STATE=$(gh pr view "$BRANCH" --json state --jq .state 2>/dev/null || echo "")
if [ "$STATE" = "OPEN" ]; then
echo "Existing sync PR updated."
gh pr edit "$BRANCH" \
--title "docs: regenerate rules from documentation@${SHORT}" \
--body "$BODY"
else
gh pr create --base main --head "$BRANCH" \
--title "docs: regenerate rules from documentation@${SHORT}" \
--body "$BODY"
fi