Skip to content

GitHub Actions Governance Gate

Official GitHub Action

uses: archetypal-ai/govern-action@v1

Complete workflow

.github/workflows/govern-build.yml
name: GOVERN Build Gate
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches: [main, develop]
schedule:
- cron: '0 6 * * *' # Daily regression at 6am UTC
workflow_dispatch: # Manual trigger
jobs:
govern-build:
name: AI Governance Gate
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # Required for SARIF upload
pull-requests: write # Required for PR comments
steps:
- name: Checkout
uses: actions/checkout@v4
- name: GOVERN Build Assessment
id: govern
uses: archetypal-ai/govern-action@v1
with:
api-key: ${{ secrets.GOVERN_API_KEY }}
org-id: ${{ secrets.GOVERN_ORG_ID }}
model: ${{ vars.AI_MODEL }}
test-prompts: tests/govern/prompts.json
baseline-branch: main
fail-on: flag
output-format: sarif
post-pr-comment: true
generate-responses: true
model-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Upload SARIF to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: govern-results.sarif
category: govern-build
- name: Upload Results Artifact
uses: actions/upload-artifact@v4
if: always()
with:
name: govern-results-${{ github.sha }}
path: |
govern-results.json
govern-results.sarif
retention-days: 30
- name: Comment on PR
if: github.event_name == 'pull_request' && failure()
uses: actions/github-script@v7
with:
script: |
const results = require('./govern-results.json');
const body = `## GOVERN Build Failed\n\n${results.summary}\n\nSee full report: ${results.report_url}`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body
});

Action inputs reference

InputRequiredDefaultDescription
api-keyYesGOVERN API key
org-idYesOrganization ID
modelYesModel ID for test generation
test-promptsYesPath to test prompts JSON
test-responsesNo(generated)Pre-generated responses (faster)
generate-responsesNotrueCall model to generate responses
model-api-keyNo*Model API key (if generating)
baseline-branchNomainBranch to use as drift baseline
fail-onNoflagblock, flag, or never
output-formatNotabletable, json, sarif, junit
post-pr-commentNotruePost results as PR comment
violation-thresholdNo0Max violations before fail
gov-configNo.govern.yamlPath to config file

Action outputs

OutputDescription
resultpass or fail
total-testsTotal test cases run
passed-testsTests that passed
failed-testsTests that failed
violationsJSON array of violations
report-urlURL to full GOVERN dashboard report

Using pre-generated responses

Generating responses costs money. For PRs, pre-generate responses and store them:

# On main branch merge: regenerate and commit responses
- name: Regenerate governance responses
if: github.ref == 'refs/heads/main'
run: |
npm install -g @archetypal-ai/govern-cli
govern assess \
--batch-file tests/govern/prompts.json \
--model ${{ vars.AI_MODEL }} \
--generate-only \
--output json > tests/govern/responses.json
env:
GOVERN_API_KEY: ${{ secrets.GOVERN_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Commit responses
run: |
git config user.name "github-actions[bot]"
git add tests/govern/responses.json
git commit -m "chore: update governance test responses [skip ci]"
git push

Then on PRs, use the committed responses:

- uses: archetypal-ai/govern-action@v1
with:
test-prompts: tests/govern/prompts.json
test-responses: tests/govern/responses.json # No API call needed
generate-responses: false

Branch protection

Add GOVERN Build as a required status check:

  1. Settings → Branches → Branch protection rules
  2. Select your protected branch (e.g., main)
  3. Check “Require status checks to pass before merging”
  4. Search and select “GOVERN Build Gate”
  5. Check “Require branches to be up to date before merging”