Skip to content

Commit 3f27c10

Browse files
nissessenapclaude
andcommitted
Add minimial image build for the hub
Add ko configuration and a GitHub Actions workflow to build, publish, and sign a multi-arch (amd64/arm64) hub container image on every tag push. The image uses a distroless base (cgr.dev/chainguard/static) and embeds the web frontend assets. The image is published as `ghcr.io/<owner>/scion:<tag>` and tagged with both the version tag and `latest`. Closes #133 (container image portion) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Edvin Norling <edvin.norling@kognic.com>
1 parent b16d6d8 commit 3f27c10

3 files changed

Lines changed: 155 additions & 1 deletion

File tree

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: Build Hub Container Image
16+
17+
on:
18+
push:
19+
tags:
20+
- "*"
21+
22+
jobs:
23+
build:
24+
name: Build and Push Hub Image
25+
runs-on: ubuntu-latest
26+
permissions:
27+
contents: read
28+
packages: write
29+
id-token: write
30+
outputs:
31+
digest: ${{ steps.build-image.outputs.digest }}
32+
steps:
33+
- name: Checkout code
34+
uses: actions/checkout@v6
35+
with:
36+
fetch-depth: 0
37+
persist-credentials: false
38+
39+
- name: Set up Go
40+
uses: actions/setup-go@v6
41+
with:
42+
go-version-file: "go.mod"
43+
cache: true
44+
45+
- name: Setup Node
46+
uses: actions/setup-node@v6
47+
with:
48+
node-version: "24"
49+
cache: "npm"
50+
cache-dependency-path: "web/package-lock.json"
51+
52+
- name: Build Web UI
53+
working-directory: ./web
54+
run: |
55+
npm ci
56+
npm run build
57+
58+
- name: Setup ko
59+
uses: ko-build/setup-ko@v0.9
60+
61+
- name: Log in to GHCR
62+
uses: docker/login-action@v4
63+
with:
64+
registry: ghcr.io
65+
username: ${{ github.actor }}
66+
password: ${{ secrets.GITHUB_TOKEN }}
67+
68+
- name: Set version metadata
69+
id: meta
70+
run: |
71+
VERSION="${GITHUB_REF_NAME}"
72+
COMMIT="${GITHUB_SHA}"
73+
BUILD_TIME="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
74+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
75+
echo "commit=${COMMIT}" >> "$GITHUB_OUTPUT"
76+
echo "build_time=${BUILD_TIME}" >> "$GITHUB_OUTPUT"
77+
78+
- name: Build and push image
79+
id: build-image
80+
env:
81+
KO_DOCKER_REPO: ghcr.io/${{ github.repository }}
82+
VERSION: ${{ steps.meta.outputs.version }}
83+
COMMIT: ${{ steps.meta.outputs.commit }}
84+
BUILD_TIME: ${{ steps.meta.outputs.build_time }}
85+
run: |
86+
ko build ./cmd/scion \
87+
--platform=linux/amd64,linux/arm64 \
88+
--tags="${VERSION},latest" \
89+
--bare \
90+
--image-refs=./image-digest \
91+
--image-label org.opencontainers.image.title=scion \
92+
--image-label org.opencontainers.image.description="Scion AI agent orchestration platform" \
93+
--image-label org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }} \
94+
--image-label org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} \
95+
--image-label org.opencontainers.image.revision=${{ github.sha }} \
96+
--image-label org.opencontainers.image.version=${VERSION} \
97+
--image-label org.opencontainers.image.created="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
98+
99+
# Extract manifest index digest for signing (first line is the index)
100+
MANIFEST_DIGEST=$(head -1 ./image-digest | cut -d@ -f2)
101+
echo "digest=${MANIFEST_DIGEST}" >> "$GITHUB_OUTPUT"
102+
echo "Manifest index digest: ${MANIFEST_DIGEST}"
103+
104+
sign:
105+
name: Sign Container Image
106+
needs: build
107+
runs-on: ubuntu-latest
108+
permissions:
109+
contents: read
110+
packages: write
111+
id-token: write
112+
steps:
113+
- name: Install cosign
114+
uses: sigstore/cosign-installer@v3
115+
116+
- name: Log in to GHCR
117+
uses: docker/login-action@v4
118+
with:
119+
registry: ghcr.io
120+
username: ${{ github.actor }}
121+
password: ${{ secrets.GITHUB_TOKEN }}
122+
123+
- name: Sign manifest index
124+
env:
125+
DIGEST: ${{ needs.build.outputs.digest }}
126+
REPO: ghcr.io/${{ github.repository }}
127+
run: |
128+
echo "Signing manifest index: ${REPO}@${DIGEST}"
129+
cosign sign --yes "${REPO}@${DIGEST}"
130+
echo "To verify: cosign verify --certificate-oidc-issuer https://token.actions.githubusercontent.com --certificate-identity-regexp 'github.com/${{ github.repository }}' ${REPO}@${DIGEST}"

.ko.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
builds:
2+
- id: scion
3+
main: ./cmd/scion
4+
flags:
5+
- -trimpath
6+
ldflags:
7+
- -s -w
8+
- -X
9+
github.com/GoogleCloudPlatform/scion/pkg/version.Version={{.Env.VERSION}}
10+
- -X
11+
github.com/GoogleCloudPlatform/scion/pkg/version.Commit={{.Env.COMMIT}}
12+
- -X
13+
github.com/GoogleCloudPlatform/scion/pkg/version.BuildTime={{.Env.BUILD_TIME}}
14+
env:
15+
- CGO_ENABLED=0

Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ GOLANGCI_LINT := $(shell command -v golangci-lint 2>/dev/null || echo $(shell go
1414

1515
.DEFAULT_GOAL := help
1616

17-
.PHONY: all build install test test-fast vet lint golangci-lint web web-typecheck fmt fmt-check ci ci-full clean help container-sciontool container-scion container-binaries
17+
.PHONY: all build install test test-fast vet lint golangci-lint web web-typecheck fmt fmt-check ci ci-full clean help container-sciontool container-scion container-binaries ko-build-local
1818

1919
## all: Build the web frontend, then compile the Go binary with embedded assets
2020
all: web install
@@ -91,6 +91,15 @@ container-binaries: container-sciontool container-scion
9191
@echo "Dev binaries ready in $(CONTAINER_DIR)/"
9292
@echo "Usage: export SCION_DEV_BINARIES=$(CONTAINER_DIR)"
9393

94+
## ko-build-local: Build the hub container image locally with ko (loads into local Docker)
95+
ko-build-local: web
96+
@echo "Building hub container image with ko..."
97+
@VERSION=$$(git describe --tags --exact-match 2>/dev/null || echo "dev") \
98+
COMMIT=$$(git rev-parse HEAD 2>/dev/null || echo "unknown") \
99+
BUILD_TIME=$$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
100+
KO_DOCKER_REPO=ko.local \
101+
ko build ./cmd/scion --bare --local
102+
94103
## web-typecheck: Run TypeScript type checking on the web frontend
95104
web-typecheck:
96105
@echo "Type-checking web frontend..."

0 commit comments

Comments
 (0)