Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,30 @@
set -u

# Files whose change can break consistency. Keep in sync with
# scripts/check-consistency.sh sources.
WATCHED_REGEX='^(references/(articles\.md|AGENTS\.md)|README\.md|README\.en\.md|AGENTS\.md|prompts/deep-research-tracker\.md|(concepts|thinking|feedback|works)/[^/]+\.md)$'
# scripts/check-consistency.sh sources: C1-C13 read the README/AGENTS/tracker,
# content markdown (any depth — nested works/practice/tools files count), and
# the images referenced by translations (C10 checks works/imgs/* existence);
# C14 additionally reads index.md, .vitepress/**, and the check script itself.
WATCHED_REGEX='^(references/(articles|AGENTS)\.md$|README(\.en)?\.md$|AGENTS\.md$|index\.md$|\.vitepress/|works/imgs/|scripts/check-consistency\.sh$|(concepts|thinking|feedback|works|practice|tools|prompts)/.+\.md$)'

# --no-renames: a rename lists only the destination path by default, letting
# `git mv README.md elsewhere` slip past the watch list unseen.
# T (typechange) included: replacing a tracked file with a symlink in place
# stages as T, not A/M — excluding it would blind both branches below.
staged=$(git diff --cached --no-renames --name-only --diff-filter=ACMRDT)

# Symlinks are banned repo-wide (C14 invariant c). Reject a staged symlink
# directly from the INDEX — running the full checks instead would scan the
# working tree, which can be swapped back to a regular file after staging
# (TOCTOU): the staged state is what gets committed, so it is what we judge.
staged_symlinks=$(git diff --cached --no-renames --raw --diff-filter=ACMRT | awk -F'\t' '$1 ~ / 120000 / { print $2 }')
if [ -n "$staged_symlinks" ]; then
echo "pre-commit blocked: symlinks are forbidden in this repo (C14) — staged:"
echo "$staged_symlinks" | sed 's/^/ /'
echo "Vite dereferences symlinks into the published site; commit the real file instead."
exit 1
fi

staged=$(git diff --cached --name-only --diff-filter=ACMRD)
if ! echo "$staged" | grep -qE "$WATCHED_REGEX"; then
exit 0
fi
Expand Down
73 changes: 73 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: deploy-docs

# 构建 VitePress 站点并部署到 GitHub Pages(自定义域名 harness.dyu.sh 在
# 仓库 Settings → Pages 配置,DNS 侧为 harness CNAME → deusyu.github.io)。
# 工作流骨架吸收自 PR #21(@Doraemonblogs),本版差异:npm ci(锁定依赖)、
# Node 22(与本地验证环境一致)。

on:
push:
branches: [main]
workflow_dispatch:

# 最小权限:build job 只读源码;pages/id-token 写权限只授给 deploy job,
# 构建(会执行仓库内脚本)不持有任何部署凭据。
permissions:
contents: read

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
pages: read # configure-pages 读取 Pages 配置(GET /pages)需要
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # lastUpdated 与 RSS 条目时间都需要完整 git 历史

- name: Setup Pages
uses: actions/configure-pages@v5

- name: Setup Node
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm

- name: Install dependencies
run: npm ci

- name: Verify sidebar completeness (C14)
run: npm run docs:verify

- name: Build site
run: npm run docs:build

- name: Verify dist contract (page ↔ markdown-copy parity)
run: npm run docs:verify:dist

- name: Disable Jekyll
run: touch .vitepress/dist/.nojekyll

- name: Upload artifact
uses: actions/upload-pages-artifact@v4
with:
path: .vitepress/dist

deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
42 changes: 42 additions & 0 deletions .github/workflows/docs-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: docs-build

# PR 上的只读构建门:完整 VitePress 构建(死链检查随构建执行)+ 侧栏完整性
# + 产物契约(html ↔ .md 副本一一对应、副本自足、无 symlink)。
# 部署仍只走 deploy-docs.yml(合并到 main 之后);本工作流不持有任何写权限。

on:
pull_request:

permissions:
contents: read

# 同一 PR 连续 push 时取消上一次未完成的构建,不浪费 runner。
concurrency:
group: docs-build-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # gitDate/lastUpdated 需要完整历史,与部署构建保持同参

- name: Setup Node
uses: actions/setup-node@v5
with:
node-version: 22
cache: npm

- name: Install dependencies
run: npm ci

- name: Verify sidebar completeness (C14)
run: npm run docs:verify

- name: Build site
run: npm run docs:build

- name: Verify dist contract (page ↔ markdown-copy parity)
run: npm run docs:verify:dist
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,12 @@ CLAUDE.md
.baoyu-skills/
translate/

# VitePress 本地缓存(构建产物已被上面的 dist/ 规则覆盖)
.vitepress/cache/

# 私密商务资料(内训洽谈、聊天截图等,永不入库)
private/

# 本地过程产物(审计报告、发布稿、课程大纲 PDF 等,站点侧已由 SRC_EXCLUDE
# 排除;这里补 git 侧防线,防止 git add -A 把商务产物带进公开仓库)
output/
Loading
Loading