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
8 changes: 8 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 发布审查:source/_posts/ 下的任何改动都需要审查人批准。
#
# 注意:CODEOWNERS 自己不会阻止合并,必须在仓库规则里勾选
# Settings → Rules → Rulesets → Require review from Code Owners
# (详见 REVIEW_POLICY.md)。单人仓库要先加一个协作者账号,
# 否则自己的 PR 永远拿不到批准,会被自己的规则卡死。

/source/_posts/ @cadywang
34 changes: 34 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!--
发布审查说明(勿删):
本模板「发布审查清单」小节里的每一项都由 CI 强制校验
(.github/workflows/review-gate.yml 里的 pr-checklist),
没勾完就不能合并;合并前还必须有人 Approve。
完整规则见 REVIEW_POLICY.md。
-->

## 变更内容

<!-- 简要说明这次改了什么、为什么改;新文章请写明主题和面向的读者 -->

## 变更类型

- [ ] 新文章
- [ ] 修改 / 删除已有文章
- [ ] 站点、主题或配置调整
- [ ] 依赖或工作流调整

## 发布审查清单

- [ ] 文章标题、日期、标签、分类已填写完整
- [ ] 正文已通读:无错别字、无未写完的段落、无占位内容
- [ ] 图片等本地资源已随文章一起提交,路径可访问
- [ ] 不含密钥、口令、内网地址等敏感信息
- [ ] 已在本地执行 `npm run build` 且构建通过

## 审查人重点看什么

<!-- 例:事实是否准确、示例命令能否复现、是否有需要脱敏的信息 -->

## 关联 Issue

<!-- 例:Closes #12 -->
93 changes: 80 additions & 13 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,51 +1,118 @@
name: Build and Deploy Blog
name: Publish Blog

# 发布流程(单人模式):源码先提交,审核通过后再手动触发编译发布。
#
# 1. 平时:把文章源码提交到 main(网页提交或本地 push 都行),
# review-gate.yml 会自动校验文章格式并试构建,但**不会发布**;
# 2. 你本人审核:在 GitHub 上看这次 diff,或本地 npm run server 预览;
# 3. 审核通过后,用下面任一方式触发本工作流,才会真正「编译 + 发布」:
# · Actions 页面 → Publish Blog → Run workflow(推荐,可填审核备注)
# · 或打一个 publish-* 标签并推送:git push origin publish-2026-10-15
#
# 也就是说:**没有你这一下人工触发,任何提交都不会上线。**

on:
workflow_dispatch:
inputs:
ref:
description: 要发布的提交(留空 = 当前分支最新提交,通常是 main)
required: false
default: ''
note:
description: 审核备注(会写进发布摘要,便于事后追溯)
required: false
default: ''
push:
branches: [main] # 合并/推送到 main → 构建并发布
pull_request:
branches: [main] # PR → 只构建校验,不发布
workflow_dispatch: # 也支持在 Actions 页面手动触发
tags:
- 'publish-*'

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages-${{ github.ref }}
cancel-in-progress: true
group: pages-publish
cancel-in-progress: false

jobs:
verify:
name: verify
runs-on: ubuntu-latest
outputs:
sha: ${{ steps.target.outputs.sha }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref || github.sha }}
fetch-tags: true
fetch-depth: 0
- name: 确认要发布的提交已经在 main 上
id: target
env:
NOTE: ${{ github.event.inputs.note }}
run: |
set -euo pipefail
sha=$(git rev-parse HEAD)
git fetch --no-tags origin main:refs/remotes/origin/main --force
if ! git merge-base --is-ancestor "$sha" origin/main; then
echo "::error::要发布的提交 $sha 不在 main 上,拒绝发布(请先把源码合并/推送到 main)"
exit 1
fi
echo "sha=$sha" >> "$GITHUB_OUTPUT"
{
echo "## 发布审核"
echo ""
echo "| 项目 | 内容 |"
echo "| --- | --- |"
echo "| 目标提交 | \`${sha}\` |"
echo "| 提交说明 | $(git log -1 --pretty=%s) |"
echo "| 提交作者 | $(git log -1 --pretty='%an <%ae>') |"
echo "| 提交时间 | $(git log -1 --pretty=%ad --date=iso) |"
echo "| 审核备注 | ${NOTE:-(未填写)} |"
echo "| 触发方式 | ${{ github.event_name }} |"
echo "| 触发人 | ${{ github.actor }} |"
echo ""
echo "> 这一下「Run workflow / 打 tag」就是本次发布的人工审核动作。"
} >> "$GITHUB_STEP_SUMMARY"
- uses: actions/setup-node@v4
with:
node-version: 20
- name: 汇总本次要发布的改动
run: node tools/publish-summary.mjs "${{ steps.target.outputs.sha }}"

build:
name: build
needs: verify
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.verify.outputs.sha }}
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: 发布前全量校验文章
run: node tools/check-posts.mjs --all
- name: Install dependencies
run: npm ci
- name: Build site
run: npx hexo clean && npx hexo generate
- uses: actions/configure-pages@v5
if: github.event_name != 'pull_request'
with:
enablement: true
- uses: actions/upload-pages-artifact@v3
if: github.event_name != 'pull_request'
with:
path: public

deploy:
# PR 不发布:只有 push 到 main 或手动触发才部署
if: github.event_name != 'pull_request'
needs: build
name: deploy
needs: [verify, build]
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v4
70 changes: 70 additions & 0 deletions .github/workflows/review-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Review Gate

