@@ -19,25 +19,31 @@ permissions:
1919 packages : write
2020
2121env :
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
2726jobs :
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 {
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