CI/CD Integration
GitHub Actions (Recommended)
Using the Official Action
The easiest way to run Axiomatic in CI is with the official GitHub Action. It runs your tests, posts a summary comment on the PR, and outputs GitHub annotations on the diff -- all without needing an Axiomatic account.
# .github/workflows/axiomatic.yml
name: Axiomatic
on:
pull_request:
branches: [main]
permissions:
pull-requests: write
jobs:
axiomatic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: exalto-ai/axiomatic@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}The Action handles everything: installs the CLI, runs tests, posts a PR comment with a results table, and sets the correct exit code. No platform login or GitHub App required.
Action Inputs
| Input | Description | Default |
|---|---|---|
anthropic-api-key | Anthropic API key | -- |
openai-api-key | OpenAI API key | -- |
args | Extra arguments passed to axm run | "" |
comment | Post a summary comment on the PR | "true" |
token | GitHub token for PR comments | GITHUB_TOKEN |
platform-token | Axiomatic platform token for dashboard sync (optional) | -- |
With Caching
Add result caching to reduce costs and speed up runs:
# .github/workflows/axiomatic.yml
name: Axiomatic
on:
pull_request:
branches: [main]
push:
branches: [main]
permissions:
pull-requests: write
jobs:
axiomatic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: .axiomatic/cache.db
key: axiomatic-${{ hashFiles('axiomatic/**/*.yml') }}-${{ github.sha }}
restore-keys: |
axiomatic-${{ hashFiles('axiomatic/**/*.yml') }}-
axiomatic-
- uses: exalto-ai/axiomatic@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
args: "--bail"Running Only Security Tests on PRs
Use args to filter by tag:
- uses: exalto-ai/axiomatic@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
args: "--tag security --bail"With Dashboard Sync
To optionally send results to the Axiomatic dashboard for history and trend tracking, add your platform token:
- uses: exalto-ai/axiomatic@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
platform-token: ${{ secrets.AXM_PLATFORM_TOKEN }}Manual Setup (Without the Action)
If you prefer not to use the composite action, you can set up the workflow manually:
# .github/workflows/axiomatic.yml
name: Axiomatic
on:
pull_request:
branches: [main]
permissions:
pull-requests: write
jobs:
axiomatic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install -g @exalto/axiomatic
- name: Validate test files
run: axm validate
- name: Run Axiomatic tests
run: axm run --format github --bail
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}The --format github flag outputs results as GitHub Actions annotations, so violations appear inline on the PR diff.
To add a PR comment with the manual approach, use a sticky comment action:
- name: Run Axiomatic tests
id: axiomatic
run: |
axm run --format github 2>&1 | tee axiomatic-output.txt
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Comment on PR
if: always() && github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@v2
with:
path: axiomatic-output.txtGitLab CI
# .gitlab-ci.yml
axiomatic:
stage: test
image: node:22
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
cache:
key: axiomatic-$CI_COMMIT_REF_SLUG
paths:
- .axiomatic/cache.db
before_script:
- npm install -g @exalto/axiomatic
script:
- axm validate
- axm run --bail
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"CircleCI
# .circleci/config.yml
version: 2.1
jobs:
axiomatic:
docker:
- image: cimg/node:22.0
steps:
- checkout
- restore_cache:
keys:
- axiomatic-{{ checksum "axiomatic.yml" }}
- axiomatic-
- run:
name: Install Axiomatic
command: npm install -g @exalto/axiomatic
- run:
name: Run Axiomatic tests
command: axm run --bail
environment:
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
- save_cache:
key: axiomatic-{{ checksum "axiomatic.yml" }}
paths:
- .axiomatic/cache.db
workflows:
test:
jobs:
- axiomaticJenkins
// Jenkinsfile
pipeline {
agent any
environment {
ANTHROPIC_API_KEY = credentials('anthropic-api-key')
}
stages {
stage('Axiomatic') {
steps {
sh 'npm install -g @exalto/axiomatic'
sh 'axm validate'
sh 'axm run --bail'
}
}
}
}Exit Codes
All CI integrations can rely on Axiomatic's exit codes:
| Code | Meaning | CI behavior |
|---|---|---|
0 | All tests passed | Pipeline passes |
1 | One or more tests failed | Pipeline fails |
2 | Configuration error or provider failure | Pipeline fails |
Exit code 1 is returned when any test has a fail status, regardless of severity. Exit code 2 indicates a configuration or provider error.
Best Practices
Cache test results between runs. This is the single most impactful optimization. Caching means unchanged tests are served at zero cost, and CI runs complete faster.
Use --bail in CI. Stop on the first failure rather than spending API credits on remaining tests when the build will fail anyway.
Use --format github for GitHub Actions. Violations appear as inline annotations on the PR diff, making them impossible to miss.
Run axm validate before axm run. Validate catches YAML errors and missing fields without making API calls. Fail fast on configuration issues.
Use tags for conditional execution. Run --tag security on every PR, but --tag architecture only on nightly builds or main branch pushes.
Set concurrency limits. Use --parallel to control how many tests run concurrently. Lower values reduce peak API usage; higher values reduce wall-clock time.
Dry-run for cost estimation. Use axm run --dry-run to estimate costs before committing to a full run in a new environment.