GitHub Actions recipe
A simple workflow that runs the formatter, linter, and analyzer on every push and pull request, with native PR annotations.
Quick setup
Create .github/workflows/mago.yml:
name: Mago Code Quality
on:
push:
pull_request:
jobs:
mago:
name: Run Mago Checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
coverage: none
tools: composer
env:
COMPOSER_ALLOW_SUPERUSER: 1
- name: Install Composer dependencies
run: composer install --prefer-dist --no-progress
- name: Set up Mago
uses: nhedger/setup-mago@v1
- name: Check formatting
run: mago format --check
- name: Lint
if: success() || failure()
run: mago lint
- name: Analyze
if: success() || failure()
run: mago analyze
A few notes on the structure:
- Splitting
format,lint, andanalyzeinto separate steps surfaces findings from all three, even when an earlier step fails. A single combinedrun:would short-circuit on the first failure and hide the rest. if: success() || failure()runs the step when the job has not been cancelled, which is what you want here.always()would also run it after setup failures.- Use
mago format --check, not--dry-run.--checkexits non-zero when files need formatting;--dry-runonly prints a diff and always exits zero. - Mago detects GitHub Actions through the
GITHUB_ACTIONSenvironment variable and switches to--reporting-format=githubautomatically, producing native PR annotations. No extra configuration needed. On 1.17.0 and earlier you must pass--reporting-format=githubtomago lintandmago analyzemanually.
Using the Docker image
If you prefer not to install Mago on the runner, run the official Docker image as a container job:
name: Mago Code Quality
on:
push:
pull_request:
jobs:
mago:
name: Run Mago Checks
runs-on: ubuntu-latest
container:
image: ghcr.io/carthage-software/mago:1
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check formatting
run: mago fmt --check
- name: Lint
if: success() || failure()
run: mago lint
- name: Analyze
if: success() || failure()
run: mago analyze
The image does not include PHP or Composer. That works fine for the formatter and linter, but the analyzer needs Composer dependencies to resolve symbols. For analysis, prefer the setup-mago approach with composer install running first.