A GitHub Action for deleting old image versions from the GitHub container registry.
Storage isn't free and registries can often get bloated with unused images. Having a retention policy to prevent clutter makes sense in most cases.
Supports both organizational and personal accounts.
To use the action, simply add it to your GitHub workflow, like this:
- uses: snok/container-retention-policy@v1
with:
image-names: dev, web, test
cut-off: two hours ago UTC+2
timestamp-to-use: updated_at
account-type: org
org-name: google
keep-at-least: 1
skip-tags: latest
token: ${{ secrets.PAT }}
You could run this as a scheduled event, or as a part of an existing workflow, but for the sake of inspiration, it might also make sense for you to trigger it with a:
- workflow_dispatch: trigger it manually in the GitHub repo UI when needed
- workflow_run: have it run as clean-up after another key workflow completes
- or triggering it with a webhook (repository_dispatch)
For an organization, a full example might look something like this:
name: Delete old container images
on:
schedule:
- cron: '0 0 * * *' # every day at midnight
jobs:
clean-ghcr:
name: Delete old unused container images
runs-on: ubuntu-latest
steps:
- name: Delete 'dev' containers older than a week
uses: snok/container-retention-policy@v1
with:
image-names: python-dev, js-dev
cut-off: A week ago UTC
account-type: org
org-name: my-org
keep-at-least: 1
untagged-only: true
token: ${{ secrets.PAT }}
- name: Delete 'test' containers older than a month
uses: snok/container-retention-policy@v1
with:
image-names: python-test, js-test
cut-off: One month ago UTC
account-type: org
org-name: my-org
keep-at-least: 1
skip-tags: latest
token: ${{ secrets.PAT }}
While for a personal account, something like this might do:
name: Delete old container images
on:
schedule:
- cron: '0 0 0 * *' # the first day of the month
jobs:
clean-ghcr:
name: Delete old unused container images
runs-on: ubuntu-latest
steps:
- name: Delete old images
uses: snok/container-retention-policy@v1
with:
image-names: dev
cut-off: One month ago UTC
keep-at-least: 1
account-type: personal
token: ${{ secrets.PAT }}
- Required:
Yes
- Example:
image-names: image1,image2,image3
The names of the container images you want to delete old versions for. Takes one or several container image names as a comma separated list.
- Required:
Yes
- Example:
cut-off: 1 week ago UTC
The timezone-aware datetime you want to delete container versions that are older than.
We use dateparser to parse the cut-off specified. This means you should
be able to specify your cut-off in relative human readable terms like Two hours ago UTC
, or by using a normal
timestamp.
The parsed datetime must contain a timezone.
- Required:
Yes
- Example:
timestamp-to-use: created_at
- Default:
updated_at
- Valid choices:
updated_at
orcreated_at
Which timestamp to use when comparing the cut-off to the container version.
Must be created_at
or updated_at
. The timestamp to use determines how we filter container versions.
- Required:
Yes
- Example:
account-type: personal
- Valid choices:
org
orpersonal
The account type of the account running the action. The account type determines which API endpoints to use in the GitHub API.
- Required:
Only if account type is org
- Example:
org-name: google
The name of your organization.
- Required:
Yes
- Example:
token: ${{ secrets.PAT }}
For the token, you need to pass a personal access token with access to the container registry. Specifically, you need to grant it the following scopes:
read:packages
, anddelete:packages
- Required:
No
- Default:
0
- Example:
keep-at-least: 5
How many versions to keep no matter what. Defaults to 0, meaning all versions older than the cut-off
date may be deleted.
Setting this to a larger value ensures that the specified number of recent versions are always retained, regardless of their age. Useful for images that are not updated very often.
- Required:
No
- Default:
false
Restricts image deletion to images without any tags, if enabled.
- Required:
No
- Example:
latest
Restrict deletions to images without specific tags, if specified.
-
The GitHub API restricts us to fetching 100 image versions per image name, so if your registry isn't 100% clean after the first job, don't be alarmed.
-
If you accidentally delete something you shouldn't have, GitHub apparently has a 30 day grace period before actually deleting your image version. See these docs for the information you need to restore your data.
Please do 👏