Skip to content

Commit c9a7706

Browse files
committed
ci+dev: ghcr.io image publishing + devcontainer Go 1.26
- .goreleaser.yaml: dockers + docker_manifests for multi-arch images at ghcr.io/css521/agentenv:<tag> and :latest (linux/amd64 + linux/arm64) - Dockerfile: distroless static image, COPYs the goreleaser-built binary - .github/workflows/release.yml: QEMU + Buildx + ghcr.io login step; packages:write permission for the workflow - .devcontainer/devcontainer.json: bump to mcr ...go:2.1-1.26 (the 1-1.x line tops out at Go 1.24 which can't compile our go 1.26 directive); prefix postCreate with sudo (lifecycle commands run as remoteUser) - README: mention ghcr.io image alongside binaries
1 parent 47554c1 commit c9a7706

5 files changed

Lines changed: 78 additions & 3 deletions

File tree

.devcontainer/devcontainer.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
// libbtrfs-dev pre-installed, seccomp relaxed so agentenv's user-namespace
55
// runner works, and the project source mounted as the workspace.
66
"name": "agentenv-dev",
7-
"image": "mcr.microsoft.com/devcontainers/go:1-1.23",
7+
// Image-version 2.x is where MS publishes Go 1.25+ (the older 1-1.xx
8+
// line tops out at Go 1.24, which fails our go.mod's `go 1.26` directive).
9+
"image": "mcr.microsoft.com/devcontainers/go:2.1-1.26",
810

911
// The agentenv runner clones into a fresh user namespace; the dev container's
1012
// default seccomp profile blocks that. Unconfining it inside the dev container
@@ -20,7 +22,9 @@
2022

2123
// libbtrfs-dev lets you build with `-tags btrfs` (the optional fast-path
2224
// backend that needs cgo); the default static build needs nothing.
23-
"postCreateCommand": "apt-get update && apt-get install -y -qq libbtrfs-dev make",
25+
// sudo: devcontainer lifecycle commands run as remoteUser (vscode), not root.
26+
// The common-utils feature gives vscode passwordless sudo.
27+
"postCreateCommand": "sudo apt-get update && sudo apt-get install -y -qq libbtrfs-dev make",
2428
// Show the Makefile target list every time the container is attached, so a new
2529
// contributor immediately sees what they can do (build / test / verify / demo).
2630
"postAttachCommand": "make help",

.github/workflows/release.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ name: Release
33
# Fires when a tag like v0.1.0 / v1.2.3 is pushed. Cross-compiles linux/amd64
44
# + linux/arm64 via goreleaser, attaches them to a DRAFT GitHub release
55
# (because `.goreleaser.yaml` sets `release.draft: true`) — review and
6-
# Publish in the GitHub UI when ready.
6+
# Publish in the GitHub UI when ready. Also builds + pushes multi-arch
7+
# container images to ghcr.io/css521/agentenv:<tag> + :latest.
78

89
on:
910
push:
@@ -12,6 +13,7 @@ on:
1213

1314
permissions:
1415
contents: write # goreleaser creates the GitHub release + uploads artifacts
16+
packages: write # docker push → ghcr.io under this org
1517

1618
jobs:
1719
goreleaser:
@@ -25,6 +27,18 @@ jobs:
2527
with:
2628
go-version: '1.26'
2729

30+
# QEMU lets the runner build linux/arm64 images from a linux/amd64 host.
31+
- uses: docker/setup-qemu-action@v3
32+
- uses: docker/setup-buildx-action@v3
33+
34+
# GITHUB_TOKEN is automatically scoped for ghcr.io publishes when the
35+
# workflow has packages:write; no separate PAT needed.
36+
- uses: docker/login-action@v3
37+
with:
38+
registry: ghcr.io
39+
username: ${{ github.actor }}
40+
password: ${{ secrets.GITHUB_TOKEN }}
41+
2842
- uses: goreleaser/goreleaser-action@v6
2943
with:
3044
version: latest

.goreleaser.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,45 @@ checksum:
3737
changelog:
3838
use: github
3939

40+
# Multi-arch container images pushed to ghcr.io. Two per-arch images are built
41+
# (each with a binary matching its target platform), then a single manifest
42+
# list points at both — so `docker pull ghcr.io/css521/agentenv:vX.Y.Z`
43+
# transparently picks amd64 or arm64.
44+
dockers:
45+
- image_templates:
46+
- "ghcr.io/css521/agentenv:{{ .Version }}-amd64"
47+
use: buildx
48+
dockerfile: Dockerfile
49+
goos: linux
50+
goarch: amd64
51+
build_flag_templates:
52+
- "--platform=linux/amd64"
53+
- "--label=org.opencontainers.image.source=https://github.com/css521/agentenv"
54+
- "--label=org.opencontainers.image.version={{ .Version }}"
55+
- "--label=org.opencontainers.image.revision={{ .FullCommit }}"
56+
- "--label=org.opencontainers.image.licenses=MIT"
57+
- image_templates:
58+
- "ghcr.io/css521/agentenv:{{ .Version }}-arm64"
59+
use: buildx
60+
dockerfile: Dockerfile
61+
goos: linux
62+
goarch: arm64
63+
build_flag_templates:
64+
- "--platform=linux/arm64"
65+
- "--label=org.opencontainers.image.source=https://github.com/css521/agentenv"
66+
- "--label=org.opencontainers.image.version={{ .Version }}"
67+
- "--label=org.opencontainers.image.revision={{ .FullCommit }}"
68+
- "--label=org.opencontainers.image.licenses=MIT"
69+
70+
docker_manifests:
71+
- name_template: "ghcr.io/css521/agentenv:{{ .Version }}"
72+
image_templates:
73+
- "ghcr.io/css521/agentenv:{{ .Version }}-amd64"
74+
- "ghcr.io/css521/agentenv:{{ .Version }}-arm64"
75+
- name_template: "ghcr.io/css521/agentenv:latest"
76+
image_templates:
77+
- "ghcr.io/css521/agentenv:{{ .Version }}-amd64"
78+
- "ghcr.io/css521/agentenv:{{ .Version }}-arm64"
79+
4080
release:
4181
draft: true

Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Minimal release image for `agentenv` — distroless static base, no shell, no
2+
# package manager, just the binary. Built and pushed to ghcr.io by goreleaser
3+
# (see `dockers:` in .goreleaser.yaml).
4+
#
5+
# The build context is goreleaser's per-arch dist/ subdirectory, which already
6+
# contains the pre-compiled `agentenv` binary — so this Dockerfile is just a
7+
# COPY + ENTRYPOINT. No `go build` happens here.
8+
#
9+
# Note: agentenv calls `bash -lc` inside the *managed rootfs* (work/current),
10+
# never inside this image. So a distroless host image is fine; bash is only
11+
# required in whatever rootfs you `init --from` or `init --tarball` later.
12+
FROM gcr.io/distroless/static-debian12:nonroot
13+
14+
COPY agentenv /usr/local/bin/agentenv
15+
16+
ENTRYPOINT ["/usr/local/bin/agentenv"]

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ CGO_ENABLED=1 go build -tags btrfs -o agentenv . # optional btrfs fast path
3434
```
3535

3636
Prebuilt binaries are attached to each [release](https://github.com/css521/agentenv/releases).
37+
Multi-arch container images at `ghcr.io/css521/agentenv` (`:latest` or `:vX.Y.Z`).
3738

3839
## Why it's different
3940

0 commit comments

Comments
 (0)