diff --git a/.github/workflows/docker-cleanup.yaml b/.github/workflows/docker-cleanup.yaml new file mode 100644 index 00000000..61121259 --- /dev/null +++ b/.github/workflows/docker-cleanup.yaml @@ -0,0 +1,56 @@ +name: Docker PR Image Cleanup + +on: + pull_request: + types: + - closed + +permissions: + contents: read + packages: write + +concurrency: + group: docker-cleanup-${{ github.event.pull_request.number }} + cancel-in-progress: false + +jobs: + enumerate: + runs-on: ubuntu-latest + if: ${{ !github.event.pull_request.head.repo.fork }} + outputs: + packages: ${{ steps.list.outputs.packages }} + steps: + - id: list + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ORG: stoatchat + REPO: ${{ github.repository }} + run: | + set -euo pipefail + packages=$(gh api --paginate \ + "/orgs/${ORG}/packages?package_type=container" \ + --jq "[.[] | select(.repository.full_name == \"${REPO}\") | .name]") + echo "packages=${packages}" >> "$GITHUB_OUTPUT" + + cleanup: + needs: enumerate + runs-on: ubuntu-latest + if: ${{ needs.enumerate.outputs.packages != '[]' }} + strategy: + fail-fast: false + matrix: + package: ${{ fromJSON(needs.enumerate.outputs.packages) }} + steps: + - env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ORG: stoatchat + PACKAGE: ${{ matrix.package }} + TAG: pr-${{ github.event.pull_request.number }} + run: | + set -euo pipefail + gh api --paginate \ + "/orgs/${ORG}/packages/container/${PACKAGE}/versions" \ + --jq ".[] | select(.metadata.container.tags | index(\"${TAG}\")) | .id" \ + | while read -r id; do + gh api -X DELETE "/orgs/${ORG}/packages/container/${PACKAGE}/versions/${id}" + done diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 2be1f438..75aefeb6 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -5,8 +5,6 @@ on: tags: - "*" pull_request: - paths: - - "Dockerfile" workflow_dispatch: permissions: @@ -19,9 +17,9 @@ concurrency: jobs: base: - name: Test base image build + name: Test base image build (fork) runs-on: arc-runner-set - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork steps: # Configure build environment - name: Checkout @@ -42,7 +40,7 @@ jobs: publish: runs-on: arc-runner-set - if: github.event_name != 'pull_request' + if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork }} name: Publish Docker images steps: # Configure build environment @@ -59,6 +57,15 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Determine base image tag + id: base + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "tag=pr-${{ github.event.number }}" >> "$GITHUB_OUTPUT" + else + echo "tag=latest" >> "$GITHUB_OUTPUT" + fi + # Build the image - name: Build base image uses: docker/build-push-action@v4 @@ -66,7 +73,9 @@ jobs: context: . push: true platforms: linux/amd64,linux/arm64 - tags: ghcr.io/${{ github.repository_owner }}/base:latest + tags: ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} + cache-from: type=gha,scope=buildx-base-multi-arch + cache-to: type=gha,scope=buildx-base-multi-arch,mode=max # stoatchat/api - name: Docker meta @@ -84,7 +93,7 @@ jobs: file: crates/delta/Dockerfile tags: ${{ steps.meta-delta.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-delta.outputs.labels }} # stoatchat/events @@ -103,7 +112,7 @@ jobs: file: crates/bonfire/Dockerfile tags: ${{ steps.meta-bonfire.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-bonfire.outputs.labels }} # stoatchat/file-server @@ -122,7 +131,7 @@ jobs: file: crates/services/autumn/Dockerfile tags: ${{ steps.meta-autumn.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-autumn.outputs.labels }} # stoatchat/proxy @@ -141,7 +150,7 @@ jobs: file: crates/services/january/Dockerfile tags: ${{ steps.meta-january.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-january.outputs.labels }} # stoatchat/gifbox @@ -160,7 +169,7 @@ jobs: file: crates/services/gifbox/Dockerfile tags: ${{ steps.meta-gifbox.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-gifbox.outputs.labels }} # stoatchat/crond @@ -179,7 +188,7 @@ jobs: file: crates/daemons/crond/Dockerfile tags: ${{ steps.meta-crond.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-crond.outputs.labels }} # stoatchat/pushd @@ -198,7 +207,7 @@ jobs: file: crates/daemons/pushd/Dockerfile tags: ${{ steps.meta-pushd.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-pushd.outputs.labels }} # stoatchat/voice-ingress @@ -217,5 +226,5 @@ jobs: file: crates/daemons/voice-ingress/Dockerfile tags: ${{ steps.meta-voice-ingress.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-voice-ingress.outputs.labels }}