Skip to content

Commit f719602

Browse files
committed
WIP: add build for arm64 and multiarch manifest
1 parent a66b706 commit f719602

4 files changed

Lines changed: 185 additions & 22 deletions

File tree

.github/workflows/build-push.yaml

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
name: Build (amd64 and arm64) and push to quay registries
2+
on:
3+
push:
4+
branches: ["main"]
5+
tags: ['[0-9]+.[0-9]+.[0-9]+']
6+
pull_request:
7+
branches: ["main"]
8+
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: read
13+
14+
env:
15+
REGISTRY: localhost
16+
NAME: patterns-operator
17+
TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || (github.ref_name == 'main' && 'latest' || github.ref_name) }}
18+
19+
jobs:
20+
build-container:
21+
strategy:
22+
matrix:
23+
include:
24+
- targetarch: amd64
25+
runner: ubuntu-latest
26+
- targetarch: arm64
27+
runner: ubuntu-24.04-arm
28+
29+
runs-on: ${{ matrix.runner }}
30+
permissions:
31+
contents: read
32+
steps:
33+
- name: Checkout repository
34+
uses: actions/checkout@v5
35+
with:
36+
persist-credentials: false
37+
38+
- name: Build container and save tarball
39+
env:
40+
TARGETARCH: ${{ matrix.targetarch }}
41+
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
42+
run: |
43+
make "podman-build-${TARGETARCH}"
44+
buildah push "${OPERATOR_IMG}-${TARGETARCH}" "docker-archive:/tmp/image-${TARGETARCH}.tar:${OPERATOR_IMG}-${TARGETARCH}"
45+
46+
- name: Upload image artifact
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: image-${{ matrix.targetarch }}-${{ github.run_id }}
50+
path: /tmp/image-${{ matrix.targetarch }}.tar
51+
retention-days: 1
52+
53+
pre-push-check:
54+
needs: [build-container]
55+
if: github.event_name != 'pull_request'
56+
runs-on: ubuntu-latest
57+
steps:
58+
- name: Checkout repository
59+
uses: actions/checkout@v5
60+
with:
61+
persist-credentials: false
62+
63+
# We use an env due to https://docs.zizmor.sh/audits/#remediation_18
64+
- name: Check that tag version corresponds to metadata version
65+
run: |-
66+
VERSION=$(yq -r '.spec.version' bundle/manifests/patterns-operator.clusterserviceversion.yaml)
67+
if [ "${VERSION}" != "${TAG}" ]; then
68+
echo "Version in metadata ${VERSION} whereas tag is different: ${TAG}"
69+
exit 1
70+
fi
71+
72+
push-multiarch-manifest:
73+
needs: [pre-push-check]
74+
if: github.event_name != 'pull_request'
75+
strategy:
76+
matrix:
77+
include:
78+
- upload_registry: quay.io/aeros
79+
legacy: false
80+
# - upload_registry: quay.io/validatedpatterns
81+
# legacy: false
82+
# - upload_registry: quay.io/hybridcloudpatterns
83+
# legacy: true
84+
runs-on: ubuntu-latest
85+
permissions:
86+
contents: read
87+
# This is used to complete the identity challenge
88+
# with sigstore/fulcio when running outside of PRs.
89+
id-token: write
90+
91+
steps:
92+
- name: Checkout repository
93+
uses: actions/checkout@v5
94+
with:
95+
persist-credentials: false
96+
97+
- name: Download AMD64 image
98+
uses: actions/download-artifact@v5
99+
with:
100+
name: image-amd64-${{ github.run_id }}
101+
path: /tmp
102+
103+
- name: Download ARM64 image
104+
uses: actions/download-artifact@v5
105+
with:
106+
name: image-arm64-${{ github.run_id }}
107+
path: /tmp
108+
109+
- name: Load tarballs into local containers-storage
110+
run: |
111+
buildah pull docker-archive:/tmp/image-amd64.tar
112+
buildah pull docker-archive:/tmp/image-arm64.tar
113+
114+
- name: Log into Quay
115+
env:
116+
USERNAME: ${{ matrix.legacy && secrets.LEGACY_QUAY_USERNAME || secrets.QUAY_USERNAME }}
117+
PASSWORD: ${{ matrix.legacy && secrets.LEGACY_QUAY_PASSWORD || secrets.QUAY_PASSWORD }}
118+
run: |
119+
buildah login -u "${USERNAME}" -p "${PASSWORD}" quay.io
120+
121+
# The compressed manifest in Quay has a different digest than the local so we
122+
# need to use skopeo to retrieve the correct digest for signing
123+
- name: Create manifest and push to Quay
124+
id: manifest-push
125+
env:
126+
UPLOADREGISTRY: ${{ matrix.upload_registry }}
127+
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
128+
run: |
129+
make buildah-manifest
130+
buildah manifest add --arch=amd64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-amd64"
131+
buildah manifest add --arch=arm64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-arm64"
132+
make buildah-push
133+
DIGEST=$(skopeo inspect --format "{{.Digest}}" "docker://${UPLOADREGISTRY}/${OPERATOR_IMG}")
134+
echo "digest=$DIGEST" >> "$GITHUB_OUTPUT"
135+
136+
- name: Install cosign
137+
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
138+
with:
139+
cosign-release: "v2.2.4"
140+
141+
# Cosign expects the docker config.json for registry authentication so we must
142+
# copy it from buildah
143+
- name: Sign the published Docker image
144+
env:
145+
DIGEST: ${{ steps.manifest-push.outputs.digest }}
146+
UPLOADREGISTRY: ${{ matrix.upload_registry }}
147+
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
148+
run: |
149+
cat "${XDG_RUNTIME_DIR}/containers/auth.json" > ~/.docker/config.json
150+
cosign sign --yes "${UPLOADREGISTRY}/${OPERATOR_IMG}@${DIGEST}"

