Skip to content

GitHub Action

jdx/mr-boxington-action installs mbx and connects it to either GitHub Actions cache or an mbx-compatible server. The examples below show the inputs that matter for each backend; the action's repository documents the complete list.

GitHub Actions cache

The default backend restores mbx's local store on every run and saves an entry only after a successful push to the repository's default branch. Pull requests, including pull requests from forks, are restore-only.

yaml
permissions:
  contents: read

steps:
  - uses: actions/checkout@v7
  - uses: jdx/mr-boxington-action@v1
  - run: mbx test --workspace

Parallel Cargo steps

Run multiple Cargo builds at the same time by starting independent lint or test configurations together. mbx gives every compiler they launch one machine-wide CPU and memory budget:

yaml
steps:
  - uses: actions/checkout@v7
  - uses: jdx/mr-boxington-action@v1
  - parallel:
      - name: Clippy with default features
        env:
          CARGO_TARGET_DIR: ${{ runner.temp }}/clippy-default
        run: mbx clippy --workspace -- -D warnings
      - name: Clippy with all features and targets
        env:
          CARGO_TARGET_DIR: ${{ runner.temp }}/clippy-all
        run: mbx clippy --workspace --all-features --all-targets -- -D warnings

Each command needs a separate CARGO_TARGET_DIR; otherwise Cargo's target directory lock serializes the supposedly parallel steps. The mbx store and scheduler stay shared, so the steps run side by side on one CPU and memory budget rather than each Cargo process trying to fill the runner on its own.

We saw mise's own lint job finish up to 45% sooner this way. Tuning and failure behavior are covered under machine-wide compile scheduling.

Before saving, the action prunes the store to 3 GB. Set max-size to change the budget, or change cache-generation when an upgrade or policy change should start fresh:

yaml
- uses: jdx/mr-boxington-action@v1
  with:
    version: 0.3.0
    cache-generation: v2
    max-size: 5GB

The operating system and architecture are included in generated keys. Advanced workflows can provide complete cache-key and restore-keys inputs.

Closure bundles for action transports

An action can transport only the cache entries produced or used by its builds, instead of archiving the whole local store. Before any build steps, assign a unique opaque value to MBX_CACHE_EXPORT_GROUP for that job. Every completed mbx command writes an immutable receipt into the group, including commands running in parallel or in different checkouts.

The action's restore phase imports a previously cached bundle:

console
mbx cache import "$RUNNER_TEMP/mbx-cache.tar"

Its post phase exports the deduplicated closure of every receipt in this job:

console
mbx cache export --group "$MBX_CACHE_EXPORT_GROUP" "$RUNNER_TEMP/mbx-cache.tar"

The group should include the run attempt, job, and matrix identity, or be a fresh random value generated by the action. It identifies builds within one job; it is not the GitHub Actions cache key. A post step should skip saving when no completed build was recorded or when the workflow's trust policy forbids a cache write.

Manual GitHub cache setup

The equivalent pieces can be assembled directly when Cargo download caches or custom save policies need to share the same entry:

yaml
- uses: actions/cache@v6
  with:
    path: |
      ~/.cargo/registry
      ~/.cargo/git
      ~/.cargo/.global-cache
      ~/.cache/mbx
    key: ${{ runner.os }}-${{ runner.arch }}-mbx-${{ github.sha }}
    restore-keys: |
      ${{ runner.os }}-${{ runner.arch }}-mbx-
- uses: jdx/mise-action@v4
  with:
    cache: false
    install_args: mr-boxington
- run: mbx test --workspace
- run: mbx gc --max-size 3GB
  if: always()

Use actions/cache/restore instead of actions/cache in pull requests so they cannot create entries.

Pin actions in production

The examples use major tags for readability. Pin third-party actions to full commit SHAs in a real workflow.

Cache server

For trusted runners and teams, mbx can talk to a compatible remote server such as the self-hostable cache server. The action exports the remote configuration for subsequent steps:

yaml
permissions:
  contents: read
  id-token: write

steps:
  - uses: actions/checkout@v7
  - uses: jdx/mr-boxington-action@v1
    with:
      backend: server
      server-url: https://cache.example.com
      namespace: acme/backend
      oidc-audience: mbx-cache
  - run: mbx build --workspace --all-features

Only a push to a protected branch may write. Pull requests and tag or release builds degrade to read-only. If fork authors must not reach the host, use the GitHub backend for those jobs instead. A bearer token can be supplied with the action's token input when OIDC is unavailable.

S3-compatible bucket

A bucket needs nothing running. aws-actions/configure-aws-credentials exchanges the runner's OIDC token for a role and exports the credentials mbx reads, so no long-lived secret is stored:

yaml
permissions:
  contents: read
  id-token: write

env:
  MBX_REMOTE_URL: s3://acme-build-cache
  MBX_REMOTE_NAMESPACE: acme/backend

steps:
  - uses: actions/checkout@v7
  - uses: aws-actions/configure-aws-credentials@v5
    with:
      role-to-assume: arn:aws:iam::111122223333:role/mbx-cache
      aws-region: us-west-2
  - uses: jdx/mise-action@v4
    with:
      cache: false
      install_args: mr-boxington
  - run: mbx build --workspace --all-features

mbx is installed rather than set up through jdx/mr-boxington-action here, because the action's GitHub Actions cache backend would store the same actions a second time. Use one or the other.

mbx still refuses to publish from a pull request. Because a bucket has no server to authorize anything, make IAM agree: scope the role's trust policy to the branches allowed to assume it, and give pull request jobs a role that can only read. See remote cache.

Do not use remote caches for production releases

A production release may still use mbx and its local cache, but should not use a remote cache so a cache-poisoning attack cannot influence published artifacts. Release jobs should also avoid restoring or saving the mbx store through actions/cache.

For a repository that combines both backends — the server for trusted runs, the GitHub cache for fork pull requests — see CI with fork pull requests.

MIT LicenseCopyright © 2026jdx.dev