diff --git a/.github/workflows/quay_binaries_push.yml b/.github/workflows/quay_binaries_push.yml index 37379008..388a62d2 100644 --- a/.github/workflows/quay_binaries_push.yml +++ b/.github/workflows/quay_binaries_push.yml @@ -1,30 +1,98 @@ # Push binaries to Quay.io, when a new release is created -name: oadp-cli binaries image push +name: Multi-Arch Binary Push to Quay.io on: push: tags: - 'v*' + pull_request: + + +env: + IMAGE_REPO: quay.io/konveyor/oadp-cli-binaries -# Check out code, podman login, run podman build, push to jobs: - push-binaries: + + multi-arch-build: + name: Build Multi-Arch Images runs-on: ubuntu-latest + strategy: + matrix: + arch: [amd64, arm64, ppc64le, s390x] steps: + - name: Checkout code uses: actions/checkout@v4 - - name: Podman login - run: podman login -u ${{ secrets.QUAY_USER }} -p ${{ secrets.QUAY_TOKEN }} quay.io + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Build Image for ${{ matrix.arch }} + id: build_image + uses: redhat-actions/buildah-build@v2 + with: + image: oadp-cli-binaries-local + tags: ${{ matrix.arch }} + archs: ${{ matrix.arch }} + containerfiles: | + ./Containerfile.download - - name: Podman build and tag + - name: Save image as tar run: | - podman build -f Dockerfile.download \ - -t quay.io/konveyor/oadp-cli-binaries:${{ github.ref_name }} \ - -t quay.io/konveyor/oadp-cli-binaries:latest . - - - name: Podman push version tag - run: podman push quay.io/konveyor/oadp-cli-binaries:${{ github.ref_name }} + buildah push ${{ steps.build_image.outputs.image-with-tag }} oci-archive:oadp-cli-${{ matrix.arch }}.tar + + - name: Upload image artifact + uses: actions/upload-artifact@v4 + with: + name: oadp-cli-image-${{ matrix.arch }} + path: oadp-cli-${{ matrix.arch }}.tar + retention-days: 1 + + push-manifest: + name: Create and Push Multi-Arch Manifest + runs-on: ubuntu-latest + needs: multi-arch-build + if: startsWith(github.ref_name, 'v') + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + pattern: oadp-cli-image-* - - name: Podman push latest tag - run: podman push quay.io/konveyor/oadp-cli-binaries:latest \ No newline at end of file + - name: Buildah login + run: buildah login -u ${{ secrets.QUAY_USER }} -p ${{ secrets.QUAY_TOKEN }} quay.io + + - name: Load images and tag archs + run: | + # Load all arch images and capture their IDs + AMD64_ID=$(buildah pull oci-archive:oadp-cli-image-amd64/oadp-cli-amd64.tar) + ARM64_ID=$(buildah pull oci-archive:oadp-cli-image-arm64/oadp-cli-arm64.tar) + PPC64LE_ID=$(buildah pull oci-archive:oadp-cli-image-ppc64le/oadp-cli-ppc64le.tar) + S390X_ID=$(buildah pull oci-archive:oadp-cli-image-s390x/oadp-cli-s390x.tar) + + # Tag the loaded images using their IDs + buildah tag $AMD64_ID ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-amd64 + buildah tag $ARM64_ID ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-arm64 + buildah tag $PPC64LE_ID ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-ppc64le + buildah tag $S390X_ID ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-s390x + + - name: Create and push multi-arch manifest (version tag) + run: | + buildah manifest create ${{ env.IMAGE_REPO }}:${{ github.ref_name }} + buildah manifest add ${{ env.IMAGE_REPO }}:${{ github.ref_name }} ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-amd64 + buildah manifest add ${{ env.IMAGE_REPO }}:${{ github.ref_name }} ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-arm64 + buildah manifest add ${{ env.IMAGE_REPO }}:${{ github.ref_name }} ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-ppc64le + buildah manifest add ${{ env.IMAGE_REPO }}:${{ github.ref_name }} ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-s390x + buildah manifest push --all ${{ env.IMAGE_REPO }}:${{ github.ref_name }} + + - name: Create and push multi-arch manifest (latest tag) + run: | + buildah manifest create ${{ env.IMAGE_REPO }}:latest + buildah manifest add ${{ env.IMAGE_REPO }}:latest ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-amd64 + buildah manifest add ${{ env.IMAGE_REPO }}:latest ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-arm64 + buildah manifest add ${{ env.IMAGE_REPO }}:latest ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-ppc64le + buildah manifest add ${{ env.IMAGE_REPO }}:latest ${{ env.IMAGE_REPO }}:${{ github.ref_name }}-s390x + buildah manifest push --all ${{ env.IMAGE_REPO }}:latest \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9085c173..1b371445 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -193,6 +193,8 @@ jobs: prerelease: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - + + # Skip this step if it is not a clean semver: eg if it has -beta, or any other suffix, do not run - name: Update new version in krew-index + if: ${{!contains(github.ref_name, '-') && !contains(github.ref_name, '+')}} uses: rajatjindal/krew-release-bot@v0.0.46 \ No newline at end of file diff --git a/Dockerfile.download b/Containerfile.download similarity index 58% rename from Dockerfile.download rename to Containerfile.download index 66f1c502..2e8428c9 100644 --- a/Dockerfile.download +++ b/Containerfile.download @@ -1,7 +1,10 @@ # This Dockerfile is used to cross-build the kubectl-oadp binaries for all platforms # It also builds a Go server that serves the binaries for download -FROM golang:1.24 AS builder +FROM --platform=$BUILDPLATFORM golang:1.24 AS builder + +ARG TARGETOS +ARG TARGETARCH WORKDIR /app @@ -10,16 +13,22 @@ RUN go mod download && go mod verify COPY . . -# Build everything, create tarballs, and clean up in one layer to reduce size +# Build ALL kubectl-oadp binaries using native Go cross-compilation (no QEMU emulation) +# The download server needs to serve binaries for all platforms, not just one arch RUN make release-build && \ - CGO_ENABLED=0 go build -o download-server ./cmd/downloads/server.go && \ mkdir -p /archives && \ for binary in kubectl-oadp_*; do \ archive_name=$(echo "$binary" | sed 's/\.exe$//' ).tar.gz; \ tar -czf "/archives/$archive_name" "$binary"; \ echo "Created /archives/$archive_name"; \ - done && \ - go clean -cache -modcache -testcache && \ + done + +# Build the download server for the TARGET platform (the arch this container will run on) +# This uses cross-compilation so the builder can run natively on amd64 +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o download-server ./cmd/downloads/server.go + +# Clean up to reduce layer size +RUN go clean -cache -modcache -testcache && \ rm -rf /root/.cache/go-build && \ rm -rf /go/pkg