Merge pull request #339 from InvolutionHell/dependabot/npm_and_yarn/n… #148
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docs Backfill (on docs changes) | |
| # 2026-04-17 起从"GH runner 直连 Neon"改为"SSH 进自建服务器跑脚本"。 | |
| # 原因:DB 从 Neon 迁到服务器自建 PG 后只绑 127.0.0.1:5432,不对公网暴露。 | |
| # 设计权衡见 wiki Frontend-Auth-And-Admin / 后端 docs/database.md。 | |
| # | |
| # ⚠️ 这个 workflow 维护的是**贡献者署名记录的生命线**——谁写了哪篇文档、 | |
| # 文件改名/移动后署名不丢,全靠底层两个脚本: | |
| # - scripts/uuid.mjs 生成/保持 docId frontmatter(永不改写已有值) | |
| # - scripts/backfill-contributors.mjs 按 docId 累加 GitHub commits 到 DB, | |
| # doc_paths 表维护历史路径并集跨改名追踪 | |
| # 若本 workflow 跑坏了(生成错 docId / 写坏 JSON / 写错 DB),署名可能丢失。 | |
| # 下面每一步前都有防御性检查,出错就 fail loud 不吞错。 | |
| # | |
| # Secrets 依赖: | |
| # SERVER_HOST / SERVER_USER / SERVER_SSH_KEY — SSH 远程登录三件套 | |
| # (私钥生成方式 + 公钥已写入服务器 ~/.ssh/authorized_keys,见 wiki) | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - feat/contributor | |
| paths: | |
| # 2026-05 i18n URL 段化:mdx 内容从 app/docs/ 迁到 content/docs/ | |
| - "content/docs/**" | |
| - "scripts/uuid.mjs" | |
| - "scripts/backfill-contributors.mjs" | |
| - "package.json" | |
| - "pnpm-lock.yaml" | |
| - ".github/workflows/sync-uuid.yml" | |
| - "generated/doc-contributors.json" | |
| workflow_dispatch: {} | |
| concurrency: | |
| group: backfill-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| backfill: | |
| # 防止 fork、限定 main / feat/contributor、并避免机器人循环 | |
| if: | |
| (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/feat/contributor') && | |
| github.actor != 'github-actions[bot]' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Run backfill on server via SSH | |
| uses: appleboy/ssh-action@v1.2.0 | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USER }} | |
| key: ${{ secrets.SERVER_SSH_KEY }} | |
| # 超时 15 分钟:backfill-contributors 要遍历所有 docs + 拉 GitHub API, | |
| # 大改动一次跑 3-5 分钟,留足余量 | |
| command_timeout: 15m | |
| # set -euo pipefail + BRANCH 透传,脚本内任何一步失败都让整个 action fail | |
| envs: GITHUB_REF_NAME | |
| script: | | |
| set -euo pipefail | |
| BRANCH="${GITHUB_REF_NAME:-main}" | |
| # SSH 非交互 shell 不加载 ~/.bashrc / ~/.zshrc,nvm + pnpm 的 PATH | |
| # 要手动 source 进来。否则 pnpm: command not found 直接卡住后面所有步骤。 | |
| # -s 开头表示"if file exists" 兼容 nvm 没装的极端情况。 | |
| export NVM_DIR="$HOME/.nvm" | |
| [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" | |
| cd /home/ubuntu/involution-hell-project/frontend | |
| # ============================================================ | |
| # 0. 脏工作树检查 | |
| # ------------------------------------------------------------ | |
| # 为什么重要:下一步 git reset --hard 会抹掉所有未提交改动。 | |
| # 如果上次 workflow 跑到一半 uuid.mjs 写了 docId 但 backfill 失败没 | |
| # commit,这些"生成了的新 docId"在脏树里。reset 后 uuid.mjs 会生成 | |
| # 不同的新 UUID——不丢署名(因为从未 commit 到 main),但浪费 id | |
| # 且可能造成 docId 分叉留给下一次排查。 | |
| # | |
| # 更严重的场景:如果有人手工在服务器上 hotfix MDX 忘 commit, | |
| # reset 会悄悄抹掉。一律 fail loud 强制人工介入更安全。 | |
| # ============================================================ | |
| if [[ -n "$(git status --porcelain)" ]]; then | |
| echo "::error::服务器 frontend 工作树不干净,拒绝 reset。先人工处理后再重跑。" | |
| git status --short | |
| exit 1 | |
| fi | |
| # 同步仓库到触发本次 workflow 的 commit | |
| git fetch --prune origin | |
| git checkout "$BRANCH" | |
| git reset --hard "origin/$BRANCH" | |
| # ============================================================ | |
| # 1. 加载环境变量 + 必要字段校验 | |
| # ------------------------------------------------------------ | |
| # DATABASE_URL 缺失时 backfill 会隐性降级(shouldSyncDb=false), | |
| # 生成的 JSON 内容是"本轮快照"而非"DB 累计值",覆盖 commit 回仓 | |
| # 会把累计呈现变成单次快照——**视觉上像数据丢了**但 DB 没动。 | |
| # 直接 fail 不给它走降级路径。 | |
| # ============================================================ | |
| set -a && . ./.env && set +a | |
| if [[ -z "${DATABASE_URL:-}" ]]; then | |
| echo "::error::DATABASE_URL 未配置,拒绝运行以免 JSON 降级成本轮快照" | |
| exit 1 | |
| fi | |
| if [[ -z "${GITHUB_TOKEN:-}" ]]; then | |
| echo "::warning::GITHUB_TOKEN 未配置,GitHub API rate limit 60/h 会打爆" | |
| fi | |
| # ============================================================ | |
| # 2. DB 健康检查 | |
| # ------------------------------------------------------------ | |
| # 如果本地 PG 意外被清库或未迁移完成,doc_contributors 表可能是空的。 | |
| # 从空 DB 起增量累计 → 早期已经超出 GitHub API 单文件 commits 最多 N 页 | |
| # 范围的老 commits 永远拉不回来 → 署名丢失。 | |
| # | |
| # 下限 200 行是保守值:迁移完成后 doc_contributors 约 295 行, | |
| # 低于 200 视为"异常状态",要人工确认后才能继续。 | |
| # ============================================================ | |
| CONTRIB_COUNT=$(docker exec involution-postgres \ | |
| psql -U neondb_owner -d involution_hell -tAc \ | |
| "SELECT count(*) FROM doc_contributors;" 2>/dev/null || echo "0") | |
| if [[ "$CONTRIB_COUNT" -lt 200 ]]; then | |
| echo "::error::doc_contributors 只有 $CONTRIB_COUNT 行(预期 >= 200),DB 状态异常,拒绝运行。" | |
| echo "::error::如果是故意重置 DB,临时把本检查注释掉,一次跑完再恢复。" | |
| exit 1 | |
| fi | |
| echo "DB 健康检查通过:doc_contributors 有 $CONTRIB_COUNT 行" | |
| # 3. 依赖和 Prisma client | |
| pnpm install --frozen-lockfile | |
| pnpm prisma generate | |
| # ============================================================ | |
| # 4. 跑脚本 | |
| # ------------------------------------------------------------ | |
| # uuid.mjs:幂等补 docId;已有 docId 的文件绝对不改。 | |
| # backfill-contributors.mjs:按 docId 增量累加,doc_paths 表合并历史路径, | |
| # 翻译版跳过,失败即 exit 1 让本 step fail 不进 commit。 | |
| # ============================================================ | |
| pnpm exec node scripts/uuid.mjs | |
| pnpm exec tsx scripts/backfill-contributors.mjs | |
| # ============================================================ | |
| # 5. 自动提交 | |
| # ------------------------------------------------------------ | |
| # 只 commit MDX frontmatter 改动 + 生成的 JSON,不包含任何其他脏文件。 | |
| # [skip ci] 防止自提交再次触发本 workflow 死循环。 | |
| # ============================================================ | |
| if ! git diff --quiet -- 'content/docs/**/*.md' 'content/docs/**/*.mdx' generated/doc-contributors.json; then | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add 'content/docs/**/*.md' 'content/docs/**/*.mdx' generated/doc-contributors.json | |
| git commit -m "chore(docs): sync doc metadata [skip ci]" | |
| git push origin "$BRANCH" | |
| else | |
| echo "No metadata changes to commit." | |
| fi |