Skip to content

GitHub Actions

This repo uses GitHub Actions for two things:

  1. publishing the Gatemole docs site to GitHub Pages
  2. running the current Gatemole gate in pull request workflows

Published docs URL:

https://duriantaco.github.io/gatemole/

GitHub Pages is configured with build_type: workflow, so content is published by .github/workflows/pages.yml after changes land on main.

Docs Deployment

The Pages workflow follows GitHub's custom Actions publishing flow:

  • actions/configure-pages
  • actions/upload-pages-artifact
  • actions/deploy-pages

Workflow file:

.github/workflows/pages.yml

Source files:

mkdocs.yml
docs/requirements.txt
docs/site/
docs/site/assets/gatemole.png

The workflow builds the MkDocs site into _site/, uploads that artifact, and deploys it to the github-pages environment.

Official references:

Gatemole PR Workflow

The current Gatemole PR workflow should start in shadow mode. It creates a PR manifest from the diff, attaches evidence artifacts, appends a job summary, and uploads the manifest/build/evidence bundle without blocking the PR.

name: Gatemole

on:
  pull_request:

permissions:
  contents: read

env:
  GATEMOLE_MANIFEST: .gatemole/manifests/pr-${{ github.event.pull_request.number }}-${{ github.run_attempt }}.json
  GATEMOLE_GATE_RESULT: .gatemole/build/gate-result.json
  GATEMOLE_JUNIT: .gatemole/artifacts/pytest.xml

jobs:
  gatemole:
    runs-on: ubuntu-latest
    continue-on-error: true
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-go@v5
        with:
          go-version: "1.26"

      - name: Install Gatemole
        run: go install github.com/duriantaco/gatemole/cmd/gatemole@latest

      - name: Compile Gatemole contracts
        run: gatemole contracts compile

      - name: Create PR manifest
        env:
          GATEMOLE_TASK_ID: pr-${{ github.event.pull_request.number }}
          GATEMOLE_TASK_SUMMARY: ${{ github.event.pull_request.title }}
          GATEMOLE_RUN_ID: ${{ github.run_id }}.${{ github.run_attempt }}
          GATEMOLE_RUNNER_IDENTITY: https://github.com/${{ github.repository }}/.github/workflows/gatemole.yml@${{ github.ref }}
        run: |
          gatemole contracts manifest create \
            --task-id "$GATEMOLE_TASK_ID" \
            --summary "$GATEMOLE_TASK_SUMMARY" \
            --agent github-actions \
            --run-id "$GATEMOLE_RUN_ID" \
            --runner-identity "$GATEMOLE_RUNNER_IDENTITY" \
            --runner-oidc-issuer https://token.actions.githubusercontent.com \
            --base "origin/${{ github.base_ref }}" \
            --head HEAD \
            --out "$GATEMOLE_MANIFEST"

      - name: Run tests for evidence
        id: tests
        run: |
          mkdir -p .gatemole/artifacts
          set +e
          pytest --junitxml "$GATEMOLE_JUNIT"
          exit_code=$?
          echo "exit_code=$exit_code" >> "$GITHUB_OUTPUT"
          exit 0

      - name: Attach JUnit evidence
        if: steps.tests.outputs.exit_code == '0'
        run: |
          gatemole contracts manifest attach-artifact \
            --manifest "$GATEMOLE_MANIFEST" \
            --id pytest \
            --kind test_coverage \
            --path "$GATEMOLE_JUNIT" \
            --producer github-actions \
            --command "pytest --junitxml $GATEMOLE_JUNIT" \
            --exit-code "${{ steps.tests.outputs.exit_code }}" \
            --out "$GATEMOLE_MANIFEST"

      - name: Gate PR
        run: gatemole --manifest "$GATEMOLE_MANIFEST" contracts gate --github-summary --out "$GATEMOLE_GATE_RESULT"

      - name: Upload Gatemole artifacts
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: gatemole-shadow-pr-${{ github.event.pull_request.number }}
          path: |
            .gatemole/manifests/
            .gatemole/build/
            .gatemole/artifacts/
          if-no-files-found: ignore

Keep normal CI test jobs in place during shadow mode. This workflow measures release-contract coverage; it should not be the only test enforcement path until the team switches to enforced mode.

Upload these paths for every shadow run:

  • .gatemole/manifests/: PR manifest and attached artifact references.
  • .gatemole/build/: compiler outputs and gate-result.json.
  • .gatemole/artifacts/: raw evidence such as JUnit XML or SARIF.

Code References

Enforced Mode

After a shadow-mode pilot, remove job-level continue-on-error: true. The CLI exits non-zero only when the final decision is block. If the test evidence step records a non-zero exit, the workflow does not attach the JUnit artifact, so the gate reports missing required-test evidence instead of treating failed tests as passing evidence.