Getting Started

Start with one workflow.

The smallest useful setup is one workflow, one declaration, one payload, and one validation command. The key idea is simple: compare expected workflow behavior with actual workflow behavior.

Use this when

  • You want workflow behavior checked explicitly.
  • You want reusable workflow interfaces linted.
  • You want CI artifacts that explain what changed.

Step 1

Bootstrap the first contract.

Start from the workflow file, not from a blank page. Generate the starter contract and baseline payload first, then tighten the generated files.

Bootstrap from the workflow file

just bootstrap-actionspec . ci.yml

# path inputs are also accepted
github-actionspec bootstrap \
  --repo . \
  --workflow .github/workflows/ci.yml

What it writes

  • .github/actionspec/ci/main.cue
  • tests/fixtures/ci/baseline.json
  • .github/actionspec/ci/bootstrap-ci-snippet.yml
  • A starter baseline that matches the current workflow shape.

Step 2

Validate locally.

Use just first. In this repo, just lint already includes reusable workflow interface validation through validate-callers.

Development

just docker-build
just build
just lint
just test

Contracts

just discover .
just validate-callers .
just validate-callers-report . \
  target/actionspec/callers-report.json

Payloads

just validate-repo-dashboard . ci.yml \
  .github/actionspec-artifacts/**/*.json \
  target/actionspec/validation-report.json \
  target/actionspec/dashboard.md

Step 3

Wire the action.

The action bundles the Rust binary and cue, so the workflow only needs a checkout plus payloads or fragments. This is the same validation model, just running inside GitHub Actions.

Start from the generated snippet

- uses: actions/checkout@v6

- name: Validate ci.yml contract
  id: actionspec
  uses: v4lproik/github-actionspec-rs@main
  with:
    workflow: ci.yml
    actual: tests/fixtures/ci/baseline.json
    report-file: /github/runner_temp/actionspec/current/validation-report.json
    dashboard-file: /github/runner_temp/actionspec/current/dashboard.md

- name: Upload validation artifacts
  if: ${{ always() }}
  uses: actions/upload-artifact@v4
  with:
    name: actionspec-ci-baseline
    path: |
      ${{ steps.actionspec.outputs.report-path }}
      ${{ steps.actionspec.outputs.dashboard-path }}

Then expand from there

  • Start with the generated baseline payload.
  • Switch to captured payloads when the workflow already emits useful fragments.
  • Add matrix dashboards when reviewers need diffs.
  • Add runtime-backed capture once the workflow is stable enough to enforce on protected branches.
  • Use the troubleshooting page when the first validation failures are not obvious.