@@ -22,8 +22,8 @@ permissions:
2222 packages : write # needed for deletions with GITHUB_TOKEN
2323
2424env :
25- # Untagged versions are orphaned GHCR package versions left after tags move or manifests/caches are rewritten.
26- UNTAGGED_RETENTION_HOURS : 12
25+ # Keep untagged versions. GHCR exposes platform child manifests for tagged OCI indexes as untagged
26+ # package versions, and deleting them can break docker pull for visible multi-arch tags.
2727 # Stale tagged versions still have tags, but those tags are no longer generated by the current image matrix.
2828 STALE_TAGGED_RETENTION_DAYS : 14
2929
@@ -76,15 +76,14 @@ jobs:
7676 KEEP_TAGS : ${{ steps.keep-tags.outputs.json }}
7777 MANAGED_IMAGES : ${{ steps.keep-tags.outputs.images }}
7878 DRY_RUN : ${{ inputs.dry_run || 'false' }}
79- UNTAGGED_RETENTION_HOURS : ${{ env.UNTAGGED_RETENTION_HOURS }}
8079 STALE_TAGGED_RETENTION_DAYS : ${{ env.STALE_TAGGED_RETENTION_DAYS }}
8180 with :
8281 script : |
8382 const keepTags = new Set(JSON.parse(process.env.KEEP_TAGS));
8483 const managedImages = JSON.parse(process.env.MANAGED_IMAGES);
8584 const dryRun = process.env.DRY_RUN === 'true';
86- const untaggedRetentionMs = Number(process.env.UNTAGGED_RETENTION_HOURS) * 60 * 60 * 1000;
87- const staleTaggedRetentionMs = Number(process.env.STALE_TAGGED_RETENTION_DAYS) * 24 * 60 * 60 * 1000;
85+ const staleTaggedRetentionMs =
86+ Number(process.env.STALE_TAGGED_RETENTION_DAYS) * 24 * 60 * 60 * 1000;
8887 const now = Date.now();
8988
9089 const owner = context.repo.owner;
@@ -127,9 +126,12 @@ jobs:
127126 const dates = `created ${version.created_at}, updated ${version.updated_at}`;
128127
129128 let reason = null;
130- if (tags.length === 0 && ageMs > untaggedRetentionMs) {
131- reason = `untagged older than ${process.env.UNTAGGED_RETENTION_HOURS} hours`;
132- } else if (
129+ if (tags.length === 0) {
130+ core.info(`keep ${version.id}: ${tagList} (${dates}; may be a multi-arch child manifest)`);
131+ continue;
132+ }
133+
134+ if (
133135 tags.length > 0 &&
134136 ageMs > staleTaggedRetentionMs &&
135137 tags.every((tag) => !keepTags.has(tag)) &&
@@ -143,7 +145,9 @@ jobs:
143145 continue;
144146 }
145147
146- core.info(`${dryRun ? 'would delete' : 'delete'} ${version.id}: ${tagList} (${reason}; ${dates})`);
148+ core.info(
149+ `${dryRun ? 'would delete' : 'delete'} ${version.id}: ${tagList} (${reason}; ${dates})`
150+ );
147151 if (!dryRun) {
148152 await deleteVersion({
149153 ...ownerArgs,
0 commit comments