Skip to content

Commit e05a226

Browse files
committed
feat(ci): auto-cleanup PR artifacts after merge
Add workflow to automatically delete PR artifacts when a PR is closed or merged, freeing up storage space and keeping artifacts organized. Changes: - Create cleanup-pr-artifacts.yml workflow - Triggers on pull_request closed event - Runs cleanup for both merged and closed PRs - Create scripts/ci/github/cleanup-pr-artifacts.js - Lists all artifacts matching PR number pattern - Deletes artifacts: stadata-example-pr-{number}-* and size-analysis-json-pr-{number}-* - Shows cleanup summary with storage freed - Proper error handling and logging Benefits: - Reduces storage usage - Keeps artifact list clean - Automatic cleanup on PR close/merge - Shows how much storage was freed
1 parent c2501f6 commit e05a226

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Cleanup PR Artifacts
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
jobs:
8+
cleanup:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
actions: write
12+
contents: read
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v5
17+
18+
- name: Delete PR artifacts
19+
uses: actions/github-script@v7
20+
with:
21+
github-token: ${{ secrets.GITHUB_TOKEN }}
22+
script: |
23+
const script = require('./scripts/ci/github/cleanup-pr-artifacts.js');
24+
await script({ github, context, core });
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Cleanup PR artifacts after PR is closed/merged
3+
*
4+
* This script deletes all artifacts associated with a PR when it's closed,
5+
* freeing up storage space and keeping the artifacts list clean.
6+
*/
7+
8+
module.exports = async ({ github, context, core }) => {
9+
const prNumber = context.payload.pull_request.number;
10+
const isMerged = context.payload.pull_request.merged;
11+
const action = isMerged ? 'merged' : 'closed without merging';
12+
13+
console.log(`PR #${prNumber} was ${action}`);
14+
console.log('🧹 Starting artifact cleanup...');
15+
16+
try {
17+
// List all artifacts in the repository
18+
const { data: artifacts } = await github.rest.actions.listArtifactsForRepo({
19+
owner: context.repo.owner,
20+
repo: context.repo.repo,
21+
per_page: 100
22+
});
23+
24+
// Filter artifacts that belong to this PR
25+
// Artifacts are named: stadata-example-pr-{prNumber}-{sha} and size-analysis-json-pr-{prNumber}-{sha}
26+
const prArtifacts = artifacts.artifacts.filter(artifact => {
27+
const patterns = [
28+
`stadata-example-pr-${prNumber}-`,
29+
`size-analysis-json-pr-${prNumber}-`
30+
];
31+
return patterns.some(pattern => artifact.name.startsWith(pattern));
32+
});
33+
34+
if (prArtifacts.length === 0) {
35+
console.log(`✅ No artifacts found for PR #${prNumber}`);
36+
return;
37+
}
38+
39+
console.log(`📦 Found ${prArtifacts.length} artifact(s) to delete:`);
40+
prArtifacts.forEach(artifact => {
41+
console.log(` - ${artifact.name} (${(artifact.size_in_bytes / 1024 / 1024).toFixed(2)} MB)`);
42+
});
43+
44+
// Delete each artifact
45+
let deletedCount = 0;
46+
let failedCount = 0;
47+
48+
for (const artifact of prArtifacts) {
49+
try {
50+
await github.rest.actions.deleteArtifact({
51+
owner: context.repo.owner,
52+
repo: context.repo.repo,
53+
artifact_id: artifact.id
54+
});
55+
console.log(`✅ Deleted: ${artifact.name}`);
56+
deletedCount++;
57+
} catch (error) {
58+
console.error(`❌ Failed to delete ${artifact.name}:`, error.message);
59+
failedCount++;
60+
}
61+
}
62+
63+
// Summary
64+
const totalSize = prArtifacts.reduce((sum, a) => sum + a.size_in_bytes, 0);
65+
const totalSizeMB = (totalSize / 1024 / 1024).toFixed(2);
66+
67+
console.log('');
68+
console.log('📊 Cleanup Summary:');
69+
console.log(` - Deleted: ${deletedCount} artifact(s)`);
70+
console.log(` - Failed: ${failedCount} artifact(s)`);
71+
console.log(` - Storage freed: ~${totalSizeMB} MB`);
72+
console.log('');
73+
console.log(`✅ Artifact cleanup complete for PR #${prNumber}`);
74+
75+
if (failedCount > 0) {
76+
core.setFailed(`Failed to delete ${failedCount} artifact(s)`);
77+
}
78+
} catch (error) {
79+
console.error('❌ Error during artifact cleanup:', error);
80+
core.setFailed(error.message);
81+
}
82+
};

0 commit comments

Comments
 (0)