Github Actions
MNE-CPP uses GitHub Actions for all continuous integration (CI) work. GitHub Actions operates on repository events — pushes, pull requests, releases, and timers — which trigger workflows defined as YAML files in .github/workflows/. Each workflow contains one or more jobs, and each job runs a series of steps on a fresh virtual machine (runner). You can read more about the terminology in the GitHub Actions documentation.
Workflow Overview
MNE-CPP's CI is organized around the Main – Staging – Feature branch model. The following table summarizes every CI workflow:
| Event type | Workflow Name | Workflow Script | Effect |
|---|---|---|---|
Pull Requests → staging or main | PullRequest | pull-request.yml | Build matrix (Qt min + max) and tests on all platforms. PR cannot be merged until all jobs pass. |
Pushes to staging | Staging | staging.yml | Dev release binaries, code coverage with threshold/regression checks, dev website + Doxygen deployment, CodeQL analysis. |
Pushes to main | Main | main.yml | Builds, tests, stable website + Doxygen deployment. |
Tag v* on main | Main (release jobs) | main.yml | Full stable release: platform binaries (Linux, macOS, Windows), installers, WebAssembly, Codecov upload. |
Pushes to the wasm branch | WasmTest | wasmtest.yml | Creates new versions of the WebAssembly capable MNE-CPP applications and makes them accessible via the repository's gh-pages branch. |
| Timer runs out | Coverity | coverity.yml | Triggers every two days to run Coverity static code analysis tools. |
Pushes to the generateqt branch | BuildQtBinaries | buildqtbinaries.yml | Triggers builds of all needed Qt versions and makes them accessible as artifacts via the Github Actions interface. |
Reusable Workflows
Common build and test logic is extracted into reusable workflows to avoid duplication:
| Workflow | Script | Purpose |
|---|---|---|
| Reusable Build | _reusable-build.yml | Cross-platform build parameterized by Qt version |
| Reusable Tests | _reusable-tests.yml | Test execution with configurable code coverage (Codecov upload, threshold check, or plain) |
These are called by the main pipeline workflows using workflow_call.
How the Pull Request Workflow Works
When a contributor opens or updates a pull request targeting staging (or main), pull-request.yml runs a build-and-test matrix:
- Checks out the PR branch.
- Builds twice — once with the minimum supported Qt version and once with the maximum — to ensure compatibility across the supported Qt range.
- Runs tests via the reusable test workflow (without coverage uploads).
- Builds Doxygen documentation to verify it compiles without errors.
The PR cannot be merged until all matrix jobs pass. This ensures that every change is validated on Linux, macOS, and Windows before it reaches the staging branch.
How the Staging Workflow Works
staging.yml is the active development pipeline, triggered on every push to staging. It:
- Creates or updates the
dev_buildpre-release on GitHub with the latest development binaries - Builds with both minimum and maximum Qt versions
- Runs tests with code coverage — enforcing a minimum threshold (50%) and detecting coverage regressions
- Invokes the platform-specific release workflows (
release-linux.yml,release-macos.yml,release-windows.yml,release-installer.yml) to produce development binaries tagged asdev_build - Deploys the dev version of the documentation website to
/dev/and Doxygen API docs to/dev/ - Runs CodeQL security analysis
How the Main / Release Workflow Works
main.yml handles two scenarios:
Pushes to main (no tag)
On every push to main, the workflow:
- Builds with minimum and maximum Qt versions
- Runs tests (with Codecov upload)
- Deploys the stable website and Doxygen API documentation (preserving the dev subdirectory)
Tagged releases (v*)
When a version tag is pushed (e.g., v2.0.0), the workflow additionally:
- Creates a GitHub Release from the tag
- Invokes platform-specific release workflows to build and upload binaries for Linux, macOS, and Windows
- Builds and uploads platform installers (
.run,.dmg,.exe) - Builds and deploys WebAssembly applications
- Uploads the Doxygen
.qchfile as a release asset
Each platform job follows the same high-level pattern: install Qt, configure CMake, build, deploy (bundle Qt libraries), package into an archive, and upload to the GitHub release.
Workflow File Structure
All workflow YAML files live in .github/workflows/ and follow a common structure:
name: WorkflowName
on:
push:
branches: [staging]
pull_request:
branches: [staging, main]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-24.04, macos-26, windows-2025]
steps:
- uses: actions/checkout@v4
- name: Install Qt
# ...
- name: Configure
run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
- name: Build
run: cmake --build build --parallel
- name: Test
run: cd build && ctest --output-on-failure
Key elements include the trigger (on:), the matrix strategy for cross-platform builds, and the steps that install dependencies, compile, test, and optionally deploy.
Secrets and Environment Variables
Some workflows require GitHub repository secrets (configured in Settings → Secrets and variables → Actions):
| Secret | Used by | Purpose |
|---|---|---|
GITHUB_TOKEN | All release workflows | Automatically provided; used to upload release assets |
GH_PAT | Release workflows | Personal access token for cross-repo operations (optional fallback) |
GIT_CREDENTIALS | Website + Doxygen deploy | Authentication for pushing to gh-pages branches |
CODECOV_TOKEN | Main workflow | Token for uploading coverage to Codecov |
COVERITY_TOKEN | coverity.yml | Authentication token for Coverity Scan |
Adding or Modifying a Workflow
To add a new workflow:
- Create a new
.ymlfile in.github/workflows/. - Define the trigger event (
on:) — push, pull_request, schedule, or workflow_dispatch. - Define one or more jobs with the appropriate runner (
runs-on:) and steps. - Test the workflow by pushing to a feature branch and opening a PR against
staging.
To modify an existing workflow, edit the corresponding .yml file and push the change. If the modification affects the PR workflow, open a PR to see the results immediately.