Skip to content

Commit 2551afe

Browse files
authored
ci: 🐛 fix Cleanup GHCR Images workflow (#8)
2 parents 475ee56 + 4dc6110 commit 2551afe

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

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

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,31 @@ permissions:
1919
packages: write
2020

2121
env:
22-
PACKAGE_TYPE: container
2322
PACKAGE_NAME: opencode-cli
2423
RETENTION_DAYS: ${{ inputs.retention_days || vars.GHCR_RETENTION_DAYS || '45' }}
2524
DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || 'false' }}
2625

2726
jobs:
28-
cleanup-by-age:
27+
cleanup:
2928
runs-on: ubuntu-latest
3029
steps:
31-
- name: Delete old container versions but keep one
30+
- name: Delete old container versions
31+
id: cleanup_by_age
3232
uses: actions/github-script@v8
33+
env:
34+
PACKAGE_NAME: ${{ env.PACKAGE_NAME }}
35+
RETENTION_DAYS: ${{ env.RETENTION_DAYS }}
36+
DRY_RUN: ${{ env.DRY_RUN }}
3337
with:
38+
result-encoding: string
3439
script: |
3540
const owner = context.repo.owner;
36-
const packageType = process.env.PACKAGE_TYPE;
41+
const packageType = 'container';
3742
const packageName = process.env.PACKAGE_NAME;
3843
const retentionDays = Number(process.env.RETENTION_DAYS);
3944
const dryRun = process.env.DRY_RUN === 'true';
4045
const cutoff = new Date(Date.now() - retentionDays * 24 * 60 * 60 * 1000);
46+
const deletedVersionIds = [];
4147
4248
const paginateVersions = async () => {
4349
try {
@@ -99,7 +105,7 @@ jobs:
99105
100106
if (sortedVersions.length <= 1) {
101107
core.info('Skipping age-based cleanup because only one package version exists.');
102-
return;
108+
return JSON.stringify(deletedVersionIds);
103109
}
104110
105111
let retainedCount = sortedVersions.length;
@@ -126,19 +132,22 @@ jobs:
126132
if (!dryRun) {
127133
await deleteVersion(scope, version.id);
128134
}
135+
deletedVersionIds.push(version.id);
129136
retainedCount -= 1;
130137
}
131138
132-
cleanup-sha-only:
133-
needs: cleanup-by-age
134-
runs-on: ubuntu-latest
135-
steps:
139+
return JSON.stringify(deletedVersionIds);
140+
136141
- name: Delete container versions that only have SHA tags
137142
uses: actions/github-script@v8
143+
env:
144+
PACKAGE_NAME: ${{ env.PACKAGE_NAME }}
145+
DRY_RUN: ${{ env.DRY_RUN }}
146+
DELETED_VERSION_IDS: ${{ steps.cleanup_by_age.outputs.result }}
138147
with:
139148
script: |
140149
const owner = context.repo.owner;
141-
const packageType = process.env.PACKAGE_TYPE;
150+
const packageType = 'container';
142151
const packageName = process.env.PACKAGE_NAME;
143152
const dryRun = process.env.DRY_RUN === 'true';
144153
@@ -201,14 +210,23 @@ jobs:
201210
(left, right) => new Date(right.updated_at) - new Date(left.updated_at),
202211
);
203212
204-
if (sortedVersions.length <= 1) {
205-
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.');
206224
return;
207225
}
208226
209-
let retainedCount = sortedVersions.length;
227+
let retainedCount = remainingVersions.length;
210228
211-
for (const [index, version] of sortedVersions.entries()) {
229+
for (const [index, version] of remainingVersions.entries()) {
212230
const tags = version.metadata?.container?.tags ?? [];
213231
const isShaOnly = tags.length > 0 && tags.every(isShaTag);
214232
const isNewest = index === 0;

0 commit comments

Comments
 (0)