Merge pull request #1399 from constructive-io/feat/export-exclude-cat… #1449
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Constructive Docker | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - v1 | |
| - release/* | |
| paths-ignore: | |
| - '**.md' | |
| workflow_dispatch: {} | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }}-docker-constructive | |
| cancel-in-progress: true | |
| jobs: | |
| build-push-constructive: | |
| if: github.event_name != 'pull_request' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: linux/amd64 | |
| arch: amd64 | |
| runner: ubuntu-latest # x86_64 | |
| - platform: linux/arm64 | |
| arch: arm64 | |
| runner: blacksmith-4vcpu-ubuntu-2404-arm # native arm | |
| runs-on: ${{ matrix.runner }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| env: | |
| REPO: ghcr.io/${{ github.repository_owner }} | |
| IMAGE_NAME: constructive | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to GHCR | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REPO }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=sha,format=short,prefix= | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| # For pull_request events (if they are re-enabled), | |
| # do a quick amd64-only build without pushing. | |
| - name: Build (no push, PR only) | |
| if: github.event_name == 'pull_request' && matrix.platform == 'linux/amd64' | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| platforms: linux/amd64 | |
| push: false | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # For non-PR events, build one architecture per runner | |
| # and push images by digest. These digests are later | |
| # assembled into a multi-arch manifest. | |
| - name: Build & push by digest | |
| if: github.event_name != 'pull_request' | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| platforms: ${{ matrix.platform }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| outputs: type=image,name=${{ env.REPO }}/${{ env.IMAGE_NAME }},push-by-digest=true,push=true | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Export digest | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| mkdir -p "${{ runner.temp }}/digests" | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "${{ runner.temp }}/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| if: github.event_name != 'pull_request' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| # Artifact names cannot contain slashes, so we use matrix.arch | |
| name: digests-${{ matrix.arch }} | |
| path: ${{ runner.temp }}/digests/* | |
| # Assemble per-architecture images into a single | |
| # multi-arch manifest for each tag. | |
| publish-constructive-manifest: | |
| if: github.event_name != 'pull_request' | |
| runs-on: ubuntu-latest | |
| needs: build-push-constructive | |
| permissions: | |
| contents: read | |
| packages: write | |
| env: | |
| REPO: ghcr.io/${{ github.repository_owner }} | |
| IMAGE_NAME: constructive | |
| DOCKERHUB_IMAGE: constructiveio/constructive | |
| steps: | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to GHCR | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Download digests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: digests-* | |
| path: ${{ runner.temp }}/digests | |
| merge-multiple: true | |
| - name: Extract metadata (GHCR) | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REPO }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=sha,format=short,prefix= | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Extract metadata (Docker Hub) | |
| id: meta-dockerhub | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: docker.io/${{ env.DOCKERHUB_IMAGE }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=sha,format=short,prefix= | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Create and push multi-arch manifests (GHCR) | |
| run: | | |
| set -euo pipefail | |
| image="${{ env.REPO }}/${{ env.IMAGE_NAME }}" | |
| digest_dir="${{ runner.temp }}/digests" | |
| if [ ! -d "$digest_dir" ]; then | |
| echo "No digests directory found at $digest_dir" | |
| exit 1 | |
| fi | |
| digests="" | |
| for digest_file in "$digest_dir"/*; do | |
| digest="$(basename "$digest_file")" | |
| digests="$digests $image@sha256:$digest" | |
| done | |
| if [ -z "$digests" ]; then | |
| echo "No digests found to create manifest" | |
| exit 1 | |
| fi | |
| echo "Creating GHCR manifests for tags:" | |
| echo "${{ steps.meta.outputs.tags }}" | |
| echo "${{ steps.meta.outputs.tags }}" | while read -r tag; do | |
| [ -z "$tag" ] && continue | |
| echo "Creating multi-arch manifest for $tag" | |
| docker buildx imagetools create -t "$tag" $digests | |
| done | |
| - name: Copy multi-arch manifests to Docker Hub | |
| if: github.ref == 'refs/heads/main' | |
| run: | | |
| set -euo pipefail | |
| ghcr_image="${{ env.REPO }}/${{ env.IMAGE_NAME }}" | |
| echo "Copying manifests to Docker Hub:" | |
| echo "${{ steps.meta-dockerhub.outputs.tags }}" | |
| echo "${{ steps.meta-dockerhub.outputs.tags }}" | while read -r tag; do | |
| [ -z "$tag" ] && continue | |
| echo "Copying to $tag" | |
| docker buildx imagetools create -t "$tag" "${ghcr_image}:latest" | |
| done |