From 92676e95b3b1d83f99bfe6d984cdaf1b0a19da8e Mon Sep 17 00:00:00 2001 From: MykytaPimonovTD Date: Mon, 18 Nov 2024 14:34:00 +0200 Subject: [PATCH 1/2] Create script that retrieves packages name. --- scripts/request-package-names.sh | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100755 scripts/request-package-names.sh diff --git a/scripts/request-package-names.sh b/scripts/request-package-names.sh new file mode 100755 index 00000000..6d019e8a --- /dev/null +++ b/scripts/request-package-names.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# +# Copyright 2024, TeamDev. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Redistribution and use in source and/or binary forms, with or without +# modification, must retain the above copyright notice and the following +# disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# Requests GitHub to retrieve package names published from a specific repository +# in the Apache Maven registry on GitHub Packages. +# +# Parameters: +# 1. The GitHub access token with the "read:packages" permission. +# 2. The name of the repository from which the packages were published. +# 3. The organization that owns the packages. +# 4. The file path where the package names should be written. +# +# The output is a file containing a JSON array of package names. For example: +# `["io.spine.config.package1","io.spine.config.package2"]`. +# + +if [ "$#" -ne 4 ]; then + echo "Usage: request-package-names.sh " + exit 1 +fi + +token=$1 +repoName=$2 +orgName=$3 +countOnThisPage=0 +page=1 +packages='' + +function requestPackages() { + url="https://api.github.com/orgs/$orgName/packages?package_type=maven&per_page=100&page=$page" + response=$(curl -s -H "Authorization: Bearer $token" "$url") + countOnThisPage=$(echo "$response" | jq -c length) + packagesOnThisPage=$(echo "$response" | \ + jq -c --arg repo "$repoName" '.[] | select(.repository.name == $repo) | .name') + if [ "$?" -ne 0 ]; then + echo "An unexpected response was received and could not be parsed." \ + "Ensure that parameters contains the correct data." + exit 1 + fi + packages="$packages $packagesOnThisPage" +} + +while true; do + requestPackages + (( page++ )) + if [ "$countOnThisPage" -eq 0 ]; then + break + fi +done + +json=$(echo $packages | sed 's/ /,/g' | sed 's/^/[/' | sed 's/$/]/') +echo "$json" >> "$4" From db5732be8c847e40aa040892d9ddc44b035e0290 Mon Sep 17 00:00:00 2001 From: MykytaPimonovTD Date: Mon, 18 Nov 2024 14:36:32 +0200 Subject: [PATCH 2/2] Create GitHub workflow for deleting obsolete artifacts. --- ...move-obsolete-artifacts-from-packages.yaml | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .github-workflows/remove-obsolete-artifacts-from-packages.yaml diff --git a/.github-workflows/remove-obsolete-artifacts-from-packages.yaml b/.github-workflows/remove-obsolete-artifacts-from-packages.yaml new file mode 100644 index 00000000..fe8ad849 --- /dev/null +++ b/.github-workflows/remove-obsolete-artifacts-from-packages.yaml @@ -0,0 +1,73 @@ +# +# Periodically removes obsolete artifacts from GitHub Packages. +# +# Only non-release artifacts—those containing "SNAPSHOT" in their version name—are eligible +# for removal. The latest non-release artifacts will be retained, with the exact number determined +# by the `VERSION_COUNT_TO_KEEP` environment variable. +# +# Please note the following details: +# +# 1. An artifact cannot be deleted if it is public and has been downloaded more than 5,000 times. +# In this scenario, contact GitHub support for further assistance. +# +# 2. This workflow only applies to artifacts published from this repository. +# +# 3. A maximum of 100 artifacts can be removed per run from each package; +# if there are more than 100 obsolete artifacts, either manually restart the workflow +# or wait for the next scheduled removal. +# +# 4. When artifacts with version `x.x.x-SNAPSHOT` are published, GitHub automatically appends +# the current timestamp, resulting in versions like `x.x.x-SNAPSHOT.20241024.173759`. +# All such artifacts are grouped into one package and treated as a single package +# in GitHub Packages with the version `x.x.x-SNAPSHOT`. Consequently, it is not possible +# to remove obsolete versions within a package; only the entire package can be deleted. +# + +name: Remove obsolete Maven artifacts from GitHub Packages + +on: + schedule: + - cron: '0 0 * * *' # Run every day at midnight. + +env: + VERSION_COUNT_TO_KEEP: 5 # Number of most recent SNAPSHOT versions to retain. + +jobs: + retrieve-package-names: + name: Retrieve the package names published from this repository + runs-on: ubuntu-latest + outputs: + package-names: ${{ steps.request-package-names.outputs.package-names }} + steps: + - uses: actions/checkout@v4 + with: + submodules: 'true' + + - name: Retrieve the names of packages + id: request-package-names + shell: bash + run: | + repoName=$(echo ${{ github.repository }} | cut -d '/' -f2) + chmod +x ./config/scripts/request-package-names.sh + ./config/scripts/request-package-names.sh ${{ github.token }} \ + $repoName ${{ github.repository_owner }} ./package-names.json + echo "package-names=$(<./package-names.json)" >> $GITHUB_OUTPUT + + delete-obsolete-artifacts: + name: Remove obsolete artifacts published from this repository to GitHub Packages + needs: retrieve-package-names + runs-on: ubuntu-latest + strategy: + matrix: + package-name: ${{ fromJson(needs.retrieve-package-names.outputs.package-names) }} + steps: + - name: Remove obsolete artifacts from '${{ matrix.package-name }}' package + uses: actions/delete-package-versions@v5 + with: + owner: ${{ github.repository_owner }} + package-name: ${{ matrix.package-name }} + package-type: 'maven' + token: ${{ github.token }} + min-versions-to-keep: ${{ env.VERSION_COUNT_TO_KEEP }} + # Ignores artifacts that do not contain the word "SNAPSHOT". + ignore-versions: '^(?!.+SNAPSHOT).*$'