-
-
Notifications
You must be signed in to change notification settings - Fork 5k
Expand file tree
/
Copy pathcloud-webhooks-docs-automation.yml
More file actions
231 lines (205 loc) · 9.37 KB
/
Copy pathcloud-webhooks-docs-automation.yml
File metadata and controls
231 lines (205 loc) · 9.37 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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
name: Cloud Webhooks Docs Automation
on:
repository_dispatch:
types:
- cloud-webhooks
workflow_dispatch:
inputs:
dispatch_payload:
description: "WebhooksDispatchPayload as JSON. Used for manual re-runs and testing."
required: true
type: string
jobs:
cloud-webhooks-docs-automation:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
# Use a PAT so the created PR triggers other workflows
# (the default GITHUB_TOKEN cannot trigger workflow runs)
token: ${{ secrets.REFERENCE_PAT }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: "yarn"
- name: Install monorepo dependencies
uses: ./.github/actions/cache-deps
with:
extension: cloud-webhooks-docs-automation
- name: Install www dependencies
working-directory: www
run: yarn install
- name: Build www packages
working-directory: www
run: yarn build:packages
- name: Install www/utils dependencies
working-directory: www/utils
run: yarn install
- name: Build www/utils packages
working-directory: www/utils
run: yarn build
- name: Write dispatch payload to file
id: write-payload
env:
MANUAL_PAYLOAD: ${{ inputs.dispatch_payload }}
run: |
node --input-type=module << 'EOF'
import { writeFileSync } from "fs"
const dispatched = ${{ toJSON(github.event.client_payload) }}
const manual = process.env.MANUAL_PAYLOAD
const payload = manual ? JSON.parse(manual) : dispatched
writeFileSync(
"/tmp/webhooks-dispatch.json",
JSON.stringify(payload, null, 2)
)
console.log("Payload written to /tmp/webhooks-dispatch.json")
EOF
- name: Analyze webhook changes
id: analyze
working-directory: www/utils/packages/docs-automator
run: yarn analyze-webhooks --dispatch-file /tmp/webhooks-dispatch.json --output /tmp/analysis.json
continue-on-error: true
- name: Check if documentation changes are needed
id: check
run: |
if [ "${{ steps.analyze.outcome }}" = "failure" ]; then
echo "needs_docs=false" >> "$GITHUB_OUTPUT"
exit 0
fi
node --input-type=module << 'EOF'
import { readFileSync, appendFileSync } from "fs"
const a = JSON.parse(readFileSync("/tmp/analysis.json", "utf8"))
const needed = a.affectedProjects.length > 0 ? "true" : "false"
appendFileSync(process.env.GITHUB_OUTPUT, `needs_docs=${needed}\n`)
EOF
- name: Configure git
if: steps.check.outputs.needs_docs == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Extract Claude prompt
id: extract-prompt
if: steps.check.outputs.needs_docs == 'true'
run: |
node --input-type=module << 'EOF'
import { readFileSync, appendFileSync } from "fs"
const a = JSON.parse(readFileSync("/tmp/analysis.json", "utf8"))
const prefix = "IMPORTANT: Only make file changes using the Write and Edit tools. Never use git commands to stage, commit, or push files.\n\nIMPORTANT: To load the writing-docs skill, use the Skill tool directly with skill='writing-docs'. Do NOT spawn a sub-agent or use the Task tool to load it.\n\n"
const suffix = "\n\n---\n\nIMPORTANT — final step: after applying all documentation changes, write these two files using the Write tool:\n\n1. /tmp/pr-title.txt — a single-line pull request title. It MUST start with \"docs: \", followed by a concise summary of what was changed, and MUST end with \" [automated]\". Keep it under 100 characters. Example: \"docs: document the deployment.succeeded webhook [automated]\"\n2. /tmp/pr-summary.md — a short summary (2-4 sentences, or a few bullet points) of what was updated. Plain markdown, no top-level heading.\n\nIf you made no documentation changes, do not create either file.\n"
const delimiter = "CLAUDE_PROMPT_EOF"
appendFileSync(
process.env.GITHUB_OUTPUT,
`CLAUDE_PROMPT<<${delimiter}\n${prefix}${a.claudePrompt}${suffix}\n${delimiter}\n`
)
EOF
- name: Run Claude Code to update webhooks docs
if: steps.check.outputs.needs_docs == 'true'
uses: anthropics/claude-code-base-action@beta
with:
anthropic_api_key: ${{ secrets.CLAUDE_CODE_API_TOKEN }}
prompt: ${{ steps.extract-prompt.outputs.CLAUDE_PROMPT }}
allowed_tools: "Skill,Read,Write,Edit,Glob,Grep,Bash(git diff:*,ls:*,find:*,cat:*)"
model: claude-sonnet-4-6
max_turns: 40
- name: Run prep script for cloud project
if: steps.check.outputs.needs_docs == 'true'
run: |
echo "Running prep for cloud..."
(cd "www/apps/cloud" && yarn prep) || true
- name: Run lint:content for cloud project
if: steps.check.outputs.needs_docs == 'true'
run: |
echo "Running lint:content for cloud..."
(cd "www/apps/cloud" && yarn lint:content) || true
- name: Check for documentation changes
id: changes
if: steps.check.outputs.needs_docs == 'true'
run: |
CHANGES=$(git diff --name-only -- www/apps/cloud/app www/apps/cloud/generated www/apps/cloud/sidebar.mjs \
| grep -E '\.(mdx|json|mjs)$' || true)
if [ -n "$CHANGES" ]; then
echo "has_changes=true" >> "$GITHUB_OUTPUT"
else
echo "has_changes=false" >> "$GITHUB_OUTPUT"
echo "No documentation changes found."
fi
- name: Build PR metadata
id: pr-body
if: steps.check.outputs.needs_docs == 'true' && steps.changes.outputs.has_changes == 'true'
run: |
node --input-type=module << 'EOF'
import { existsSync, readFileSync, appendFileSync } from "fs"
const a = JSON.parse(readFileSync("/tmp/analysis.json", "utf8"))
const flagged = Array.isArray(a.featureFlaggedFeatures) ? a.featureFlaggedFeatures : []
const summaryLines = Array.isArray(a.changeSummary) ? a.changeSummary : []
// Title generated by Claude, with a fallback if it is missing or malformed
let title = existsSync("/tmp/pr-title.txt")
? readFileSync("/tmp/pr-title.txt", "utf8").split("\n")[0].trim()
: ""
if (!title.startsWith("docs: ") || !title.endsWith("[automated]")) {
title = "docs: update cloud webhooks documentation [automated]"
}
const summary = existsSync("/tmp/pr-summary.md")
? readFileSync("/tmp/pr-summary.md", "utf8").trim()
: ""
const lines = [
"## Automated Cloud Webhooks Documentation Updates",
"",
`This PR contains automated documentation changes for webhook events delivered on **${a.changelogDate}**.`,
"",
summary || "_No summary was generated._",
"",
"> Review carefully before merging. Claude may have missed context or made incorrect assumptions.",
]
if (summaryLines.length > 0) {
lines.push("")
lines.push("---")
lines.push("")
lines.push("### Reported changes")
lines.push("")
for (const line of summaryLines) {
lines.push(`- ${line}`)
}
}
if (flagged.length > 0) {
lines.push("")
lines.push("---")
lines.push("")
lines.push("### ⚠️ Feature flag warning")
lines.push("")
lines.push(
"The following events appear to be gated by a feature flag. " +
"**Confirm they have been fully rolled out before merging this PR:**"
)
lines.push("")
for (const f of flagged) {
lines.push(`- ${f}`)
}
}
const body = lines.join("\n")
const delimiter = "PR_BODY_EOF"
appendFileSync(process.env.GITHUB_OUTPUT, `TITLE=${title}\n`)
appendFileSync(process.env.GITHUB_OUTPUT, `BODY<<${delimiter}\n${body}\n${delimiter}\n`)
EOF
- name: Create Pull Request
if: steps.check.outputs.needs_docs == 'true' && steps.changes.outputs.has_changes == 'true'
uses: peter-evans/create-pull-request@38e0b6e68b4c852a5500a94740f0e535e0d7ba54 # v4
with:
token: ${{ secrets.REFERENCE_PAT }}
commit-message: "chore(docs): automated cloud webhooks documentation update"
base: develop
branch: docs/cloud-webhooks-docs
branch-suffix: timestamp
title: ${{ steps.pr-body.outputs.TITLE }}
labels: "type: docs"
add-paths: |
www/apps/cloud/app
www/apps/cloud/generated
www/apps/cloud/sidebar.mjs
body: ${{ steps.pr-body.outputs.BODY }}