Automatically approve or block PRs based on Overmind's risk analysis and change signals.
The action parses the Overmind markdown comment that already appears in PRs and makes approval/blocking decisions based on configurable thresholds.
The action reads the markdown comment that Overmind posts containing:
- π΄ Signals (Routine, Cost, Policies, Custom)
- π₯ Risks (High, Medium, Low severity)
- π₯ Blast Radius (Items/Edges count)
- Expected Changes
Based on the parsed analysis, the action:
- Approves the PR if all safety checks pass
- Blocks the PR (requests changes) if risks exceed thresholds
- Comments with explanation of the decision
- Outputs structured data for other workflow steps
- Parse the Markdown Comment - Extracts signals, risks, and blast radius from Overmind's comment
- Apply Decision Logic - Evaluates against configurable thresholds in priority order
- Take GitHub Action - Creates PR review (approve or request changes) with explanation
Rules are checked in order:
- High risks β BLOCK (if
block-on-high-risks: true) - Policy violations β BLOCK (if policy signals <= threshold)
- Cost concerns β BLOCK (if cost signals <= threshold)
- Too many medium risks β BLOCK (if count >
max-medium-risks) - Too many low risks β BLOCK (if count >
max-low-risks) - Non-routine changes β BLOCK (if routine score <
min-routine-score) - All checks pass β APPROVE
name: Overmind Analysis
on: [pull_request]
jobs:
terraform-plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Plan
run: |
terraform init
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
- uses: overmindtech/actions/submit-plan@main
with:
ovm-api-key: ${{ secrets.OVM_API_KEY }}
plan-json: ./tfplan.json
auto-approval:
runs-on: ubuntu-latest
needs: terraform-plan
permissions:
pull-requests: write
steps:
- uses: overmindtech/approval-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
block-on-high-risks: true
max-medium-risks: 3jobs:
auto-approval-prod:
if: github.base_ref == 'main'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: overmindtech/approval-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
block-on-high-risks: true
max-medium-risks: 1 # Stricter for prod
min-routine-score: 0 # Only routine changes
policy-signal-threshold: -1 # Any policy concern blocks
auto-approval-dev:
if: github.base_ref == 'develop'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: overmindtech/approval-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
block-on-high-risks: true
max-medium-risks: 5 # More permissive for dev
min-routine-score: -2 # Allow some variation| Input | Description | Default | Required |
|---|---|---|---|
github-token |
GitHub token for PR access | - | β Yes |
block-on-high-risks |
Block if any high risks found | true |
No |
max-medium-risks |
Maximum medium risks before blocking | 3 |
No |
max-low-risks |
Maximum low risks before blocking | 10 |
No |
policy-signal-threshold |
Block if policy signals <= value | -2 |
No |
cost-signal-threshold |
Block if cost signals <= value | -2 |
No |
min-routine-score |
Require routine score >= value | -1 |
No |
auto-approve |
Actually approve/block PRs (vs just comment) | true |
No |
wait-timeout |
Seconds to wait for Overmind comment | 300 |
No |
| Output | Description |
|---|---|
decision |
The decision made: approved, blocked, or skipped |
reason |
Human-readable explanation of the decision |
risks-summary |
JSON object with risk counts: {"high": 0, "medium": 1, "low": 2} |
change-url |
Link to Overmind analysis |
- uses: overmindtech/approval-action@v1
id: approval
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check decision
run: |
echo "Decision: ${{ steps.approval.outputs.decision }}"
echo "Reason: ${{ steps.approval.outputs.reason }}"
echo "Risks: ${{ steps.approval.outputs.risks-summary }}"Signal severity is calculated from the emoji color and bar chart length in Overmind comments:
- Emoji: π΄ = -1, π’ = +1, βͺ = 0
- Bar Chart: Length determines magnitude (e.g.,
ββ βββ= 5) - Severity:
emoji_sign Γ bar_length
Examples:
π΄ ββ βββ= -1 Γ 5 = -5π’ βββ= +1 Γ 3 = +3βͺ β= 0 Γ 1 = 0
- Timeout waiting for comment β Decision:
skipped(doesn't block deployment) - Parse error β Decision:
skipped(fails safe, skips approval) - GitHub API error β Retries 3x with exponential backoff, then fails the action
The action requires the following GitHub permissions:
permissions:
pull-requests: write # To create reviews and commentsnpm install
npm run buildnpm test
npm run test:coverageUse act to test the action locally:
act pull_request -e .github/workflows/test.ymlApache 2.0 - See LICENSE file for details.