Skip to content

Commit 5d5d64b

Browse files
committed
ci: setup ARM64 builds with CGO_ENABLED=1 compatibility
Signed-off-by: Doug Edgar <dedgar@redhat.com>
1 parent 47bf4e8 commit 5d5d64b

File tree

5 files changed

+189
-25
lines changed

5 files changed

+189
-25
lines changed

.github/workflows/build-image.yml

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,23 @@ permissions:
88
actions: write
99
contents: read
1010

11+
env:
12+
IMG: quay.io/llamastack/llama-stack-k8s-operator:latest
13+
1114
jobs:
12-
build-latest-image:
15+
build-arch:
1316
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main'
14-
runs-on: ubuntu-24.04
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
include:
21+
- arch: amd64
22+
runner: ubuntu-24.04
23+
platform: linux/amd64
24+
- arch: arm64
25+
runner: ubuntu-24.04-arm
26+
platform: linux/arm64
27+
runs-on: ${{ matrix.runner }}
1528
steps:
1629
- name: Checkout code
1730
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -31,5 +44,30 @@ jobs:
3144
username: ${{ secrets.APP_QUAY_USERNAME }}
3245
password: ${{ secrets.APP_QUAY_TOKEN }}
3346

34-
- name: Build and push multi-arch image
35-
run: make image-buildx -e IMG=quay.io/llamastack/llama-stack-k8s-operator:latest
47+
- name: Build and push single-arch image
48+
run: |
49+
make image-build-push-single \
50+
CONTAINER_TOOL=docker \
51+
PLATFORM=${{ matrix.platform }} \
52+
IMG=${{ env.IMG }}-${{ matrix.arch }}
53+
54+
create-manifest:
55+
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main'
56+
needs: build-arch
57+
runs-on: ubuntu-24.04
58+
steps:
59+
- name: Set up Docker Buildx
60+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
61+
62+
- name: Login to Quay.io
63+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
64+
with:
65+
registry: quay.io
66+
username: ${{ secrets.APP_QUAY_USERNAME }}
67+
password: ${{ secrets.APP_QUAY_TOKEN }}
68+
69+
- name: Create and push multi-arch manifest
70+
run: |
71+
docker buildx imagetools create -t ${{ env.IMG }} \
72+
${{ env.IMG }}-amd64 \
73+
${{ env.IMG }}-arm64

.github/workflows/generate-release.yml

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,6 @@ jobs:
165165
run: |
166166
make test
167167
168-
- name: Set up Docker Buildx
169-
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
170-
171168
- name: Check E2E Test Results
172169
run: |
173170
echo "E2E Test Results:"
@@ -183,10 +180,10 @@ jobs:
183180
echo "E2E tests passed - proceeding with release"
184181
fi
185182
186-
- name: Validate build release image
183+
- name: Validate release image build
187184
shell: bash
188185
run: |
189-
make image-buildx-build IMG=quay.io/llamastack/llama-stack-k8s-operator:v${{ steps.validate.outputs.operator_version }}
186+
make image-build IMG=quay.io/llamastack/llama-stack-k8s-operator:v${{ steps.validate.outputs.operator_version }}
190187
191188
- name: Commit and push changes
192189
shell: bash
@@ -203,13 +200,58 @@ jobs:
203200
echo "✅ Committed release changes to ${{ steps.validate.outputs.release_branch }}"
204201
fi
205202
206-
finalize-release:
203+
build-release-arch:
207204
needs: generate-release
205+
strategy:
206+
fail-fast: false
207+
matrix:
208+
include:
209+
- arch: amd64
210+
runner: ubuntu-24.04
211+
platform: linux/amd64
212+
- arch: arm64
213+
runner: ubuntu-24.04-arm
214+
platform: linux/arm64
215+
runs-on: ${{ matrix.runner }}
216+
env:
217+
operator_version: ${{ needs.generate-release.outputs.operator_version }}
218+
release_branch: ${{ needs.generate-release.outputs.release_branch }}
219+
steps:
220+
- name: Checkout code
221+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
222+
with:
223+
ref: ${{ env.release_branch }}
224+
225+
- name: Set up Go
226+
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
227+
with:
228+
go-version-file: go.mod
229+
230+
- name: Set up Docker Buildx
231+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
232+
233+
- name: Log in to Quay.io
234+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
235+
with:
236+
registry: quay.io
237+
username: ${{ secrets.APP_QUAY_USERNAME }}
238+
password: ${{ secrets.APP_QUAY_TOKEN }}
239+
240+
- name: Build and push single-arch release image
241+
run: |
242+
make image-build-push-single \
243+
CONTAINER_TOOL=docker \
244+
PLATFORM=${{ matrix.platform }} \
245+
IMG=quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }}-${{ matrix.arch }}
246+
247+
finalize-release:
248+
needs: [generate-release, build-release-arch]
208249
runs-on: ubuntu-24.04
209250
env:
210251
operator_version: ${{ needs.generate-release.outputs.operator_version }}
211252
llamastack_version: ${{ needs.generate-release.outputs.llamastack_version }}
212253
release_branch: ${{ needs.generate-release.outputs.release_branch }}
254+
IMG: quay.io/llamastack/llama-stack-k8s-operator
213255
steps:
214256
- name: Checkout code
215257
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
@@ -268,11 +310,6 @@ jobs:
268310
env:
269311
GH_TOKEN: ${{ github.token }}
270312

