Refresh.yml run 104's last step failed with HTTP 403 from urllib. Root cause: wrong API path (the script appended /versions which Gitea interprets as a version literal) plus Cloudflare WAF blocking Python-urllib's default User-Agent. Dry-run on the current package keeps latest + date tag + sha-short, skips 2 blob versions, deletes nothing yet (cutoff is 90 days).
Refresh.yml run 104's last step failed with HTTP 403 from urllib. Root cause: wrong API path (the script appended `/versions` which Gitea interprets as a version literal) plus Cloudflare WAF blocking Python-urllib's default User-Agent. Dry-run on the current package keeps latest + date tag + sha-short, skips 2 blob versions, deletes nothing yet (cutoff is 90 days).
The script was hitting /api/v1/packages/{owner}/container/{name}/versions
which doesn't exist (Gitea returns 404 — interpreting the request as a
version named "versions"). Replaced with the actual endpoint
/api/v1/packages/{owner}/container/{name} which returns the array of
version rows directly. Delete path is now
/api/v1/packages/{owner}/container/{name}/{version} (URL-encoded version
string, not numeric ID).
Refactored the keep-set: always preserve `latest`, top --keep-latest
YYYY.MM.DD date tags AND top --keep-latest short-SHA tags (the rollback
pins) by created_at desc. Anything within --keep-days is kept; older
date/sha tags are deleted. sha256:* blob versions are skipped — Gitea's
internal package GC reclaims them when their last tag goes away.
Also added an explicit User-Agent header because git.jpaul.io sits
behind Cloudflare, whose Bot Fight Mode 403s the default
"Python-urllib/X.Y" UA with error code 1010. Affected run 104's GC
step (curl was fine; urllib was blocked).
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
justin
merged commit 761552fe69 into main2026-05-22 13:44:44 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Refresh.yml run 104's last step failed with HTTP 403 from urllib. Root cause: wrong API path (the script appended
/versionswhich Gitea interprets as a version literal) plus Cloudflare WAF blocking Python-urllib's default User-Agent. Dry-run on the current package keeps latest + date tag + sha-short, skips 2 blob versions, deletes nothing yet (cutoff is 90 days).The script was hitting /api/v1/packages/{owner}/container/{name}/versions which doesn't exist (Gitea returns 404 — interpreting the request as a version named "versions"). Replaced with the actual endpoint /api/v1/packages/{owner}/container/{name} which returns the array of version rows directly. Delete path is now /api/v1/packages/{owner}/container/{name}/{version} (URL-encoded version string, not numeric ID). Refactored the keep-set: always preserve `latest`, top --keep-latest YYYY.MM.DD date tags AND top --keep-latest short-SHA tags (the rollback pins) by created_at desc. Anything within --keep-days is kept; older date/sha tags are deleted. sha256:* blob versions are skipped — Gitea's internal package GC reclaims them when their last tag goes away. Also added an explicit User-Agent header because git.jpaul.io sits behind Cloudflare, whose Bot Fight Mode 403s the default "Python-urllib/X.Y" UA with error code 1010. Affected run 104's GC step (curl was fine; urllib was blocked). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>