aer
GitHub Actions CI

GitHub Actions CI

Run Apex tests automatically on every push or pull request using the aer GitHub Action. The action installs the aer CLI, runs your test suite, and surfaces failures directly in your workflow logs—no Salesforce org deployment required.

Basic setup

Add a workflow file to your repository at .github/workflows/apex-tests.yml:

name: Apex Tests

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Run aer tests
        uses: octoberswimmer/aer-dist@v1
        with:
          source: force-app/main/default
        env:
          AER_LICENSE_KEY: ${{ secrets.AER_LICENSE_KEY }}

The AER_LICENSE_KEY secret is required for CI usage. Add it to your repository secrets at Settings > Secrets and variables > Actions > New repository secret. Subscribe at octoberswimmer.com/tools/aer/subscribe to obtain a license key.

Action inputs

Configure the action with these inputs under the with key:

source

Path or paths to your Apex source directories. Pass a single directory:

with:
  source: force-app/main/default

Or multiple directories on separate lines:

with:
  source: |
    force-app/main/default
    force-app-common/main/default

Space-separated paths also work:

with:
  source: force-app/main/default force-app-common/main/default

Defaults to . (current directory) if omitted.

flags

Additional arguments passed to aer test. Use this to specify schemas, packages, filters, or any other CLI flags:

with:
  source: force-app/main/default
  flags: --schema build/schema.gob --package packages/oslog.pkg

Skip specific tests with the --skip flag:

with:
  source: force-app/main/default
  flags: --skip BrokenTest.testMethod

version

Pin the action to a specific aer release:

with:
  source: force-app/main/default
  version: v0.0.31

Defaults to latest, which resolves to the most recent published release. Pinning a version ensures consistent behavior across builds and prevents unexpected failures when new releases ship.

Example workflows

Filter tests by name

Run only tests that match a pattern:

- name: Run integration tests
  uses: octoberswimmer/aer-dist@v1
  with:
    source: force-app/main/default
    flags: --filter Integration
  env:
    AER_LICENSE_KEY: ${{ secrets.AER_LICENSE_KEY }}

Matrix strategy for multiple source directories

Test several independent projects in parallel:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        project:
          - force-app/main/default
          - force-app-common/main/default
          - force-app-api/main/default
    steps:
      - uses: actions/checkout@v4

      - name: Run tests for ${{ matrix.project }}
        uses: octoberswimmer/aer-dist@v1
        with:
          source: ${{ matrix.project }}
        env:
          AER_LICENSE_KEY: ${{ secrets.AER_LICENSE_KEY }}

Troubleshooting

License errors

If the workflow fails with a license error, verify that:

  • The AER_LICENSE_KEY secret exists in your repository settings
  • The license key is valid and not expired
  • The license is a CI license, not a developer license (developer licenses cannot be used in GitHub Actions)
  • The secret name in your workflow matches exactly (case-sensitive)

Source directory not found

The action fails if the specified source path does not exist. Common causes:

  • Forgetting to run actions/checkout@v4 before the aer action
  • Specifying the wrong path (check your repository structure)
  • Using a relative path from the wrong working directory

Tests fail in CI but pass locally

Check that your CI environment includes all dependencies:

  • Package files (.pkg) must be present if you use --package or --package-dir
  • Schema files must exist if you use --schema
  • Any bootstrap databases must be generated or checked in before the test step

Run the same aer test command locally with identical flags to reproduce CI behavior.

Related documentation

© 2012–2026 October Swimmer.