271-
- name: Set up Go
272-
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
273-
with:
274-
go-version-file: go.mod
275-
276313
- name: Set up Docker Buildx
277314
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
278315

@@ -283,17 +320,20 @@ jobs:
283320
username: ${{ secrets.APP_QUAY_USERNAME }}
284321
password: ${{ secrets.APP_QUAY_TOKEN }}
285322

286-
- name: Build and push multi-arch release image
323+
- name: Create and push multi-arch manifest
287324
shell: bash
288325
run: |
289-
make image-buildx IMG=quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }}
290-
echo "✅ Pushed multi-arch image: quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }}"
326+
docker buildx imagetools create \
327+
-t ${{ env.IMG }}:v${{ env.operator_version }} \
328+
${{ env.IMG }}:v${{ env.operator_version }}-amd64 \
329+
${{ env.IMG }}:v${{ env.operator_version }}-arm64
330+
echo "✅ Pushed multi-arch image: ${{ env.IMG }}:v${{ env.operator_version }}"
291331
292332
- name: Release complete
293333
shell: bash
294334
run: |
295335
echo "🚀 Release v${{ env.operator_version }} completed successfully!"
296-
echo "📦 Container image: quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }}"
336+
echo "📦 Container image: ${{ env.IMG }}:v${{ env.operator_version }}"
297337
echo "📝 Release notes: https://github.com/${{ github.repository }}/releases/tag/v${{ env.operator_version }}"
298338
echo "🔧 Install with: kubectl apply -f https://raw.githubusercontent.com/llamastack/llama-stack-k8s-operator/v${{ env.operator_version }}/release/operator.yaml"
299339
echo "🌿 Release branch: ${{ env.release_branch }}"

.github/workflows/release-image.yml

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,22 @@ permissions:
1616
actions: write
1717
contents: read
1818

19+
env:
20+
IMG: quay.io/llamastack/llama-stack-k8s-operator:${{ github.event.inputs.version }}
21+
1922
jobs:
20-
build-release-image:
21-
runs-on: ubuntu-24.04
23+
build-arch:
24+
strategy:
25+
fail-fast: false
26+
matrix:
27+
include:
28+
- arch: amd64
29+
runner: ubuntu-24.04
30+
platform: linux/amd64
31+
- arch: arm64
32+
runner: ubuntu-24.04-arm
33+
platform: linux/arm64
34+
runs-on: ${{ matrix.runner }}
2235
steps:
2336
- name: Set up Go
2437
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
@@ -40,6 +53,29 @@ jobs:
4053
username: ${{ secrets.APP_QUAY_USERNAME }}
4154
password: ${{ secrets.APP_QUAY_TOKEN }}
4255

43-
- name: Build and push multi-arch release image
56+
- name: Build and push single-arch release image
57+
run: |
58+
make image-build-push-single \
59+
CONTAINER_TOOL=docker \
60+
PLATFORM=${{ matrix.platform }} \
61+
IMG=${{ env.IMG }}-${{ matrix.arch }}
62+
63+
create-manifest:
64+
needs: build-arch
65+
runs-on: ubuntu-24.04
66+
steps:
67+
- name: Set up Docker Buildx
68+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
69+
70+
- name: Login to Quay.io
71+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
72+
with:
73+
registry: quay.io
74+
username: ${{ secrets.APP_QUAY_USERNAME }}
75+
password: ${{ secrets.APP_QUAY_TOKEN }}
76+
77+
- name: Create and push multi-arch manifest
4478
run: |
45-
make image-buildx -e IMG=quay.io/llamastack/llama-stack-k8s-operator:${{ github.event.inputs.version }}
79+
docker buildx imagetools create -t ${{ env.IMG }} \
80+
${{ env.IMG }}-amd64 \
81+
${{ env.IMG }}-arm64

Makefile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,42 @@ else
227227
endif
228228
@echo "Successfully built multi-arch image: ${IMG}"
229229

