Skip to content

Commit

Permalink
Pipeline - Adding acr img clean up (#2222)
Browse files Browse the repository at this point in the history
* Pipeline - Adding acr img clean up

TODO
Fixed #2210

* Adding step to login into Azure

* Updating job name and order of azure login step

* Updating cli command

* Updating cli to get the list of acr images

* Adding ACR name and correct image name to get the list

* removing show-tags from the cmd

* Adding image tag for the list

* removing extra tags for the list

* updating cmd to get the tags

* Filtering out the tags

* Adding order by command for the repo

* Updating the variable name

* Removing limit on the query

* Adding comparison for the active PR and images

* Adding pipeline to run the matrix

* Adding output for the comparison step

* Adding prop as JSON param

* Deleting test image

* Adding image name with tag to delete it

* Updating schedule and adding login steps for Azure

* cleaning weekly check and adding updated checks

* removing the tags limit

* Adding limiting to 250

* Adding deletion step to clean up the image

* Adding comment and reducing noise

* Adding non-pr prefixed tags

* Tags - Wrapping it with quote

* Updating the variable name

* echoing non-pr tags

* merging non-pr tags

* Fixing the variable name

* updating variable name

* Adding prefix condition for non-pr tags

* wrapping text around input values

* Adding additional checks to not delete production and staging acr

* Adding staging and production sha

* removing PRs for temporary

* deleting based on digest value

* Getting digest data for specific ACR

* replacing repository with registery

* manifest for the specific tag

* getting digest value in a different way

* removing test docker image

* Adding github sha to track it

* adding period with the output

* Removing sha tag from the docker img

* Adding prs tags only to delete

* prefixing with dollar sign

* Adding non-prs tags

* Changing the limit of tag list

* Cleaning up the steps for the delete slots

* Removing redundant steps

* wrapping the tags within a quote

* Removing acr login

* Adding condition to stop the second flow

* Removing PR trigger

* Passing JSON to call delete pr flow

* Adding step to remove untagged digests

* Adding PR trigger

* Updating the query to retrieve the manifest

* Adding acr tag

* Updating the props for the list

* adding delete command to delete untagged shas

* Adding yes prop to confirm delete

* removing PR trigger

* Removing testing scripts
  • Loading branch information
amankumarrr committed Mar 5, 2024
1 parent 05ee207 commit 438aaf8
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 13 deletions.
1 change: 1 addition & 0 deletions .github/.env
@@ -1,4 +1,5 @@
ACR_LOGIN_SERVER=acrsswwebsite.azurecr.io
ACR_NAME=acrsswwebsite
APP_SERVICE_NAME=app-sswwebsite-9eb3
AZURE_RESOURCE_GROUP=ssw.com.au
AZURE_RESOURCE_GROUP_LOCATION=australiaeast
Expand Down
22 changes: 14 additions & 8 deletions .github/workflows/pr-close-delete-env.yml
Expand Up @@ -33,15 +33,13 @@ jobs:
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Converting slots into JSON Formatted Array
- name: Get slot ids from input
id: set-matrix
run: |
# TODO: Tech Debt - need to use it as JSON instead of space delimited - Github issue - https://github.com/SSWConsulting/SSW.Website/issues/1228
$slotIDs = '${{ env.SLOT_NAME }}' -split ' '
$slotIDsInJSonArray = ConvertTo-Json -Compress @($slotIDs)
echo "matrix=$slotIDsInJSonArray" >> $env:GITHUB_OUTPUT
$slotIDs = '${{ env.SLOT_NAME }}'
echo "matrix=$slotIDs" >> $env:GITHUB_OUTPUT
delete-slot:
delete-slot-and-acr-cleanup:
runs-on: ubuntu-latest
needs: setting-up-slot-ids
strategy:
Expand All @@ -63,7 +61,7 @@ jobs:
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Cleanup ACR Pull & Key Vault permission
- name: Cleanup ACR and Key Vault Permissions
run: |
$acrId = az acr show `
--resource-group ${{ env.AZURE_RESOURCE_GROUP }} `
Expand Down Expand Up @@ -109,7 +107,15 @@ jobs:
Write-Host '❌ Key Vault not found'
}
- name: Delete slot on staging site
- name: ACR - Delete image
run: |
$imageTagWithPrefix = '${{ env.SLOT_PREFIX }}${{ matrix.SLOT_NAME}}'
az acr repository delete --name ${{ env.ACR_NAME }} `
--image ${{ env.IMAGE_NAME }}:$imageTagWithPrefix --yes
Write-Output "✅ ACR - ${{ env.IMAGE_NAME }}:$imageTagWithPrefix image deleted successfully."
- name: Delete slot
run: |
az webapp deployment slot delete `
--resource-group ${{ env.AZURE_RESOURCE_GROUP }} `
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/template-build.yml
Expand Up @@ -123,5 +123,4 @@ jobs:
NEXT_PUBLIC_CHATBASE_BOT_ID=${{ env.NEXT_PUBLIC_CHATBASE_BOT_ID }}
SITE_URL=https://www.ssw.com.au
tags: |
${{ env.ACR_LOGIN_SERVER }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
${{ env.ACR_LOGIN_SERVER }}/${{ env.IMAGE_NAME }}:${{ inputs.tag }}
72 changes: 72 additions & 0 deletions .github/workflows/template-delete-acr-image.yml
@@ -0,0 +1,72 @@
name: Delete - Docker image from ACR

on:
workflow_call:
inputs:
imageTags:
type: string
description: "Image Tags or PR numbers"
required: true
workflow_dispatch:
inputs:
imageTag:
description: "Image Tag or PR number"
required: true

defaults:
run:
shell: pwsh

env:
IMAGE_TAGS: ${{ inputs.imageTags || inputs.imageTag }}
PREFIX: pr-
permissions:
id-token: write
contents: read

jobs:
setting-up-img-tags:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Get image tags from input
id: set-matrix
run: |
$imageTags = '${{ env.IMAGE_TAGS }}'
echo "matrix=$imageTags" >> $env:GITHUB_OUTPUT
delete-acr-image:
runs-on: ubuntu-latest
needs: setting-up-img-tags
strategy:
matrix:
IMAGE_TAG: ${{ fromJson(needs.setting-up-img-tags.outputs.matrix) }}

steps:
- uses: actions/checkout@v4

- name: Load .env file
uses: xom9ikk/dotenv@v2
with:
path: ./.github

- name: Azure CLI - Login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: ACR - Delete image
run: |
if('${{ matrix.IMAGE_TAG }}'.Length -le 4) # PR tags consist of 4 digits (i.e pr-xxxx)
{
$imageTagWithPrefix = '${{ env.PREFIX }}${{ matrix.IMAGE_TAG}}'
}else{
$imageTagWithPrefix = '${{ matrix.IMAGE_TAG }}'
}
az acr repository delete --name ${{ env.ACR_NAME }} `
--image ${{ env.IMAGE_NAME }}:$imageTagWithPrefix --yes
Write-Output "✅ ACR - ${{ env.IMAGE_NAME }}:$imageTagWithPrefix image deleted successfully."
103 changes: 103 additions & 0 deletions .github/workflows/weekly-acr-images-cleanup.yml
@@ -0,0 +1,103 @@
name: Weekly ACR images cleanup

