GitHub Actions¶
This repo uses GitHub Actions for two things:
- publishing the Gatemole docs site to GitHub Pages
- 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-pagesactions/upload-pages-artifactactions/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:
- Configuring a publishing source for your GitHub Pages site
- actions/upload-pages-artifact
- actions/deploy-pages
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 andgate-result.json..gatemole/artifacts/: raw evidence such as JUnit XML or SARIF.
Code References¶
- CLI command and
--github-summaryflag:internal/gatemole/cli.go $GITHUB_STEP_SUMMARYhandling:appendGitHubSummary- Markdown summary rendering:
RenderGitHubSummary - Gate result JSON:
GateResultFromEvidence - Default release policy:
DefaultReleasePolicy
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.