Re-vendor the canonical files from sneak/prompts at dd4027b (closes #121)
check / check (push) Waiting to run

The vendored files are copies from sneak/prompts dd4027b, with this
repository's own entries after the canonical content. golangci-lint is
v2.14.0. Lint and test are phases of the Dockerfile, which script/lint
and script/test build with --no-cache; Dockerfile.lint and
script/lint-darwin are gone, and the lint phase also checks the macOS
build. The tests run on the Debian Go image with cgo and the race
detector. script/cibuild bootstraps, runs script/check and builds the
image; CHECK_EPOCH and the memlock ulimit are gone. Go's build cache
stays in a cache mount, out of the test image's layer. The rules in
CLAUDE.md that AGENTS.md lacked are now in AGENTS.md.

Model: opus-5-5
This commit is contained in:
2026-10-07 02:15:32 +00:00
parent ed6af50ea5
commit e91ed34d2c
18 changed files with 610 additions and 396 deletions
+56 -63
View File
@@ -1,86 +1,79 @@
# node and yarn, copied into the lint stage for prettier, which checks the
# markdown formatting: node of the version script/bootstrap pins, built on
# Debian as the lint stage's image is.
# node:22.17.0-bookworm-slim, 2025-07-08
FROM node@sha256:b04ce4ae4e95b522112c2e5c52f781471a5cbc3b594527bcddedee9bc48c03a0 AS node
# Lint stage — fast feedback on formatting and lint issues
# golangci/golangci-lint:v2.12.2 (Debian-based), 2026-08-07
FROM golangci/golangci-lint:v2.12.2@sha256:5cceeef04e53efe1470638d4b4b4f5ceefd574955ab3941b2d9a68a8c9ad5240 AS lint
COPY --from=node /usr/local/bin/node /usr/local/bin/node
COPY --from=node /opt/yarn-v1.22.22 /opt/yarn-v1.22.22
ENV PATH="/opt/yarn-v1.22.22/bin:${PATH}"
# script/bootstrap downloads the Go modules and installs prettier
# Lint phase. The linter is invoked directly rather than through `make
# lint` or `script/lint`, which are themselves a docker build.
# golangci/golangci-lint:v2.14.0 (Debian-based), 2026-09-24
FROM golangci/golangci-lint@sha256:ad862ba6b3798cbe0fd9fd7408d498fd74fbd2623a92406b2fd3898faf0bf98f AS lint
WORKDIR /src
COPY script/ script/
COPY go.mod go.sum package.json yarn.lock ./
RUN script/bootstrap
# script/cibuild sets CHECK_EPOCH to the current time, so the RUN steps
# below run again on each build, an unchanged tree included, while the
# steps above stay cached. ARG is per stage: the build stage declares it too.
ARG CHECK_EPOCH
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN make fmt-check
# Not make lint or make lint-darwin: script/lint and script/lint-darwin are
# docker builds, which cannot run in here. These are their commands.
RUN go vet ./...
RUN golangci-lint run --config .golangci.yml ./...
# The same checks on the code as a macOS build compiles it, which a Linux
# build never compiles. Cgo is off, because compiling cgo code for macOS
# needs Apple's SDK headers. That leaves out the files built only with cgo
# on macOS: the keychain unlocker's calls into the keychain
# (keychainunlocker_cgo.go, and keychainunlocker_test.go) and the Secure
# Enclave bindings (internal/macse). Nothing on Linux checks those.
RUN GOOS=darwin CGO_ENABLED=0 go vet ./...
RUN GOOS=darwin CGO_ENABLED=0 golangci-lint run --config .golangci.yml ./...
# Build stage — tests and compilation
# golang 1.24.13-alpine (2026-03-10)
FROM golang@sha256:8bee1901f1e530bfb4a7850aa7a479d17ae3a18beb6e09064ed54cfd245b7191 AS builder
# Force BuildKit to run the lint stage
COPY --from=lint /src/go.sum /dev/null
RUN apk add --no-cache gcc musl-dev make git gnupg
WORKDIR /build
# Test phase. -race needs cgo and so a C compiler, which the Debian Go
# image ships and the alpine one does not.
# golang:1.24.13-trixie, 2026-02-04
FROM golang@sha256:5835f052b784aa39f2fe9070def3568605c8bc3fcd810f10402066348b61e716 AS test
ENV CGO_ENABLED=1
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Go's build cache goes in a cache mount, not the image layer, which would
# take seconds longer to export. --no-cache, on every build in script/,
# starts the mount empty; -count=1 keeps a build without it from taking
# test results from there.
RUN --mount=type=cache,id=sneak/secret/go-build-test,target=/root/.cache/go-build \
go test -count=1 -timeout 90s -race -cover ./... || \
{ echo "--- Rerunning with -v for details ---"; \
go test -count=1 -timeout 90s -race -v ./...; exit 1; }
# As in the lint stage: the RUN steps below run again on each script/cibuild.
ARG CHECK_EPOCH
# Build stage. Nothing is wanted from either phase above; the copies are
# what make BuildKit build them first, so this stage cannot run unless
# lint and test passed.
# golang 1.24.13-alpine, 2026-03-10
FROM golang@sha256:8bee1901f1e530bfb4a7850aa7a479d17ae3a18beb6e09064ed54cfd245b7191 AS builder
COPY --from=lint /src/go.sum /dev/null
COPY --from=test /src/go.sum /dev/null
# script/build compiles with cgo, so it needs a C compiler too.
RUN apk add --no-cache gcc musl-dev make git
# A tar-stream context keeps the sender's file owners, which git refuses.
RUN git config --system --add safe.directory /src
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# This cache mount keeps Go's build cache between builds for make test and
# make build; -count=1 in script/test keeps test results out of it. Go's cache
# does not notice C header changes, so the mount has its own id: change the id
# when the C packages installed above change.
RUN --mount=type=cache,id=sneak/secret/go-build,target=/root/.cache/go-build \
make test
# The version stamped into the binary: the VERSION build argument when one
# is given, otherwise `git describe --tags --always` of the .git the build
# context carries: the tag on a tagged commit, tag-N-gHASH on a commit after
# one, the short commit when no tag is reachable. A context that carries .git
# and still yields no version fails the build.
# The VERSION build arg when one is given, otherwise
# `git describe --tags --always` on the .git in the build context. With
# .git present, a version that is still empty, dev or unknown fails the
# build: git is missing or could not read the checkout.
ARG VERSION
RUN --mount=type=cache,id=sneak/secret/go-build,target=/root/.cache/go-build \
version="${VERSION:-$(git describe --tags --always)}"; \
if [ -e .git ] && { [ -z "$version" ] || [ "$version" = dev ] || \
[ "$version" = unknown ]; }; then \
echo "no version could be derived although the build context carries .git" >&2; \
exit 1; \
RUN VERSION="${VERSION:-$(git describe --tags --always)}"; \
if [ -e .git ]; then \
case "$VERSION" in ""|dev|unknown) \
echo "version is '$VERSION' although .git is present" >&2; \
exit 1 ;; \
esac; \
fi; \
make build VERSION="${version:-dev}"
make build VERSION="${VERSION:-dev}"
# Runtime stage
# alpine 3.23 (2026-03-10)
# Runtime stage, and the last one
# alpine 3.23, 2026-03-10
FROM alpine@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659
RUN apk add --no-cache ca-certificates gnupg
RUN adduser -D -s /bin/sh secret
COPY --from=builder /build/secret /usr/local/bin/secret
COPY --from=builder /src/secret /usr/local/bin/secret
RUN chmod +x /usr/local/bin/secret
USER secret