flowpactworkflow contracts

Comparison

How flowpact relates to actionlint, zizmor and the lockfile tools for GitHub Actions.

ToolFocusOverlap with flowpact
actionlintDeep single-file checks: expression types, shell scripts (shellcheck), runner labels, action inputs, one level of local workflow_callMissing/unknown inputs and secrets on direct calls, needs references
zizmor, ghalintSecurity: injection, permissions, pinningNone
gh-actions-lockfile, ghasum, actionspack, GitHub's dependencies: lockPin action and workflow versions (SHAs, hashes)None — they lock what code runs, flowpact checks what data flows

Recommendation: run actionlint and flowpact together. flowpact focuses on what crosses file boundaries and matrix combinations.

Measured on the fixture repositories

The repositories under fixtures/ were linted with both tools:

Fixtureactionlintflowpact
incident-matrix — one include entry without config0 findingsFP401 naming { name: windows }, the include entry and the receiving input
deep-nesting — four levels of reusable workflows4 findingsthe same 4 at identical positions plus 9: optional→required forwarding, dropped pass-throughs, unused inputs/outputs/secrets, an output never written by its step, inherited secrets, an undefined env var
composite-actions4 findingsthe same 4 at identical positions plus unused action inputs/outputs
clean00

What only flowpact reports

  • per-matrix-combination evaluation of bindings (FP401, FP402);
  • values forwarded from optional inputs into required ones (FP107);
  • dead inputs, secrets and outputs computed across all callers (FP104, FP106, FP203, FP303);
  • step outputs read but never written to $GITHUB_OUTPUT (FP304);
  • what secrets: inherit actually needs (FP204);
  • call cycles and nesting depth across the whole repository (FP601, FP602);
  • flowpact trace for any value, in both directions.

On this page