Skip to content

Commit 1d64aa7

Browse files
authored
Chore: [AEA-0000] - Workflow to clean up old images (#14)
## Summary - Routine Change ### Details - clear up old images
1 parent 4d60793 commit 1d64aa7

File tree

4 files changed

+171
-19
lines changed

4 files changed

+171
-19
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
get_container_package_name() {
5+
local container_name=$1
6+
7+
if [[ -z "${container_name}" ]]; then
8+
echo "Container name is required" >&2
9+
return 1
10+
fi
11+
12+
# URL-encode the package path (eps-devcontainers/${container_name}) for the GH API
13+
printf 'eps-devcontainers/%s' "${container_name}" | jq -sRr @uri
14+
}
15+
16+
get_container_versions_json() {
17+
local container_name=$1
18+
local package_name
19+
20+
package_name=$(get_container_package_name "${container_name}")
21+
22+
gh api \
23+
-H "Accept: application/vnd.github+json" \
24+
"/orgs/nhsdigital/packages/container/${package_name}/versions" \
25+
--paginate
26+
}
27+
28+
delete_pr_images() {
29+
local container_name=$1
30+
local package_name
31+
local versions_json
32+
local tags
33+
34+
if [[ -z "${container_name}" ]]; then
35+
echo "Container name is required" >&2
36+
return 1
37+
fi
38+
39+
package_name=$(get_container_package_name "${container_name}")
40+
versions_json=$(get_container_versions_json "${container_name}")
41+
tags=$(jq -r '[.[].metadata.container.tags[]?] | unique | .[]' <<<"${versions_json}")
42+
43+
if [[ -z "${tags}" ]]; then
44+
return 0
45+
fi
46+
47+
while IFS= read -r tag; do
48+
if [[ "${tag}" =~ ^pr-[0-9]+- ]]; then
49+
local pull_request
50+
local pr_json
51+
local pr_state
52+
53+
pull_request=${tag#pr-}
54+
pull_request=${pull_request%%-*}
55+
56+
if ! pr_json=$(gh api \
57+
-H "Accept: application/vnd.github+json" \
58+
"/repos/NHSDigital/eps-devcontainers/pulls/${pull_request}"); then
59+
continue
60+
fi
61+
echo "Checking PR #${pull_request} for tag ${tag} in container ${container_name}..."
62+
pr_state=$(jq -r '.state // empty' <<<"${pr_json}")
63+
if [[ "${pr_state}" != "closed" ]]; then
64+
echo "State is not closed - not deleting images"
65+
continue
66+
fi
67+
68+
jq -r --arg tag "${tag}" '.[] | select(.metadata.container.tags[]? == $tag) | .id' \
69+
<<<"${versions_json}" \
70+
| while IFS= read -r version_id; do
71+
if [[ -n "${version_id}" ]]; then
72+
echo "Deleting image with tag ${tag} (version ID: ${version_id}) from container ${container_name}..."
73+
gh api \
74+
-H "Accept: application/vnd.github+json" \
75+
-X DELETE \
76+
"/orgs/nhsdigital/packages/container/${package_name}/versions/${version_id}"
77+
fi
78+
done
79+
fi
80+
done <<<"${tags}"
81+
}
82+
83+
84+
language_folders=$(find src/languages -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]')
85+
project_folders=$(find src/projects -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]')
86+
87+
for container_name in $(jq -r '.[]' <<<"${project_folders}"); do
88+
delete_pr_images "${container_name}"
89+
done
90+
91+
for container_name in $(jq -r '.[]' <<<"${language_folders}"); do
92+
delete_pr_images "${container_name}"
93+
done
94+
95+
delete_pr_images "base"
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: "Delete old cloudformation stacks"
2+
3+
# Controls when the action will run - in this case triggered manually and on schedule
4+
on:
5+
workflow_dispatch:
6+
schedule:
7+
- cron: "0 1,13 * * *"
8+
push:
9+
branches: [main]
10+
11+
jobs:
12+
delete-old-cloudformation-stacks:
13+
runs-on: ubuntu-22.04
14+
permissions:
15+
id-token: write
16+
contents: read
17+
18+
steps:
19+
- name: Checkout local code
20+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
21+
with:
22+
ref: ${{ env.BRANCH_NAME }}
23+
fetch-depth: 0
24+
25+
- name: Configure AWS Credentials
26+
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7
27+
with:
28+
aws-region: eu-west-2
29+
role-to-assume: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }}
30+
role-session-name: psu-delete-old-stacks
31+
32+
- name: delete stacks
33+
shell: bash
34+
working-directory: .github/scripts
35+
run: ./delete_stacks.sh
36+
env:
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
39+
delete-old-proxygen-deployments:
40+
runs-on: ubuntu-22.04
41+
permissions:
42+
id-token: write
43+
contents: read
44+
45+
steps:
46+
- name: Checkout local code
47+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
48+
with:
49+
ref: ${{ env.BRANCH_NAME }}
50+
fetch-depth: 0
51+
52+
- name: delete unused images
53+
shell: bash
54+
working-directory: .github/scripts
55+
run: ./delete_unused_images.sh

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ build-image: guard-CONTAINER_NAME guard-BASE_VERSION guard-BASE_FOLDER
2525
npx devcontainer build \
2626
--workspace-folder ./src/$${BASE_FOLDER}/$${CONTAINER_NAME} \
2727
--push false \
28+
--cache-from "${CONTAINER_PREFIX}$${CONTAINER_NAME}:latest" \
2829
--label "org.opencontainers.image.revision=$$DOCKER_TAG" \
2930
--image-name "${CONTAINER_PREFIX}$${CONTAINER_NAME}${IMAGE_TAG}"
3031

@@ -70,3 +71,9 @@ test:
7071

7172
lint-githubactions:
7273
actionlint
74+
75+
github-login:
76+
gh auth login --scopes read:packages
77+
78+
lint-githubaction-scripts:
79+
shellcheck .github/scripts/*.sh

poetry.lock

Lines changed: 14 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)