Files
gatekeep/action.yml
T
layue13 05f8fad38a
Gatekeep evals / eval-floor (push) Successful in 8s
Dogfood: run Gatekeep on this repo's PRs
Add .github/workflows/gatekeep-pr.yml with uses: ./ and
OPENROUTER_API_KEY from secrets. Forge-agnostic API helper for Gitea.
2026-10-26 20:40:51 +00:00

127 lines
4.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Gatekeep
description: >
Parallel multi-model AI PR review across providers. Agreed findings become
inline comments; disagreements stay in the summary. Fail-closed risk tier.
Self-contained remote uses: git-url@ref. Provider secrets via free-form env names.
author: Gatekeep
inputs:
github-token:
description: Token with pull-requests + checks write
required: true
config-dir:
description: >
Optional consumer config directory (e.g. .github/gatekeep with providers.yaml).
Empty = Action defaults/providers.yaml.
required: false
default: ""
models:
description: >
Optional override of 2–3 models as comma-separated provider:model
(or bare names unique in config). Empty = providers.yaml lists.
required: false
default: ""
skip-draft:
description: Skip draft PRs
required: false
default: "true"
run-verify:
description: Discover + run verify/benchmarks layer
required: false
default: "true"
retain-artifacts:
description: Upload last-good style artifacts from verify
required: false
default: "true"
outputs:
risk_tier:
description: Final published risk tier
value: ${{ steps.review.outputs.risk_tier }}
security_blocking:
description: Whether security check should block
value: ${{ steps.review.outputs.security_blocking }}
agreed_count:
description: Count of multi-model agreed findings
value: ${{ steps.review.outputs.agreed_count }}
runs:
using: composite
steps:
- name: Setup Node (stdlib only)
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install PyYAML (providers.yaml)
shell: bash
run: |
python3 -m pip install --user pyyaml -q
python3 -c "import yaml; print('pyyaml ok', yaml.__version__)"
- name: Discover entry points
id: discover
shell: bash
env:
GATEKEEP_ROOT: ${{ github.workspace }}
GATEKEEP_ACTION: ${{ github.action_path }}
CONFIG_DIR: ${{ inputs.config-dir }}
run: bash "${{ github.action_path }}/scripts/discover.sh"
- name: Policy floor + security scan
id: floor
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
CONFIG_DIR: ${{ inputs.config-dir }}
GATEKEEP_ROOT: ${{ github.workspace }}
GATEKEEP_ACTION: ${{ github.action_path }}
run: bash "${{ github.action_path }}/scripts/policy-floor.sh"
- name: Parallel multi-model review
id: review
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
CONFIG_DIR: ${{ inputs.config-dir }}
GATEKEEP_MODELS: ${{ inputs.models }}
SKIP_DRAFT: ${{ inputs.skip-draft }}
GATEKEEP_ROOT: ${{ github.workspace }}
GATEKEEP_ACTION: ${{ github.action_path }}
POLICY_FLOOR: ${{ steps.floor.outputs.floor }}
POLICY_REASONS: ${{ steps.floor.outputs.reasons }}
SCAN_HARD_FAIL: ${{ steps.floor.outputs.scan_hard_fail }}
DISCOVER_JSON: ${{ steps.discover.outputs.discover_json }}
# Provider API keys: set free-form names from providers.yaml `key`
# on this step's env (inherited from the workflow step). Example:
# env:
# OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
# MY_CUSTOM_KEY: ${{ secrets.MY_CUSTOM_KEY }}
run: |
export PATH="$HOME/.local/bin:$PATH"
# Ensure user-site packages (PyYAML) are importable
export PYTHONPATH="$(python3 -c 'import site; print(site.getusersitepackages())'):${PYTHONPATH:-}"
bash "${{ github.action_path }}/scripts/review.sh"
- name: Verify layer (benchmarks)
if: inputs.run-verify == 'true'
id: verify
shell: bash
env:
GATEKEEP_ROOT: ${{ github.workspace }}
CONFIG_DIR: ${{ inputs.config-dir }}
GATEKEEP_ACTION: ${{ github.action_path }}
DISCOVER_JSON: ${{ steps.discover.outputs.discover_json }}
run: bash "${{ github.action_path }}/scripts/verify-benchmarks.sh"
- name: Retain artifacts
if: inputs.retain-artifacts == 'true' && always()
uses: actions/upload-artifact@v4
with:
name: gatekeep-last-good-${{ github.run_id }}
path: |
${{ github.workspace }}/.gatekeep/out/
${{ github.workspace }}/.gatekeep/verify/
if-no-files-found: ignore
retention-days: 14