230+
# PLATFORM defines the target platform for single-arch image builds used by CI matrix jobs.
231+
# Each architecture is built natively on its own runner (e.g., ARM64 on ARM64 runner),
232+
# ensuring CGO_ENABLED=1 with full OpenSSL FIPS support for all architectures.
233+
PLATFORM ?= linux/amd64
234+
235+
.PHONY: image-build-push-single
236+
image-build-push-single: ## Build and push a single-arch image (set PLATFORM and IMG)
237+
@echo "Building and pushing single-arch image for platform: $(PLATFORM)"
238+
ifeq ($(CONTAINER_TOOL),docker)
239+
- $(CONTAINER_TOOL) buildx create --name x-builder 2>/dev/null || true
240+
$(CONTAINER_TOOL) buildx use x-builder
241+
$(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORM) --tag ${IMG} .
242+
else
243+
$(CONTAINER_TOOL) build --platform $(PLATFORM) -t ${IMG} .
244+
$(CONTAINER_TOOL) push ${IMG}
245+
endif
246+
@echo "Successfully pushed single-arch image: ${IMG} ($(PLATFORM))"
247+
248+
# ARCH_IMGS is a space-separated list of per-architecture image references
249+
# used to create a multi-arch manifest (e.g., "myregistry/myimage:v1-amd64 myregistry/myimage:v1-arm64").
250+
ARCH_IMGS ?=
251+
252+
.PHONY: image-create-manifest
253+
image-create-manifest: ## Create and push a multi-arch manifest from per-arch images (set IMG and ARCH_IMGS)
254+
@echo "Creating multi-arch manifest: ${IMG}"
255+
ifeq ($(CONTAINER_TOOL),docker)
256+
- $(CONTAINER_TOOL) buildx create --name x-builder 2>/dev/null || true
257+
$(CONTAINER_TOOL) buildx use x-builder
258+
$(CONTAINER_TOOL) buildx imagetools create -t ${IMG} $(ARCH_IMGS)
259+
else
260+
$(CONTAINER_TOOL) manifest rm ${IMG} 2>/dev/null || true
261+
$(CONTAINER_TOOL) manifest create ${IMG} $(ARCH_IMGS)
262+
$(CONTAINER_TOOL) manifest push ${IMG}
263+
endif
264+
@echo "Successfully pushed multi-arch manifest: ${IMG}"
265+
230266
.PHONY: image-build-arm
231267
image-build-arm: ## Build ARM64 image with the manager
232268
$(CONTAINER_TOOL) build --platform linux/arm64 -t ${IMG} .

README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,9 @@ This will cause all LlamaStackDistribution resources using the `starter` distrib
238238

239239
**Note**:
240240
- The `image-buildx` target works with both Docker and Podman. It will automatically detect which tool is being used.
241-
- **Native cross-compilation**: The Dockerfile uses `--platform=$BUILDPLATFORM` to run Go compilation natively on the build host, avoiding QEMU emulation for the build process. This dramatically improves build speed and reliability. Only the minimal final stage (package installation) runs under QEMU for cross-platform builds.
242-
- **FIPS adherence**: Native builds use `CGO_ENABLED=1` with full OpenSSL FIPS support. Cross-compiled builds use `CGO_ENABLED=0` with pure Go FIPS (via `GOEXPERIMENT=strictfipsruntime`). Both approaches are Designed for FIPS.
241+
- **Native builds in CI**: CI workflows use a matrix strategy with native runners for each architecture (AMD64 and ARM64). Each architecture is built on its own runner, avoiding QEMU emulation entirely. Per-architecture images are pushed separately, then combined into a single multi-arch manifest list. This ensures `CGO_ENABLED=1` with full OpenSSL FIPS support for all architectures.
242+
- **Local cross-compilation**: For local development, the Dockerfile uses `--platform=$BUILDPLATFORM` to run Go compilation natively on the build host. When cross-compiling (e.g., building ARM64 on an AMD64 host), `CGO_ENABLED=0` is used with pure Go FIPS (via `GOEXPERIMENT=strictfipsruntime`). Native local builds use `CGO_ENABLED=1` with full OpenSSL FIPS support.
243+
- **FIPS adherence**: All CI-produced images use `CGO_ENABLED=1` with full OpenSSL FIPS support via native builds on architecture-matched runners.
243244
- For Docker: Multi-arch builds require Docker Buildx. Ensure Docker Buildx is set up:
244245

245246
```commandline
@@ -249,6 +250,19 @@ This will cause all LlamaStackDistribution resources using the `starter` distrib
249250
- For Podman: Podman 4.0+ supports `podman buildx` (experimental). If buildx is unavailable, the Makefile will automatically fall back to using podman's native manifest-based multi-arch build approach.
250251
- The resulting images are multi-arch manifest lists, which means Kubernetes will automatically select the correct architecture when pulling the image.
251252

253+
**CI Build Targets**:
254+
255+
The CI workflows use the following Makefile targets for the matrix-based build strategy:
256+
257+
```commandline
258+
# Build and push a single-arch image (used by each matrix job on its native runner)
259+
make image-build-push-single PLATFORM=linux/amd64 IMG=quay.io/<username>/llama-stack-k8s-operator:<tag>-amd64
260+
261+
# Create a multi-arch manifest from per-arch images (used by the final manifest job)
262+
make image-create-manifest IMG=quay.io/<username>/llama-stack-k8s-operator:<tag> \
263+
ARCH_IMGS="quay.io/<username>/llama-stack-k8s-operator:<tag>-amd64 quay.io/<username>/llama-stack-k8s-operator:<tag>-arm64"
264+
```
265+
252266
- Building ARM64-only images
253267

254268
To build a single ARM64 image (useful for testing or ARM-native systems):

0 commit comments

Comments
 (0)