feat: Build and publish vantagectl

The scratch runtime stage copies an explicit /tmp: restore extracts an
archive there before verifying it, and a scratch image has none.

shared/ now fans out to four Go images rather than three.
This commit is contained in:
2026-09-07 14:09:00 +00:00
parent 3ce963b0cd
commit e08cc2f928
3 changed files with 107 additions and 2 deletions
+11 -2
View File
@@ -71,15 +71,16 @@ jobs:
fi
}
# The three Go images build from the repo root and COPY
# The four Go images build from the repo root and COPY
# shared/ plus their own directory, so shared/ rebuilds all
# three. proto/ is in server's list as insurance: the
# four. proto/ is in server's list as insurance: the
# generated pb is committed under server/, but a proto change
# that someone regenerates in the same push should not depend
# on that ordering.
flag server '^(server/|shared/|proto/|default_steps/|go\.work)'
flag sitesvc '^(sitesvc/|shared/|go\.work)'
flag admin '^(admin/|shared/|go\.work)'
flag vantagectl '^(vantagectl/|shared/|go\.work)'
# The three Next images and the docs site use their own
# directory as the build context, so nothing outside it can
@@ -159,6 +160,14 @@ jobs:
docker build -t "$IMAGE" -f admin/Dockerfile .
docker push "$IMAGE"
- name: Build and push vantagectl image
if: steps.changed.outputs.vantagectl == 'true'
run: |
IMAGE="${{ vars.DOCKER_HOST }}/${{ github.repository_owner }}/vantage/vantagectl:latest"
# Root context: vantagectl depends on the shared module.
docker build -t "$IMAGE" -f vantagectl/Dockerfile .
docker push "$IMAGE"
- name: Build and push adminsite image
if: steps.changed.outputs.adminsite == 'true'
run: |
+60
View File
@@ -0,0 +1,60 @@
name: vantagectl Release
on:
push:
tags:
- "vantagectl/v*"
jobs:
build:
runs-on: ubuntu-docker
container: node:26
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: true
cache-dependency-path: vantagectl/go.sum
- name: Extract version
id: version
run: echo "VERSION=${GITHUB_REF_NAME#vantagectl/}" >> $GITHUB_OUTPUT
- name: Test
working-directory: vantagectl
run: go test ./...
- name: Build
working-directory: vantagectl
env:
VERSION: ${{ steps.version.outputs.VERSION }}
run: |
mkdir -p dist
for target in linux/amd64 linux/arm64 darwin/arm64 windows/amd64; do
goos="${target%/*}"
goarch="${target#*/}"
out="dist/vantagectl-${goos}-${goarch}"
if [ "$goos" = "windows" ]; then out="${out}.exe"; fi
CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" go build \
-ldflags="-s -w -X main.Version=${VERSION}" \
-o "$out" .
done
- name: Checksums
working-directory: vantagectl/dist
run: sha256sum vantagectl-* > checksums.txt
- name: Create release
uses: https://gitea.com/actions/gitea-release-action@v1
with:
token: ${{ secrets.RELEASE_TOKEN }}
files: |
vantagectl/dist/vantagectl-linux-amd64
vantagectl/dist/vantagectl-linux-arm64
vantagectl/dist/vantagectl-darwin-arm64
vantagectl/dist/vantagectl-windows-amd64.exe
vantagectl/dist/checksums.txt
+36
View File
@@ -0,0 +1,36 @@
# Build stage
#
# Context is the repository root, not vantagectl/, because vantagectl depends on
# the shared module through a replace directive.
FROM golang:1.26 AS builder
WORKDIR /src
# Manifests first so the dependency layer caches independently of source edits.
COPY shared/go.mod shared/go.sum ./shared/
COPY vantagectl/go.mod vantagectl/go.sum ./vantagectl/
RUN cd vantagectl && go mod download
COPY shared/ ./shared/
COPY vantagectl/ ./vantagectl/
ARG VERSION=dev
RUN cd vantagectl && CGO_ENABLED=0 GOOS=linux go build \
-ldflags="-s -w -X main.Version=${VERSION}" -o /vantagectl .
# Staged so the scratch image below can have a /tmp. It cannot mkdir one
# itself — scratch has no shell.
RUN mkdir -p /staging/tmp && chmod 1777 /staging/tmp
# Runtime stage
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# restore extracts an archive here before verifying its checksums, and backup
# stages nothing but still inherits os.MkdirTemp's requirements. Without this
# every restore stops at "temp dir: stat /tmp: no such file or directory".
COPY --from=builder /staging/tmp /tmp
COPY --from=builder /vantagectl /vantagectl
ENTRYPOINT ["/vantagectl"]