Dockerfile

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest AS builder
2-
RUN microdnf install git-core jq tar -y && microdnf clean all
1+
ARG GO_VERSION=1.24.6
2+
FROM registry.access.redhat.com/ubi9/go-toolset:${GO_VERSION} AS builder
3+
ARG GOARCH=amd64
34

45
# Build the manager binary
56

@@ -9,18 +10,6 @@ WORKDIR /workspace
910
COPY go.mod go.mod
1011
COPY go.sum go.sum
1112

12-
# use latest Go z release
13-
ENV GOTOOLCHAIN=auto
14-
ENV GO_INSTALL_DIR=/golang
15-
16-
# Ensure correct Go version
17-
RUN export GO_VERSION=$(grep -E "go [[:digit:]]\.[[:digit:]][[:digit:]]" go.mod | awk '{print $2}') && \
18-
export GO_FILENAME=$(curl -sL 'https://go.dev/dl/?mode=json&include=all' | jq -r "[.[] | select(.version | startswith(\"go${GO_VERSION}\"))][0].files[] | select(.os == \"linux\" and .arch == \"amd64\") | .filename") && \
19-
curl -sL -o go.tar.gz "https://golang.org/dl/${GO_FILENAME}" && \
20-
mkdir -p ${GO_INSTALL_DIR} && \
21-
tar -C ${GO_INSTALL_DIR} -xzf go.tar.gz && \
22-
rm go.tar.gz && ln -sf ${GO_INSTALL_DIR}/go/bin/go /usr/bin/go
23-
2413
# Copy the go sources
2514
COPY vendor/ vendor/
2615
COPY cmd/main.go cmd/main.go
@@ -29,11 +18,12 @@ COPY version/ version/
2918
COPY internal/controller/ internal/controller/
3019
COPY hack/ hack/
3120
COPY .git/ .git/
32-
RUN mkdir /licenses
33-
COPY LICENSE /licenses
21+
COPY LICENSE /licenses/
22+
COPY Makefile .
3423

3524
# Build
36-
RUN --mount=type=secret,id=apikey hack/build.sh
25+
USER root
26+
RUN --mount=type=secret,id=apikey GOARCH=${GOARCH} make build
3727

