Skip to content

feat(hygiene): add an advisory org-wide repository hygiene sweep - #125

Merged
ExtraToast merged 1 commit into
mainfrom
feat/org-wide-hygiene-sweep
Aug 29, 2026
Merged

feat(hygiene): add an advisory org-wide repository hygiene sweep#125
ExtraToast merged 1 commit into
mainfrom
feat/org-wide-hygiene-sweep

Conversation

@ExtraToast

Copy link
Copy Markdown
Contributor

What

Adds repository-hygiene-sweep.yml — an advisory org-wide counterpart to repository-hygiene-guard.yml. The guard is untouched.

Why

The blocking guard runs in the repo being checked, so every private repo firing it pays a billable minute for a job that averages 6.6 seconds~292 minutes/month across fleet-infra and nix-config.

The check reads PR metadata and a diff. It needs no private repository content, so it can run against the API from a public repo and cost nothing. Minutes are billed to the caller, so the existing uses: shim into this repo saves nothing on its own.

The trade-off, stated plainly

This is advisory. It reports; it cannot block a merge. That's a real difference from the guard, not an implementation detail. repository-hygiene-guard.yml is unchanged, and no repo should lose its blocking gate without someone deciding advisory is acceptable there — exclude-repos exists for the ones that keep it. That decision belongs in #34, not here.

The sweep fails its own run when it finds something, so it's visibly red in Actions without touching any PR's mergeability.

Design notes

  • Changed files come from the pulls/{n}/files API, not a clone. A sweep would otherwise have to check out all 30 repos to diff two refs.
  • Comments are sticky, keyed off an HTML marker and updated in place. An advisory check that appends a new comment every tick is one people mute.
  • Unreadable repos warn and are skipped rather than failing the sweep.

Verification

Run against the live org — including proving the gate can fail, not just that it passed:

Configuration Result
Default deny-globs 30 repos, 38 open PRs, 0 offenders, exit 0
deny: **/*.yml (negative control) 21 offenders detected, run fails
Same globs + allowlist: .* back to 0
exclude-repos: fleet-infra, workspace 30→28 repos, 21→19 offenders

The negative control caught this PR's sibling branches, which is the sort of confirmation that the matching actually works rather than the glob list silently never matching anything.

actionlint clean.

Closes #123

The blocking guard runs in the repo being checked, so every private repo
firing it pays a billable minute for a job that averages 6.6 seconds --
~292 minutes a month across fleet-infra and nix-config.

The check reads pull request metadata and a diff. It needs no private
repository content, so it can run against the API from a public repo and
cost nothing.

This is ADVISORY and says so in its own comment text. It reports; it cannot
block a merge. That is a real difference from the guard, not an
implementation detail -- repository-hygiene-guard.yml stays exactly as it is,
and no repo should lose its blocking gate without someone deciding that
advisory is acceptable there. exclude-repos exists for the repos that keep
the gate.

Changed files come from the pulls/{n}/files API rather than a clone: a sweep
would otherwise have to check out every repo in the org to diff two refs.

Findings are posted as a sticky comment on the offending pull request, keyed
off an HTML marker and updated in place. An advisory check that appends a new
comment every tick is one people mute.

Verified against the live org, including that the gate can fail rather than
only that it passed:
  - default globs: 30 repos, 38 open PRs, 0 offenders, exit 0
  - deny '**/*.yml': 21 offenders detected, run fails
  - allowlist '.*' over the same globs: back to 0
  - exclude-repos: 30 -> 28 repos, 21 -> 19 offenders

Refs #123

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AJYmuNrmiYv9wGRABoQYUi
@ExtraToast ExtraToast added type: feature New user-facing or operator-facing capability. area: tooling Reusable workflows, Gradle, templates, Renovate, and API tooling. component: ci Continuous integration workflow or check behavior. priority: P2 Medium; normal planned work. labels Aug 27, 2026
@ExtraToast
ExtraToast merged commit 345d473 into main Aug 29, 2026
6 checks passed
@ExtraToast
ExtraToast deleted the feat/org-wide-hygiene-sweep branch August 29, 2026 18:47
ExtraToast added a commit to JorisJonkers-dev/.github that referenced this pull request Aug 29, 2026
…runner (#37)

* feat(hygiene): schedule the advisory org hygiene sweep from a public runner

Actions minutes are billed to the caller, never to the repo holding the
reusable workflow. The blocking guard runs in the repo being checked, so each
private repo firing it pays for the run -- ~292 minutes a month across
fleet-infra and nix-config for a job averaging 6.6 seconds. Standard runners
are free in public repositories, and this repo is public.

This does not replace repository-hygiene-guard.yml. The guard blocks a merge;
this only reports. fleet-infra and nix-config are excluded for now precisely
because they still run the blocking guard, so the sweep would otherwise
report the same thing twice. Remove a name from that list in the same change
that removes its gate.

Every 6 hours rather than every 15 minutes: advisory findings gain nothing
from a tighter loop, and the sticky PR comment is the real signal.

Depends on the sweep added in JorisJonkers-dev/github-workflows#125.

Refs #34

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AJYmuNrmiYv9wGRABoQYUi

* docs(hygiene): correct the claim that the guard blocks merges

Repository Hygiene is not a required status check in any repo in this org --
only Pipeline Complete is, and no repo uses classic branch protection.
Verified by reading the rulesets directly rather than inferring from the
workflow's name.

So the guard already only reports, and replacing it with the sweep gives up
nothing. The previous comment claimed a blocking gate that does not exist.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AJYmuNrmiYv9wGRABoQYUi

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: tooling Reusable workflows, Gradle, templates, Renovate, and API tooling. component: ci Continuous integration workflow or check behavior. priority: P2 Medium; normal planned work. type: feature New user-facing or operator-facing capability.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an org-wide repository hygiene sweep that runs on a public runner

1 participant