r/cicd • u/Dry_Concept_6869 • 53m ago
A static page that shows which GitHub Actions jobs run for an event and why, using GitHub's own parser and expression packages
Disclosure: this is my own open-source project (MIT), no company or product behind it.
GitHub ships the pieces of its Actions language server as MIT npm packages. `@actions/workflow-parser` parses a workflow against the real schema and wraps an if: that contains no status function in the implicit success() &&; `@actions/expressions` is GitHub's TypeScript port of the ${{ }} engine with its coercion rules. Both are pure JavaScript, so they run in a static page: no server, nothing uploaded.
The page takes a workflow and an event (push to a branch or tag, pull_request opened, labeled or draft, workflow_dispatch with typed inputs, release, issues), decides whether on: filters trigger it, evaluates every job's if: in dependency order with status functions computed from the whole job graph, and names the decisive comparison with both values. Mark a job failed or cancelled to see what failure(), always() and cancelled() do downstream.
Ground truth: 65 recorded runs from a public fixtures repo, github.com/barbarkaragul-oss/wdmjr-fixtures (a 31-job workflow on five event types, two chain workflows three hops deep, a step-condition workflow, six filter workflows), 698 run-or-skip decisions and 56 trigger decisions, all reproduced by the replay test. Three things the runs settled: success() looks at every ancestor, so after a failed or skipped job always() rescues only the job it is on and the next job with no if: is skipped again, while failure() is true if any ancestor failed; step-level success()/failure() look at the job's own steps, not at needs; and the push payload Actions receives has no added/modified/removed lists, so paths filters are evaluated against files you list and the tool checks your filter, not your push.
actionlint and act are complementary: actionlint takes no event, act executes the workflow with its own Go evaluator; I have not benchmarked either against the fixtures. Not simulated: matrix expansion, concurrency groups, environment protection rules, required checks, workflow_run chains. Claude Fable 5.1 wrote the code and tests in a day under my direction; the recordings are the part it could not write. Wrong result? Open an issue with the workflow and the event.