From 46b3487d58741402f7abb705ba626ec79bbb2b84 Mon Sep 17 00:00:00 2001 From: Chip Kent <5250374+chipkent@users.noreply.github.com> Date: Wed, 10 Nov 2021 21:23:00 -0700 Subject: [PATCH 1/2] Initial code --- README.md | 27 +++++++++++++++++-- action.yml | 23 ++++++++++++++++ docker-cleanup.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 action.yml create mode 100644 docker-cleanup.py diff --git a/README.md b/README.md index 6980532..95dbac1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,25 @@ -# action-cleanup_package -GitHub Action to clean up unwanted GitHub packages +# action-cleanup-package + +This is a GitHub Action to delete GitHub packages. It is very useful to clean up unneeded Docker images in ghcr.io after a PR is closed. + +``` +# Delete Docker images after PR merge +# + +name: 'Clean up Docker images from PR' + +on: + pull_request: + types: [closed] + +jobs: + purge-image: + name: Delete image from ghcr.io + runs-on: ubuntu-latest + steps: + - uses: chipkent/action-cleanup-package@v1.0.0 + with: + package-name: ${{ github.event.repository.name }} + tag: pr-${{ github.event.pull_request.number }} + github-token: ${{ secrets.CI_ACTION_TOKEN }} +``` diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..23b07aa --- /dev/null +++ b/action.yml @@ -0,0 +1,23 @@ + +name: 'Delete ghcr.io package tag' +description: 'Delete a tagged package from ghcr.io' +inputs: + package-name: + description: 'Package name' + required: true + tag: + description: 'Package tag' + required: true + github-token: + description: 'GitHub Personal Access Token with package deletion permissions.' + required: true +runs: + using: "composite" + steps: + - uses: actions/setup-python@v2 + with: + python-version: '3.8' + - name: Install packages + run: pip install requests + - name: Delete image from ghcr.io + run: python ${{ github.action_path }}/docker-cleanup.py ${{ inputs.package-name }} ${{ inputs.tag }} ${{ inputs.github-token }} diff --git a/docker-cleanup.py b/docker-cleanup.py new file mode 100644 index 0000000..b49beab --- /dev/null +++ b/docker-cleanup.py @@ -0,0 +1,69 @@ +# Script to delete tagged docker images. +# Usage: +# + + +import requests + + +def get_package_versions(package_name, package_type): + print("get_package_versions", package_name, package_type) + # https://docs.github.com/en/rest/reference/packages#get-all-package-versions-for-a-package-owned-by-the-authenticated-user + result = [] + done = False + page = 1 + + while not done: + response = session.get(f"https://api.github.com/user/packages/{package_type}/{package_name}/versions", params={"per_page" : 100, "page": page}) + response.raise_for_status() + json = response.json() + result.extend(json) + done = len(json) != 100 + page += 1 + + return result + + +def delete_package_version(package_name, package_type, id): + print("delete_package_version", package_name, package_type, id) + + # https://docs.github.com/en/rest/reference/packages#delete-a-package-version-for-the-authenticated-user + response = session.delete(f"https://api.github.com/user/packages/{package_type}/{package_name}/versions/{id}") + response.raise_for_status() + + +def get_tagged_container(package_name, tag): + print("get_tagged_container", package_name, tag) + packages = get_package_versions(package_name, "container") + return [version for version in packages if tag in version["metadata"]["container"]["tags"]] + + +def delete_tagged_container(package_name, tag): + print("delete_tagged_container", package_name, tag) + tags = get_tagged_container(package_name, tag) + + if tags: + for tag in tags: + delete_package_version(package_name, "container", tag["id"]) + else: + raise Exception(f"No containers to delete: {package_name} {tag}") + + +################################ + +import sys + +if len(sys.argv) != 4: + raise SystemExit("Usage: docker-cleanup.py ") + +package_name = sys.argv[1] +tag = sys.argv[2] +token = sys.argv[3] + +print("package_name = ", package_name) +print("tag = ", tag) + +session = requests.Session() +session.headers.update({"Authorization": f"token {token}", "Accept" : "application/vnd.github.v3+json"}) +delete_tagged_container(package_name, tag) + From 29dec7ebfa8e271c363dbcc384d3d50aa1e890e0 Mon Sep 17 00:00:00 2001 From: Chip Kent <5250374+chipkent@users.noreply.github.com> Date: Wed, 10 Nov 2021 21:25:47 -0700 Subject: [PATCH 2/2] Updated readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 95dbac1..85f13ad 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # action-cleanup-package -This is a GitHub Action to delete GitHub packages. It is very useful to clean up unneeded Docker images in ghcr.io after a PR is closed. +This is a GitHub Action to delete GitHub packages. It is very useful to clean up unneeded Docker +images in the GitHub Container Registry (ghcr.io) after a PR is closed. ``` # Delete Docker images after PR merge