|
2 | 2 | # |
3 | 3 | # This workflow cleans up old images from GitHub Container Registry |
4 | 4 | # to prevent unlimited storage growth. It runs weekly and removes: |
5 | | -# 1. Old dated nightly tags for vector (keeps last 30) |
6 | | -# 2. Old test-runner versions (keeps 5 most recent) |
| 5 | +# 1. Old test-runner versions (keeps 5 most recent) |
| 6 | +# |
| 7 | +# Note: cleanup of dated vector nightly images requires a token with |
| 8 | +# delete:packages scope (GITHUB_TOKEN is insufficient for org-owned |
| 9 | +# container packages). This is tracked separately. |
7 | 10 |
|
8 | 11 | name: Cleanup GHCR Images |
9 | 12 |
|
|
12 | 15 | # Run weekly on Sundays at 2 AM UTC |
13 | 16 | - cron: "0 2 * * 0" |
14 | 17 | workflow_dispatch: |
15 | | - inputs: |
16 | | - max_deletions: |
17 | | - description: "Max versions to delete (use 1 for testing; 0 = unlimited)" |
18 | | - required: false |
19 | | - default: "1" |
20 | 18 |
|
21 | 19 | permissions: |
22 | 20 | contents: read # Restrictive default |
23 | 21 |
|
24 | 22 | jobs: |
25 | | - cleanup-vector-nightlies: |
26 | | - runs-on: ubuntu-24.04 |
27 | | - permissions: |
28 | | - packages: write # Required to delete package versions from GHCR |
29 | | - steps: |
30 | | - - name: Delete old dated nightly vector images |
31 | | - env: |
32 | | - GH_TOKEN: ${{ github.token }} |
33 | | - # Scheduled runs delete everything beyond the threshold; dispatch defaults to 1 for safety. |
34 | | - MAX_DELETIONS: ${{ inputs.max_deletions || '0' }} |
35 | | - run: | |
36 | | - # Fetch only tagged versions whose tags don't match the ignore pattern. |
37 | | - # (nightly = rolling tag, \d+\.\d+ = stable releases like 0.46, 0.46.1) |
38 | | - # Untagged arch-specific child manifests are excluded; GHCR cleans them up |
39 | | - # automatically when their parent manifest list is deleted. |
40 | | - mapfile -t eligible < <( |
41 | | - gh api /users/vectordotdev/packages/container/vector/versions \ |
42 | | - --paginate \ |
43 | | - --jq '.[] | select( |
44 | | - (.metadata.container.tags | length > 0) and |
45 | | - (.metadata.container.tags | map(test("^(nightly$|[0-9]+[.][0-9]+)")) | any | not) |
46 | | - ) | [.created_at, (.id | tostring), (.metadata.container.tags | join(","))] | @tsv' \ |
47 | | - | sort |
48 | | - ) |
49 | | -
|
50 | | - total=${#eligible[@]} |
51 | | - to_delete=$(( total > 30 ? total - 30 : 0 )) |
52 | | -
|
53 | | - if [[ "$MAX_DELETIONS" -gt 0 && "$to_delete" -gt "$MAX_DELETIONS" ]]; then |
54 | | - echo "Capping deletions at MAX_DELETIONS=$MAX_DELETIONS (would delete $to_delete)." |
55 | | - to_delete=$MAX_DELETIONS |
56 | | - fi |
57 | | -
|
58 | | - echo "Tagged eligible versions: $total; deleting $to_delete oldest, keeping at least 30." |
59 | | -
|
60 | | - deleted=0 |
61 | | - failed=0 |
62 | | - for (( i=0; i<to_delete; i++ )); do |
63 | | - version_id=$(cut -f2 <<< "${eligible[$i]}") |
64 | | - tag=$(cut -f3 <<< "${eligible[$i]}") |
65 | | - if gh api -X DELETE "/users/vectordotdev/packages/container/vector/versions/$version_id" > /dev/null; then |
66 | | - deleted=$(( deleted + 1 )) |
67 | | - echo "Deleted: $tag (id=$version_id)" |
68 | | - else |
69 | | - failed=$(( failed + 1 )) |
70 | | - echo "Failed to delete: $tag (id=$version_id)" |
71 | | - fi |
72 | | - if (( (i+1) % 100 == 0 )); then |
73 | | - echo "Progress: $deleted deleted, $failed failed so far..." |
74 | | - fi |
75 | | - done |
76 | | -
|
77 | | - echo "Done. Deleted: $deleted, failed: $failed." |
78 | | - if [[ "$failed" -gt 0 ]]; then |
79 | | - exit 1 |
80 | | - fi |
81 | | -
|
82 | | - - name: Verify nightly cleanup succeeded |
83 | | - if: always() |
84 | | - env: |
85 | | - GH_TOKEN: ${{ github.token }} |
86 | | - run: | |
87 | | - mapfile -t remaining < <( |
88 | | - gh api /users/vectordotdev/packages/container/vector/versions \ |
89 | | - --paginate \ |
90 | | - --jq '.[] | select( |
91 | | - (.metadata.container.tags | length > 0) and |
92 | | - (.metadata.container.tags | map(test("^(nightly$|[0-9]+[.][0-9]+)")) | any | not) |
93 | | - ) | .id | tostring' |
94 | | - ) |
95 | | - count=${#remaining[@]} |
96 | | - echo "Tagged eligible versions remaining after cleanup: $count" |
97 | | - if [[ "${{ github.event_name }}" == "schedule" && "$count" -gt 30 ]]; then |
98 | | - echo "::error::Cleanup may have failed: $count tagged eligible versions remain (threshold: 30)." |
99 | | - exit 1 |
100 | | - fi |
101 | | - echo "Verified: $count tagged eligible versions remain." |
102 | | -
|
103 | 23 | cleanup-test-runner: |
104 | 24 | runs-on: ubuntu-24.04 |
105 | 25 | permissions: |
|
0 commit comments