@andwhy/e2e-pipeline 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/init.js
CHANGED
|
@@ -117,8 +117,10 @@ const run = async () => {
|
|
|
117
117
|
" deployment protection",
|
|
118
118
|
" SLACK_WEBHOOK_URL — auto-heal notifications",
|
|
119
119
|
"(ANTHROPIC_API_KEY is an org-level secret inherited by all repos —",
|
|
120
|
-
"nothing to add
|
|
121
|
-
"
|
|
120
|
+
"nothing to add; if the heal agent fails to authenticate, a repo",
|
|
121
|
+
"secret of the same name overrides it.) The auto-heal workflow stays",
|
|
122
|
+
"inert until a Checkly webhook alert channel dispatches to it — the",
|
|
123
|
+
"skill walks through that.",
|
|
122
124
|
].join("\n"));
|
|
123
125
|
}
|
|
124
126
|
console.log("Next steps:");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andwhy/e2e-pipeline",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Scaffolds the full e2e testing pipeline: agent-assisted Playwright tests, CI runs against Vercel previews, and Checkly monitors that follow production deploys",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -92,8 +92,13 @@ The scaffold writes templates, not a working setup. Walk these with the user:
|
|
|
92
92
|
value from 1Password ("e2e Slack webhook"). Same value in every repo;
|
|
93
93
|
do not walk the user through creating a Slack app or webhook — routing
|
|
94
94
|
to the project channel happens via a Slack rule in Phase 5.
|
|
95
|
-
- `ANTHROPIC_API_KEY` needs **no action**: it is an
|
|
96
|
-
secret inherited by every repo
|
|
95
|
+
- `ANTHROPIC_API_KEY` usually needs **no action**: it is an
|
|
96
|
+
organization-level secret inherited by every repo — do not walk the
|
|
97
|
+
user through adding it up front. But it can fail to reach a repo
|
|
98
|
+
(org-secret scoping, or a stale stored value): if a heal run's agent
|
|
99
|
+
step fails to authenticate, have the user add a repository-level
|
|
100
|
+
`ANTHROPIC_API_KEY` — a repo secret with the same name overrides the
|
|
101
|
+
organization one.
|
|
97
102
|
5. **Existing tests under `tests/`** (unit, a11y — the scaffold lists them as
|
|
98
103
|
"outside tests/e2e"): leave `testDir` at `./tests/e2e` and give that suite
|
|
99
104
|
its own Playwright project with its own `testDir` if it should run under
|
|
@@ -181,7 +186,9 @@ overwritten):
|
|
|
181
186
|
`CHECKLY_API_KEY` and `CHECKLY_ACCOUNT_ID` for the deploy and auto-heal,
|
|
182
187
|
`VERCEL_AUTOMATION_BYPASS_SECRET` for the PR run through deployment
|
|
183
188
|
protection, `SLACK_WEBHOOK_URL` for auto-heal notifications
|
|
184
|
-
(`ANTHROPIC_API_KEY` is inherited from the organization — nothing to add
|
|
189
|
+
(`ANTHROPIC_API_KEY` is inherited from the organization — nothing to add
|
|
190
|
+
unless a heal run fails to authenticate; then a repo-level secret of the
|
|
191
|
+
same name overrides it, see Phase 0).
|
|
185
192
|
If the scaffold just created the workflows, say so explicitly and list the
|
|
186
193
|
secrets — a merge without them fails CI and looks like a pipeline bug.
|
|
187
194
|
|
|
@@ -201,7 +208,9 @@ Set up once per project:
|
|
|
201
208
|
|
|
202
209
|
1. Confirm the `SLACK_WEBHOOK_URL` repository secret from Phase 0 exists —
|
|
203
210
|
the workflow escalates nothing without it. (`ANTHROPIC_API_KEY` comes
|
|
204
|
-
from the organization automatically
|
|
211
|
+
from the organization automatically — but if the dry run in step 6 ends
|
|
212
|
+
agent-failed with an authentication error, override it with a repo-level
|
|
213
|
+
secret of the same name, per Phase 0.)
|
|
205
214
|
2. The shared `GH_DISPATCH_TOKEN` secret exists in Checkly and covers this
|
|
206
215
|
repo. This is **one-time organization setup, not yours to perform**: the
|
|
207
216
|
token (`checkly-heal-dispatch`, a fine-grained PAT) is created once and
|
|
@@ -11,7 +11,9 @@ name: Checkly auto-heal
|
|
|
11
11
|
# commit, PR, and Slack are workflow steps.
|
|
12
12
|
# Needs repo secrets CHECKLY_API_KEY, CHECKLY_ACCOUNT_ID, SLACK_WEBHOOK_URL
|
|
13
13
|
# (the org-shared e2e-channel webhook; values in 1Password); ANTHROPIC_API_KEY
|
|
14
|
-
# is inherited from the organization
|
|
14
|
+
# is inherited from the organization (a repo secret of the same name
|
|
15
|
+
# overrides it if the org value fails to authenticate). Slack messages
|
|
16
|
+
# carry an [e2e:<repo>]
|
|
15
17
|
# tag so Slack Workflow Builder rules route them from the shared channel to
|
|
16
18
|
# project channels. Setup docs: the playwright-test-pipeline skill walks
|
|
17
19
|
# through the Checkly webhook channel and the Slack rule.
|
|
@@ -310,28 +312,48 @@ jobs:
|
|
|
310
312
|
run: |
|
|
311
313
|
case "${MODE}:${CLASSIFICATION}" in
|
|
312
314
|
repeat:*)
|
|
313
|
-
|
|
315
|
+
title=":rotating_light: *\`$CHECK_NAME\` is failing again*"
|
|
316
|
+
body="A heal PR for this check merged within the last $REPEAT_WINDOW_DAYS days, so no second automatic fix was attempted. This needs a developer." ;;
|
|
314
317
|
*:healed)
|
|
315
|
-
|
|
318
|
+
title=":wrench: *\`$CHECK_NAME\` failed — fix ready for review*"
|
|
319
|
+
body="$SUMMARY" ;;
|
|
316
320
|
*:flaky)
|
|
317
|
-
|
|
321
|
+
title=":wrench: *\`$CHECK_NAME\` was flaky — test hardened, fix ready for review*"
|
|
322
|
+
body="$SUMMARY" ;;
|
|
318
323
|
*:regression)
|
|
319
|
-
|
|
324
|
+
title=":rotating_light: *\`$CHECK_NAME\` failed — production regression*"
|
|
325
|
+
body="The test is correct; the site is broken. $SUMMARY" ;;
|
|
320
326
|
*:needs-app-change)
|
|
321
|
-
|
|
327
|
+
title=":warning: *\`$CHECK_NAME\` failed — fix needs an app code change*"
|
|
328
|
+
body="$SUMMARY" ;;
|
|
322
329
|
*:not-reproducible)
|
|
323
330
|
# Transient blip, nothing to act on — summary only, no ping.
|
|
324
331
|
echo "Not reproducible — no Slack notification." >> "$GITHUB_STEP_SUMMARY"
|
|
325
332
|
exit 0 ;;
|
|
326
333
|
*)
|
|
327
|
-
|
|
334
|
+
title=":rotating_light: *\`$CHECK_NAME\` failed and the auto-heal run did not finish cleanly*"
|
|
335
|
+
body="${SUMMARY:-Check the run logs.} This needs a developer." ;;
|
|
328
336
|
esac
|
|
329
|
-
|
|
330
|
-
#
|
|
331
|
-
#
|
|
332
|
-
|
|
333
|
-
[ "$
|
|
334
|
-
|
|
337
|
+
|
|
338
|
+
# Repeat mode skips the agent, so there is no outcome classification;
|
|
339
|
+
# label it as what it is rather than defaulting to agent-failed.
|
|
340
|
+
label="${CLASSIFICATION:-agent-failed}"
|
|
341
|
+
[ "$MODE" = "repeat" ] && label="repeat-offender"
|
|
342
|
+
|
|
343
|
+
# Failing test titles, best effort from the Checkly result's embedded
|
|
344
|
+
# Playwright report — the recursive search tolerates schema changes,
|
|
345
|
+
# and an empty result simply omits the field.
|
|
346
|
+
failed_tests=""
|
|
347
|
+
if [ -f .checkly-heal/result.json ]; then
|
|
348
|
+
failed_tests=$(jq -r '[.. | objects | select((.status? == "failed") or (.outcome? == "unexpected")) | .title? // empty] | unique | .[0:3] | join(", ")' .checkly-heal/result.json 2>/dev/null || true)
|
|
349
|
+
fi
|
|
350
|
+
|
|
351
|
+
# Plain-text fallback: what notifications, search, and the Slack
|
|
352
|
+
# routing rule see — the Workflow Builder rule matches the [e2e:<repo>]
|
|
353
|
+
# tag here and forwards this text, so it stays a complete message.
|
|
354
|
+
repo="${GITHUB_REPOSITORY##*/}"
|
|
355
|
+
text="[e2e:$repo] $title — $body"
|
|
356
|
+
[ -n "$PR_URL" ] && text="$text\nPR: $PR_URL"
|
|
335
357
|
text="$text\nRun: $RUN_URL"
|
|
336
358
|
|
|
337
359
|
if [ -z "$SLACK_WEBHOOK_URL" ]; then
|
|
@@ -339,7 +361,51 @@ jobs:
|
|
|
339
361
|
printf '%b\n' "$text" >> "$GITHUB_STEP_SUMMARY"
|
|
340
362
|
exit 0
|
|
341
363
|
fi
|
|
342
|
-
|
|
364
|
+
|
|
365
|
+
# Block Kit body: title, classification/repo fields, failing tests
|
|
366
|
+
# when known, the diagnosis, and link buttons assembled per outcome —
|
|
367
|
+
# a button never renders without its target.
|
|
368
|
+
jq -n \
|
|
369
|
+
--arg text "$(printf '%b' "$text")" \
|
|
370
|
+
--arg title "$title" \
|
|
371
|
+
--arg body "$body" \
|
|
372
|
+
--arg classification "$label" \
|
|
373
|
+
--arg repo "$repo" \
|
|
374
|
+
--arg failed "$failed_tests" \
|
|
375
|
+
--arg app_change "$APP_CHANGE" \
|
|
376
|
+
--arg pr "$PR_URL" \
|
|
377
|
+
--arg run "$RUN_URL" \
|
|
378
|
+
--arg result "$RESULT_LINK" \
|
|
379
|
+
--arg rerun "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/workflows/checkly-heal.yml" \
|
|
380
|
+
'
|
|
381
|
+
def btn($label; $url): {type: "button", text: {type: "plain_text", text: $label}, url: $url};
|
|
382
|
+
{
|
|
383
|
+
text: $text,
|
|
384
|
+
blocks: (
|
|
385
|
+
[
|
|
386
|
+
{type: "section", text: {type: "mrkdwn", text: $title}},
|
|
387
|
+
{type: "section", fields: ([
|
|
388
|
+
{type: "mrkdwn", text: ("*Classification*\n" + $classification)},
|
|
389
|
+
{type: "mrkdwn", text: ("*Repository*\n" + $repo)}
|
|
390
|
+
] + (if $failed != "" then
|
|
391
|
+
[{type: "mrkdwn", text: ("*Failed test*\n" + $failed)}]
|
|
392
|
+
else [] end))}
|
|
393
|
+
]
|
|
394
|
+
+ (if $body != "" then
|
|
395
|
+
[{type: "section", text: {type: "mrkdwn", text: $body}}]
|
|
396
|
+
else [] end)
|
|
397
|
+
+ (if $app_change == "true" then
|
|
398
|
+
[{type: "context", elements: [{type: "mrkdwn", text: "Includes app-side test hooks — the PR'\''s preview run validates them."}]}]
|
|
399
|
+
else [] end)
|
|
400
|
+
+ [{type: "actions", elements: (
|
|
401
|
+
(if $pr != "" then [btn("Review PR"; $pr)] else [] end)
|
|
402
|
+
+ [btn("View run"; $run)]
|
|
403
|
+
+ (if $result != "" then [btn("Checkly result"; $result)] else [] end)
|
|
404
|
+
+ (if $classification == "agent-failed" then [btn("Re-run heal"; $rerun)] else [] end)
|
|
405
|
+
)}]
|
|
406
|
+
+ [{type: "context", elements: [{type: "mrkdwn", text: ("[e2e:" + $repo + "]")}]}]
|
|
407
|
+
)
|
|
408
|
+
}' \
|
|
343
409
|
| curl -sf --max-time 15 -X POST -H "Content-Type: application/json" -d @- "$SLACK_WEBHOOK_URL" \
|
|
344
410
|
|| echo "Slack notification failed — see summary." >> "$GITHUB_STEP_SUMMARY"
|
|
345
411
|
|