Repository navigation
Description
What's wrong
cleanup-pr-artifacts.yml's InventoryNotAuthorized handling only treats a 401/403
as a soft failure when it happens on the top-level org package listing call:
if (method == "GET" and endpoint.split("?", 1)[0] == "orgs/Cratis/packages"
and status in (401, 403)):
raise InventoryNotAuthorized("Package inventory not authorized")Every other GET in inventory() — fetching a specific package
(orgs/Cratis/packages/{type}/{name}) or its versions
(orgs/Cratis/packages/{type}/{name}/versions?state=active) — falls through to the
generic require(status in allowed, ...) check and raises a hard CleanupError on the
same class of authorization failure, failing the job with exit code 1 and no actionable
message beyond API GET failed (HTTP 403).
Where this was observed
Cratis/cratis.studio's "Cleanup PR Artifacts" workflow (which calls this reusable
workflow with secrets: inherit) has been hard-failing on every PR close since
2026-09-10, consistently with API GET failed (HTTP 403):
https://github.com/Cratis/cratis.studio/actions/runs/36643627101
The top-level orgs/Cratis/packages?package_type=... listing succeeds (it enumerates
packages and finds ones associated with the calling repository), so the failure happens
on one of the narrower per-package/per-version lookups once a candidate package is
found — the same authorization gap the InventoryNotAuthorized fix (5435636, 193b80c,
c64bc9b) was meant to close for the listing call, just one level deeper.
(Note: cratis.studio itself never publishes GitHub Packages — no Dockerfile,
.csproj, or .nuspec — so for that repository the workflow is inert; we removed the
caller workflow there rather than carry a permanently-failing check with nothing to
clean up. This issue is about the reusable workflow itself, since any repository that
does publish packages but hits a 403 on a per-package/version lookup would hit the
exact same unhandled hard failure.)
Suggested fix
Extend the InventoryNotAuthorized check to cover the per-package and per-version
endpoints the same way it covers the top-level listing (e.g. match on
orgs/Cratis/packages/ as a prefix rather than only the exact top-level path), so an
authorization gap discovered partway through inventory degrades to the same warning
and No versions deleted outcome instead of a hard failure.
Status
State: Done — Merged in #210, bootstrap rollout succeeded; post-rollout spot-check watch j510 running
Branch: stage-422-atomic-execution (#209, #210)
Scope: 403 on per-package/version lookups -> logged skip; shipped with #138 in one patch PR
Delivered: Nothing yet.
Remaining: To be confirmed.
Follow-ups: None.
Activity
cratis-direct commentedon Oct 9, 2026
Confirming a second affected repository: Cratis/Architecture has been hitting this same hard failure.
Architecture publishes a real NuGet package (
Cratis.Architecture.CodeAnalysis, built fromSource/CodeAnalysis/Cratis.Architecture.CodeAnalysis.csproj) with PR-tagged prerelease versions, so its "Cleanup PR Artifacts" caller workflow (secrets: inherit) exercises the per-package/version lookups ininventory(), not just the top-level org listing.Its workflow run history shows the same pattern described here: every run from 2026-09-10 onward (right after the fail-closed rewrite in c46f3bc) failed at the "Inventory, approve, delete, and verify PR versions" step within a few seconds, e.g. https://github.com/Cratis/Architecture/actions/runs/36643495642 and https://github.com/Cratis/Architecture/actions/runs/36629207860. I couldn't pull the exact
HTTP 403text for those specific runs — GitHub had already expired/purged the logs (410 Gone) by the time I looked — but the timing, the step name, and the fast (~2-4s) failure duration line up exactly with the per-package/version gap this issue describes, and Architecture is a repository that genuinely has packages to inventory, unlikecratis.studio.No code change needed in Architecture's own workflow file — it's a correct, minimal reusable-workflow caller. It'll pick up the fix automatically via
@mainonce this is resolved here.cratis-direct commentedon Oct 9, 2026
Confirming this same failure mode on another repository:
Cratis/Chronicle.Kotlin's "Cleanup PR Artifacts" workflow (which also calls this reusable workflow withsecrets: inherit) hard-failed on PR #119's close with the identicalAPI GET failed (HTTP 403)— https://github.com/Cratis/Chronicle.Kotlin/actions/runs/36843442560.Like
cratis.studio, Chronicle.Kotlin never publishes GitHub Packages either (it publishes exclusively to Maven Central viacom.vanniktech.maven.publish), so a package must have been associated with it from an earlier iteration of its CI for the per-package/version lookup to even be reached. We removed Chronicle.Kotlin's caller workflow for the same reasoncratis.studio's was removed — it has nothing to ever clean up, and this issue plus #103 are the tracked path to a real fix upstream.woksin commentedon Oct 25, 2026
Delivered in #210: a 403 on one package's version inventory is now a warned skip; manual apply and other errors still fail. Rolled out by Bootstrap Common Workflows run 40145560859.