From 174d89c81f0a6e7115f78f8ddbf8af33762e062b Mon Sep 17 00:00:00 2001 From: Adrian Priestley <47989725+a-priestley@users.noreply.github.com> Date: Sun, 14 Sep 2025 09:54:53 -0230 Subject: [PATCH] feat(workflow): Implement new Github workflow for building and pushing container images (#5242) * fix(workflows): Update Docker workflow tag pattern - Change tag pattern from "v*" to "*.*.*" for better version matching - Add new semver pattern type for major version * squash! fix(workflows): Update Docker workflow tag pattern - Change tag pattern from "v*" to "*.*.*" for better version matching - Add new semver pattern type for major version * Update docker.yml * Update docker.yml * Update docker.yml * fix(docker): Correct copy command to use recursive flag for EnemizerCLI - Changed 'cp' to 'cp -r' to properly copy EnemizerCLI directory * fixup! Update docker.yml * fix(docker): Correct copy command to use recursive flag for EnemizerCLI - Changed 'cp' to 'cp -r' to properly copy EnemizerCLI directory * chore(workflow): Update Docker workflow to support multiple platforms - Removed matrix strategy for platform selection - Set platforms directly in the Docker Buildx step * docs(deployment): Update container deployment documentation - Specify minimum versions for Docker and Podman - Add requirement for Docker Buildx plugin * fix(workflows): Exclude specific paths from Docker build triggers - Prevent unnecessary builds for documentation and deployment files * feat(ci): Update Docker workflow for multi-architecture builds - Added new build job for ARM64 architecture support - Created a multi-arch manifest to manage image variants - Improved Docker Buildx setup and push steps for both architectures * fixup! feat(ci): Update Docker workflow for multi-architecture builds - Added new build job for ARM64 architecture support - Created a multi-arch manifest to manage image variants - Improved Docker Buildx setup and push steps for both architectures * fixup! feat(ci): Update Docker workflow for multi-architecture builds - Added new build job for ARM64 architecture support - Created a multi-arch manifest to manage image variants - Improved Docker Buildx setup and push steps for both architectures * fixup! feat(ci): Update Docker workflow for multi-architecture builds - Added new build job for ARM64 architecture support - Created a multi-arch manifest to manage image variants - Improved Docker Buildx setup and push steps for both architectures * fix(workflow): Cleanup temporary image tags * fixup! fix(workflow): Cleanup temporary image tags * fixup! fix(workflow): Cleanup temporary image tags * fixup! fix(workflow): Cleanup temporary image tags * fix(workflow): Apply scoped build cache to eliminate race condition between jobs. * fixup! fix(workflow): Apply scoped build cache to eliminate race condition between jobs. * Remove branch wildcard * Test comment * Revert wildcard removal * Remove `pr` event * Revert `pr` event removal * fixup! Revert `pr` event removal * Update docker.yml * Update docker.yml * Update docker.yml * feat(workflows): Add docker workflow to compute final tags - Introduce a step to compute final tags based on GitHub ref type - Ensure 'latest' tag is set for version tags * chore(workflow): Enable manual dispatch for Docker workflow - Add workflow_dispatch event trigger to allow manual runs * fix(workflows): Update Docker workflow to handle tag outputs correctly - Use readarray to handle tags as an array - Prevent duplicate latest tags in the tags list - Set multiline output for tags in GitHub Actions * Update docker.yml Use new `is_not_default_branch` condition * Update docker.yml Allow "v" prefix for semver git tags qualifying for `latest` image tag * Update docker.yml Tighten up `tags` push pattern mirroring that of `release` workflow. * Merge branch 'ArchipelagoMW:main' into main * Update docker.yml * Merge branch 'ArchipelagoMW:main' into docker_wf * Update docker.yml Use new `is_not_default_branch` condition * Update docker.yml Allow "v" prefix for semver git tags qualifying for `latest` image tag * Update docker.yml Tighten up `tags` push pattern mirroring that of `release` workflow. * ci(docker): refactor multi-arch build to use matrix strategy - Consolidate separate amd64 and arm64 jobs into a single build job - Introduce matrix for platform, runner, suffix, and cache-scope - Generalize tag computation and build steps with matrix variables * fixup! ci(docker): refactor multi-arch build to use matrix strategy - Consolidate separate amd64 and arm64 jobs into a single build job - Introduce matrix for platform, runner, suffix, and cache-scope - Generalize tag computation and build steps with matrix variables --- .github/workflows/docker.yml | 154 +++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..cf9ce08f --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,154 @@ +name: Build and Publish Docker Images + +on: + push: + paths: + - "**" + - "!docs/**" + - "!deploy/**" + - "!setup.py" + - "!.gitignore" + - "!.github/workflows/**" + - ".github/workflows/docker.yml" + branches: + - "*" + tags: + - "v?[0-9]+.[0-9]+.[0-9]*" + workflow_dispatch: + +env: + REGISTRY: ghcr.io + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + image-name: ${{ steps.image.outputs.name }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + package-name: ${{ steps.package.outputs.name }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set lowercase image name + id: image + run: | + echo "name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT + + - name: Set package name + id: package + run: | + echo "name=$(basename ${GITHUB_REPOSITORY,,})" >> $GITHUB_OUTPUT + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ steps.image.outputs.name }} + tags: | + type=ref,event=branch,enable={{is_not_default_branch}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=nightly,enable={{is_default_branch}} + + - name: Compute final tags + id: final-tags + run: | + readarray -t tags <<< "${{ steps.meta.outputs.tags }}" + + if [[ "${{ github.ref_type }}" == "tag" ]]; then + tag="${{ github.ref_name }}" + if [[ "$tag" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + full_latest="${{ env.REGISTRY }}/${{ steps.image.outputs.name }}:latest" + # Check if latest is already in tags to avoid duplicates + if ! printf '%s\n' "${tags[@]}" | grep -q "^$full_latest$"; then + tags+=("$full_latest") + fi + fi + fi + + # Set multiline output + echo "tags<> $GITHUB_OUTPUT + printf '%s\n' "${tags[@]}" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + build: + needs: prepare + runs-on: ${{ matrix.runner }} + permissions: + contents: read + packages: write + strategy: + matrix: + include: + - platform: amd64 + runner: ubuntu-latest + suffix: amd64 + cache-scope: amd64 + - platform: arm64 + runner: ubuntu-24.04-arm + suffix: arm64 + cache-scope: arm64 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Compute suffixed tags + id: tags + run: | + readarray -t tags <<< "${{ needs.prepare.outputs.tags }}" + suffixed=() + for t in "${tags[@]}"; do + suffixed+=("$t-${{ matrix.suffix }}") + done + echo "tags=$(IFS=','; echo "${suffixed[*]}")" >> $GITHUB_OUTPUT + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + platforms: linux/${{ matrix.platform }} + push: true + tags: ${{ steps.tags.outputs.tags }} + labels: ${{ needs.prepare.outputs.labels }} + cache-from: type=gha,scope=${{ matrix.cache-scope }} + cache-to: type=gha,mode=max,scope=${{ matrix.cache-scope }} + provenance: false + + manifest: + needs: [prepare, build] + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create and push multi-arch manifest + run: | + readarray -t tag_array <<< "${{ needs.prepare.outputs.tags }}" + + for tag in "${tag_array[@]}"; do + docker manifest create "$tag" \ + "$tag-amd64" \ + "$tag-arm64" + + docker manifest push "$tag" + done