Skip to content

Commit 4544ba2

Browse files
committed
ci(ghcr): 🏗️ consolidate cleanup jobs and pass deleted versions between steps
Merge the separate cleanup-sha-only job into the main cleanup job to share deleted version IDs between steps. This prevents SHA-only cleanup from evaluating versions already marked for deletion by age-based cleanup, improving accuracy during dry runs and avoiding redundant processing.
1 parent dbc7b0f commit 4544ba2

1 file changed

Lines changed: 22 additions & 10 deletions

File tree

.github/workflows/cleanup-ghcr-images.yml

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,26 @@ env:
2424
DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || 'false' }}
2525

2626
jobs:
27-
cleanup-by-age:
27+
cleanup:
2828
runs-on: ubuntu-latest
2929
steps:
3030
- name: Delete old container versions but keep one
31+
id: cleanup_by_age
3132
uses: actions/github-script@v8
3233
env:
3334
PACKAGE_NAME: ${{ env.PACKAGE_NAME }}
3435
RETENTION_DAYS: ${{ env.RETENTION_DAYS }}
3536
DRY_RUN: ${{ env.DRY_RUN }}
3637
with:
38+
result-encoding: string
3739
script: |
3840
const owner = context.repo.owner;
3941
const packageType = 'container';
4042
const packageName = process.env.PACKAGE_NAME;
4143
const retentionDays = Number(process.env.RETENTION_DAYS);
4244
const dryRun = process.env.DRY_RUN === 'true';
4345
const cutoff = new Date(Date.now() - retentionDays * 24 * 60 * 60 * 1000);
46+
const deletedVersionIds = [];
4447
4548
const paginateVersions = async () => {
4649
try {
@@ -102,7 +105,7 @@ jobs:
102105
103106
if (sortedVersions.length <= 1) {
104107
core.info('Skipping age-based cleanup because only one package version exists.');
105-
return;
108+
return JSON.stringify(deletedVersionIds);
106109
}
107110
108111
let retainedCount = sortedVersions.length;
@@ -129,18 +132,18 @@ jobs:
129132
if (!dryRun) {
130133
await deleteVersion(scope, version.id);
131134
}
135+
deletedVersionIds.push(version.id);
132136
retainedCount -= 1;
133137
}
134138
135-
cleanup-sha-only:
136-
needs: cleanup-by-age
137-
runs-on: ubuntu-latest
138-
steps:
139+
return JSON.stringify(deletedVersionIds);
140+
139141
- name: Delete container versions that only have SHA tags
140142
uses: actions/github-script@v8
141143
env:
142144
PACKAGE_NAME: ${{ env.PACKAGE_NAME }}
143145
DRY_RUN: ${{ env.DRY_RUN }}
146+
DELETED_VERSION_IDS: ${{ steps.cleanup_by_age.outputs.result }}
144147
with:
145148
script: |
146149
const owner = context.repo.owner;
@@ -207,14 +210,23 @@ jobs:
207210
(left, right) => new Date(right.updated_at) - new Date(left.updated_at),
208211
);
209212
210-
if (sortedVersions.length <= 1) {
211-
core.info('Skipping SHA-only cleanup because only one package version exists.');
213+
let remainingVersions = sortedVersions;
214+
215+
if (dryRun) {
216+
const deletedVersionIds = new Set(JSON.parse(process.env.DELETED_VERSION_IDS || '[]').map(String));
217+
core.info('Dry run enabled; excluding versions marked by the age-based cleanup step from SHA-only evaluation.');
218+
219+
remainingVersions = sortedVersions.filter((version) => !deletedVersionIds.has(String(version.id)));
220+
}
221+
222+
if (remainingVersions.length <= 1) {
223+
core.info('Skipping SHA-only cleanup because only one package version would remain after age-based cleanup.');
212224
return;
213225
}
214226
215-
let retainedCount = sortedVersions.length;
227+
let retainedCount = remainingVersions.length;
216228
217-
for (const [index, version] of sortedVersions.entries()) {
229+
for (const [index, version] of remainingVersions.entries()) {
218230
const tags = version.metadata?.container?.tags ?? [];
219231
const isShaOnly = tags.length > 0 && tags.every(isShaTag);
220232
const isNewest = index === 0;

0 commit comments

Comments
 (0)