3828
# Use distroless as minimal base image to package the manager binary
3929
# Refer to https://github.com/GoogleContainerTools/distroless for more details

Makefile

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ VERSION ?= 0.0.4
77
OPERATOR_NAME ?= patterns
88
GOFLAGS=-mod=vendor
99
GOLANGCI_VERSION ?= 2.5.0
10+
REGISTRY ?= localhost
11+
UPLOADREGISTRY ?= quay.io/validatedpatterns
1012

1113
# CI uses a non-writable home dir, make sure .cache is writable
1214
ifeq ("${HOME}", "/")
@@ -65,6 +67,7 @@ BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION)
6567

6668
# Image URL to use all building/pushing image targets
6769
IMG ?= $(IMAGE_TAG_BASE):$(VERSION)
70+
OPERATOR_IMG ?= $(OPERATOR_NAME)-operator:$(VERSION)
6871
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
6972
ENVTEST_K8S_VERSION = 1.30
7073

@@ -148,6 +151,31 @@ clean: ## Remove build artifacts and downloaded tools
148151
run: apikey manifests generate fmt vet ## Run a controller from your host.
149152
GOOS=${GOOS} GOARCH=${GOARCH} hack/build.sh run
150153

154+
155+
##@ Conatiner-related tasks
156+
.PHONY: buildah-manifest
157+
buildah-manifest: ## creates the buildah manifest for multi-arch images
158+
# The rm is needed due to bug https://www.github.com/containers/podman/issues/19757
159+
buildah manifest rm "${REGISTRY}/${OPERATOR_IMG}" || /bin/true
160+
buildah manifest create "${REGISTRY}/${OPERATOR_IMG}"
161+
162+
.PHONY: podman-build-amd64
163+
podman-build-amd64: buildah-manifest ## build the container in amd64
164+
@echo "Building the operator amd64"
165+
buildah build --secret id=apikey,src=$(APIKEYFILE) --platform linux/amd64 --format docker -f Dockerfile -t "${OPERATOR_IMG}-amd64"
166+
buildah manifest add --arch=amd64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-amd64"
167+
168+
.PHONY: podman-build-arm64
169+
podman-build-arm64: buildah-manifest ## build the container in arm64
170+
@echo "Building the operator arm64"
171+
buildah build --secret id=apikey,src=$(APIKEYFILE) --platform linux/arm64 --build-arg GOARCH="arm64" --format docker -f Dockerfile -t "${OPERATOR_IMG}-arm64"
172+
buildah manifest add --arch=arm64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-arm64"
173+
174+
.PHONY: buildah-push
175+
buildah-push: ## Uploads the container to quay.io/validatedpatterns/${CONTAINER}
176+
@echo "Uploading the ${REGISTRY}/${OPERATOR_IMG} container to ${UPLOADREGISTRY}/${OPERATOR_IMG}"
177+
buildah manifest push --all "${REGISTRY}/${OPERATOR_IMG}" "docker://${UPLOADREGISTRY}/${OPERATOR_IMG}"
178+
151179
.PHONY: docker-build
152180
docker-build: apikey ## Build docker image with the manager.
153181
docker build --secret id=apikey,src=$(APIKEYFILE) --platform $(CONTAINER_OS)/$(CONTAINER_PLATFORM) -t ${IMG} .

hack/build.sh

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
#!/bin/bash
22
set -ex
33

4-
# GOOS and GOARCH will be set if calling from make. Dockerfile calls this script
5-
# directly without calling make so the default values need to be set here also.
6-
[[ -z "$GOOS" ]] && GOOS=linux
7-
[[ -z "$GOARCH" ]] && GOARCH=amd64
8-
94
GIT_VERSION=$(git describe --always --tags || true)
105
VERSION=${CI_UPSTREAM_VERSION:-${GIT_VERSION}}
116
GIT_COMMIT=$(git rev-list -1 HEAD || true)

0 commit comments

Comments
 (0)