# 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
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 . .

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 golangci-lint run --config .golangci.yml ./...
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
COPY go.mod go.sum ./
RUN go mod download

# As in the lint stage: the RUN steps below run again on each script/cibuild.
ARG CHECK_EPOCH

COPY . .

RUN 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.
ARG VERSION
RUN 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; \
    fi; \
    make build VERSION="${version:-dev}"

# Runtime stage
# 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
RUN chmod +x /usr/local/bin/secret

USER secret
WORKDIR /home/secret

ENTRYPOINT ["secret"]
