Cleanup Old Artifacts #1
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
| name: Cleanup Old Artifacts | |
| on: | |
| schedule: | |
| - cron: '0 0 * * 0' # Midnight UTC every Sunday | |
| workflow_dispatch: | |
| jobs: | |
| cleanup-artifacts: | |
| name: Cleanup Artifacts | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Delete old artifacts | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| // Get all artifacts | |
| const artifacts = await github.rest.actions.listArtifactsForRepo({ | |
| owner, | |
| repo, | |
| per_page: 100 | |
| }); | |
| const now = new Date(); | |
| const retentionDays = 30; | |
| let deletedCount = 0; | |
| for (const artifact of artifacts.data.artifacts) { | |
| const createdAt = new Date(artifact.created_at); | |
| const ageInDays = (now - createdAt) / (1000 * 60 * 60 * 24); | |
| if (ageInDays > retentionDays) { | |
| console.log(`Deleting artifact: ${artifact.name} (${ageInDays.toFixed(1)} days old)`); | |
| await github.rest.actions.deleteArtifact({ | |
| owner, | |
| repo, | |
| artifact_id: artifact.id | |
| }); | |
| deletedCount++; | |
| } | |
| } | |
| console.log(`Deleted ${deletedCount} artifacts older than ${retentionDays} days`); | |
| core.summary | |
| .addHeading('🧹 Artifact Cleanup Report') | |
| .addRaw(`**Deleted:** ${deletedCount} artifacts\n`) | |
| .addRaw(`**Retention:** ${retentionDays} days\n`) | |
| .addRaw(`**Date:** ${now.toISOString()}\n`) | |
| .write(); | |
| cleanup-caches: | |
| name: Cleanup Caches | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Cleanup old caches | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| // Get all caches | |
| const caches = await github.rest.actions.getActionsCacheList({ | |
| owner, | |
| repo, | |
| per_page: 100 | |
| }); | |
| const now = new Date(); | |
| const retentionDays = 7; | |
| let deletedCount = 0; | |
| for (const cache of caches.data.actions_caches) { | |
| const createdAt = new Date(cache.created_at); | |
| const ageInDays = (now - createdAt) / (1000 * 60 * 60 * 24); | |
| // Only delete caches that haven't been accessed recently | |
| const lastAccessedAt = new Date(cache.last_accessed_at); | |
| const daysSinceAccess = (now - lastAccessedAt) / (1000 * 60 * 60 * 24); | |
| if (ageInDays > retentionDays && daysSinceAccess > 3) { | |
| console.log(`Deleting cache: ${cache.key} (${ageInDays.toFixed(1)} days old, ${daysSinceAccess.toFixed(1)} days since access)`); | |
| try { | |
| await github.rest.actions.deleteActionsCacheById({ | |
| owner, | |
| repo, | |
| cache_id: cache.id | |
| }); | |
| deletedCount++; | |
| } catch (error) { | |
| console.log(`Failed to delete cache ${cache.key}: ${error.message}`); | |
| } | |
| } | |
| } | |
| console.log(`Deleted ${deletedCount} caches older than ${retentionDays} days`); | |
| core.summary | |
| .addHeading('🧹 Cache Cleanup Report') | |
| .addRaw(`**Deleted:** ${deletedCount} caches\n`) | |
| .addRaw(`**Retention:** ${retentionDays} days\n`) | |
| .addRaw(`**Date:** ${now.toISOString()}\n`) | |
| .write(); | |
| cleanup-container-images: | |
| name: Cleanup Old Container Images | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Delete old untagged images | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const packageName = 'analytics-api'; | |
| try { | |
| // Get all package versions | |
| const versions = await github.rest.packages.getAllPackageVersionsForPackageOwnedByOrg({ | |
| package_type: 'container', | |
| package_name: packageName, | |
| org: owner, | |
| per_page: 100, | |
| state: 'active' | |
| }); | |
| const now = new Date(); | |
| const retentionDays = 30; | |
| let deletedCount = 0; | |
| for (const version of versions.data) { | |
| // Skip tagged versions | |
| if (version.metadata && version.metadata.container && version.metadata.container.tags.length > 0) { | |
| continue; | |
| } | |
| const createdAt = new Date(version.created_at); | |
| const ageInDays = (now - createdAt) / (1000 * 60 * 60 * 24); | |
| if (ageInDays > retentionDays) { | |
| console.log(`Deleting untagged image: ${version.name} (${ageInDays.toFixed(1)} days old)`); | |
| try { | |
| await github.rest.packages.deletePackageVersionForOrg({ | |
| package_type: 'container', | |
| package_name: packageName, | |
| org: owner, | |
| package_version_id: version.id | |
| }); | |
| deletedCount++; | |
| } catch (error) { | |
| console.log(`Failed to delete version ${version.name}: ${error.message}`); | |
| } | |
| } | |
| } | |
| console.log(`Deleted ${deletedCount} untagged images older than ${retentionDays} days`); | |
| core.summary | |
| .addHeading('🧹 Container Image Cleanup Report') | |
| .addRaw(`**Deleted:** ${deletedCount} untagged images\n`) | |
| .addRaw(`**Retention:** ${retentionDays} days\n`) | |
| .addRaw(`**Date:** ${now.toISOString()}\n`) | |
| .write(); | |
| } catch (error) { | |
| console.log(`Cleanup skipped: ${error.message}`); | |
| console.log('This is expected if package does not exist yet'); | |
| } | |
| summary: | |
| name: Cleanup Summary | |
| runs-on: ubuntu-latest | |
| needs: [cleanup-artifacts, cleanup-caches, cleanup-container-images] | |
| if: always() | |
| steps: | |
| - name: Generate summary | |
| run: | | |
| echo "### 🧹 Cleanup Complete" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Date:** $(date)" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Jobs:**" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Artifacts cleanup" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Caches cleanup" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Container images cleanup" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Retention Policies:**" >> $GITHUB_STEP_SUMMARY | |
| echo "- Artifacts: 30 days" >> $GITHUB_STEP_SUMMARY | |
| echo "- Caches: 7 days (if not accessed for 3 days)" >> $GITHUB_STEP_SUMMARY | |
| echo "- Container images: 30 days (untagged only)" >> $GITHUB_STEP_SUMMARY |