feat(ci): self-host gatekeeper — repo gates its own PRs (dogfooding)
- 根 gatekeeper.yaml:本仓库声明自己的合并策略(版本化、可审计)
- .gitea/workflows/gatekeeper.yml:PR 触发跑自家 gatekeeper(dry-run/–skip-ci), REQUEST_CHANGES(返回码2)→CI fail 挡 PR,PASS/COMMENT 放行;上传评分卡产物
- 即「用自己的门禁守自己的仓库」——需仓库启用 Actions + 配 GITLINK_TOKEN secret
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802047560号
gitlink-gatekeeper
Languages: English · 简体中文 Jump to: SKILL.md · REFERENCE.md · Design (SSOT) · LICENSE Workflows (Sub-task 3): 1 · Route · 2 · Decide · 3 · Write-back & follow-up
Why gitlink-gatekeeper
PR governance on open-source repos suffers from three real pain points:
gitlink-code-reviewproduces review remarks with no thresholds and no clear “pass/fail” conclusion.gitlink-gatekeeper turns the merge bar into versioned code. A team writes its standards into
gatekeeper.yaml; the gate then aggregates multi-signal evidence for a PR, computes a transparent 0–100 scorecard, issues a three-state verdict, and writes the conclusion back to the PR as a structured comment plus a verdict label.Core values: consistency · auditability · reproducibility · safety.
How it differs from existing Skills
How it differs from the wider industry
Compared with mainstream PR-gate tooling — Danger.js, reviewdog, Mergify, and GitHub branch-protection rulesets — gitlink-gatekeeper differentiates on four points:
common/approved/rejectedthree-state review status, rather than assuming a GitHub-style data model.auto_merge: true, a merge still requiresverdict == PASSand an explicit--apply; the default writes nothing.gatekeeper.yamlthat is auditable, diffable, and shareable across repos.(These are complementary positioning notes, not a knock on those tools — each excels in its own ecosystem.)
Install & prerequisites
The Skill drives the GitLink platform entirely through
gitlink-cli. The companiongitlink-sharedSkill (installed alongside gitlink-cli) covers authentication, global flags, and platform-specific API caveats — read it before first use; see also SKILL.md.Directory structure
Quick start (dry-run — see the scorecard, change nothing)
The gate is dry-run by default: without
--applyit only prints the scorecard. It does not comment, label, or merge.Once you’ve reviewed the verdict, write it back (comment + label) by adding
--apply. The gate still will not merge unlessauto_merge: trueand verdict isPASSand you pass--applyexplicitly.Real-platform validation (not a mock)
The scorecard above is not a hand-written sample — the gate has been run end-to-end against live GitLink PRs through
gitlink-cli. Two runs, two opposite verdicts, both reproducible:① Dry-run on a real upstream PR → ✅ PASS 90/100 ·
Gitlink/gitlink-cli#15222 — “feat(org): add team project binding shortcuts” · evidence:workflow/demo/real-run-pr15222/scorecard.md→ total 90 ≥ pass(85) and no hard-gate failure → PASS. Dry-run, so nothing was written to the upstream repo.
② Apply on a fork PR → ❌ REQUEST_CHANGES 40/100, with a real write-back ·
recorder/gitlink-cli#1 (pull_request_id 15289) — a deliberately under-tested change · evidence:workflow/demo/real-run-apply-pr15289/scorecard.md→ hard gate
require_tests_for_src_changesfired (source changed, no tests), short-circuiting to REQUEST_CHANGES at total 40. With--apply, the gate actually wrote back to the live platform:id 472741);recorder/gitlink-clisummarising the must-fix items (the divide-by-zeropanicwhenqps=0) and the failed hard gate, linked back to the PR.Determinism, machine-checked. Same policy + same PR input → the same scorecard, bit-for-bit. The runnable orchestrator’s output (
scripts/gatekeeper_workflow.py, pure stdlib) matches every number in these documented scorecards exactly — seeworkflow/docs/verification.mdfor the full reproduction commands and the parse-bug found and fixed during the live run.gatekeeper.yamlat a glanceThe policy file is read from the repo root
gatekeeper.yaml(override with--policy <path>), falling back to a built-in default. Five weighted dimensions must sum to 100; hard gates short-circuit toREQUEST_CHANGES; thresholds map the total to a verdict.See REFERENCE.md for every field and the full scoring algorithm.
Three-state verdict
total ≥ thresholds.passand no hard-gate failuregatekeeper:pass; merge only ifauto_merge: true+--applytotal < thresholds.request_changesgatekeeper:needs-changes; posted as a labelledCOMMENTgatekeeper:review; advisory commentSafe defaults (never auto-merge)
--applymeans nothing is written, labelled, or merged.auto_mergeisfalse; even whentrue, a merge requiresverdict == PASSand an explicit--apply.Contest mapping (CCF GitLink Contribution Track)
gitlink-gatekeeper is the flagship deliverable of Sub-task 2 (intelligent PR governance) for the CCF GitLink intelligent-service contribution track, and it threads through all three sub-tasks:
labelcommand. The gate writes verdicts as labels (gatekeeper:pass/:needs-changes/:review), which is exactly why this work contributes the newlabelshortcut group to gitlink-cli — upstream PRGitLink/gitlink-cli#89. Label CRUD has been separately verified all-green on the real platform. The gate writes every verdict as an advisorycommoncomment + a label, leaving strong approve/reject to humans.gatekeeper.yamlpolicy → deterministic scorecard → three-state verdict → structured write-back. This README + SKILL.md + REFERENCE.md are the core.workflow/. A reproducible “PR gatekeeper loop” of ≥3 steps: route (suggest reviewers by changed-file path) → decide (run the gate) → write-back & follow-up (post the scorecard, apply the label, and onREQUEST_CHANGESopen a tracking issue summarising the must-fix items, linked to the PR).License
MulanPSL-2.0 — consistent with the upstream gitlink-cli.