Files
knowledge-governance/Dockerfile
T
姚章浩 5f3a71cade
build / build (push) Successful in 26s
feat(version): 版本号唯一来源 = CHANGELOG.md,并要求写清改了什么与怎么验收
背景:本仓此前没有任何版本/构建元信息 —— 没有 ldflags 注入、也没有产物可读的
版本号,"线上跑的是哪个提交"答不出来;"这次改了什么、怎么验收"也没有载体。

落地:
- CHANGELOG.md:**版本号的唯一来源**(正本 §6.1:版本号只准有一处)。刻意不放
  VERSION 文件、也不靠 git tag —— CI 是 `git fetch --depth 50`,取不到 tag,
  `git describe` 会静默退化。每个已发布版本必须有两节:### 改了什么 与 ### 怎么验收。
- scripts/version.py:从 CHANGELOG 顶部解析版本号;解析不到即非 0 退出(构建据此失败)。
- scripts/check_changelog.py:结构自检(两节齐、带日期、版本号不重复且严格递减、
  小节不为空),带 --self-test 反向自检。
- internal/version:三个构建期注入变量 + 契约测试(注入的号必须等于 CHANGELOG 顶部)。
- Makefile:build 带 -ldflags 注入;verify 增加 changelog-check 与 version-contract。
- Dockerfile:ARG VERSION/COMMIT_SHA/BUILD_TIME + ldflags(未透传时落 dev —— 故意显眼,
  好过看起来正常的假版本号)。
- CI:新增「版本与变更记录契约」步,并显式断言契约测试真的 PASS(被跳过的断言等于没有断言)。
- docs/提交规范.md(ci_gate.py 的报错文案一直在指它)、docs/agents/traps.md(7 条实测陷阱)。

验证(都真跑过):
- make version → 0.1.0;make changelog-check → 合规
- make version-contract → PASS;注入 9.9.9(CHANGELOG 里没有)→ FAIL(反向自检)
- 删掉真实 CHANGELOG 的「怎么验收」小节 → 报红(对真实文件做,不只是夹具)
- go build ./... 与 go vet ./internal/version/... 通过

未做(会与在审 PR #2 冲突,待其合并后在 main 上补):
- GET /version 端点(internal/httpapi/server.go)与 cmd/api 的 -version 开关
- compose.yaml 透传 build args(当前由 compose 构建的镜像会报 dev)

⚠️ 未跑 make verify 全量(含 go test ./... 与前端),CI 是本次的测试证据。
2026-10-10 18:13:24 +08:00

51 lines
3.1 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
FROM golang:1.26-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY cmd ./cmd
COPY internal ./internal
# 构建期身份:由调用方 --build-arg 传入。来源是仓库根 CHANGELOG.md 顶部的已发布版本
# (`python3 scripts/version.py`),**不要手填**。不传就落成 dev / unknown —— 那是故意的:
# 一个显眼的 dev 好过一个看起来正常的假版本号(正本 §6.1)。
# ⚠️ TODO:compose.yaml 还没把这三个 args 透传进来(改动会与在审的 PR #2 冲突),
# 所以当前由 compose 构建出的镜像会报 dev;透传后即报真实版本。
ARG VERSION=dev
ARG COMMIT_SHA=unknown
ARG BUILD_TIME=unknown
RUN LDFLAGS="-X knowledge-governance/internal/version.Number=${VERSION} -X knowledge-governance/internal/version.CommitSHA=${COMMIT_SHA} -X knowledge-governance/internal/version.BuildTime=${BUILD_TIME}" \
&& CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "$LDFLAGS" -o /out/api ./cmd/api \
&& CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "$LDFLAGS" -o /out/worker ./cmd/worker \
&& CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "$LDFLAGS" -o /out/release-worker ./cmd/release-worker \
&& CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "$LDFLAGS" -o /out/test-publication-seed ./cmd/test-publication-seed \
&& CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "$LDFLAGS" -o /out/test-weknora-e2e-report ./cmd/test-weknora-e2e-report \
&& CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "$LDFLAGS" -o /out/test-weknora-probe ./cmd/test-weknora-probe
FROM alpine:3.22
ENV PYTHONDONTWRITEBYTECODE=1
RUN apk add --no-cache ca-certificates python3 postgresql-client curl openssh-client gcompat libc6-compat \
&& addgroup -g 65532 governance \
&& adduser -D -H -u 65532 -G governance governance
# ssh 客户端需要"本机 uid 有 passwd 条目"(否则报 No user exists for uid 1000);
# 备份计划的下发与读回都走 ssh,容器以 1000 运行,这里给该 uid 建一个名字。
RUN adduser -D -u 1000 -h /home/app appuser 2>/dev/null || true
# dws (DingTalk Workspace CLI) v1.0.63:版本+校验和固定(禁用 dws upgrade)。
# 官方产物是动态链接 glibc 的二进制,alpine(musl) 靠 gcompat/libc6-compat 运行,
# 已验证端到端取件并与 glibc 原生环境字节一致。构建期 `dws version` 即自检。
ARG DWS_VERSION=v1.0.63
ARG DWS_SHA256=78cab668bf671c17128ac55347627fb28f80c15b9c30c5f86e32e2b5ee6e34bc
RUN set -eux; \
curl -fsSL -o /tmp/dws.tgz \
"https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli/releases/download/${DWS_VERSION}/dws-linux-amd64.tar.gz"; \
echo "${DWS_SHA256} /tmp/dws.tgz" | sha256sum -c -; \
tar -xzf /tmp/dws.tgz -C /tmp ./dws; \
install -m 0755 /tmp/dws /usr/local/bin/dws; \
rm -rf /tmp/dws.tgz /tmp/dws; \
dws version
WORKDIR /app
COPY --from=build /out/ /app/
COPY scripts/source_catalog_import.py scripts/live_catalog_refresh.py scripts/artifact_fetch.py \
scripts/axls_to_xlsx.py scripts/dws_error_map.py /app/scripts/
USER 65532:65532
CMD ["/app/api"]