GitHub Integration
In v0.13.0, we introduced integration with GitHub. We hope to refine and improve this integration in the next few releases. Please give it a try and let us know what your experience is.
Currently, GitHub mode is only meant to run in GitHub
actions, where Maelstrom test runners
(cargo-maelstrom
, maelstrom-go-test
, maelstrom-pytest
),
maelstrom-broker
, and the workers (maelstrom-worker
) are all running inside
of a single GitHub workflow. This mode allows you to run your CI tests with
parallel workers. What it doesn’t do (yet) is allow you to use your GitHub
workers to run tests ad hoc from your development machine.
How It Works
(In this section, when we talk about “jobs”, we’re referring to the GitHub Actions concept, not the Maelstrom concept.)
Inside of a workflow, you start multiple, parallel jobs. One of those jobs runs the broker, and the rest run worker instances. These jobs form a Maelstrom cluster that you can then use from any number of other jobs in the workflow.
When a Maelstrom test runner is run from a GitHub job inside the workflow, instead of running the test on the job’s runner, the test is passed to one of the Maelstrom workers to run. In this way, the tests all run in parallel in multiple jobs, on separate runners.
When all of the jobs that require the Maelstrom cluster have completed, you
stop the Maelstrom cluster with maelstrom-admin
, which is
provided by the
maelstrom-admin-action
.
The main implementation challenge we face is that GitHub doesn’t allow jobs to communicate directly with each other using normal TCP/IP. To work around this, we use the artifact store.
Broker Job
You must start one instance of the broker on its own job. This should be started at the beginning of the workflow. It will be terminated when the Maelstrom cluster is stopped, as discussed below.
The broker job is run using the
maelstrom-broker-action
:
jobs:
# [Other jobs...]
maelstrom-broker:
name: Maelstrom Broker
runs-on: ubuntu-24.04
steps:
- name: Install and Run Maelstrom Broker
uses: maelstrom-software/maelstrom-broker-action@v1
Worker Jobs
You must start some number of worker instances on their own jobs. These should be started at the beginning of the workflow as well. They will be terminated when the broker is stopped.
A worker job is run using the
maelstrom-broker-action
.
It’s recommended that you use a matrix strategy to start a number of them:
jobs:
# [Other jobs...]
maelstrom-worker:
strategy:
matrix:
worker-number: [1, 2, 3, 4]
name: Maelstrom Worker ${{ matrix.worker-number }}
runs-on: ubuntu-24.04
steps:
- name: Install and Run Maelstrom Worker
uses: maelstrom-software/maelstrom-worker-action@v1
The worker can be run on an Ubuntu x86-64 image (e.g. ubuntu-24.04
), or an
Ubuntu AArch64 image (e.g. ubuntu-24.04-arm
). The architecture must match the
architecture of the client jobs.
Client Jobs
You can run any number of client jobs: jobs that run Maelstrom clients that talk to the workflow’s Maelstrom cluster. You set that up like this:
jobs:
# [Other jobs...]
run-tests-1:
name: Run Tests 1
runs-on: ubuntu-24.04
steps:
- name: Check Out Repository
uses: actions/checkout@v4
- name: Install and Configure cargo-maelstrom
uses: maelstrom-software/cargo-maelstrom-action@v1
- name: Run cargo-maelstrom
run: cargo maelstrom
run-tests-2:
name: Run Tests 2
runs-on: ubuntu-24.04
steps:
- name: Check Out Repository
uses: actions/checkout@v4
- name: Install and Configure maelstrom-go-test
uses: maelstrom-software/maelstrom-go-test-action@v1
- name: Run cargo-maelstrom
run: maelstrom-go-test
stop-maelstrom:
name: Stop Maelstrom Cluster
runs-on: ubuntu-24.04
if: ${{ always() }}
needs: [run-tests-1, run-tests-2]
steps:
- name: Install and Configure maelstrom-admin
uses: maelstrom-software/maelstrom-admin-action@v1
- name: Stop Maelstrom Cluster
run: maelstrom-admin stop
The main points are:
- You run the appropriate action for the Maelstrom test runner(s) you want to use
(
cargo-maelstrom-action
ormaelstrom-go-test-action
in this example). This installs the test runner and configures it to use the Maelstrom cluster running in the workflow. - When all client jobs are done, you use the
maelstrom-admin-action
to installmaelstrom-admin
, which you then run to stop the cluster. This is what stops the broker and worker jobs running in parallel. - You want to guarantee that job is run to stop the cluster, even if one of
of the client job fails. For this reason, it’s advisable to run it in its
own job with
if: ${{ always() }}
. You should probably do this even if you only have a single client job. - You don’t have to wait for the Maelstrom cluster to start before running client jobs: The clients and workers will wait for the broker to start.
Hardware Architecture
Maelstrom only support single-architecture clusters. The clients and the
workers all need to be running on the same architecture (x86-64 or ARM64).
Technically, neither maelstrom-broker
nor maelstrom-admin
whether their
architectures match those of the clients or workers, but it’s usually easiest
to just run everything on one architecture.
In the future, we plan to allow clusters to support multiple architectures.
If you need to run Maelstrom test runners against multiple architectures in CI, one solution is to use GitHub Workflow Templates. That’s what we do in the examples repository.
Example
You can look at the workflow in the example repository here.
Here is the example from above all put together:
jobs:
maelstrom-broker:
name: Maelstrom Broker
runs-on: ubuntu-24.04
steps:
- name: Install and Run Maelstrom Broker
uses: maelstrom-software/maelstrom-broker-action@v1
maelstrom-worker:
strategy:
matrix:
worker-number: [1, 2, 3, 4]
name: Maelstrom Worker ${{ matrix.worker-number }}
runs-on: ubuntu-24.04
steps:
- name: Install and Run Maelstrom Worker
uses: maelstrom-software/maelstrom-worker-action@v1
run-tests-1:
name: Run Tests 1
runs-on: ubuntu-24.04
steps:
- name: Check Out Repository
uses: actions/checkout@v4
- name: Install and Configure cargo-maelstrom
uses: maelstrom-software/cargo-maelstrom-action@v1
- name: Run cargo-maelstrom
run: cargo maelstrom
run-tests-2:
name: Run Tests 2
runs-on: ubuntu-24.04
steps:
- name: Check Out Repository
uses: actions/checkout@v4
- name: Install and Configure maelstrom-go-test
uses: maelstrom-software/maelstrom-go-test-action@v1
- name: Run cargo-maelstrom
run: maelstrom-go-test
stop-maelstrom:
name: Stop Maelstrom Cluster
runs-on: ubuntu-24.04
if: ${{ always() }}
needs: [run-tests-1, run-tests-2]
steps:
- name: Install and Configure maelstrom-admin
uses: maelstrom-software/maelstrom-admin-action@v1
- name: Stop Maelstrom Cluster
run: maelstrom-admin stop