diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index 3ad396edc..baa96903b 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -7,37 +7,20 @@ on: tags: - "v*" -jobs: - # Determine tags to use for all platforms - determine-tags: - runs-on: ubuntu-latest - permissions: - contents: read - outputs: - tags: ${{ steps.determine_tags.outputs.tags }} - image_name: ${{ steps.determine_tags.outputs.image_name }} - steps: - - name: Determine tags - id: determine_tags - run: | - IMAGE_NAME=ghcr.io/${{ github.repository_owner }}/clawdbot - - if [[ $GITHUB_REF == refs/heads/main ]]; then - echo "tags=${IMAGE_NAME}:latest" >> $GITHUB_OUTPUT - echo "image_name=${IMAGE_NAME}" >> $GITHUB_OUTPUT - elif [[ $GITHUB_REF == refs/tags/v* ]]; then - VERSION=$(echo ${GITHUB_REF#refs/tags/v}) - echo "tags=${IMAGE_NAME}:${VERSION},${IMAGE_NAME}:latest" >> $GITHUB_OUTPUT - echo "image_name=${IMAGE_NAME}" >> $GITHUB_OUTPUT - fi +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} +jobs: # Build amd64 image build-amd64: runs-on: ubuntu-latest - needs: determine-tags permissions: packages: write contents: read + outputs: + image-digest: ${{ steps.build.outputs.digest }} + image-metadata: ${{ steps.meta.outputs.json }} steps: - name: Checkout uses: actions/checkout@v4 @@ -57,33 +40,51 @@ jobs: done exit 1 - - name: Setup Docker Buildx + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: - registry: ghcr.io + registry: ${{ env.REGISTRY }} username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{version}},suffix=-amd64 + type=semver,pattern={{version}},suffix=-arm64 + type=ref,event=branch,suffix=-amd64 + type=ref,event=branch,suffix=-arm64 + - name: Build and push amd64 image + id: build uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64 - push: true - tags: ${{ needs.determine-tags.outputs.tags }}-amd64 + labels: ${{ steps.meta.outputs.labels }} + tags: ${{ steps.meta.outputs.tags }} cache-from: type=gha cache-to: type=gha,mode=max + provenance: false + push: true # Build arm64 image build-arm64: - runs-on: ubuntu-latest-arm64 - needs: determine-tags + runs-on: ubuntu-24.04-arm permissions: packages: write contents: read + outputs: + image-digest: ${{ steps.build.outputs.digest }} + image-metadata: ${{ steps.meta.outputs.json }} steps: - name: Checkout uses: actions/checkout@v4 @@ -103,57 +104,70 @@ jobs: done exit 1 - - name: Setup Docker Buildx + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: - registry: ghcr.io + registry: ${{ env.REGISTRY }} username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{version}},suffix=-amd64 + type=semver,pattern={{version}},suffix=-arm64 + type=ref,event=branch,suffix=-amd64 + type=ref,event=branch,suffix=-arm64 + - name: Build and push arm64 image + id: build uses: docker/build-push-action@v6 with: context: . platforms: linux/arm64 - push: true - tags: ${{ needs.determine-tags.outputs.tags }}-arm64 + labels: ${{ steps.meta.outputs.labels }} + tags: ${{ steps.meta.outputs.tags }} cache-from: type=gha cache-to: type=gha,mode=max + provenance: false + push: true # Create multi-platform manifest create-manifest: runs-on: ubuntu-latest - needs: [determine-tags, build-amd64, build-arm64] permissions: packages: write contents: read + needs: [build-amd64, build-arm64] steps: - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: - registry: ghcr.io + registry: ${{ env.REGISTRY }} username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata for manifest + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + - name: Create and push manifest run: | - # Split tags string into array - IFS=',' read -r -a TAGS <<<"${{ needs.determine-tags.outputs.tags }}" - IMAGE_NAME="${{ needs.determine-tags.outputs.image_name }}" - - for TAG in "${TAGS[@]}"; do - # Create manifest - docker manifest create ${TAG} \ - ${TAG}-amd64 \ - ${TAG}-arm64 - - # Annotate manifest - docker manifest annotate ${TAG} ${TAG}-amd64 --os linux --arch amd64 - docker manifest annotate ${TAG} ${TAG}-arm64 --os linux --arch arm64 --variant v8 - - # Push manifest - docker manifest push ${TAG} - done + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + ${{ needs.build-amd64.outputs.image-digest }} \ + ${{ needs.build-arm64.outputs.image-digest }} + env: + DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta.outputs.json }}