Design System Guard / guard (push) Successful in 5m33s
run 9 已跑通环境,暴露两处真实缺口:
① schema-consistency-test.js → server/shared/repository.js → require('pg'),
干净 clone 无 node_modules,报 Cannot find module 'pg'。
补 npm ci(server,走 npmmirror)。
② clock_test / host_ffi_test 在 loading 阶段要 libinkwatch_core.so,
找不到即整份失败。补 rustup(rsproxy 镜像)+ cargo build --release,
产物落在 rust-core/target/release,正是 core_lib.dart 的候选路径。
153 lines
8.3 KiB
YAML
153 lines
8.3 KiB
YAML
# 墨观 InkWatch V4.0 · 设计系统双向护栏 CI 入口
|
||
#
|
||
# 前提:本 workflow 只有在 Gitea 实例「启用 Actions」时才会真正运行;
|
||
# 未启用时该文件仅作声明,不会触发任何检查。
|
||
# 本地复现(无需 Actions、无需 Gitea):cd <repo> && bash tests/run-guards.sh
|
||
# 不在本文件里引 CDN、不写任何凭据;Flutter 用官方 flutter-action 安装。
|
||
#
|
||
# Flutter / Dart 段说明:
|
||
# client/scripts/test.sh 默认找 $HOME/development/flutter/bin/flutter,
|
||
# 下面把 flutter 装到同一位置并把绝对路径经 FLUTTER_BIN 显式传给 test.sh,
|
||
# 以保证默认跑全量 Dart(含 token_parity_test.dart 的 CSS ↔ Dart 双向护栏)。
|
||
# SDK 取自 storage.flutter-io.cn 的 stable 归档(非 git clone),版本钉死。
|
||
# 若 runner 无法安装 Flutter:设 SKIP_FLUTTER_TESTS=1 降级 —— Dart 段会在
|
||
# 汇总表里显式标 SKIPPED (explicit),绝不静默通过。
|
||
#
|
||
# 管理台 axe 段(第 6 套件,默认不跑):
|
||
# run-guards.sh 只在 RUN_AXE=1 时执行 node tests/admin-axe-audit.mjs
|
||
# (3 视口 × 2 皮肤 × 6 页 + E-Ink 6 格 = 42 格,单跑约 45s)。
|
||
# **runner 必须自带 Chromium 系浏览器(google-chrome / microsoft-edge /
|
||
# chromium)并能联网安装 axe-core,否则保持默认不跑**;若强行启用而浏览器缺失,
|
||
# 该套件以退出码 2 失败(汇总表 FAIL,不会伪造成 PASS)。
|
||
# 两种启用方式(任选其一,均不硬编码任何凭据):
|
||
# ① 手动触发:Actions 里 Run workflow → run_axe 勾选 true;
|
||
# ② 仓库变量:Gitea 仓库 Settings → Actions → Variables 设 IW_RUN_AXE=1,
|
||
# 之后 push / pull_request 也会带上该套件。
|
||
# 若所在 Gitea 版本不支持 vars 上下文,删掉下面 job 级 env 里
|
||
# IW_RUN_AXE 那一行即可(其余逻辑不变,退回「默认不跑」)。
|
||
|
||
name: Design System Guard
|
||
|
||
on:
|
||
push:
|
||
pull_request:
|
||
workflow_dispatch:
|
||
inputs:
|
||
run_axe:
|
||
# 用字符串而非 type: boolean —— 兼容不支持 inputs.type 的旧版 Gitea
|
||
description: '启用管理台 axe 42 格矩阵(填 true 启用;需 runner 自带 Chromium/Edge)'
|
||
default: 'false'
|
||
|
||
jobs:
|
||
guard:
|
||
runs-on: ubuntu-latest
|
||
# 2026-11-09:历史上 6 次运行全红,根因两处,均已在此固化:
|
||
# ① subosito/flutter-action@v2 的 setup.sh 依赖 jq,而 runner 的
|
||
# node:20-bookworm 容器没有 jq → 首行即 "jq not found" 退出。
|
||
# 故本文件不再使用该 action,改为直取官方镜像的 tar.xz(无需 jq)。
|
||
# ② 该 runner 到 github.com 与 nodejs.org 的直连极慢/超时
|
||
# (实测 setup-node 重试 3 轮烧掉 8 分钟才靠 fallback 成功;
|
||
# flutter-action 默认 `git clone github.com/flutter/flutter` 必挂)。
|
||
# 故 Flutter 全程改走国内镜像。
|
||
# setup-node 也已删除:其 `mirror` 参数只影响 dist 下载,解析版本清单
|
||
# 时仍打 github.com/actions/node-versions,实测照样 ETIMEDOUT。
|
||
# 本 job 只用 fs/path/crypto 三个内置模块,容器自带的 node 20 足够
|
||
# (runner 的 ubuntu-latest 映射到 node:20-bookworm,见运行日志)。
|
||
timeout-minutes: 30
|
||
env:
|
||
# 仓库变量(可选);未设置时为空串,等价于「默认不跑 axe」
|
||
IW_RUN_AXE: ${{ vars.IW_RUN_AXE }}
|
||
# Flutter/Dart 官方中国镜像(下载 SDK 与 pub 包均走它,避开 github/pub.dev)
|
||
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
|
||
PUB_HOSTED_URL: https://pub.flutter-io.cn
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Report toolchain
|
||
run: |
|
||
# 不使用 setup-node:容器自带 Node,版本随镜像走,此处只记录以便追溯。
|
||
command -v node >/dev/null 2>&1 || { echo "容器内无 node,无法跑护栏脚本" >&2; exit 1; }
|
||
echo "node $(node --version) / npm $(npm --version 2>/dev/null || echo n/a)"
|
||
|
||
# schema-consistency-test.js 会 require server/shared/repository.js,
|
||
# 后者 require('pg')。本地能过是因为 node_modules 已装;干净 clone 没有。
|
||
- name: Install Node deps (pg, for schema guard)
|
||
run: |
|
||
set -euo pipefail
|
||
cd server
|
||
npm ci --omit=dev --no-audit --no-fund --registry=https://registry.npmmirror.com
|
||
node -e "require('pg'); console.log('pg ok')"
|
||
|
||
# 不用 subosito/flutter-action:它硬依赖 jq,且默认 git clone github。
|
||
# 直接取官方镜像归档,1.58GB,走 storage.flutter-io.cn。
|
||
# node:20-bookworm 自带 curl/tar/xz/git,故本步骤无需 apt。
|
||
- name: Setup Flutter (mirror archive, no jq)
|
||
run: |
|
||
set -euo pipefail
|
||
FLUTTER_VERSION="3.47.9" # Dart 3.13.7,满足 pubspec 的 sdk: ^3.13.3
|
||
ARCHIVE="flutter_linux_${FLUTTER_VERSION}-stable.tar.xz"
|
||
URL="${FLUTTER_STORAGE_BASE_URL}/flutter_infra_release/releases/stable/linux/${ARCHIVE}"
|
||
mkdir -p "$HOME/development"
|
||
echo "下载 $URL"
|
||
curl -fsSL --retry 3 --retry-delay 5 --connect-timeout 20 -o /tmp/flutter.tar.xz "$URL"
|
||
# --no-same-owner:归档内的 uid 不是 0,按原 uid 解压会让
|
||
# /root/development/flutter 属主≠root,git 2.35+ 随即报
|
||
# "fatal: detected dubious ownership",而 flutter 工具链启动时
|
||
# 会调用 git 取版本 → 直接 exit 128。run 8 就死在这里。
|
||
tar --no-same-owner -xf /tmp/flutter.tar.xz -C "$HOME/development"
|
||
rm -f /tmp/flutter.tar.xz
|
||
echo "$HOME/development/flutter/bin" >> "$GITHUB_PATH"
|
||
echo "FLUTTER_BIN=$HOME/development/flutter/bin/flutter" >> "$GITHUB_ENV"
|
||
# 双保险:即便属主仍有偏差,也让 git 认这个目录。
|
||
git config --global --add safe.directory "$HOME/development/flutter"
|
||
"$HOME/development/flutter/bin/flutter" --version
|
||
|
||
# clock_test / host_ffi_test 会 NativeLibrary.open 找 libinkwatch_core.so,
|
||
# 找不到就在 loading 阶段整份失败(Bad state: 未找到 libinkwatch_core.so)。
|
||
# 该 crate 只依赖 sysinfo/serde,跨平台可编;Linux 编出 .so 后
|
||
# core_lib.dart 的「仓库内构建产物」候选路径正好命中 rust-core/target/release。
|
||
- name: Build Rust core (for clock/host_ffi tests)
|
||
env:
|
||
RUSTUP_DIST_SERVER: https://rsproxy.cn
|
||
RUSTUP_UPDATE_ROOT: https://rsproxy.cn/rustup
|
||
run: |
|
||
set -euo pipefail
|
||
mkdir -p "$HOME/.cargo"
|
||
# 用 printf 而非 heredoc:YAML 的 block scalar 会带上缩进,
|
||
# 写进 config.toml 虽仍合法(TOML 忽略行首空白),但看着脏。
|
||
printf '%s\n' \
|
||
'[source.crates-io]' \
|
||
'replace-with = "rsproxy-sparse"' \
|
||
'' \
|
||
'[source.rsproxy-sparse]' \
|
||
'registry = "sparse+https://rsproxy.cn/index/"' \
|
||
> "$HOME/.cargo/config.toml"
|
||
curl -fsSL --retry 3 --retry-delay 5 -o /tmp/rustup-init.sh https://rsproxy.cn/rustup-init.sh
|
||
sh /tmp/rustup-init.sh -y --profile minimal --default-toolchain stable
|
||
. "$HOME/.cargo/env"
|
||
rustc --version
|
||
cargo build --release --manifest-path rust-core/Cargo.toml
|
||
ls -la rust-core/target/release/libinkwatch_core.so
|
||
|
||
- name: Run design system guards
|
||
run: |
|
||
# FLUTTER_BIN 由 Setup Flutter 步骤写入 GITHUB_ENV,此处优先采用
|
||
if [ -n "${FLUTTER_BIN:-}" ] && [ -x "$FLUTTER_BIN" ]; then
|
||
:
|
||
elif [ -n "${FLUTTER_ROOT:-}" ] && [ -x "$FLUTTER_ROOT/bin/flutter" ]; then
|
||
export FLUTTER_BIN="$FLUTTER_ROOT/bin/flutter"
|
||
elif command -v flutter >/dev/null 2>&1; then
|
||
export FLUTTER_BIN="$(command -v flutter)"
|
||
fi
|
||
|
||
# 管理台 axe 段:默认 0;手动触发时取 run_axe 输入;否则看仓库变量 IW_RUN_AXE
|
||
RUN_AXE="${IW_RUN_AXE:-0}"
|
||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||
if [ "${{ inputs.run_axe }}" = "true" ]; then RUN_AXE=1; else RUN_AXE=0; fi
|
||
fi
|
||
export RUN_AXE
|
||
echo "RUN_AXE=$RUN_AXE(0=跳过管理台 axe 42 格矩阵,1=执行)"
|
||
|
||
bash tests/run-guards.sh
|