Mirror Cleanup: Deleting Private GHCR Packages ποΈΒΆ
The cli.contributing.mirror.cleanup module deletes GHCR container packages filtered by
prefix and visibility. Use it to remove stale private mirror packages that
were pushed before the repository switched to GITHUB_TOKEN-based
authentication (which now makes packages public automatically).
Prerequisites πΒΆ
You MUST have a classic Personal Access Token (PAT) with the
delete:packages scope. The gh auth token and GITHUB_TOKEN issued by
GitHub Actions do NOT include this scope and will fail with HTTP 403.
Create a classic PAT πΒΆ
Go to github.com/settings/tokens.
Click Generate new token β Generate new token (classic).
Enable the
delete:packagesscope.Copy the generated token.
Export it before running the script:
export GITHUB_TOKEN=<your-pat>
Usage π»ΒΆ
python -m cli.contributing.mirror.cleanup \
--ghcr-namespace <user|org> \
--ghcr-prefix <repo>/mirror \
--visibility private \
--dry-run
Remove --dry-run to actually delete.
Arguments βοΈΒΆ
Argument |
Default |
Description |
|---|---|---|
|
required |
GitHub username or org that owns the packages |
|
|
Only delete packages whose name starts with |
|
|
Delete packages with this visibility ( |
|
off |
List matching packages without deleting them |
Example: Delete all private mirror packages for infinito-nexus-core π§ΉΒΆ
# Preview (requires a classic PAT with delete:packages)
GITHUB_TOKEN=<your-pat> python -m cli.contributing.mirror.cleanup \
--ghcr-namespace kevinveenbirkenbach \
--ghcr-prefix infinito-nexus-core/mirror \
--visibility private \
--dry-run
# Delete
GITHUB_TOKEN=<your-pat> python -m cli.contributing.mirror.cleanup \
--ghcr-namespace kevinveenbirkenbach \
--ghcr-prefix infinito-nexus-core/mirror \
--visibility private
How It Works βοΈΒΆ
Resolves whether the namespace is a GitHub org or personal account.
Lists all container packages with the requested visibility via the GitHub Packages REST API (
GET /user/packagesorGET /orgs/{org}/packages).Filters by prefix.
Deletes each matching package via
DELETE /user/packages/container/{name}(or the org equivalent).
Pagination is handled automatically. The script exits non-zero if any deletion fails.