Skip to content

specshield26/bdct-action

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SpecShield BDCT — GitHub Action

GitHub Marketplace License

Run SpecShield Bi-Directional Contract Testing in your GitHub Actions pipelines. Publish provider OpenAPI specs, publish consumer contracts, verify compatibility, and gate deployments with can-i-deploy — all without hand-writing the YAML.

- uses: specshield26/bdct-action@v1
  with:
    command: can-i-deploy
    org: ${{ vars.SPECSHIELD_ORG }}
    service: payment-service
    version: ${{ github.sha }}
    env: production
    api-token: ${{ secrets.SPECSHIELD_API_KEY }}

If the contract is broken, the action exits non-zero and the deploy job is skipped.


What this action does

It is a thin, audited wrapper around the specshield CLI (v3 and up). Every BDCT subcommand the CLI exposes is reachable here through the command input. The action:

  1. Sets up Node 20 on the runner.
  2. Caches and installs specshield from npm at the requested version.
  3. Runs the chosen BDCT subcommand with --json so structured output is exposed back to your workflow.
  4. Sets typed outputs for the two commands users branch on (can-i-deploydeployable, verifyverification-id and status).
  5. Writes a one-line result into the GitHub Step Summary so the run page tells you what happened at a glance.

It is a composite action — no Docker images, no build-time dependencies, runs on ubuntu-*, macos-*, and windows-* runners (via the bundled bash shell on Windows).


Quick start

1. Provision an API key

Sign up at specshield.io, generate an API key, and add it to your repo as SPECSHIELD_API_KEY. The Pro plan is required for BDCT operations.

Settings → Secrets and variables → Actions → New repository secret

Optionally, store your organization key as a repo or org variable named SPECSHIELD_ORG so it does not have to be repeated on every step.

2. Drop the action into a workflow

The three idiomatic entry points are in examples/ — copy any of them straight into your .github/workflows/ folder:

Workflow When it fires What it does
pr-check.yml Every pull request that changes the OpenAPI spec Verifies the change against published consumers and fails the check if it would break someone.
publish-on-merge.yml Every push to main Publishes the latest provider spec; auto-verifies all known consumers.
can-i-deploy-gate.yml Just before the deploy step in your release workflow Hard-gates production deploys on contract compatibility.

Inputs

Input Required Default Description
command yes One of publish-provider, publish-consumer, verify, can-i-deploy, matrix, list-providers, list-consumers.
api-token yes Your SpecShield API key. Always pass via a secret.
org yes Organization key. Required by every backend endpoint.
provider command-dependent Provider service name.
consumer command-dependent Consumer service name.
service for can-i-deploy Service to gate (consumer or provider — the engine checks both directions).
version for publish + can-i-deploy Version tag. Use ${{ github.sha }} for immutable per-commit publishing.
consumer-version for verify Consumer version to verify.
provider-version for verify Provider version to verify against.
spec for publish-provider Path to provider OpenAPI spec.
contract for publish-consumer Path to consumer contract (OpenAPI YAML/JSON or Pact JSON).
format optional, for publish-consumer OPENAPI Contract format: OPENAPI or PACT.
branch optional Git branch tag stored alongside a provider spec (purely informational).
env optional Environment label (e.g. staging, production).
cli-version optional 3.1.1 npm version of the specshield CLI to install. Pinned by default for reproducible builds; pass latest to follow the newest published release.
server optional https://specshield.io API base URL. Override only for self-hosted or staging environments.
fail-on-error optional true Set false if you want to inspect outputs in a later step before failing the job.

Outputs

Output Set after Description
json every command Raw JSON response from the CLI. Parse with fromJSON() or jq.
exit-code every command 0 clean / deployable, 1 breaking / not deployable, 2 config or runtime error.
deployable can-i-deploy true or false.
verification-id verify Numeric id of the verification record.
status verify COMPATIBLE or INCOMPATIBLE.

Branching on outputs

- id: gate
  uses: specshield26/bdct-action@v1
  with:
    command: can-i-deploy
    org: ${{ vars.SPECSHIELD_ORG }}
    service: payment-service
    version: ${{ github.sha }}
    env: production
    api-token: ${{ secrets.SPECSHIELD_API_KEY }}
    fail-on-error: false   # do not fail the job here

- name: Deploy
  if: steps.gate.outputs.deployable == 'true'
  run: ./deploy.sh

- name: Notify Slack on block
  if: steps.gate.outputs.deployable == 'false'
  run: |
    REASON=$(echo '${{ steps.gate.outputs.json }}' | jq -r .reason)
    curl -X POST -H 'Content-type: application/json' \
      -d "{\"text\":\"🚫 Blocked by SpecShield: $REASON\"}" \
      ${{ secrets.SLACK_WEBHOOK }}

Versioning

This action follows GitHub's recommended major-version pattern.

Tag What it tracks Recommended use
@v1 Floating tag — always points to the latest 1.x.y release Most users
@v1.0.0 Immutable per-release tag Reproducible / audited builds
@main The default branch — may be in flux Don't use in production

@v1 will receive backward-compatible features and bug fixes. Breaking changes will land on @v2.


Compatibility matrix

cli-version Notes
3.1.1 (default) Pinned by this action's v1.0.2 release. Includes the --json exit-code fix that the action's typed outputs depend on.
3.1.x Full BDCT + specshield init wizard + .specshield.yml config defaulting.
3.0.x Full BDCT but the action's --json exit-code path returns 0 even when deployable: false. Avoid — use 3.1.1 or newer.
<3.0 Not supported.

Security notes

  • API tokens must be passed via ${{ secrets.* }}. The action injects them as SPECSHIELD_API_KEY for the CLI to read; they never appear on the command line and are auto-redacted from logs by GitHub.
  • The action runs npm install -g specshield@<cli-version> on the runner. If you want a fully air-gapped build, install the CLI in a dependency-cache step yourself and call specshield directly instead.
  • Every BDCT request carries the org you configure. Cross-tenant data exposure is impossible by design; the backend rejects any request whose JWT-resolved customer does not own the given org.

License

MIT.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors