Files
gatekeep/action.yml
T
layue13 7b25fefdaa
Gatekeep evals / eval-floor (push) Successful in 6s
Gatekeep evals / eval-floor (pull_request) Successful in 3s
gatekeep / security PR risk high — no open security blockers
Gatekeep / gatekeep (pull_request) Failing after 1m33s
fix: run without setup-node mirror; install PyYAML via venv
Gitea dogfood failed because actions/setup-node is not mirrored
(404 on git.potatolab.uk/actions/setup-node) and pip --user is
blocked by PEP 668. Prefer runner Node with an optional mirrored
setup-node, and install PyYAML into a workspace venv.
2026-10-27 08:02:08 +00:00

151 lines
5.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:
# Gitea forges often lack an actions/setup-node mirror (clone → 404).
# Prefer runner-provided Node; only call setup-node when the mirror exists.
- name: Setup Node (optional mirror)
id: setup_node
continue-on-error: true
uses: actions/setup-node@v4
with:
node-version: "20"
- 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 "Mirror actions/setup-node on this forge, preinstall Node on the runner, or add setup-node 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