CI integration
Learn how to set up Acton checks, tests, and reports in CI pipelines
Set up CI by running the same Acton validation commands locally and in the pipeline: build, test, check, and fmt checks. Use the GitHub Actions and GitLab examples below as a starting point for contract-only projects and projects that also include a frontend.
The CI setup is ready when:
- local validation commands pass;
- GitHub Actions or GitLab pipelines exit successfully on a test commit;
- lint findings appear as annotations in GitHub or as a Code Quality report in GitLab;
- coverage uploads succeed when the coverage job is enabled.
Run the checks locally
Run the same commands locally before wiring them into CI:
acton build
acton test
acton check
acton fmt --checkThese commands should exit with status 0.
If Acton is not installed on the host machine, run the same checks through the published Docker image:
docker run --rm \
-v "$PWD":/workspace \
-w /workspace \
ghcr.io/ton-blockchain/acton:1.1.0 \
buildReplace build with test, check, or fmt --check as needed.
Choose the lint output format
Use the lint output format that matches the CI system:
- Default (or plain) output format prints diagnostics with source locations in the standard terminal output.
githubprints GitHub workflow commands and creates annotations in GitHub Actions.gitlabwrites a GitLab Code Quality report (Code Climate style) and is the best default for GitLab CI.sarifis useful when the pipeline uploads SARIF artifacts to GitHub code scanning or another SARIF consumer. In private GitHub repositories, use it only when code scanning is enabled for the repository.jsonis useful for custom automation and editor integrations.
--fix works only with the default plain output format. With json, sarif, github, or
gitlab, Acton rejects --fix instead of rewriting files.
To specify the format, use the --output-format flag. To specify the output file, use the --output-file flag.
For example, to write a SARIF file in CI, run:
acton check --output-format sarif --output-file .acton/reports/lint.sarifJSON output
acton check --output-format jsonThis prints the linting report as a JSON object to stdout with:
success:trueorfalsediagnostics: array of diagnostics
Each diagnostic includes:
fileas an absolute file pathseverity,name,message, and optionalcodeorhelpannotations[]with 0-basedrange.start/end.{line,character},is_primary, optionalmessage, and optionaltagsfixes[]withmessage,applicability(autoormanual), and structurededits[]
To print the exact JSON Schema of the report to stdout, run:
acton meta get-schema lint-reportUse JSON mode for editor integrations and custom tooling.
SARIF report
acton check --output-format sarif --output-file .acton/reports/lint.sarifThis creates a SARIF report in .acton/reports/lint.sarif.
The output includes:
SRCROOT-relative artifact locations when possible;- primary location and
relatedLocations; - per-rule metadata such as docs
helpUri, lifecycle status, and fixability; - structured SARIF fixes with Acton-specific applicability metadata.
Private GitHub repositories
GitHub shows uploaded SARIF files through code scanning. For private and internal repositories, SARIF upload works only when GitHub Code Security or GitHub Advanced Security is enabled for the repository. If it is not enabled, upload-sarif fails and the SARIF file will not create pull request annotations.
In that setup, keep SARIF only when another CI step or external tool consumes it. For GitHub pull request feedback without code scanning, use acton check --output-format github or an annotation layer such as reviewdog.
Set up GitHub Actions
Acton offers a GitHub action to set itself up. setup-acton downloads a release binary, restores and saves it with the GitHub Actions cache, adds acton to PATH, and exposes install details as outputs:
- name: Setup Acton
uses: ton-blockchain/setup-acton@2d38fd579e1bf8753a3e0cff9ad695612b98a676 # v1.0.0
id: setup-acton
with:
# (optional) Acton version to install.
# Supported values include 'latest', a release tag such as 'v1.1.0',
# a bare semantic version such as '1.1.0', or 'trunk'.
# Defaults to [toolchain].acton in Acton.toml, then 'latest'.
version: '1.1.0'
# (optional) Target architecture.
# Supported values: x86_64, aarch64.
# Auto-detected from the runner if not specified.
architecture: 'x86_64'
# (optional) Target platform.
# Supported values: linux, apple, windows.
# Auto-detected from the runner if not specified.
platform: 'linux'
# (optional) Working directory for the Acton project.
# Used when reading Acton.toml. Defaults to the GitHub workspace.
working-directory: ${{ github.workspace }}
# (optional) Restore and save the resolved Acton binary with the
# GitHub Actions cache. Defaults to true.
save-cache: true
# (optional) GitHub token.
# Used for authenticated release metadata and asset downloads.
# Defaults to the current github.token value.
github-token: ${{ github.token }}
# The setup action produces the following outputs: acton-path, acton-version, and cache-hit.
- run: |
# acton-path contains full path to the installed Acton binary.
echo "Path: ${{ steps.setup-acton.outputs.acton-path }}"
# acton-version contains installed Acton version parsed from `acton --version`.
# If the version cannot be detected, acton-version returns 'unknown'.
echo "Version: ${{ steps.setup-acton.outputs.acton-version }}"
# cache-hit is true when the binary was restored from the Actions cache.
echo "Cache hit: ${{ steps.setup-acton.outputs.cache-hit }}"If version is omitted, setup-acton reads [toolchain].acton from Acton.toml in working-directory; if no project version is configured, it installs the latest release:
[toolchain]
acton = "1.1.0"The action accepts versioned releases, latest, trunk, and custom release tags. Pin a versioned release in Acton.toml or in the version input for reproducible workflows. Use trunk only for preview workflows.
Caching is enabled by default. The cache key includes the binary name, resolved version, platform target, and architecture, and the post-step saves the cache only after a successful job. When version: 'trunk' is used, the action skips saving the cache because trunk is a moving target.
For a contract-only repository, create .github/workflows/contracts.yml:
name: Contracts
on:
push:
# Keep the primary protected branch:
branches:
- main
- master
pull_request:
branches:
- main
- master
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: { }
jobs:
build-and-test:
name: Build and Test
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Acton
uses: ton-blockchain/setup-acton@2d38fd579e1bf8753a3e0cff9ad695612b98a676 # v1.0.0
- name: Build
run: acton build
- name: Formatter
run: acton fmt --check
- name: Linter
run: acton check --output-format github
- name: Test
run: acton test-
The
acton check --output-format githubcommand emits workflow annotations directly in the GitHub Actions log and pull request checks. -
The
acton checkcommand exits with a non-zero status when it reports at least one error, or when warning count exceedsmax-warnings. To fail CI on any warning, set:Acton.toml [lint] max-warnings = 0
Add coverage reporting
Acton can generate lcov output directly from the test runner. Add this to a GitHub Actions job that uploads coverage to Codecov:
name: Coverage
on:
pull_request:
branches:
# Keep the primary protected branch:
- main
- master
permissions: {}
jobs:
coverage:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Acton
uses: ton-blockchain/setup-acton@2d38fd579e1bf8753a3e0cff9ad695612b98a676 # v1.0.0
- name: Run tests with coverage
run: acton test --coverage --coverage-format lcov --coverage-file lcov.info
- name: Upload coverage
uses: codecov/codecov-action@v6
with:
files: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}To fail the job when coverage drops below a threshold, add --coverage-minimum-percent <PERCENT> to the test command, where <PERCENT> is a number from 0 to 100. Alternatively, set the default value in the manifest:
[test.coverage]
minimum-percent = 50Add frontend checks
If the repository also contains a frontend created with acton new --app or a custom one, create a separate frontend workflow with Node.js setup and validation steps. Keep Acton installed in this job when the frontend build can call acton build, as the generated contract-aware app templates do.
name: dApp
on:
push:
# Keep the primary protected branch:
branches:
- main
- master
pull_request:
branches:
- main
- master
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
build-and-test:
name: Build and Test
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Acton
uses: ton-blockchain/setup-acton@2d38fd579e1bf8753a3e0cff9ad695612b98a676 # v1.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Formatter
run: npm run fmt:check
- name: Typecheck
run: npm run typecheck
- name: Build
run: npm run build
- name: Test
run: npm run testSet up GitLab CI
For GitLab, run Acton from the published Docker image. The example pins the image to 1.1.0; use latest only if the pipeline should always follow the newest release.
image:
name: ghcr.io/ton-blockchain/acton:1.1.0
entrypoint: [""]
stages:
- validate
validate:
stage: validate
script:
- acton --version
- acton build
- acton fmt --check
- acton check --output-format gitlab --output-file gl-code-quality-report.json
- acton test
artifacts:
when: always
reports:
codequality: gl-code-quality-report.jsonThe entrypoint: [""] override is required because the Acton Docker image uses acton as its entrypoint, while GitLab Runner expects to run job scripts through a shell. acton check --output-format gitlab writes a Code Quality report that GitLab can show directly in merge requests.
Store secrets and wallet mnemonics
Validation jobs do not need to set up wallets. For noninteractive deployment jobs, use mnemonic-env to store and retrieve mnemonics:
[wallets.deployer]
kind = "v5r1"
keys = { mnemonic-env = "DEPLOYER_MNEMONIC" }Then expose the secret in CI:
env:
DEPLOYER_MNEMONIC: ${{ secrets.DEPLOYER_MNEMONIC }}In GitLab CI, store DEPLOYER_MNEMONIC as a masked protected variable with the same name.
Never commit mnemonic phrases, plaintext wallet files, or .env files that contain production secrets.
Last updated on