Check drift in CI
Keep a mock honest covers what apifae diff finds and
why it checks two things at once. This guide is the other half: wiring that
check into GitHub Actions so it runs on every pull request, or every night,
without anyone remembering to run it by hand.
apifae/action is a small GitHub Action
that installs the CLI and runs apifae diff for you:
steps:
- name: Check the API for drift
uses: apifae/action@v1
with:
url: https://api.example.com
That checks https://api.example.com against the APIFae workspace at the
root of the repository — the apifae.yaml and mocks/ that apifae up
would serve locally. Point working-directory at it if the workspace lives
somewhere else in the repository.
It supports Linux and macOS runners. On Windows it refuses immediately, with
one ::error:: line saying so, rather than failing partway through an
install that was never going to work.
What each exit code does in CI
The action reads the same three exit codes As a CI
gate describes, and turns each into a
result output:
| Exit | result |
The step |
|---|---|---|
| 0 | clean |
passes |
| 1 | drift |
fails |
| 2 | error |
fails |
Both 1 and 2 fail the step — a pull request is blocked either way — but they
are not the same finding. Exit 1 means the API answered and something about
it disagrees with your mocks or your spec. Exit 2 means the check could not
run at all: connection refused, a timeout, a 401 or a 403. Read the job's
result output, or its log, to tell them apart; see As a CI
gate and the exit-code
table for what each one means for diff itself,
and Troubleshooting for the fix when a
run exits 2.
The full output — what apifae diff prints on the command line — is written
to the job's step summary as well as its log, so a failing check is readable
from the pull request without opening the raw log.
Nightly, against staging
A pull request only runs the check on the code that pull request touches. The API itself can drift on its own — a deploy on a Tuesday, a config change with no matching commit — in a week where nobody happens to open a pull request at all. A scheduled run catches that:
name: nightly contract check
on:
schedule:
- cron: '17 3 * * *'
workflow_dispatch: {}
jobs:
diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: apifae/action@v1
with:
url: ${{ vars.STAGING_URL }}
workflow_dispatch is there so the same check can be run on demand — right
after a deploy, rather than waiting for 03:17 UTC to find out whether it
worked.
Pinning a version
version defaults to latest, which is the right default for a check you
want to keep up with the CLI's own bug fixes. Pin it once the check is one you
rely on:
steps:
- uses: apifae/action@v1
with:
url: https://api.example.com
version: 0.5.0