Cleanup Packages #14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ============================================ | |
| # Cleanup Untagged Package Versions | |
| # Removes ONLY untagged images (orphan digests) | |
| # Keeps ALL versioned/tagged images | |
| # Runs weekly on Sunday at 3 AM UTC | |
| # ============================================ | |
| name: Cleanup Packages | |
| on: | |
| schedule: | |
| # Run every Sunday at 3 AM UTC | |
| - cron: '0 3 * * 0' | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: 'Dry run (no deletion)' | |
| required: false | |
| default: false | |
| type: boolean | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: jigsawfr/aiometadata-docker | |
| permissions: | |
| packages: write | |
| jobs: | |
| cleanup: | |
| name: Cleanup Untagged Images | |
| runs-on: ubuntu-latest | |
| steps: | |
| # Delete ONLY untagged images (orphan digests/manifests) | |
| - name: Delete untagged images | |
| if: inputs.dry_run != true | |
| uses: actions/delete-package-versions@v5 | |
| with: | |
| package-name: aiometadata-docker | |
| package-type: container | |
| delete-only-untagged-versions: true | |
| min-versions-to-keep: 0 | |
| - name: Get cleanup stats | |
| id: stats | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| try { | |
| // Get all package versions to count | |
| const { data: versions } = await github.rest.packages.getAllPackageVersionsForPackageOwnedByUser({ | |
| package_type: 'container', | |
| package_name: 'aiometadata-docker', | |
| username: context.repo.owner, | |
| per_page: 100 | |
| }); | |
| let taggedCount = 0; | |
| let untaggedCount = 0; | |
| const taggedVersions = []; | |
| for (const version of versions) { | |
| const tags = version.metadata?.container?.tags || []; | |
| if (tags.length === 0) { | |
| untaggedCount++; | |
| } else { | |
| taggedCount++; | |
| taggedVersions.push(tags.join(', ')); | |
| } | |
| } | |
| console.log(`Total versions: ${versions.length}`); | |
| console.log(`Tagged versions (kept): ${taggedCount}`); | |
| console.log(`Untagged versions: ${untaggedCount}`); | |
| console.log(`Tagged: ${taggedVersions.slice(0, 10).join(' | ')}...`); | |
| core.setOutput('total', versions.length); | |
| core.setOutput('tagged', taggedCount); | |
| core.setOutput('untagged', untaggedCount); | |
| } catch (error) { | |
| console.log(`Error getting stats: ${error.message}`); | |
| core.setOutput('total', 0); | |
| core.setOutput('tagged', 0); | |
| core.setOutput('untagged', 0); | |
| } | |
| - name: Summary | |
| run: | | |
| echo "## 🧹 Cleanup Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Package Statistics" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Total versions**: ${{ steps.stats.outputs.total }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Tagged versions**: ${{ steps.stats.outputs.tagged }} ✅ (all kept)" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Untagged versions**: ${{ steps.stats.outputs.untagged }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "ℹ️ **Policy**: Only untagged/orphan digests are deleted. All versioned images are preserved indefinitely." >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ inputs.dry_run }}" = "true" ]; then | |
| echo "⚠️ **Dry run** - no versions were deleted." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "✅ Cleanup completed!" >> $GITHUB_STEP_SUMMARY | |
| fi |