Files
gatekeep/action.yml
T
layue13 ef13f8806a
Gatekeep evals / eval-floor (push) Successful in 2s
Gatekeep evals / eval-floor (pull_request) Successful in 2s
gatekeep / security PR 风险 medium — 无未关闭安全阻断
Gatekeep / gatekeep (pull_request) Successful in 10m1s
feat: configurable report language (default zh-CN)
Add providers.yaml `language` / Action input `language`; prompts and
published summary/inline honor it. Soften fail-closed messaging when
models 429; prefer cohere/nvidia in the first-3 parallel set for dogfood.
2026-10-27 08:29:48 +00:00

151 lines
5.4 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: ""
language:
description: >
Report language for model prose + published summary/inline comments
(e.g. zh-CN, en). Empty = providers.yaml `language`, else en.
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 }}
GATEKEEP_LANGUAGE: ${{ inputs.language }}
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