GitHub Actions Integration¶
Automate contract validation, breaking-change detection and publishing in your CI/CD pipeline using the official Pacto CLI GitHub Action.
Quick start¶
The action is command-driven: command: setup installs the pacto binary for later run: steps, while command: validate, diff, push or doc run those operations natively.
name: Contract CI
on:
pull_request:
paths:
- 'pacto.yaml'
- 'interfaces/**'
- 'configuration/**'
- 'policy/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Pacto CLI
uses: TrianaLab/pacto-actions@v1
with:
command: setup
- name: Validate contract
run: pacto validate .
Common workflows¶
The quick start already runs pacto validate . on every pull request to catch schema and cross-field errors before merge. The workflows below add breaking-change detection and publishing.
Detect breaking changes¶
Compare the PR contract against the published version and fail the job on a breaking change. pacto diff takes the old contract first and the new one second, and exits non-zero on a BREAKING result (see change classification rules):
- name: Check for breaking changes
uses: TrianaLab/pacto-actions@v1
with:
command: diff
old: oci://ghcr.io/acme/my-service-pacto
new: .
comment-on-pr: 'true'
fail-on-breaking defaults to true, so the step blocks the merge on a breaking change and comment-on-pr posts the diff. To gate in a plain run: step instead, pacto diff oci://ghcr.io/acme/my-service-pacto . exits non-zero on the same result.
comment-on-pr posts as the workflow's GITHUB_TOKEN, which is read-only by default, so the job has to be granted the permission or the comment fails with a 403 while the diff itself passes:
Publish on release¶
Push the contract bundle to an OCI registry when a release is created:
name: Publish Contract
on:
release:
types: [published]
jobs:
push:
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: actions/checkout@v4
- name: Install Pacto CLI
uses: TrianaLab/pacto-actions@v1
with:
command: setup
- name: Push contract
uses: TrianaLab/pacto-actions@v1
with:
command: push
ref: oci://ghcr.io/${{ github.repository }}-pacto
path: .
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Environment-specific validation¶
Validate the contract with environment-specific overrides:
Action reference¶
The tables below cover TrianaLab/pacto-actions@v1 (currently v1.8.2).
Inputs¶
| Input | Applies to | Default | What it does |
|---|---|---|---|
command |
every command | (required) | setup, validate, diff, push or doc |
version |
setup |
latest |
Pacto version to install (e.g. v3.2.1) |
github-token |
every command | ${{ github.token }} |
Passed to the command as GH_TOKEN |
cache |
every command | true |
Reuse the OCI bundle cache (~/.cache/pacto/oci/) across runs |
path |
validate, push, doc |
. |
Contract directory or oci:// reference |
old |
diff |
— | Baseline contract: directory path or oci:// reference |
new |
diff |
— | Updated contract: directory path or oci:// reference |
output-format |
diff |
text |
text, json or markdown |
fail-on-breaking |
diff |
true |
Fail the step when pacto diff exits non-zero |
ref |
push |
— | Target OCI reference (e.g. oci://ghcr.io/org/name:tag) |
registry |
push |
— | Registry hostname to authenticate against (e.g. ghcr.io) |
username |
push |
— | Registry username |
password |
push |
— | Registry password or token |
values |
validate, diff, doc, push |
— | Values file(s) merged into the contract — newline-separated, last wins |
set |
validate, diff, doc, push |
— | Inline contract values, newline-separated (e.g. service.version=2.0.0) |
old-values |
diff |
— | Values file(s) merged into the old contract only |
old-set |
diff |
— | Inline values set on the old contract only |
new-values |
diff |
— | Values file(s) merged into the new contract only |
new-set |
diff |
— | Inline values set on the new contract only |
output-path |
doc |
— | File path to save the generated markdown |
comment-on-pr |
diff, doc |
false |
Post the output as a pull-request comment |
add-to-summary |
doc |
true |
Add the documentation to the GitHub step summary |
Outputs¶
Give the step an id to read its outputs.
| Output | Set by | Value |
|---|---|---|
version |
setup |
The exact Pacto version installed |
has-breaking-changes |
diff |
"true" or "false" |
diff-output |
diff |
The full diff output, in output-format |
doc-output |
doc |
The generated markdown documentation |
has-breaking-changes is set from the CLI exit code. pacto diff exits non-zero
on a BREAKING classification, so a POTENTIAL_BREAKING result reads "false".
A diff that fails to run — an unresolvable reference, an unparseable contract —
also exits non-zero and so also reads "true"; check the step log before treating
it as a contract verdict. The output is written whether or not
fail-on-breaking stops the step, so you can gate on it yourself:
- name: Check for breaking changes
id: contract-diff
uses: TrianaLab/pacto-actions@v1
with:
command: diff
old: oci://ghcr.io/acme/my-service-pacto
new: .
fail-on-breaking: 'false'
- name: Require an approved exception
if: steps.contract-diff.outputs.has-breaking-changes == 'true'
run: exit 1
Further reading¶
For advanced configuration options, see the pacto-actions repository.