# 这是「发布前的自动校验」,只校验、不发布:
# validate-posts —— 文章的 front-matter / 文件名 / 本地资源校验
# pr-checklist —— 走 PR 时,PR 描述里的「发布审查清单」必须逐条勾选
# build-check —— 确认站点能构建(npm ci + hexo generate)
#
# 真正上线由 deploy.yml 手动触发(Actions → Publish Blog → Run workflow),
# 所以这里失败只是提醒你「先修好再发布」。完整规则见 REVIEW_POLICY.md。
#
# 注意:job 名字(validate-posts / pr-checklist / build-check)如果要写进
# 仓库规则集的必需检查里,改名必须同步更新 REVIEW_POLICY.md。

on:
pull_request:
branches: [main]
push:
branches: [main]

permissions:
contents: read

concurrency:
group: review-gate-${{ github.ref }}
cancel-in-progress: true

jobs:
validate-posts:
name: validate-posts
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- name: 校验文章格式
env:
BASE_REF: "${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}"
run: node tools/check-posts.mjs --base "$BASE_REF"

pr-checklist:
name: pr-checklist
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: 校验 PR 审查清单
env:
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
PR_BODY: ${{ github.event.pull_request.body }}
run: node tools/check-pr.mjs

build-check:
name: build-check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Build site
run: npx hexo clean && npx hexo generate
69 changes: 49 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,26 @@

- 线上地址:<https://cadywang.github.io>
- 仓库地址:<https://github.com/cadywang/cadywang.github.io>
- 发布规则:[REVIEW_POLICY.md](REVIEW_POLICY.md)——**源码先提交,本人审核通过后手动触发才编译发布**
- 工作流:[.github/workflows/deploy.yml](.github/workflows/deploy.yml)

---

## 一、日常使用:只需要放文档
## 一、日常使用:写文章 → 审核 → 发布

你不需要懂前端,也不需要本地装任何东西,**只要往 `source/_posts/` 目录上传 Markdown 文件**,博客就会自动更新。
你不需要懂前端,也不需要本地装任何东西,**只要往 `source/_posts/` 目录上传 Markdown 文件**,提交后自己审核一遍,再在 Actions 里点一次发布就能上线(规则见 [REVIEW_POLICY.md](REVIEW_POLICY.md))。

### 在网页上发一篇新文章
### 发一篇新文章(源码先提交,审核后再发布)

> 本站是**单人模式**:源码提交到 `main` **不会**立刻上线。
> 你自己审核通过后,在 Actions 里手动触发一次发布,才会编译并上线。
> 完整规则见 [REVIEW_POLICY.md](REVIEW_POLICY.md)。

**第一步:提交文章源码**

1. 打开 <https://github.com/cadywang/cadywang.github.io/tree/main/source/_posts>
2. 点右上角 **Add file → Create new file**
3. 文件名填 `my-new-post.md`(**建议用英文/拼音**,它会出现在文章网址里)
3. 文件名填 `my-new-post.md`(建议用英文/拼音,它会出现文章网址里)
4. 内容格式:

```markdown
Expand All @@ -30,10 +37,25 @@
正文,正常写 Markdown 即可。
```

5. 页面底部点 **Commit changes**
6. 大约 1~2 分钟后,刷新 <https://cadywang.github.io> 即可看到
5. 页面底部选 **Commit directly to the main branch**,点 **Commit changes**

**第二步:等自动校验,然后自己审核**

6. 仓库 **Actions** 里 `Review Gate` 会跑 `validate-posts`(文章格式)和 `build-check`(能否构建),全绿说明没问题
7. 审核方式随你挑:看这次提交的 diff、在 GitHub 上读一遍源码,或本地 `npm run server` 预览效果

> 修改已有文章:点开该文件 → 右上角铅笔图标 → 改完提交,同样会自动发布。
**第三步:审核通过 → 手动触发发布**

8. 打开 <https://github.com/cadywang/cadywang.github.io/actions/workflows/deploy.yml>
9. 点 **Run workflow** → 分支选 `main` →(可选)填一句审核备注 → 点 **Run workflow**
10. 看这次运行的 **Summary** 里「本次发布内容」,确认要发的东西没错,再等 `build` / `deploy` 变绿
11. 约 1~2 分钟刷新 <https://cadywang.github.io> 即可看到

> 命令行等价操作:`gh workflow run deploy.yml`;或者打标签 `git tag publish-2026-10-15 && git push origin publish-2026-10-15`。
> 两种方式都只会发布 `main` 上已有的提交,未进 main 的东西发布不出去。
>
> 修改已有文章同理:改完提交 → 校验变绿 → 手动发布一次。
> 还没打算发的稿子:在 front-matter 加 `draft: true`,它不会被生成。

### front-matter 各项含义

Expand Down Expand Up @@ -133,19 +155,26 @@ npm run new -- "标题" # 按模板新建一篇文章

## 五、发布原理

```
提交 Markdown 到 main 分支
│
▼
GitHub Actions(ubuntu-latest)
1. checkout 代码
2. 安装 Node 20 + npm 依赖
3. npx hexo generate → 生成 public/ 静态文件
4. 上传产物并发布到 GitHub Pages
│
▼
https://cadywang.github.io 自动更新
```
提交文章源码到 main(直接提交或走 PR 都行)
│
▼
Review Gate(自动校验,不发布)
validate-posts 文章格式 / 文件名 / 本地资源
pr-checklist 走 PR 时的审查清单
build-check 站点能否构建成功
│
▼
你本人审核(看 diff / 本地预览)
│ 审核通过
▼
Actions → Publish Blog → Run workflow(人工触发,或推 publish-* 标签)
verify 确认要发布的提交已经在 main 上
全量校验 check-posts --all
构建 npm ci + hexo generate
发布 deploy-pages → GitHub Pages
│
▼
https://cadywang.github.io 更新

查看每次发布是否成功:仓库页 **Actions** 标签。

Expand Down
Loading
Loading