Files
gatekeep/action.yml
T
layue13 7a581254bf
Gatekeep evals / eval-floor (push) Successful in 2s
Gatekeep evals / eval-floor (pull_request) Successful in 2s
gatekeep / security PR risk high — no open security blockers
Gatekeep / gatekeep (pull_request) Successful in 1m12s
fix: drop setup-node uses; fix GITHUB_OUTPUT python quoting
Remove the optional setup-node step (still 404s as ##[error] on this
forge). Fix review.sh output writer — escaped quotes in a one-liner
caused SyntaxError after an otherwise successful publish.
2026-10-27 08:06:30 +00:00

144 lines
5.2 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:
# Do not uses: actions/setup-node — many Gitea forges have no mirror (404).
# Runner image / consumer workflow must provide Node >= 18.
- name: Require Node.js
shell: bash
run: |
if ! command -v node >/dev/null 2>&1; then
echo "::error::Node.js >= 18 required for Gatekeep (merge-findings.js / publish.js)."
echo "Preinstall Node on the runner, or add a mirrored setup-node step before uses: ./."
exit 1
fi
node --version
# PEP 668 blocks pip --user on many runners; use a workspace venv instead.
- name: Install PyYAML (providers.yaml)
shell: bash
run: |
if python3 -c "import yaml" 2>/dev/null; then
python3 -c "import yaml; print('pyyaml ok', yaml.__version__)"
exit 0
fi
VENV="${{ github.workspace }}/.gatekeep/.venv"
mkdir -p "$(dirname "$VENV")"
python3 -m venv "$VENV"
"$VENV/bin/pip" install -q pyyaml
echo "$VENV/bin" >> "$GITHUB_PATH"
echo "VIRTUAL_ENV=$VENV" >> "$GITHUB_ENV"
"$VENV/bin/python" -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