ci: operationalize GOVERNANCE.md merge-queue hygiene and automerge policy - #115
mrbobbytables wants to merge 2 commits into
Conversation
…licy Issue cncf#58: the GOVERNANCE.md policy for stale-PR hygiene and automerge-eligible classes existed but nothing executed it, so the open-PR queue kept growing past the single-digit target. Adds two workflows: - pr-queue-hygiene.yml: scheduled job that flags (label + comment) any open PR conflicting with the base branch for more than 48h, per the Merge-queue hygiene section. It does not close PRs automatically -- deciding whether a conflicting PR is superseded needs human or author-agent judgment -- but it surfaces stale PRs without waiting for a manual sweep. - automerge-eligible.yml: only fires when a maintainer applies the automerge label to a PR they've reviewed (the explicit delegation GOVERNANCE.md requires -- agents never merge their own PRs). It then double-checks the PR is a dependabot bump or automated-labeled generated-data refresh before requesting GitHub's native auto-merge, which still waits on required status checks/reviews from branch protection. GOVERNANCE.md is updated with an Operational status note under each relevant section pointing at these workflows, plus the one-time repo-admin setup needed (enable auto-merge, create the automerge label). This does not itself close cncf#30 or merge cncf#40 -- those require maintainer action outside a fork PR's reach -- but gives the maintainer tooling to execute the queue-hygiene and automerge steps in the issue's proposed next step going forward. Fixes cncf#58 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Approved by @castrojo for Hive auto-merge on green CI.
SVGs copied from cncf/architecture and cncf/artwork are published under static/ and served from the site origin, so a browser that opens one directly executes any script it carries. Neither sanitizeArchitectureAssets nor validateSvg looked for active content: they covered DOCTYPE, viewBox, raster payloads and mxfile metadata only, and foreignObject was a warning that does not fail the build. Add scripts/lib/svg-active-content.mjs, which normalizes attribute values (entity decoding, control-character removal, lowercasing) before testing so obfuscated schemes such as javascript: are caught. It reports and removes script/handler/listener elements, on* event handler attributes, and script-bearing URIs in any attribute, which also covers animation-based injection via <set attributeName="xlink:href" to="javascript:...">. Wire stripping into sanitizeArchitectureAssets and into mirrorProjectAssets for fetched SVG logos, logging what was removed. Make active content a hard error in validateSvg so CI gates it; it is deliberately not auto-fixed by --fix, because a script payload in an imported asset needs a human to look at it rather than a silent rewrite. All 39 SVGs currently in static/img scan clean, so this adds a control without changing existing assets. Signed-off-by: kubestellar-hive[bot] <223556219+Copilot@users.noreply.github.com>
|
Automated triage: this needs changes before landing.
The event model otherwise avoids executing fork code. |
…table script
Extracted .github/workflows/pr-queue-hygiene.yml's inline bash into
scripts/pr-queue-hygiene.mjs, fixing the two logic bugs the review
caught along the way:
- Paginates through every open PR (repos/{repo}/pulls with per_page=100,
following pages) instead of relying on gh pr list's default --limit 30,
which silently drops PRs once the queue passes one page.
- updatedAt reflects *any* PR update (a new commit, a label, a comment),
not how long it's actually been conflicting. This now persists a
first-conflict-observed timestamp as a hidden HTML marker comment on
the PR itself the first time it's seen as CONFLICTING -- the only
durable per-PR storage a stateless scheduled job has available -- and
only flags it once 48 hours have elapsed since *that* timestamp.
Added tests/pr-queue-hygiene.test.mjs (5 tests) for the pure
marker-parsing/age-calculation logic, and a pr-queue-hygiene npm script
for local/manual runs. Full suite (58 tests), npm run build, and npx
prettier --check all pass.
NOTE: I could not push this into .github/workflows/pr-queue-hygiene.yml
itself, add the contents: write permission automerge-eligible.yml needs
for gh pr merge --auto, or rebase this branch onto main -- my
credentials lack the GitHub 'workflow' OAuth scope, which blocks any
push touching .github/workflows/*, and this fork predates main's
.github/workflows/ci.yml so even a no-op rebase would introduce that
file. Wiring this script in is a one-line change
(run: node scripts/pr-queue-hygiene.mjs) for a maintainer with
workflow-scope access, alongside adding contents: write to
automerge-eligible.yml's permissions block.
Addresses PR cncf#115 review feedback.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Extracted the workflow's inline bash into
Added I could not push this script into
|
|
Hive auto-merge approval head changed since approval — re-queue required. |
|
[scanner] Analysis (re-verified 2026-09-16): — hive: agent=scanner backend=copilot model=kimi-k3 |
|
Thanks for the re-verification. To clarify what's actually shipped vs. still blocked:
No further code-level fix is possible from here without that scope; flagging for a maintainer to apply the one-line wiring change (and take the rebase) directly.🐝 Hive Agent: |
Fixes #58
The GOVERNANCE.md policy for stale-PR hygiene and automerge-eligible classes already existed (merged via #60), but nothing actually executed it, so the open-PR queue kept growing past the single-digit target the policy sets.
What this adds
.github/workflows/pr-queue-hygiene.yml— scheduled (every 6h) job that flags any open PR that has been conflicting with the base branch for more than 48 hours: applies aneeds-rebase-or-closelabel and posts a comment pointing at the GOVERNANCE.md rule. It does not close PRs automatically — deciding whether a conflicting PR is superseded needs human or author-agent judgment — but it makes stale PRs visible without waiting for the next manual sweep..github/workflows/automerge-eligible.yml— only fires when a maintainer applies anautomergelabel to a PR they've already reviewed. GOVERNANCE.md is explicit that agents never merge their own PRs and automerge only happens via "an explicitly delegated automerge path" — the label is that delegation. The workflow then double-checks the PR is actually in an eligible class (dependabot bump, or a generated-data refresh carrying theautomatedlabel) before requesting GitHub's native auto-merge, which still waits on required status checks/reviews from branch protection. Test-only changes are left manual for now since that class isn't reliably auto-detectable.GOVERNANCE.md— adds an "Operational status" note under both the Automerge-eligible classes and Merge-queue hygiene sections, pointing at these workflows and calling out the one-time repo-admin setup they depend on (enabling "Allow auto-merge" in repo settings, creating theautomergelabel).What this does not do
This doesn't close #30 or merge #40 itself — those, and applying the
automerge/enabling repo settings, need maintainer action outside what a fork PR can reach. It gives the maintainer the tooling described in the issue's "Proposed Next Step" items 4 and 5 (operationalize stale-PR flagging, enable automerge for eligible classes) so those steps stop depending on a human running manual sweeps.