From 6a05c5affd52952696c6fe95ece7e0181a47b047 Mon Sep 17 00:00:00 2001 From: KingPin <28669+KingPin@users.noreply.github.com> Date: Tue, 19 May 2026 09:25:50 -0400 Subject: [PATCH 1/2] ci: scheduled prune of untagged GHCR staging digests Per-arch builds in docker-ci.yml push by digest to ghcr.io/kingpin/php-docker and accumulate as untagged versions over time. dataaxiom/ghcr-cleanup-action removes children of live manifest lists from its working set before pruning, so per-arch digests referenced by current tags remain safe. Starts in dry-run mode; window is 28 days to survive a couple of missed weekly builds. Closes #39 --- .github/workflows/ghcr-prune.yml | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/ghcr-prune.yml diff --git a/.github/workflows/ghcr-prune.yml b/.github/workflows/ghcr-prune.yml new file mode 100644 index 0000000..f27fc08 --- /dev/null +++ b/.github/workflows/ghcr-prune.yml @@ -0,0 +1,40 @@ +name: GHCR untagged prune + +# Per-arch staging digests pushed during docker-ci.yml accumulate as untagged +# versions on the ghcr.io/kingpin/php-docker package. The cleanup action's +# algorithm removes children of live manifest lists from the working set +# before applying any deletion rule, so the per-arch digests referenced by +# current tags are safe even though they appear untagged in the GHCR UI. +# +# older-than: 28d keeps a buffer wide enough to survive 2-3 weeks without a +# successful build (weekly schedule + ad-hoc dispatches). +# +# dry-run: true initially — verify the planned deletions in a run summary +# before flipping to false. + +on: + schedule: + - cron: '0 5 * * 3' # Wednesday 05:00 UTC, day after the weekly build + workflow_dispatch: + inputs: + dry-run: + description: 'Dry run (list deletions without performing them)' + type: boolean + default: true + +concurrency: + group: ghcr-prune + cancel-in-progress: false + +jobs: + prune: + runs-on: ubuntu-latest + permissions: + packages: write + steps: + - uses: dataaxiom/ghcr-cleanup-action@v1 + with: + package: php-docker + delete-untagged: true + older-than: 28d + dry-run: ${{ github.event_name == 'workflow_dispatch' && inputs.dry-run || true }} From 51c1daff5d1039193dc73582625d2208c67ee60f Mon Sep 17 00:00:00 2001 From: KingPin <28669+KingPin@users.noreply.github.com> Date: Tue, 19 May 2026 09:45:23 -0400 Subject: [PATCH 2/2] ci(ghcr-prune): honor workflow_dispatch dry-run input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous expression had the classic A && B || C pitfall — dispatching with dry-run unchecked still evaluated to true, so the input toggle was inert. Invert the event check so the || branch only fires for non-dispatch events. --- .github/workflows/ghcr-prune.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ghcr-prune.yml b/.github/workflows/ghcr-prune.yml index f27fc08..8ccbd7d 100644 --- a/.github/workflows/ghcr-prune.yml +++ b/.github/workflows/ghcr-prune.yml @@ -37,4 +37,4 @@ jobs: package: php-docker delete-untagged: true older-than: 28d - dry-run: ${{ github.event_name == 'workflow_dispatch' && inputs.dry-run || true }} + dry-run: ${{ github.event_name != 'workflow_dispatch' || inputs.dry-run }}