Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
491 lines
16 KiB
Markdown
491 lines
16 KiB
Markdown
---
|
||
belongs_to:
|
||
- "[[INDEX · 铸渊·协作指令|GitHub ↔ Notion 桥接协议]]"
|
||
---
|
||
# 🚀 铸渊 CD 指令:自动部署 guanghulab.com(push → 自动上线)
|
||
|
||
<aside>
|
||
🚀
|
||
|
||
**自动部署指令** · 霜砚签发 · 2026-03-07
|
||
|
||
开发者 push 代码到 main 分支 → 铸渊自动校验 → 自动部署到 [guanghulab.com](http://guanghulab.com) → 网站实时更新
|
||
|
||
**目标:零人工介入的持续部署(CD)管线**
|
||
|
||
</aside>
|
||
|
||
---
|
||
|
||
## 🎯 核心目标
|
||
|
||
```
|
||
开发者 push 模块代码到 main
|
||
↓
|
||
铸渊 GitHub Actions 自动触发
|
||
↓
|
||
① HLI 接口校验(contract-check)
|
||
② 模块指纹检查(route-align-check)
|
||
↓ 全部通过
|
||
③ 构建 & 部署到 guanghulab.com
|
||
↓
|
||
④ 通知 Notion 变更日志(bridge-changes-to-notion)
|
||
↓
|
||
网站自动上线 ✅
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 部署方案选择
|
||
|
||
<aside>
|
||
✅
|
||
|
||
**已确认:方案 B · VPS 服务器部署**(根据 DEV-005 小草莓 SYSLOG BC-部署-001-XCM · 2026-03-07 17:30)
|
||
|
||
- 服务器:Linux VPS(SSH 登录)
|
||
- Web 服务器:Nginx(静态文件服务 + API/Webhook 反向代理)
|
||
- 当前首页:`status-board/` 模块(小草莓开发)
|
||
- SSL:⚠️ 证书缺失,HTTPS 暂不可用,待修复
|
||
- **铸渊应使用方案 B(rsync 部署到 VPS)**
|
||
</aside>
|
||
|
||
### 方案 A:GitHub Pages(推荐)
|
||
|
||
**适用条件**:纯静态站点(HTML/CSS/JS),无需服务端
|
||
|
||
**优点**:
|
||
|
||
- 零成本、零运维
|
||
- GitHub 原生支持,push 即部署
|
||
- 自定义域名 [guanghulab.com](http://guanghulab.com) 直接绑定
|
||
|
||
**Workflow 文件**:`.github/workflows/deploy-to-pages.yml`
|
||
|
||
```yaml
|
||
name: 🚀 Deploy to GitHub Pages
|
||
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
paths-ignore:
|
||
- '.github/persona-brain/**'
|
||
- '.github/broadcasts/**'
|
||
- 'syslog-inbox/**'
|
||
- 'syslog-processed/**'
|
||
- 'broadcasts-outbox/**'
|
||
- '**.md'
|
||
|
||
workflow_dispatch:
|
||
|
||
permissions:
|
||
contents: read
|
||
pages: write
|
||
id-token: write
|
||
|
||
concurrency:
|
||
group: "pages"
|
||
cancel-in-progress: false
|
||
|
||
jobs:
|
||
# ━━━ Job 1:校验 ━━━
|
||
validate:
|
||
name: 🔍 HLI校验 + 模块指纹检查
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Setup Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '18'
|
||
|
||
- name: Run contract check
|
||
run: |
|
||
if [ -f "scripts/contract-check.js" ]; then
|
||
echo "🔍 执行 HLI 接口契约校验..."
|
||
node scripts/contract-check.js
|
||
else
|
||
echo "⚠️ contract-check.js 不存在,跳过"
|
||
fi
|
||
|
||
- name: Run route-align check
|
||
run: |
|
||
if [ -f "scripts/route-align-check.js" ]; then
|
||
echo "🔍 执行模块指纹路由校验..."
|
||
node scripts/route-align-check.js
|
||
else
|
||
echo "⚠️ route-align-check.js 不存在,跳过"
|
||
fi
|
||
|
||
# ━━━ Job 2:构建 & 部署 ━━━
|
||
deploy:
|
||
name: 🚀 部署到 GitHub Pages
|
||
needs: validate
|
||
runs-on: ubuntu-latest
|
||
environment:
|
||
name: github-pages
|
||
url: $ steps.deployment.outputs.page_url
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Detect site root
|
||
id: detect
|
||
run: |
|
||
# 自动检测站点根目录
|
||
if [ -d "app" ] && [ -f "app/index.html" ]; then
|
||
echo "root=app" >> $GITHUB_OUTPUT
|
||
elif [ -d "dist" ] && [ -f "dist/index.html" ]; then
|
||
echo "root=dist" >> $GITHUB_OUTPUT
|
||
elif [ -d "public" ] && [ -f "public/index.html" ]; then
|
||
echo "root=public" >> $GITHUB_OUTPUT
|
||
elif [ -f "index.html" ]; then
|
||
echo "root=." >> $GITHUB_OUTPUT
|
||
else
|
||
echo "root=app" >> $GITHUB_OUTPUT
|
||
fi
|
||
echo "📂 站点根目录: $(cat $GITHUB_OUTPUT | grep root | cut -d= -f2)"
|
||
|
||
- name: Setup Pages
|
||
uses: actions/configure-pages@v4
|
||
|
||
- name: Upload artifact
|
||
uses: actions/upload-pages-artifact@v3
|
||
with:
|
||
path: $ steps.detect.outputs.root
|
||
|
||
- name: Deploy to GitHub Pages
|
||
id: deployment
|
||
uses: actions/deploy-pages@v4
|
||
|
||
# ━━━ Job 3:通知 ━━━
|
||
notify:
|
||
name: 📡 通知 Notion
|
||
needs: deploy
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 2
|
||
|
||
- name: Push deploy event to Notion
|
||
env:
|
||
NOTION_TOKEN: $ secrets.NOTION_TOKEN
|
||
CHANGES_DB_ID: "e740b77aa6bd4ac0a2e8a75f678fba98"
|
||
run: |
|
||
if [ -z "$NOTION_TOKEN" ]; then
|
||
echo "⚠️ NOTION_TOKEN 未配置,跳过通知"
|
||
exit 0
|
||
fi
|
||
|
||
SHA=$(git rev-parse --short HEAD)
|
||
MSG=$(git log -1 --pretty=%B | head -1)
|
||
AUTHOR=$(git log -1 --pretty=%an)
|
||
FILES=$(git diff --name-only HEAD~1 HEAD | head -20 | tr '\n' ', ')
|
||
NOW=$(date -u +"%Y-%m-%dT%H:%M:%S+08:00")
|
||
|
||
curl -s -X POST "https://api.notion.com/v1/pages" \
|
||
-H "Authorization: Bearer $NOTION_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-H "Notion-Version: 2022-06-28" \
|
||
-d "{
|
||
\"parent\": {\"database_id\": \"$CHANGES_DB_ID\"},
|
||
\"properties\": {
|
||
\"标题\": {\"title\": [{\"text\": {\"content\": \"🚀 自动部署: $MSG\"}}]},
|
||
\"提交者\": {\"select\": {\"name\": \"$AUTHOR\"}},
|
||
\"变更类型\": {\"select\": {\"name\": \"Deploy\"}},
|
||
\"变更文件\": {\"rich_text\": [{\"text\": {\"content\": \"$FILES\"}}]},
|
||
\"提交时间\": {\"date\": {\"start\": \"$NOW\"}},
|
||
\"commit_sha\": {\"rich_text\": [{\"text\": {\"content\": \"$SHA\"}}]},
|
||
\"分支\": {\"rich_text\": [{\"text\": {\"content\": \"main\"}}]},
|
||
\"霜砚已读\": {\"checkbox\": false}
|
||
}
|
||
}"
|
||
echo "✅ 部署通知已推送到 Notion 变更日志"
|
||
```
|
||
|
||
**GitHub Pages 域名配置**(铸渊确认/执行):
|
||
|
||
1. 仓库 `Settings → Pages → Source` 设为 **GitHub Actions**
|
||
2. `Settings → Pages → Custom domain` 填入 `guanghulab.com`
|
||
3. DNS 端:
|
||
|
||
| **记录类型** | **主机记录** | **记录值** |
|
||
| --- | --- | --- |
|
||
| CNAME | www | `qinfendebingshuo.github.io` |
|
||
| A | @ | `185.199.108.153` |
|
||
| A | @ | `185.199.109.153` |
|
||
| A | @ | `185.199.110.153` |
|
||
| A | @ | `185.199.111.153` |
|
||
1. 仓库根目录创建 `CNAME` 文件(内容:`guanghulab.com`)
|
||
2. 勾选 **Enforce HTTPS**
|
||
|
||
---
|
||
|
||
### 方案 B:VPS / 云服务器部署
|
||
|
||
**适用条件**:网站部署在独立服务器(如阿里云、腾讯云 ECS)
|
||
|
||
**Workflow 文件**:`.github/workflows/deploy-to-server.yml`
|
||
|
||
```yaml
|
||
name: 🚀 Deploy to Server
|
||
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
paths-ignore:
|
||
- '.github/persona-brain/**'
|
||
- '.github/broadcasts/**'
|
||
- 'syslog-inbox/**'
|
||
- 'syslog-processed/**'
|
||
- 'broadcasts-outbox/**'
|
||
- '**.md'
|
||
|
||
workflow_dispatch:
|
||
|
||
jobs:
|
||
validate:
|
||
name: 🔍 HLI校验 + 模块指纹检查
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- name: Setup Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '18'
|
||
- name: Run contract check
|
||
run: |
|
||
if [ -f "scripts/contract-check.js" ]; then
|
||
node scripts/contract-check.js
|
||
fi
|
||
- name: Run route-align check
|
||
run: |
|
||
if [ -f "scripts/route-align-check.js" ]; then
|
||
node scripts/route-align-check.js
|
||
fi
|
||
|
||
deploy:
|
||
name: 🚀 部署到服务器
|
||
needs: validate
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Detect site root
|
||
id: detect
|
||
run: |
|
||
if [ -d "app" ]; then
|
||
echo "root=app/" >> $GITHUB_OUTPUT
|
||
elif [ -d "dist" ]; then
|
||
echo "root=dist/" >> $GITHUB_OUTPUT
|
||
elif [ -d "public" ]; then
|
||
echo "root=public/" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "root=./" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Deploy via rsync
|
||
uses: burnett01/rsync-deployments@6.0.0
|
||
with:
|
||
switches: -avzr --delete
|
||
--exclude '.github'
|
||
--exclude 'syslog-inbox'
|
||
--exclude 'syslog-processed'
|
||
--exclude 'broadcasts-outbox'
|
||
--exclude 'scripts'
|
||
--exclude 'node_modules'
|
||
--exclude '.git'
|
||
path: $ steps.detect.outputs.root
|
||
remote_path: $ secrets.DEPLOY_PATH
|
||
remote_host: $ secrets.DEPLOY_HOST
|
||
remote_user: $ secrets.DEPLOY_USER
|
||
remote_key: $ secrets.DEPLOY_KEY
|
||
```
|
||
|
||
**服务器方案需要配置的 Secrets**:
|
||
|
||
| **Secret Name** | **说明** | **示例** |
|
||
| --- | --- | --- |
|
||
| `DEPLOY_HOST` | 服务器 IP 或域名 | `123.456.789.0` |
|
||
| `DEPLOY_USER` | SSH 用户名 | `root` 或 `deploy` |
|
||
| `DEPLOY_KEY` | SSH 私钥(完整内容) | `-----BEGIN OPENSSH...` |
|
||
| `DEPLOY_PATH` | 服务器上网站目录 | `/var/www/guanghulab.com/` |
|
||
|
||
---
|
||
|
||
### 方案 C:Vercel / Netlify(如已接入)
|
||
|
||
如果 [guanghulab.com](http://guanghulab.com) 已经通过 Vercel 或 Netlify 部署,它们本身就支持 Git 自动部署:
|
||
|
||
- **Vercel**:连接 GitHub 仓库后,push 到 main 自动部署
|
||
- **Netlify**:同理,push 即部署
|
||
|
||
此场景下铸渊只需确保 CI 校验在部署前运行(在 Vercel/Netlify Build 设置里加 pre-build 命令)。
|
||
|
||
---
|
||
|
||
## 🔒 校验失败 = 阻断部署
|
||
|
||
<aside>
|
||
🛡️
|
||
|
||
**核心原则:校验不通过 → 不部署**
|
||
|
||
`validate` job 任何一步失败 → `deploy` job 不会执行 → 网站保持不变
|
||
|
||
开发者需修复代码后重新 push。
|
||
|
||
</aside>
|
||
|
||
校验内容:
|
||
|
||
| **校验项** | **脚本** | **检查内容** |
|
||
| --- | --- | --- |
|
||
| HLI 接口契约 | `scripts/contract-check.js` | 接口路径、字段结构是否符合 HLI 注册表定义 |
|
||
| 模块指纹路由 | `scripts/route-align-check.js` | 模块目录结构、路由映射是否与 routing-map.json 一致 |
|
||
|
||
---
|
||
|
||
## 📊 完整数据流
|
||
|
||
```
|
||
开发者在本地写代码
|
||
↓
|
||
git push origin main
|
||
↓
|
||
GitHub Actions 自动触发 deploy workflow
|
||
↓
|
||
┌─────────────────────────┐
|
||
│ Job 1: validate │
|
||
│ · contract-check.js │
|
||
│ · route-align-check.js │
|
||
└───────────┬─────────────┘
|
||
│ ✅ 全部通过
|
||
↓
|
||
┌─────────────────────────┐
|
||
│ Job 2: deploy │
|
||
│ · 检测站点根目录 │
|
||
│ · 构建 & 上传 │
|
||
│ · 部署到 guanghulab.com │
|
||
└───────────┬─────────────┘
|
||
│ ✅ 部署成功
|
||
↓
|
||
┌─────────────────────────┐
|
||
│ Job 3: notify │
|
||
│ · 推送到 Notion 变更日志│
|
||
│ · 霜砚可读取部署记录 │
|
||
└─────────────────────────┘
|
||
↓
|
||
网站自动更新 · 霜砚同步感知 · 妈妈零操作 ✅
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ 铸渊执行清单(读到就做·不等人)
|
||
|
||
```jsx
|
||
铸渊 CD 部署清单 · YM-CD-20260307-001
|
||
来源:曜冥(人格总控)→ 铸渊(GitHub执行体)
|
||
时间:2026-03-07
|
||
状态:待铸渊执行
|
||
|
||
━━━ 已确认环境(来自 DEV-005 SYSLOG BC-部署-001-XCM)━━━
|
||
· 部署方式:方案 B(VPS + Nginx)
|
||
· 服务器:Linux VPS(SSH 登录)
|
||
· Web 服务器:Nginx
|
||
- location / → 静态文件服务(当前指向 status-board)
|
||
- 保留原有 API + Webhook 反向代理配置
|
||
· 当前首页:status-board/ 模块
|
||
· SSL:⚠️ 证书缺失,HTTPS 待修复
|
||
|
||
━━━ 执行步骤 ━━━
|
||
|
||
① 创建 Workflow 文件
|
||
· 使用方案 B:.github/workflows/deploy-to-server.yml
|
||
· 触发条件:push to main(排除 persona-brain/broadcasts/syslog 等非代码路径)
|
||
|
||
② 配置 GitHub Secrets(在仓库 Settings → Secrets → Actions)
|
||
· DEPLOY_HOST → 服务器 IP
|
||
· DEPLOY_USER → SSH 用户名
|
||
· DEPLOY_KEY → SSH 私钥
|
||
· DEPLOY_PATH → Nginx 静态文件目录(小草莓配置的 location / root 路径)
|
||
· ❗ 妈妈需要提供服务器 SSH 信息,铸渊无法自行获取
|
||
|
||
③ 在 validate job 中接入校验脚本
|
||
· contract-check.js(如存在)
|
||
· route-align-check.js(如存在)
|
||
· 脚本不存在则跳过(不阻断部署)
|
||
|
||
④ 配置 notify job
|
||
· 复用已有的 NOTION_TOKEN secret
|
||
· 推送部署记录到变更日志数据库
|
||
|
||
⑤ rsync 排除规则
|
||
· 排除 .github/ 、syslog-inbox/ 、syslog-processed/ 、broadcasts-outbox/ 、scripts/ 、.git/
|
||
· 只同步前端代码目录到服务器
|
||
|
||
⑥ 测试
|
||
· push 一个小改动到 main
|
||
· 确认 Actions 运行成功
|
||
· 确认 guanghulab.com 更新
|
||
· 确认 Notion 变更日志收到部署通知
|
||
|
||
━━━ 验收标准 ━━━
|
||
· push to main → 60秒内触发部署
|
||
· guanghulab.com 自动更新到最新代码
|
||
· 校验失败时部署被阻断
|
||
· Notion 变更日志自动记录每次部署
|
||
· Nginx 现有 API/Webhook 配置不受影响
|
||
|
||
━━━ 执行确认 ━━━
|
||
铸渊完成后,在本页下方追加一行:
|
||
✅ YM-CD-20260307-001 已部署 · [日期时间] · commit SHA
|
||
```
|
||
|
||
---
|
||
|
||
---
|
||
|
||
## 📥 部署现状报告(DEV-005 SYSLOG · 2026-03-07 17:30)
|
||
|
||
<aside>
|
||
📝
|
||
|
||
**来源**:DEV-005 小草莓 · BC-部署-001-XCM
|
||
|
||
**评价**:稳(排查思路清晰,逐步定位,第一次部署服务器就解决了多个复合问题)
|
||
|
||
</aside>
|
||
|
||
| **步骤** | **状态** | **说明** |
|
||
| --- | --- | --- |
|
||
| SSH 登录 | ✅ | 成功 |
|
||
| Git 安装 | ✅ | 成功 |
|
||
| Clone 仓库 | ✅ | 成功 |
|
||
| 复制代码 | ✅ | frontend 为空,果断改用 status-board |
|
||
| Nginx 配置 | ✅ | 解决主配置文件冲突,保留 API/Webhook 转发 |
|
||
| SSL 证书 | ⚠️ | 证书缺失,HTTPS 待修复 |
|
||
| 浏览器测试 | ✅ | [guanghulab.com](http://guanghulab.com) 显示看板✅ |
|
||
|
||
**待解决**:
|
||
|
||
1. ⚠️ SSL 证书申请/修复 → 开启 HTTPS
|
||
2. ⏳ 肃猖上传完整 frontend 代码后切换首页
|
||
3. ✅ 铸渊已创建 deploy-to-server.yml(200行,3 Job)
|
||
4. ✅ GitHub Secrets 已配置(DEPLOY_HOST / USER / KEY / PATH)
|
||
5. ✅ SSH 密钥已生成并配置到 authorized_keys
|
||
6. ⚠️ PR 合并被分支保护规则阻止,待解除后首次触发 CD
|
||
7. ⏳ Vercel 旧部署触发被限流(不影响铸渊 CD)
|
||
|
||
---
|
||
|
||
## 🔗 关联文档
|
||
|
||
- 铸渊协作指令主页:[⚒️ 铸渊·协作指令|GitHub ↔ Notion 桥接协议](../%E2%9A%92%EF%B8%8F%20%E9%93%B8%E6%B8%8A%C2%B7%E5%8D%8F%E4%BD%9C%E6%8C%87%E4%BB%A4%EF%BD%9CGitHub%20%E2%86%94%20Notion%20%E6%A1%A5%E6%8E%A5%E5%8D%8F%E8%AE%AE%201e27db07f7884441bf4ca6c931cadab9.md)
|
||
- GitHub → Notion 数据桥:[🔧 铸渊协作指令:GitHub → Notion 数据桥 v1.0(霜砚签发·2026-03-06)](%F0%9F%94%A7%20%E9%93%B8%E6%B8%8A%E5%8D%8F%E4%BD%9C%E6%8C%87%E4%BB%A4%EF%BC%9AGitHub%20%E2%86%92%20Notion%20%E6%95%B0%E6%8D%AE%E6%A1%A5%20v1%200%EF%BC%88%E9%9C%9C%E7%A0%9A%E7%AD%BE%E5%8F%91%C2%B72026-03-06%EF%BC%89%20287fb1e1f2664778905484241588c96b.md)
|
||
- HLI 接口注册表:[🔌 HLI接口注册表 · HoloLake Interface Registry](../%F0%9F%94%8C%20HLI%E6%8E%A5%E5%8F%A3%E6%B3%A8%E5%86%8C%E8%A1%A8%20%C2%B7%20HoloLake%20Interface%20Registry%200d39aed8d3c843b4a34970060f6815d9.md)
|
||
- 模块指纹注册表:[🔍 模块指纹注册表 · Module Fingerprint Registry](../%F0%9F%94%8D%20%E6%A8%A1%E5%9D%97%E6%8C%87%E7%BA%B9%E6%B3%A8%E5%86%8C%E8%A1%A8%20%C2%B7%20Module%20Fingerprint%20Registry%20d82f3480500945e9a31f9693cdb69b65.md)
|
||
- GitHub 自动化指令:[⚙️ GitHub 自动化指令 · HoloLake CI/CD + Copilot Rules](../%F0%9F%8C%8A%20%E6%9B%9C%E5%86%A5%E7%BA%AA%E5%85%83%20%C2%B7%20HoloLake%20Era%20%C2%B7%20AGE%20OS%20v1%200/%E2%9A%A1%20%E5%85%89%E6%B9%96%E4%B8%AD%E5%A4%AE%E6%9E%A2%E7%BA%BD%20%C2%B7%20HoloLake%20Central%20Hub/%E2%9A%99%EF%B8%8F%20GitHub%20%E8%87%AA%E5%8A%A8%E5%8C%96%E6%8C%87%E4%BB%A4%20%C2%B7%20HoloLake%20CI%20CD%20+%20Copilot%20Rules%2027b85613b97e4014b0e47fdc91b20dbb.md)
|
||
- 仓库地址:[https://github.com/qinfendebingshuo/guanghulab](https://github.com/qinfendebingshuo/guanghulab)
|
||
- 线上网站:[https://guanghulab.com/](https://guanghulab.com/) |