# release-tools image
# Versions are pinned via ARGs sourced from VERSIONS.md.
# Base: Project Hummingbird hi/go (registry.access.redhat.com/hi/go)
# TAG-FLOATING RISK: only `latest-builder` is available from Hummingbird as of 2026-05-25.
# Switch to `1.26-builder` or `1.26.3-builder` when Hummingbird publishes a specific tag.

ARG HI_GO_TAG=latest-builder
ARG HI_GO_DIGEST=sha256:d8c8b702b8a54150e8fdca86753f581d98c551ab8a3fd429886d4ddd4e949894
ARG SYFT_VERSION=v1.44.0
ARG SYFT_SHA256=0e91737aee2b5baf1d255b959630194a302335d848ff97bb07921eb6205b5f5a
ARG GORELEASER_VERSION=v2.16.0
ARG GORELEASER_SHA256=eaae05b5eba07533bd0f06846b68c808399504784df00c62eb219541fc04e5e2
ARG COSIGN_VERSION=v3.0.6
ARG GOVULNCHECK_VERSION=latest
ARG GO_LICENSES_VERSION=v1.6.0
ARG MCPB_VERSION=2.1.2

# ---------------------------------------------------------------------------
# Stage: tools-builder
# Compile/fetch syft, goreleaser, cosign. Pre-warm npm cache for mcpb.
# ---------------------------------------------------------------------------
FROM registry.access.redhat.com/hi/go:${HI_GO_TAG}@${HI_GO_DIGEST} AS tools-builder

ARG SYFT_VERSION
ARG SYFT_SHA256
ARG GORELEASER_VERSION
ARG GORELEASER_SHA256
ARG COSIGN_VERSION
ARG GOVULNCHECK_VERSION
ARG GO_LICENSES_VERSION
ARG MCPB_VERSION

# Install build-time deps: tar+gzip+xz for syft install.sh archive extraction; curl for binary fetches
RUN dnf install -y nodejs npm curl ca-certificates tar gzip xz && dnf clean all

# govulncheck: install via go install (Go module proxy + sumdb integrity)
RUN GOBIN=/usr/local/bin go install golang.org/x/vuln/cmd/govulncheck@${GOVULNCHECK_VERSION}

# go-licenses: install via go install (pinned semver tag, Go sumdb integrity).
# Used by go-ci task to fail PRs that pull in forbidden/restricted licenses (GPL/AGPL/LGPL/MPL).
RUN GOBIN=/usr/local/bin go install github.com/google/go-licenses@${GO_LICENSES_VERSION}

# goreleaser: download prebuilt tarball + SHA256-verify against publisher checksums.txt.
# Avoids go install re-resolving the transitive dep graph from proxy.golang.org each build.
# Expected SHA256 is recorded in VERSIONS.md; update both together on version bumps.
RUN set -ex \
    && curl -sSfLo /tmp/goreleaser_Linux_x86_64.tar.gz \
       "https://github.com/goreleaser/goreleaser/releases/download/${GORELEASER_VERSION}/goreleaser_Linux_x86_64.tar.gz" \
    && curl -sSfLo /tmp/goreleaser-checksums.txt \
       "https://github.com/goreleaser/goreleaser/releases/download/${GORELEASER_VERSION}/checksums.txt" \
    && echo "${GORELEASER_SHA256}  goreleaser_Linux_x86_64.tar.gz" > /tmp/goreleaser-expected.txt \
    && cd /tmp && sha256sum -c goreleaser-expected.txt \
    && grep " goreleaser_Linux_x86_64.tar.gz$" /tmp/goreleaser-checksums.txt | sha256sum -c - \
    && tar -xzf /tmp/goreleaser_Linux_x86_64.tar.gz -C /usr/local/bin goreleaser \
    && chmod +x /usr/local/bin/goreleaser \
    && rm /tmp/goreleaser_Linux_x86_64.tar.gz /tmp/goreleaser-checksums.txt /tmp/goreleaser-expected.txt

# syft: download prebuilt tarball + SHA256-verify against publisher checksums.
# Replaces piped install.sh (no integrity control) with explicit checksum verification.
# Expected SHA256 is recorded in VERSIONS.md; update both together on version bumps.
RUN set -ex \
    && SYFT_VER="${SYFT_VERSION#v}" \
    && curl -sSfLo "/tmp/syft_${SYFT_VER}_linux_amd64.tar.gz" \
       "https://github.com/anchore/syft/releases/download/${SYFT_VERSION}/syft_${SYFT_VER}_linux_amd64.tar.gz" \
    && curl -sSfLo /tmp/syft-checksums.txt \
       "https://github.com/anchore/syft/releases/download/${SYFT_VERSION}/syft_${SYFT_VER}_checksums.txt" \
    && echo "${SYFT_SHA256}  syft_${SYFT_VER}_linux_amd64.tar.gz" > /tmp/syft-expected.txt \
    && cd /tmp && sha256sum -c syft-expected.txt \
    && grep " syft_${SYFT_VER}_linux_amd64.tar.gz$" /tmp/syft-checksums.txt | sha256sum -c - \
    && tar -xzf "/tmp/syft_${SYFT_VER}_linux_amd64.tar.gz" -C /usr/local/bin syft \
    && chmod +x /usr/local/bin/syft \
    && rm "/tmp/syft_${SYFT_VER}_linux_amd64.tar.gz" /tmp/syft-checksums.txt /tmp/syft-expected.txt

