Continuous Integration (CI)¶
Integrating astli into your CI pipeline provides fast, automated checks on every pull request. Because astli exits with code 1 whenever an error or unformatted file is encountered, wiring it into automated workflows is straightforward.
Example GitHub Actions workflows¶
Choose either uv (recommended for speed) or pipx (pre-installed on standard GitHub-hosted runners):
name: SystemVerilog CI
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up uv
uses: astral-sh/setup-uv@v7
# Cache downloaded Git dependencies between workflow runs
- name: Cache astli dependencies
uses: actions/cache@v4
with:
path: ~/.cache/astli
key: astli-${{ runner.os }}-${{ hashFiles('astli.lock') }}
restore-keys: |
astli-${{ runner.os }}-
- name: Format check
run: uvx astli@0.3.0 fmt --check
- name: Lint
run: uvx astli@0.3.0 lint --locked
- name: Semantic and elaboration check
run: uvx astli@0.3.0 check --locked --top soc_top
name: SystemVerilog CI
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Cache astli dependencies
uses: actions/cache@v4
with:
path: ~/.cache/astli
key: astli-${{ runner.os }}-${{ hashFiles('astli.lock') }}
- name: Format check
run: pipx run --spec astli==0.3.0 astli fmt --check
- name: Lint
run: pipx run --spec astli==0.3.0 astli lint --locked
- name: Semantic and elaboration check
run: pipx run --spec astli==0.3.0 astli check --locked --top soc_top
CI best practices¶
1. Pin the astli executable version¶
Prevent unexpected CI breaks
Always pin the exact version of astli in your workflow (e.g. astli@0.3.0). As new linter rules or formatter refinements are released, an unpinned version could unexpectedly fail builds on unchanged legacy code.
2. Enforce lockfiles with --locked¶
Passing --locked instructs astli to verify that astli.lock exists and matches the dependency definitions in astli.toml. If a dependency has drifted or the lockfile is missing, astli fails the build immediately rather than silently modifying files in CI.
3. Caching dependencies¶
astli stores downloaded repositories in $HOME/.cache/astli (or the path defined by ASTLI_CACHE_DIR). Caching this directory with actions/cache keyed on astli.lock avoids redundant Git clones across workflow runs, accelerating CI runtimes.
Pull request annotations¶
To have GitHub Actions show each diagnostic on the line of the pull request's diff it is about, write them as workflow commands:
astli lint --diag github
Each diagnostic becomes an ::error, ::warning or ::notice command, which the runner turns into an annotation; the log still shows its file:line:col: severity[code]: message line. The runner places an annotation by the file's path inside the checkout, which a package run writes in full; a file named relative to the working directory, as passed on the command line, is placed only when astli runs from the repository's root. To use the format for every step of a job, set it once:
env:
ASTLI_DIAGNOSTICS: github
Other CI systems and editors read the plain one-line format, --diag short.