Skip to content

ops(ci): sweep closed-PR preview environments daily#8620

Merged
JSONbored merged 1 commit into
mainfrom
claude/cleanup-preview-environments
Jul 25, 2026
Merged

ops(ci): sweep closed-PR preview environments daily#8620
JSONbored merged 1 commit into
mainfrom
claude/cleanup-preview-environments

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Investigated why the repo had 1260 GitHub Environments — 1254 of them were preview/pr-<N> entries (spanning PR #4140#8617), all for already-closed PRs.

Root cause: ui-preview.yml/ui-preview-deploy.yml (via the shared deploy-ui-preview composite action) call createDeployment({ environment: "preview/pr-<N>", transient_environment: true, ... }) for every PR that gets a UI preview build. GitHub auto-creates the Environment object the first time a deployment targets a name that doesn't exist — transient_environment: true is purely a display hint for the Deployments UI, it does not trigger any cleanup. Nothing in the repo ever called the delete-environment API. Confirmed none of the 1254 carry protection rules (pure disposable deploy-tracking metadata).

Immediate fix: swept and deleted all 1254 directly via the API (using my own already-sufficiently-scoped session token) — 0 environments remain today besides release, release-beta, preview, and two other pre-existing ones.

Ongoing fix (this PR): a new scheduled workflow, mirroring cache-cleanup.yml's existing fix for the identical class of problem (GHA caches instead of environments) — batched on a daily schedule (07:20 UTC, offset from the other daily cron cluster), not a pull_request: [closed] trigger, so PR-close bursts never queue a runner per event and compete with real CI for the org's concurrent-runner cap. There's no storage-budget urgency here the way there was for the 10GB cache cap, so daily (vs. cache-cleanup's 6-hourly) is plenty.

Required before this can actually run

ENVIRONMENT_ADMIN_TOKEN — a new repo secret. Deleting an environment requires repo scope (classic PAT) or Administration: write (fine-grained PAT) — confirmed against GitHub's own docs that the default GITHUB_TOKEN can never be granted this via a permissions: block, unlike cache deletion (which actions: write already covers). Scope a fine-grained PAT to this repo only with Administration: write, add it as a repo secret (not environment-scoped — this workflow doesn't use a GitHub Environment itself).

Test plan

  • python3 -c "import yaml; yaml.safe_load(...)" — valid YAML
  • npm run actionlint — clean
  • Verified live: GET /repos/JSONbored/loopover/environments now returns 0 preview/pr-* entries

ui-preview.yml / ui-preview-deploy.yml (via the shared deploy-ui-preview
composite) create a "preview/pr-<N>" GitHub Environment via createDeployment
the first time a PR gets a preview build -- transient_environment: true is
only a display hint, it never triggers deletion, and nothing else in the
repo ever calls the delete-environment API. Confirmed live: 1254 of 1260
environments were preview/pr-* entries for already-closed PRs (spanning PR
#4140-#8617), none carrying protection rules -- cleaned up directly via the
API as a one-time sweep before adding this workflow.

Mirrors cache-cleanup.yml's existing fix for the identical class of
problem (GHA caches instead of environments): batched on a daily schedule,
not a pull_request:[closed] trigger, so PR-close bursts never queue a
runner per event and compete with real CI. No storage-budget urgency here
unlike the 10GB cache cap, so daily is enough.

Needs a new ENVIRONMENT_ADMIN_TOKEN secret -- deleting an environment
requires repo scope (classic PAT) or Administration:write (fine-grained
PAT); GITHUB_TOKEN can never be granted this via a permissions: block,
confirmed against GitHub's own docs.
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@JSONbored JSONbored self-assigned this Jul 25, 2026
@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.76%. Comparing base (a266d7a) to head (b75da18).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8620   +/-   ##
=======================================
  Coverage   92.76%   92.76%           
=======================================
  Files         797      797           
  Lines       79355    79355           
  Branches    24034    24034           
=======================================
  Hits        73616    73616           
  Misses       4592     4592           
  Partials     1147     1147           
Flag Coverage Δ
backend 93.64% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 25, 2026
@JSONbored
JSONbored merged commit 9e58bf5 into main Jul 25, 2026
7 checks passed
@JSONbored
JSONbored deleted the claude/cleanup-preview-environments branch July 25, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant