Files
layue13 c6c2d071fb
Gatekeep evals / eval-floor (push) Successful in 3s
Gatekeep evals / eval-floor (pull_request) Successful in 15s
Gatekeep / gatekeep (pull_request) Failing after 1m46s
fix: harden partial 429 success, fallbacks, zh errors
Retry HTTP 429 with backoff; keep models beyond first 3 as
fallbacks; degrade agreement when some models fail; force-high
risk only if zero usable responses. Clearer zh-CN errors/docs for
dogfood uses: ./ rebase + workflow_dispatch re-run.
2026-10-27 08:35:52 +00:00

159 lines
5.8 KiB
YAML
Raw Permalink 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
env:
GATEKEEP_LANGUAGE: ${{ inputs.language }}
run: |
if ! command -v node >/dev/null 2>&1; then
lang="${GATEKEEP_LANGUAGE:-}"
if [[ "${lang,,}" == zh* ]]; then
echo "::error::Gatekeep 需要 Node.js ≥ 18(merge-findings.js / publish.js)。"
echo "请在 runner 预装 Node,或在 uses: ./ 之前加本 forge 已镜像的 setup-node;不要依赖未镜像的 actions/setup-node。"
else
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: ./."
fi
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