From 9eb6c6a8fa502105aa39d7a0b25ee551ccc38a05 Mon Sep 17 00:00:00 2001 From: Xi Xu Date: Mon, 23 Mar 2026 20:30:57 +0800 Subject: [PATCH] ci: publish multi-arch images --- .github/workflows/publish-images.yml | 5 ++++- Dockerfile | 13 +++++++------ scripts/publish-images.test.ts | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 scripts/publish-images.test.ts diff --git a/.github/workflows/publish-images.yml b/.github/workflows/publish-images.yml index 6c5a275..d6ac269 100644 --- a/.github/workflows/publish-images.yml +++ b/.github/workflows/publish-images.yml @@ -47,6 +47,9 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Log in uses: docker/login-action@v4 with: @@ -70,7 +73,7 @@ jobs: context: . file: Dockerfile push: true - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64 build-args: | VITE_SITE_URL=${{ vars.VITE_SITE_URL }} VITE_API_BASE_URL=/api/v1 diff --git a/Dockerfile b/Dockerfile index 11f09cf..1aaeda7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM oven/bun:alpine AS web-build +FROM --platform=$BUILDPLATFORM oven/bun:alpine AS web-build WORKDIR /workspace @@ -14,26 +14,27 @@ COPY apps/web ./apps/web RUN bun install --frozen-lockfile RUN bun run build:web -FROM golang:1.26-alpine AS api-build +FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS api-build WORKDIR /src/apps/api +ARG TARGETOS +ARG TARGETARCH + COPY apps/api/go.mod apps/api/go.sum ./ RUN go mod download COPY apps/api ./ -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /out/xdrop-api ./cmd/api +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} go build -o /out/xdrop-api ./cmd/api FROM nginx:1.29-alpine COPY infra/xdrop/nginx.conf.template /etc/nginx/templates/default.conf.template -COPY infra/xdrop/entrypoint.sh /usr/local/bin/xdrop-entrypoint +COPY --chmod=755 infra/xdrop/entrypoint.sh /usr/local/bin/xdrop-entrypoint COPY --from=web-build /workspace/apps/web/dist /usr/share/nginx/html COPY --from=api-build /out/xdrop-api /usr/local/bin/xdrop-api -RUN chmod +x /usr/local/bin/xdrop-entrypoint - EXPOSE 80 ENTRYPOINT ["/usr/local/bin/xdrop-entrypoint"] diff --git a/scripts/publish-images.test.ts b/scripts/publish-images.test.ts new file mode 100644 index 0000000..49b4dda --- /dev/null +++ b/scripts/publish-images.test.ts @@ -0,0 +1,25 @@ +import { readFileSync } from 'node:fs' +import { join } from 'node:path' + +import { describe, expect, it } from 'bun:test' + +const repoRoot = join(import.meta.dir, '..') + +describe('publish image configuration', () => { + it('publishes a multi-platform image for amd64 and arm64', () => { + const workflow = readFileSync( + join(repoRoot, '.github', 'workflows', 'publish-images.yml'), + 'utf8', + ) + + expect(workflow).toContain('platforms: linux/amd64,linux/arm64') + }) + + it('builds the API binary for the target image architecture', () => { + const dockerfile = readFileSync(join(repoRoot, 'Dockerfile'), 'utf8') + + expect(dockerfile).toContain('ARG TARGETOS') + expect(dockerfile).toContain('ARG TARGETARCH') + expect(dockerfile).toContain('GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} go build') + }) +})