diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 1f20706..dcbde2c 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -91,3 +91,20 @@ jobs: - name: scan server Go runtime SQL for MySQL-specific constructs run: bash ci/scan-portable-sql.sh + + # ── Job 6: Codegen Drift (支柱 2:token 单源不漂移)────────────────────── + # 重新生成 client/lib/pangolin_tokens.gen.dart,与已提交版本不一致即失败 + # (改了 design/colors_and_type.css 没重生成,或手改了生成物)。 + codegen-drift: + name: Codegen Drift — token 生成物未漂移 + runs-on: nas + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: regenerate flutter tokens & assert no drift + run: | + docker run --rm \ + -v "$PWD:/repo" -w /repo \ + node:20 \ + bash ci/check-codegen-drift.sh diff --git a/ci/check-codegen-drift.sh b/ci/check-codegen-drift.sh new file mode 100755 index 0000000..3b95492 --- /dev/null +++ b/ci/check-codegen-drift.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# check-codegen-drift.sh — codegen 漂移检查(支柱 2:契约单源 / token 单源)。 +# +# design/colors_and_type.css 是唯一 token 真相源,client/lib/pangolin_tokens.gen.dart +# 由 design/codegen/gen_flutter_tokens.mjs 生成、勿手改(CLAUDE.md 铁律)。本检查重新 +# 生成一遍,若生成物与已提交版本不一致 → 漂移:要么改了 CSS 没重生成,要么手改了 +# 生成物。两者都会让"单源"失效、契约悄悄分叉。 +# +# 依赖: node(零依赖纯脚本) + git。CI 在 node:20 镜像内跑(含 git/bash)。 +# 发现漂移 → 非零退出码(CI fail)。 +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$REPO_ROOT" + +# docker 内挂载目录 owner 与进程 uid 不一致时 git 会拒绝;本地是 owner 时此行无副作用。 +git config --global --add safe.directory "$REPO_ROOT" 2>/dev/null || true + +GEN="client/lib/pangolin_tokens.gen.dart" + +echo "→ 重新生成 Flutter token (design/codegen/gen_flutter_tokens.mjs) ..." +node design/codegen/gen_flutter_tokens.mjs + +if ! git diff --quiet -- "$GEN"; then + echo "❌ codegen 漂移:$GEN 与 design/colors_and_type.css 不一致。" >&2 + echo " 原因:改了 CSS 真相源却没重生成,或手改了生成物(铁律:勿手改 *.gen.dart)。" >&2 + echo " 修复:node design/codegen/gen_flutter_tokens.mjs 后提交生成物。" >&2 + echo " ── diff(前 40 行)──" >&2 + git --no-pager diff -- "$GEN" | head -40 >&2 + exit 1 +fi + +echo "✅ codegen 无漂移:token 生成物与 CSS 真相源一致。"