on:
schedule:
# Monday at 2 PM UTC - https://cron.help/#0_14_*_*_MON
- cron: "0 14 * * MON"
workflow_dispatch:

env:
GH_TOKEN: ${{ github.token }}

defaults:
run:
shell: pwsh

permissions:
id-token: write
contents: read

jobs:
check-acr-images:
runs-on: ubuntu-latest
outputs:
imageTagList: ${{ steps.comparison.outputs.imageTagList }}
steps:
- name: Checking out
uses: actions/checkout@v4

- name: Load .env file
uses: xom9ikk/dotenv@v2
with:
path: ./.github

- name: Azure CLI - Login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Delete all untagged images
run: |
$untaggedDigests = az acr manifest list-metadata -r ${{ env.ACR_NAME }} -n `
${{ env.IMAGE_NAME }} --query "[?tags==null].digest" -o tsv | `
%{ az acr repository delete -n ${{ env.ACR_NAME }} -t ${{ env.IMAGE_NAME }}@$_ --yes}
Write-Host "✅ All untagged images have been deleted"
- name: Get list of active PRs
id: prList
run: |
$active_prs=$(gh pr list --state open --json number | jq -r '.[].number')
echo "active_prs=$active_prs" >> $env:GITHUB_OUTPUT
- name: Get list of ACR image tags
id: imageTags
run: |
$images = az acr repository show-tags `
--name ${{ env.ACR_NAME }} --repository ${{ env.IMAGE_NAME }} `
--top 250 --orderby time_asc --output tsv # Limiting to 250 tags because of the GitHub action matrix limit
# Filter tags that start with "pr-"
$filteredTags = $images | Where-Object { $_ -like "pr-*" }
# Remove the "pr-" prefix from filtered tags
$filteredTagsWithoutPrefix = $filteredTags -replace "^pr-", ""
echo "filteredTags=$filteredTagsWithoutPrefix" >> $env:GITHUB_OUTPUT
- name: Compare active PRs with existing ACR images
id: comparison
run: |
# Comparing the number of images and PRs
$prList = "${{ steps.PRList.outputs.active_prs }}" -split ' '
$imageTags = "${{ steps.imageTags.outputs.filteredTags }}" -split ' '
$imagesExistThatRequireDeletion = $imageTags | Where-Object { $_ -notin $prList }
$imagesNeedDeletion = $imagesExistThatRequireDeletion.Length -gt 0
if ( ! $imagesNeedDeletion ) {
echo "✅ - Number of docker images are equal to number of active PRs - 🏃 Skipping next step"
}
else {
echo "❌ - Number of docker images are not equal to number of active PRs"
Write-Host "⚡- These images need to be deleted : $imagesExistThatRequireDeletion"
}
# Convert string into Array
$tags = $imagesExistThatRequireDeletion -split ' '
$imageTagList = ConvertTo-Json -Compress @($tags)
echo "imageTagList=$imageTagList" >> $env:GITHUB_OUTPUT
invokeDeleteImage:
name: Invoking delete-acr-image
needs:
- check-acr-images #Adding second check to avoid running this flow
if: needs.check-acr-images.outputs.imageTagList != '[]'
uses: ./.github/workflows/template-delete-acr-image.yml
with:
imageTags: ${{ needs.check-acr-images.outputs.imageTagList }}
permissions:
id-token: write
contents: read
secrets: inherit
12 changes: 8 additions & 4 deletions .github/workflows/weekly-slots-cleanup.yml
Expand Up @@ -21,7 +21,7 @@ jobs:
check-pr-slots:
runs-on: ubuntu-latest
outputs:
slotsExistThatRequireDeletion: ${{ steps.comparision.outputs.slotsExistThatRequireDeletion }}
slotList: ${{ steps.comparision.outputs.slotList }}

steps:
- name: Checking out
Expand Down Expand Up @@ -74,16 +74,20 @@ jobs:
echo "❌ - Number of slots are not equal to number of active PRs"
Write-Host "⚡- These slots need to be deleted : $slotsExistThatRequireDeletion"
}
echo "slotsExistThatRequireDeletion=$slotsExistThatRequireDeletion" >> $env:GITHUB_OUTPUT
# Convert string into Array
$slots = $slotsExistThatRequireDeletion -split ' '
$slotList = ConvertTo-Json -Compress @($slots)
echo "slotList=$slotList" >> $env:GITHUB_OUTPUT
invokeDeleteSlot:
name: Invoking PR Close/Delete
needs:
- check-pr-slots #Adding second check to avoid running this flow
if: needs.check-pr-slots.outputs.slotsExistThatRequireDeletion != ''
if: needs.check-pr-slots.outputs.slotList != '[]'
uses: ./.github/workflows/pr-close-delete-env.yml
with:
slotIDs: ${{ needs.check-pr-slots.outputs.slotsExistThatRequireDeletion }}
slotIDs: ${{ needs.check-pr-slots.outputs.slotList }}
permissions:
id-token: write
contents: read
Expand Down

0 comments on commit 438aaf8

Please sign in to comment.