Checking designs in CI
Keep project files under version control and let a build pipeline solve every one of them with axm check, failing when a check fails, with a GitHub Actions example that keeps the access key in the repository's secrets.
Projects are plain .axm.json files, so they live well in a Git repository beside the drawings and the code. axm check solves many of them at once and fails with a non-zero exit code when any check fails, any file is incomplete or any file cannot be opened: the same rule a build pipeline uses for tests. This tutorial sets it up locally, then in GitHub Actions.
Step 1: check a folder of designs
axm check "designs/**/*.axm.json"
axm check takes files, folders (their *.axm.json files) and patterns with *, ?, [a-z] and **. It expands the patterns itself, the same in every shell, so quote them. It solves each file against the limits stored in it and prints one line per file:
status file checks worst utilisation / error
PASS gearbox.axm.json 42 of 42 pass 0.6254 gears.G2.pinionContactSafety
FAIL narrow.axm.json 40 of 42 pass 1.174 gears.G2.pinionContactSafety
2 files: 1 pass, 1 FAIL
The worst utilisation is the check closest to its limit (or furthest past it): 1.174 means 117 % of the limit. The exit code says what happened:
| Exit code | Meaning |
|---|---|
| 0 | Every check of every file passes |
| 4 | A check fails |
| 3 | A file could not be solved completely |
| 1 | A file could not be opened, or a pattern matched nothing |
| 5 | No licence: the access key is missing or wrong |
--json gives one row per file (its status, its checks, the failing ones by id and the worst) and a summary, for a script to read.
Step 2: an access key for the build server
axm needs an account; a build server has no browser to sign in with. Make an access key for it on your own computer, signed in:
axm license key create CI
The key is shown once: copy it. With the key in the environment variable AXM_API_KEY, axm gets a licence of its own for two days whenever it needs one. axm license key list lists your keys and axm license key delete <id> withdraws one.
Never write the key into a file of the repository. In GitHub, open the repository's Settings › Secrets and variables › Actions and add it as a repository secret named AXM_API_KEY.
Step 3: the workflow
axm comes with the Axomek Windows app. The workflow runs on a Windows runner of your own on which the app is installed, so axm is on its PATH: register the computer as a self-hosted runner with the labels self-hosted and windows. The workflow installs nothing, and the key comes only from the secrets.
Save this as .github/workflows/designs.yml:
name: Check designs
on:
push:
paths: ["designs/**"]
pull_request:
paths: ["designs/**"]
permissions:
contents: read
jobs:
check:
runs-on: [self-hosted, windows]
steps:
- uses: actions/checkout@v4
- name: Solve every design and check it against its limits
env:
AXM_API_KEY: ${{ secrets.AXM_API_KEY }}
run: axm check "designs/**/*.axm.json"
A push or pull request that changes a design now solves every project under designs. The job fails when a check fails, and its log shows the table above with the file and the check to look at.
Step 4: show what a pull request changed
axm diff compares two versions of a project: the inputs that differ, the checks that flipped and the results that moved. In a pull request, compare each changed design with its version on the base branch. Add fetch-depth: 0 to the checkout step, then this step after the check:
- name: What the changed designs do
if: github.event_name == 'pull_request'
env:
AXM_API_KEY: ${{ secrets.AXM_API_KEY }}
BASE: ${{ github.event.pull_request.base.sha }}
shell: pwsh
run: |
$changed = git diff --name-only $env:BASE HEAD -- 'designs/*.axm.json'
foreach ($file in $changed) {
if (-not (Test-Path $file)) { continue }
git show "${env:BASE}:$file" > base.axm.json 2>$null
if ($LASTEXITCODE -ne 0) { "$file is new"; continue }
"== $file"
axm diff base.axm.json $file
if ($LASTEXITCODE -gt 1) { exit $LASTEXITCODE }
}
exit 0
axm diff exits with 1 when the projects differ, which is the expected case here; only 2, a file that cannot be read, fails the step.
Tips
- Put the limits in the projects: the checks use each project's own limits (for a shaft, Limits for the checks in its Material tab), so a design is checked against what its engineer set.
- An agent that edits the designs can run the same check through the MCP tool
axm_checkbefore it hands the change over. axm solve --strict file.axm.jsondoes the same for one file: exit code 4 when a check fails.