源码快照 @ 2026-09-02 (source-only, 剔除非源码素材)
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
# Warden security clearance.
|
||||
#
|
||||
# Grants or revokes a "security clearance" review on PRs based on blocking
|
||||
# findings from the Warden skills: all security findings plus high desktop↔den
|
||||
# sync findings. Advisory sync findings never withhold clearance. Humans still
|
||||
# review and merge; the clearance only satisfies the required-review gate in
|
||||
# the branch ruleset for clean diffs.
|
||||
#
|
||||
# Why workflow_run: this file always executes from the default branch, so a
|
||||
# PR cannot tamper with the clearance logic. The verdict step additionally
|
||||
# refuses to self-clear any PR that touches review machinery
|
||||
# (.github/, warden.toml, .warden/, .agents/skills/, .claude/skills/).
|
||||
#
|
||||
# Identity: a dedicated GitHub App (WARDEN_APP_ID / WARDEN_PRIVATE_KEY in the
|
||||
# `warden-clearance` environment). The app never pushes commits, so
|
||||
# require_last_push_approval always holds (clearance identity != pusher !=
|
||||
# author). Until the app secrets are configured this workflow no-ops.
|
||||
|
||||
name: Warden Clearance
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Warden]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
concurrency:
|
||||
group: warden-clearance-${{ github.event.workflow_run.head_branch }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
clearance:
|
||||
if: >-
|
||||
github.event.workflow_run.event == 'pull_request' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
github.event.workflow_run.head_repository.full_name == github.repository
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
environment: warden-clearance
|
||||
steps:
|
||||
- name: Check clearance identity is configured
|
||||
id: identity
|
||||
env:
|
||||
APP_ID: ${{ secrets.WARDEN_APP_ID }}
|
||||
run: |
|
||||
if [ -z "$APP_ID" ]; then
|
||||
echo "WARDEN_APP_ID is not configured; clearance disabled."
|
||||
echo "configured=false" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "configured=true" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Download clearance summary
|
||||
if: steps.identity.outputs.configured == 'true'
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
name: warden-summary
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
- name: Evaluate verdict
|
||||
if: steps.identity.outputs.configured == 'true'
|
||||
id: verdict
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
REPO: ${{ github.repository }}
|
||||
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
verdict() { echo "verdict=$1" >> "$GITHUB_OUTPUT"; exit 0; }
|
||||
|
||||
summary_sha="$(jq -r '.head_sha' warden-summary.json)"
|
||||
blocking="$(jq -r '.blocking_count // .findings_count' warden-summary.json)"
|
||||
advisory="$(jq -r '.sync_advisory_count // 0' warden-summary.json)"
|
||||
echo "advisory=$advisory" >> "$GITHUB_OUTPUT"
|
||||
|
||||
if [ "$summary_sha" != "$HEAD_SHA" ]; then
|
||||
echo "Summary SHA ($summary_sha) does not match analyzed SHA ($HEAD_SHA); skipping."
|
||||
verdict skip
|
||||
fi
|
||||
|
||||
pr="$(gh api "repos/$REPO/commits/$HEAD_SHA/pulls" --jq '.[0].number // empty')"
|
||||
if [ -z "$pr" ]; then
|
||||
echo "No PR associated with $HEAD_SHA; skipping."
|
||||
verdict skip
|
||||
fi
|
||||
echo "pr=$pr" >> "$GITHUB_OUTPUT"
|
||||
|
||||
current_head="$(gh api "repos/$REPO/pulls/$pr" --jq '.head.sha')"
|
||||
if [ "$current_head" != "$HEAD_SHA" ]; then
|
||||
echo "PR #$pr head moved to $current_head; skipping stale run."
|
||||
verdict skip
|
||||
fi
|
||||
|
||||
# Never self-clear a PR that touches the review machinery.
|
||||
guarded="$(gh api --paginate "repos/$REPO/pulls/$pr/files" --jq '.[].filename' \
|
||||
| grep -E '^(\.github/|warden\.toml$|\.warden/|\.agents/skills/|\.claude/skills/)' || true)"
|
||||
if [ -n "$guarded" ]; then
|
||||
echo "PR #$pr touches review machinery; human review required:"
|
||||
echo "$guarded"
|
||||
verdict guarded
|
||||
fi
|
||||
|
||||
if [ "$blocking" = "0" ]; then
|
||||
echo "No blocking findings for $HEAD_SHA."
|
||||
verdict clear
|
||||
else
|
||||
echo "$blocking blocking finding(s) on $HEAD_SHA."
|
||||
verdict flagged
|
||||
fi
|
||||
|
||||
- name: Mint clearance token
|
||||
if: steps.verdict.outputs.verdict == 'clear' || steps.verdict.outputs.verdict == 'flagged'
|
||||
id: app
|
||||
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
|
||||
with:
|
||||
app-id: ${{ secrets.WARDEN_APP_ID }}
|
||||
private-key: ${{ secrets.WARDEN_PRIVATE_KEY }}
|
||||
|
||||
- name: Grant clearance
|
||||
if: steps.verdict.outputs.verdict == 'clear'
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.app.outputs.token }}
|
||||
REPO: ${{ github.repository }}
|
||||
PR: ${{ steps.verdict.outputs.pr }}
|
||||
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
RUN_URL: ${{ github.event.workflow_run.html_url }}
|
||||
ADVISORY: ${{ steps.verdict.outputs.advisory }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
BODY="**Warden security clearance: clear.** No blocking findings (security or desktop↔den sync) in this diff (\`$HEAD_SHA\`)."
|
||||
if [[ "$ADVISORY" =~ ^[0-9]+$ ]] && [ "$ADVISORY" -gt 0 ]; then
|
||||
BODY="$BODY $ADVISORY advisory desktop↔den sync note(s) were posted as review comments; they do not affect clearance."
|
||||
fi
|
||||
BODY="$BODY Automated clearance satisfies the required-review gate only — a human still reviews and merges. [Analysis run]($RUN_URL)"
|
||||
gh api "repos/$REPO/pulls/$PR/reviews" \
|
||||
-f event=APPROVE \
|
||||
-f commit_id="$HEAD_SHA" \
|
||||
-f body="$BODY"
|
||||
|
||||
- name: Revoke stale clearance
|
||||
if: steps.verdict.outputs.verdict == 'flagged'
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.app.outputs.token }}
|
||||
REPO: ${{ github.repository }}
|
||||
PR: ${{ steps.verdict.outputs.pr }}
|
||||
APP_SLUG: ${{ steps.app.outputs.app-slug }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
rid="$(gh api "repos/$REPO/pulls/$PR/reviews" \
|
||||
--jq "[.[] | select(.user.login == \"${APP_SLUG}[bot]\" and .state == \"APPROVED\")] | last | .id // empty")"
|
||||
if [ -n "$rid" ]; then
|
||||
gh api -X PUT "repos/$REPO/pulls/$PR/reviews/$rid/dismissals" \
|
||||
-f message="Warden found new blocking findings (security or desktop↔den sync) on the latest diff; clearance revoked." \
|
||||
|| echo "Could not dismiss review $rid (may already be dismissed)."
|
||||
else
|
||||
echo "No active clearance to revoke."
|
||||
fi
|
||||
Reference in New Issue
Block a user