Skip to content

Docker Cleanup

Docker Cleanup #141

name: Docker Cleanup
on:
pull_request:
types: [closed]
branches: ["main", "develop"]
schedule:
# Cleanup obsolete images daily at 2:00 AM UTC
- cron: '0 2 * * *'
workflow_dispatch:
env:
DOCKERHUB_IMAGE: johandevl/export-trakt-4-letterboxd
GITHUB_REGISTRY: ghcr.io
GITHUB_IMAGE: ghcr.io/johandevl/export_trakt_4_letterboxd
jobs:
cleanup-pr:
name: Cleanup PR Docker Images
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
permissions:
packages: write
steps:
- name: Delete PR Docker image from GitHub Container Registry
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr_number = context.payload.pull_request.number;
const tag = `PR-${pr_number}`;
const imageName = '${{ github.repository }}'.toLowerCase();
console.log(`Attempting to delete GitHub Container Registry image with tag: ${tag}`);
try {
const { data: versions } = await github.rest.packages.getAllPackageVersionsForPackageOwnedByAuthenticatedUser({
package_type: 'container',
package_name: imageName,
});
const versionToDelete = versions.find(version =>
version.metadata.container.tags.includes(tag)
);
if (versionToDelete) {
console.log(`Found version: ${versionToDelete.id} with tag ${tag}`);
await github.rest.packages.deletePackageVersionForAuthenticatedUser({
package_type: 'container',
package_name: imageName,
package_version_id: versionToDelete.id
});
console.log(`Successfully deleted GitHub Container Registry image with tag: ${tag}`);
} else {
console.log(`No GitHub Container Registry image found with tag: ${tag}`);
}
} catch (error) {
console.log(`Error deleting GitHub Container Registry image: ${error.message}`);
}
- name: Delete PR Docker image from Docker Hub
uses: actions/github-script@v7
with:
script: |
const pr_number = context.payload.pull_request.number;
const tag = `PR-${pr_number}`;
console.log(`Attempting to delete Docker Hub image with tag: ${tag}`);
try {
const response = await fetch(`https://hub.docker.com/v2/repositories/${{ env.DOCKERHUB_IMAGE }}/tags/${tag}/`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${{ secrets.DOCKERHUB_TOKEN }}`
}
});
if (response.ok) {
console.log(`Successfully deleted Docker Hub image with tag: ${tag}`);
} else if (response.status === 404) {
console.log(`No Docker Hub image found with tag: ${tag}`);
} else {
console.log(`Error deleting Docker Hub image: ${response.statusText}`);
}
} catch (error) {
console.log(`Error deleting Docker Hub image: ${error.message}`);
}
- name: Summary
run: |
echo "🧹 Cleanup completed for PR-${{ github.event.pull_request.number }} Docker images"
cleanup-obsolete:
name: Cleanup Obsolete Docker Images
runs-on: ubuntu-latest
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
permissions:
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get active PR numbers
id: active-prs
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data: prs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open'
});
const activePRs = prs.map(pr => `PR-${pr.number}`);
console.log('Active PR tags:', activePRs.join(', '));
return activePRs;
- name: Cleanup obsolete GitHub Container Registry images
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const activePRs = ${{ steps.active-prs.outputs.result }};
const imageName = '${{ github.repository }}'.toLowerCase();
const protectedTags = ['latest', 'main', 'develop'];
console.log('Protected tags:', protectedTags.join(', '));
console.log('Active PR tags:', activePRs.join(', '));
try {
const { data: versions } = await github.rest.packages.getAllPackageVersionsForPackageOwnedByAuthenticatedUser({
package_type: 'container',
package_name: imageName,
});
let deletedCount = 0;
for (const version of versions) {
const tags = version.metadata.container.tags;
// Skip if no tags
if (!tags || tags.length === 0) continue;
// Check if any tag is protected
const hasProtectedTag = tags.some(tag =>
protectedTags.includes(tag) ||
tag.match(/^v\d+\.\d+\.\d+$/) || // Semantic version tags
activePRs.includes(tag)
);
if (!hasProtectedTag) {
console.log(`Deleting version ${version.id} with tags: ${tags.join(', ')}`);
try {
await github.rest.packages.deletePackageVersionForAuthenticatedUser({
package_type: 'container',
package_name: imageName,
package_version_id: version.id
});
deletedCount++;
} catch (error) {
console.log(`Failed to delete version ${version.id}: ${error.message}`);
}
} else {
console.log(`Keeping version ${version.id} with protected tags: ${tags.join(', ')}`);
}
}
console.log(`Cleanup completed. Deleted ${deletedCount} obsolete image versions.`);
} catch (error) {
console.log(`Error during cleanup: ${error.message}`);
}
- name: Summary
run: |
echo "🧹 Cleanup of obsolete Docker images completed"