Skip to content

feat: affected flows, evidence bundles and webhook notifications - #5

Merged
piekstra merged 3 commits into
mainfrom
piekstra/ci-helpers
Oct 7, 2026
Merged

piekstra merged 3 commits into
mainfrom
piekstra/ci-helpers

Conversation

@piekstra

@piekstra piekstra commented Oct 7, 2026

Copy link
Copy Markdown
Member

Summary

Three CLI capabilities for running Lest in CI, documented in the new docs/ci.md:

  • lest affected --base <ref> lists the flows a change touches. A flow counts when a changed file matches its affects: globs, when its own file changed, or when it calls an affected flow, so suites are included. Changes are taken from the merge base, plus staged, unstaged and untracked files, with paths relative to the project root. --id prints ids for scripts.
  • lest bundle <run> -o evidence.zip zips the run's report and artifacts with a manifest.json that lists every file's SHA-256.
  • Webhook notifications come from notify: in lest.yaml, sent on failed, passed or always. The format is a json summary or a slack incoming-webhook message. The URL can reference secrets. Notifications go out after the report is written and time out after 10s. They never print the URL, and each one emits a notified event that the CLI shows.

Evidence

make check passes. A new runner test, failed_runs_notify_webhooks_with_a_summary, posts to a local listener and checks three things: the secret inside the webhook URL is resolved, the summary carries the failing step's headline, and the event never includes the URL.

Dogfooded against the examples. After touching app/server.mjs:

$ lest affected --base origin/main
FLOW            | WHY
connect-weather | calls sign-in
dashboard       | app/server.mjs, calls sign-in
everything      | calls dashboard, calls plants-api
plants-api      | app/server.mjs
sign-in         | app/server.mjs

lest bundle on a plants-api run wrote a zip containing report.json, the service log and manifest.json.

`lest affected --base <ref>` lists the flows a change touches (affects
globs, the flow file itself, and callers of affected flows). `lest bundle`
zips a run's report and artifacts with a manifest of checksums. Projects
can notify webhooks after a run, as a JSON summary or a Slack-compatible
message.
@piekstra

piekstra commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

A review found 14 issues. Dispositions:

  1. The docs' CI loop ignored a failing lest affected. The snippet now captures the output on its own line under set -e. The docs also explain that on the base branch the merge base is HEAD.
  2. Renames reported only the new path. Now uses --no-renames, so a rename counts as both paths. Verified with git mv.
  3. A broken flow file was silently left out. lest affected exits 2 and prints the validation errors.
  4. Non-ASCII paths were dropped. Git output is read with -z. Verified with src/ünicode.txt.
  5. diff.relative=true broke the changed-file list. Now passes --no-relative. Untracked files are listed from the repository root.
  6. The bundle included unredacted files. It now contains only report.json and the files the report lists: artifacts, service logs and demo files. Verified that an undeclared file a step wrote stays out. The docs now say binary artifacts are included as they are.
  7. Notifications blocked one after another. They are sent concurrently, so the slowest one bounds the wait at 10s.
  8. The Slack message was not escaped. &, < and > are escaped in every interpolated value, with a test.
  9. The bundle read whole files into memory. Files are now streamed into the zip and the hash, and large_file is set for files of 4 GiB or more.
  10. The manifest name could collide. It can no longer collide, since only listed files (under artifacts/ plus report.json) go in. The zip is written to a temp file and renamed.
  11. Browser scripts and lest.yaml were ignored. A changed browser script: affects its flow, and a changed lest.yaml affects every flow. Both are documented, with tests.
  12. * crossed /. affects: globs now use literal_separator, so * stays within a directory and ** crosses them. Documented, with a test.
  13. Missing files were skipped silently. Listed files that are missing or outside the run directory are now recorded in the manifest's missing.
  14. Notified events arrive after run_finished. That ordering is intended and is now documented on the event.

make check passes.

@piekstra
piekstra marked this pull request as ready for review October 7, 2026 14:22
@piekstra
piekstra merged commit 1e631c7 into main Oct 7, 2026
5 checks passed
@piekstra
piekstra deleted the piekstra/ci-helpers branch October 7, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant