Compare commits

...
2 Commits
Author SHA1 Message Date
aneurinandClaude Sonnet 5 321e4dc9ec build a multi-arch (amd64 + arm64) image
PR Checks / checks (pull_request) Successful in 2m17s
Zampler is pure Go with CGO disabled (modernc.org/sqlite), so both
architectures cross-compile from the amd64 runner at native speed with
no emulation. The runtime Dockerfile has no RUN steps, so buildx can
assemble the arm64 image on the amd64 host without QEMU too.

- Cross-compile dist/zampler-linux-{amd64,arm64} in one job.
- Dockerfile copies dist/zampler-linux-${TARGETARCH}; buildx sets
  TARGETARCH per platform leg.
- Replace `docker build`/`push` with a single `docker buildx build
  --platform linux/amd64,linux/arm64 --push`, producing a manifest list
  at :latest.
- Promote :latest to :previous with `buildx imagetools create`, which
  copies the manifest list registry-side instead of pulling a single
  arch and re-pushing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 01:40:12 +01:00
aneurinandClaude Sonnet 5 2c288ca1e2 add PR checks workflow
PR Checks / checks (pull_request) Successful in 2m14s
Build / build-and-push (push) Successful in 1m26s
Runs on pull requests to main: frontend type-check and build, then
gofmt, go mod tidy verification, go vet, go build, and go test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 20:27:22 +01:00
5 changed files with 106 additions and 18 deletions
+3 -2
View File
@@ -1,3 +1,4 @@
# Build context only needs the prebuilt ./zampler binary and the Dockerfile.
# Build context only needs the prebuilt per-arch binaries and the Dockerfile.
*
!zampler
!dist/zampler-linux-amd64
!dist/zampler-linux-arm64
+23 -11
View File
@@ -12,9 +12,10 @@ jobs:
image: golang:1.26-alpine
env:
CGO_ENABLED: "0"
IMAGE: code.aneur.in/${{ gitea.repository }}
steps:
- name: Install toolchain deps
run: apk add --no-cache nodejs npm docker-cli git tar
run: apk add --no-cache nodejs npm docker-cli docker-cli-buildx git tar
- uses: actions/checkout@v4
@@ -42,8 +43,17 @@ jobs:
npm ci
npx vite build --outDir ../internal/server/static --emptyOutDir
- name: Build binary
run: go build -ldflags="-s -w" -o zampler .
- name: Cross-compile binaries
run: |
for arch in amd64 arm64; do
GOOS=linux GOARCH="$arch" \
go build -ldflags="-s -w" -o "dist/zampler-linux-$arch" .
done
- name: Set up Docker buildx
run: |
docker buildx rm multi 2>/dev/null || true
docker buildx create --name multi --driver docker-container --use
- name: Log in to the container registry
env:
@@ -52,14 +62,16 @@ jobs:
- name: Promote current "latest" to "previous"
run: |
IMAGE="code.aneur.in/${{ gitea.repository }}"
if docker pull "$IMAGE:latest"; then
docker tag "$IMAGE:latest" "$IMAGE:previous"
docker push "$IMAGE:previous"
if docker buildx imagetools inspect "$IMAGE:latest" >/dev/null 2>&1; then
docker buildx imagetools create -t "$IMAGE:previous" "$IMAGE:latest"
else
echo "No existing :latest to promote; skipping."
fi
- name: Build and push "latest"
- name: Build and push multi-arch "latest"
run: |
IMAGE="code.aneur.in/${{ gitea.repository }}:latest"
docker build -t "$IMAGE" .
docker push "$IMAGE"
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag "$IMAGE:latest" \
--push \
.
+70
View File
@@ -0,0 +1,70 @@
name: PR Checks
on:
pull_request:
branches: [main]
workflow_dispatch:
jobs:
checks:
runs-on: ubuntu-latest
container:
image: golang:1.26-alpine
env:
CGO_ENABLED: "0"
steps:
- name: Install toolchain deps
run: apk add --no-cache nodejs npm git tar
- uses: actions/checkout@v4
- name: Cache npm downloads
uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: npm-
- name: Cache Go modules and build cache
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: go-${{ hashFiles('go.sum') }}-${{ hashFiles('**/*.go') }}
restore-keys: |
go-${{ hashFiles('go.sum') }}-
go-
- name: Install frontend dependencies
working-directory: frontend
run: npm ci
- name: Type-check and build frontend
working-directory: frontend
run: |
npx vue-tsc -b
npx vite build --outDir ../internal/server/static --emptyOutDir
- name: Check Go formatting
run: |
unformatted="$(gofmt -l .)"
if [ -n "$unformatted" ]; then
echo "These files are not gofmt-formatted:"
echo "$unformatted"
exit 1
fi
- name: Verify go.mod is tidy
run: |
go mod tidy
git diff --exit-code go.mod go.sum
- name: Vet
run: go vet ./...
- name: Build
run: go build ./...
- name: Test
run: go test ./...
+1
View File
@@ -4,3 +4,4 @@
zampler.files
zampler.sqlite3
internal/server/static
dist
+9 -5
View File
@@ -1,12 +1,16 @@
# The zampler binary is built in CI (.gitea/workflows/build.yml) so the compile
# can use a persistent Go module + build cache. This image is just the runtime
# wrapper around the prebuilt static binary.
# The zampler binaries are cross-compiled in CI (.gitea/workflows/build.yml) so
# the compile can use a persistent Go module + build cache and avoid emulation.
# This image is just the runtime wrapper around the prebuilt static binary;
# buildx sets TARGETARCH per platform and we copy the matching binary.
#
# For a local build: `go build -o zampler .` first, then `docker build .`.
# For a local build:
# GOOS=linux GOARCH=amd64 go build -o dist/zampler-linux-amd64 .
# docker build --build-arg TARGETARCH=amd64 .
FROM alpine:3.24
COPY zampler /usr/local/bin/zampler
ARG TARGETARCH
COPY dist/zampler-linux-${TARGETARCH} /usr/local/bin/zampler
ENTRYPOINT ["zampler"]
CMD ["-s", "/db/zampler.sqlite3", "/data"]