Sign in

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 codeMeaning
0Every check of every file passes
4A check fails
3A file could not be solved completely
1A file could not be opened, or a pattern matched nothing
5No 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_check before it hands the change over.
  • axm solve --strict file.axm.json does the same for one file: exit code 4 when a check fails.