-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e0ee104
Showing
13 changed files
with
1,385 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
""" | ||
Simple script used to tag our releases with major and minor git tags. | ||
This lets users use the action with @v1 or @v1.1 references, and not have | ||
to use the complete tag (with patch version specified). | ||
""" | ||
|
||
import sys | ||
|
||
from packaging import version | ||
|
||
if __name__ == '__main__': | ||
ref = sys.argv[1] # ref will usually look like refs/tags/v1.0.1 | ||
major = sys.argv[2] == 'major' | ||
version = version.parse(ref.split('refs/tags/v')[1]) | ||
|
||
if major: | ||
print(f'v{version.major}') | ||
else: | ||
print(f'v{version.major}.{version.minor}') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# TODO: When upgrading to v1 and above, implement this: | ||
# https://github.com/snok/install-poetry/blob/main/.github/workflows/tag_release.yml | ||
name: Tag releases with minor versions | ||
|
||
on: | ||
release: | ||
types: [published] | ||
|
||
jobs: | ||
tag-v1: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Update tag | ||
run: | | ||
minor_tag="$(python .github/get_version.py "${GITHUB_REF}" minor)" | ||
git tag $minor_tag | ||
git push origin HEAD:refs/heads/master --tags --force | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
name: Test | ||
|
||
on: | ||
pull_request: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
linting: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Check out repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: 3.10.0-rc.1 | ||
|
||
- name: Load pre-commit cache | ||
uses: actions/cache@v2 | ||
with: | ||
path: | | ||
~/.cache/pip | ||
~/.cache/pre-commit | ||
key: ${{ runner.os }}-pip-2 | ||
restore-keys: | | ||
${{ runner.os }}-pip- | ||
${{ runner.os }}- | ||
- name: Install pre-commit | ||
run: python -m pip install pre-commit | ||
|
||
- name: Run pre-commit | ||
run: pre-commit run --all-files | ||
|
||
test: | ||
needs: linting | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Check out repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: 3.10.0-rc.1 | ||
|
||
- name: Load cached Poetry installation | ||
uses: actions/cache@v2 | ||
with: | ||
path: ~/.local | ||
key: poetry-cache-0 | ||
|
||
- name: Install Poetry | ||
uses: snok/install-poetry@v1 | ||
with: | ||
version: 1.2.0a2 | ||
virtualenvs-in-project: true | ||
|
||
- name: Load cached venv | ||
uses: actions/cache@v2 | ||
id: cache-venv | ||
with: | ||
path: .venv | ||
key: ${{ hashFiles('**/poetry.lock') }}-0 | ||
|
||
- name: Install dependencies | ||
run: poetry install --no-interaction --no-root | ||
if: steps.cache-venv.outputs.cache-hit != 'true' | ||
|
||
- name: Run tests | ||
run: source $VENV && pytest main_tests.py --cov-report=xml | ||
|
||
- uses: codecov/codecov-action@v2 | ||
with: | ||
file: ./coverage.xml | ||
fail_ci_if_error: true | ||
token: ${{ secrets.CODECOV_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.env | ||
.venv | ||
.idea/ | ||
.mypy_cache/ | ||
__pycache__/ | ||
.coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
repos: | ||
- repo: https://github.com/ambv/black | ||
rev: 21.7b0 | ||
hooks: | ||
- id: black | ||
args: ['--quiet'] | ||
- repo: https://github.com/pycqa/isort | ||
rev: 5.9.3 | ||
hooks: | ||
- id: isort | ||
- repo: https://github.com/pre-commit/pre-commit-hooks | ||
rev: v4.0.1 | ||
hooks: | ||
- id: check-ast | ||
- id: check-added-large-files | ||
- id: check-merge-conflict | ||
- id: check-case-conflict | ||
- id: check-docstring-first | ||
- id: check-json | ||
- id: check-yaml | ||
- id: double-quote-string-fixer | ||
- id: end-of-file-fixer | ||
- id: trailing-whitespace | ||
- id: mixed-line-ending | ||
- id: trailing-whitespace | ||
- repo: https://github.com/asottile/pyupgrade | ||
rev: v2.23.3 | ||
hooks: | ||
- id: pyupgrade | ||
args: ['--py36-plus', '--py37-plus', '--keep-runtime-typing'] | ||
- repo: https://gitlab.com/pycqa/flake8 | ||
rev: 3.9.2 | ||
hooks: | ||
- id: flake8 | ||
additional_dependencies: [ | ||
'flake8-bugbear', | ||
'flake8-comprehensions', | ||
'flake8-deprecated', | ||
'flake8-use-fstring', | ||
'flake8-docstrings', | ||
'flake8-type-checking', | ||
] | ||
- repo: https://github.com/pre-commit/mirrors-mypy | ||
rev: 'v0.910' | ||
hooks: | ||
- id: mypy | ||
additional_dependencies: [types-dateparser] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FROM python:3.10.0rc1-alpine | ||
|
||
RUN apk add build-base | ||
|
||
RUN pip install httpx dateparser | ||
|
||
COPY main.py /main.py | ||
|
||
ENTRYPOINT ["python", "main.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
[![release](https://img.shields.io/github/release/sondrelg/container-retention-policy.svg)](https://github.com/sondrelg/container-retention-policy/releases/latest) | ||
[![coverage](https://codecov.io/gh/snok/drf-openapi-tester/branch/master/graph/badge.svg)](https://codecov.io/gh/sondrelg/container-retention-policy) | ||
|
||
# 📘 GHCR Container Retention Policy | ||
|
||
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. | ||
|
||
# Content | ||
|
||
- [Usage](#usage) | ||
- [Examples](#examples) | ||
- [Parameters](#parameters) | ||
- [Contributing](#contributing) | ||
|
||
# Usage | ||
|
||
To use the action, simply add it to your Github workflow, like this: | ||
|
||
```yaml | ||
- uses: sondrelg/[email protected] | ||
with: | ||
image-names: dev, web, test | ||
cut-off: two hours ago UTC+2 | ||
timestamp-to-use: updated_at | ||
account-type: org | ||
org-name: google | ||
token: ${{ secrets.PAT }} | ||
``` | ||
You could run this as | ||
a [scheduled event](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#schedule), 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](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch): trigger it manually in the Github repo UI when needed | ||
- [workflow_run](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_run): have it run as clean-up after another key workflow completes | ||
- or triggering it with a | ||
webhook ([repository_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#repository_dispatch)) | ||
# Examples | ||
For an organization, a full example might look something like this: | ||
```yaml | ||
name: Delete old container images | ||
|
||
on: | ||
schedule: | ||
- cron: '0 0 * * *' # every day at midnight | ||
|
||
jobs: | ||
delete-old-container-images: | ||
- name: Delete 'dev' containers older than a week | ||
uses: sondrelg/[email protected] | ||
with: | ||
image-names: app1/dev, app2/dev | ||
cut-off: A week ago UTC | ||
account-type: org | ||
org-name: my-org | ||
token: ${{ secrets.PAT }} | ||
|
||
- name: Delete 'test' containers older than a month | ||
uses: sondrelg/[email protected] | ||
with: | ||
image-names: app1/test, app2/test | ||
cut-off: One month ago UTC | ||
account-type: org | ||
org-name: my-org | ||
token: ${{ secrets.PAT }} | ||
``` | ||
While for a personal account, something like this might do: | ||
```yaml | ||
name: Delete old container images | ||
|
||
on: | ||
schedule: | ||
- cron: '0 0 0 * *' # the first day of the month | ||
|
||
jobs: | ||
delete-old-container-images: | ||
- name: Delete old images | ||
uses: sondrelg/[email protected] | ||
with: | ||
image-names: dev | ||
cut-off: One month ago UTC | ||
account-type: personal | ||
token: ${{ secrets.PAT }} | ||
``` | ||
# Parameters | ||
## image-names | ||
* **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. | ||
|
||
## cut-off | ||
|
||
* **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](https://dateparser.readthedocs.io/en/latest/) 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. | ||
|
||
## timestamp-to-use | ||
|
||
* **Required**: `Yes` | ||
* **Example**: `timestamp-to-use: created_at` | ||
* **Default**: `updated_at` | ||
* **Valid choices**: `updated_at` or `created_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. | ||
|
||
## account-type | ||
|
||
* **Required**: `Yes` | ||
* **Example**: `account-type: personal` | ||
* **Valid choices**: `org` or `personal` | ||
|
||
The account type of the account running the action. The account type determines which API endpoints to use in the Github | ||
API. | ||
|
||
## org-name | ||
|
||
* **Required**: `Only if account type is org` | ||
* **Example**: `org-name: google` | ||
|
||
The name of your organization. | ||
|
||
## token | ||
|
||
* **Required**: `Yes` | ||
* **Example**: `token: ${{ secrets.PAT }}` | ||
|
||
For the token, you need to pass a [personal access token](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token) | ||
with access to the container registry. Specifically, you need to grant | ||
it the following scopes: | ||
|
||
- `read:packages`, and | ||
- `delete:packages` | ||
|
||
# Contributing | ||
|
||
Please do 👏 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
name: 'Container Retention Policy' | ||
description: 'Lets you create a retention policy for GHCR hosted container images' | ||
branding: | ||
icon: "book" | ||
color: "blue" | ||
inputs: | ||
account-type: | ||
description: "The type of account. Can be either 'org' or 'personal'." | ||
required: true | ||
org-name: | ||
description: "The name of the organization. Only required if the account type is 'personal'." | ||
default: '' | ||
required: false | ||
image-names: | ||
description: 'Image name to delete. Supports passing several names as a comma-separated list.' | ||
required: true | ||
timestamp-to-use: | ||
description: 'Whether to use updated_at or created_at timestamps. Defaults to updated_at.' | ||
required: true | ||
default: 'updated_at' | ||
cut-off: | ||
description: "The cut-off for which to delete images older than. For example '2 days ago UTC'. Timezone is required." | ||
required: true | ||
token: | ||
description: 'Personal access token with read and delete scopes.' | ||
required: true | ||
|
||
runs: | ||
using: 'docker' | ||
image: 'Dockerfile' | ||
args: | ||
- ${{ inputs.account-type }} | ||
- ${{ inputs.org-name }} | ||
- ${{ inputs.image-names }} | ||
- ${{ inputs.timestamp-to-use }} | ||
- ${{ inputs.cut-off }} | ||
- ${{ inputs.token }} |
Oops, something went wrong.