# cosign: curl prebuilt linux/amd64 binary + verify against release checksum manifest.
# Download to /tmp/cosign-linux-amd64 so sha256sum -c can find the file by its original
# name (sha256sum resolves filenames in the checksum file relative to cwd).
RUN set -ex \
    && curl -sSfLo /tmp/cosign-linux-amd64 \
       "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64" \
    && curl -sSfLo /tmp/cosign-checksums.txt \
       "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign_checksums.txt" \
    && cd /tmp && grep " cosign-linux-amd64$" cosign-checksums.txt | sha256sum -c - \
    && mv /tmp/cosign-linux-amd64 /usr/local/bin/cosign \
    && rm /tmp/cosign-checksums.txt \
    && chmod +x /usr/local/bin/cosign

# npm packages (mcpb, openspec): install from pinned lockfile into a staging
# directory, then copy the integrity-verified tree to global node_modules.
# npm ci reads package-lock.json (integrity-hash-pinned); npm install -g does NOT
# read the lockfile and re-resolves transitive deps from the registry, defeating
# the supply-chain guarantee. Copy instead of re-resolve.
COPY npm/package.json npm/package-lock.json /npm-src/
RUN cd /npm-src \
 && npm ci --ignore-scripts \
 && mkdir -p /usr/local/lib/node_modules \
 && cp -r /npm-src/node_modules/. /usr/local/lib/node_modules/ \
 && npm cache clean --force

# ---------------------------------------------------------------------------
# Stage: final
# Based on the same Hummingbird builder so Go toolchain is present.
# GoReleaser invokes `go build` at release time; a thin runtime variant
# would be insufficient. See design D2.
# ---------------------------------------------------------------------------
FROM registry.access.redhat.com/hi/go:${HI_GO_TAG}@${HI_GO_DIGEST}

ARG HI_GO_TAG
ARG SYFT_VERSION
ARG GORELEASER_VERSION
ARG COSIGN_VERSION
ARG GOVULNCHECK_VERSION
ARG GO_LICENSES_VERSION
ARG MCPB_VERSION

# Install runtime tools from dnf
RUN dnf install -y nodejs npm jq curl ca-certificates && dnf clean all

# Copy compiled/fetched binaries from builder stage
COPY --from=tools-builder /usr/local/bin/goreleaser    /usr/local/bin/goreleaser
COPY --from=tools-builder /usr/local/bin/syft          /usr/local/bin/syft
COPY --from=tools-builder /usr/local/bin/cosign        /usr/local/bin/cosign
COPY --from=tools-builder /usr/local/bin/govulncheck   /usr/local/bin/govulncheck
COPY --from=tools-builder /usr/local/bin/go-licenses   /usr/local/bin/go-licenses

# Copy globally installed mcpb package tree from builder stage.
# Do NOT COPY the bin wrapper — buildah dereferences symlinks, producing a plain
# script file outside node_modules whose Node import resolution fails.
# Recreate the symlink explicitly so Node resolves modules correctly.
COPY --from=tools-builder /usr/local/lib/node_modules /usr/local/lib/node_modules
RUN ln -sf /usr/local/lib/node_modules/@anthropic-ai/mcpb/dist/cli/cli.js /usr/local/bin/mcpb \
 && chmod +x /usr/local/lib/node_modules/@anthropic-ai/mcpb/dist/cli/cli.js
RUN ln -sf /usr/local/lib/node_modules/@fission-ai/openspec/bin/openspec.js /usr/local/bin/openspec \
 && chmod +x /usr/local/lib/node_modules/@fission-ai/openspec/bin/openspec.js

# OCI image labels
LABEL org.opencontainers.image.source="https://codeberg.org/goern/forgejo-mcp" \
      org.opencontainers.image.version="${GORELEASER_VERSION}" \
      org.opencontainers.image.vendor="Operate First, by #B4mad" \
      org.opencontainers.image.licenses="Apache-2.0" \
      org.opencontainers.image.description="Release toolchain image: go, goreleaser, syft, cosign, govulncheck, go-licenses, node, npm, jq, curl, @anthropic-ai/mcpb, @fission-ai/openspec" \
      org.opencontainers.image.base.name="registry.access.redhat.com/hi/go:${HI_GO_TAG}"

# Smoke-check: every bundled tool must report a version or build fails
# npx check runs with --network=host (build network); offline check is in verify.sh
RUN go version && \
    syft version && \
    goreleaser --version && \
    cosign version && \
    govulncheck -version && \
    go-licenses --help >/dev/null && \
    jq --version && \
    curl --version && \
    node --version && \
    npm --version && \
    mcpb --version && \
    openspec --version
