Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/scripts/delete_unused_images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -e

get_container_package_name() {
local container_name=$1

if [[ -z "${container_name}" ]]; then
echo "Container name is required" >&2
return 1
fi

# URL-encode the package path (eps-devcontainers/${container_name}) for the GH API
printf 'eps-devcontainers/%s' "${container_name}" | jq -sRr @uri
}

get_container_versions_json() {
local container_name=$1
local package_name

package_name=$(get_container_package_name "${container_name}")

gh api \
-H "Accept: application/vnd.github+json" \
"/orgs/nhsdigital/packages/container/${package_name}/versions" \
--paginate
}

delete_pr_images() {
local container_name=$1
local package_name
local versions_json
local tags

if [[ -z "${container_name}" ]]; then
echo "Container name is required" >&2
return 1
fi

package_name=$(get_container_package_name "${container_name}")
versions_json=$(get_container_versions_json "${container_name}")
tags=$(jq -r '[.[].metadata.container.tags[]?] | unique | .[]' <<<"${versions_json}")

if [[ -z "${tags}" ]]; then
return 0
fi

while IFS= read -r tag; do
if [[ "${tag}" =~ ^pr-[0-9]+- ]]; then
local pull_request
local pr_json
local pr_state

pull_request=${tag#pr-}
pull_request=${pull_request%%-*}

if ! pr_json=$(gh api \
-H "Accept: application/vnd.github+json" \
"/repos/NHSDigital/eps-devcontainers/pulls/${pull_request}"); then
continue
fi
echo "Checking PR #${pull_request} for tag ${tag} in container ${container_name}..."
pr_state=$(jq -r '.state // empty' <<<"${pr_json}")
if [[ "${pr_state}" != "closed" ]]; then
echo "State is not closed - not deleting images"
continue
fi

jq -r --arg tag "${tag}" '.[] | select(.metadata.container.tags[]? == $tag) | .id' \
<<<"${versions_json}" \
| while IFS= read -r version_id; do
if [[ -n "${version_id}" ]]; then
echo "Deleting image with tag ${tag} (version ID: ${version_id}) from container ${container_name}..."
gh api \
-H "Accept: application/vnd.github+json" \
-X DELETE \
"/orgs/nhsdigital/packages/container/${package_name}/versions/${version_id}"
fi
done
fi
done <<<"${tags}"
}


language_folders=$(find src/languages -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]')
project_folders=$(find src/projects -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]')

for container_name in $(jq -r '.[]' <<<"${project_folders}"); do
delete_pr_images "${container_name}"
done

for container_name in $(jq -r '.[]' <<<"${language_folders}"); do
delete_pr_images "${container_name}"
done

delete_pr_images "base"
55 changes: 55 additions & 0 deletions .github/workflows/delete_old_images.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: "Delete old cloudformation stacks"

# Controls when the action will run - in this case triggered manually and on schedule
on:
workflow_dispatch:
schedule:
- cron: "0 1,13 * * *"
push:
branches: [main]

jobs:
delete-old-cloudformation-stacks:
runs-on: ubuntu-22.04
permissions:
id-token: write
contents: read

steps:
- name: Checkout local code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: ${{ env.BRANCH_NAME }}
fetch-depth: 0

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7
with:
aws-region: eu-west-2
role-to-assume: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }}
role-session-name: psu-delete-old-stacks

- name: delete stacks
shell: bash
working-directory: .github/scripts
run: ./delete_stacks.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

delete-old-proxygen-deployments:
runs-on: ubuntu-22.04
permissions:
id-token: write
contents: read

steps:
- name: Checkout local code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: ${{ env.BRANCH_NAME }}
fetch-depth: 0

- name: delete unused images
shell: bash
working-directory: .github/scripts
run: ./delete_unused_images.sh
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ build-image: guard-CONTAINER_NAME guard-BASE_VERSION guard-BASE_FOLDER
npx devcontainer build \
--workspace-folder ./src/$${BASE_FOLDER}/$${CONTAINER_NAME} \
--push false \
--cache-from "${CONTAINER_PREFIX}$${CONTAINER_NAME}:latest" \
--label "org.opencontainers.image.revision=$$DOCKER_TAG" \
--image-name "${CONTAINER_PREFIX}$${CONTAINER_NAME}${IMAGE_TAG}"

Expand Down Expand Up @@ -70,3 +71,9 @@ test:

lint-githubactions:
actionlint

github-login:
gh auth login --scopes read:packages

lint-githubaction-scripts:
shellcheck .github/scripts/*.sh
33 changes: 14 additions & 19 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.