hostweb 目录同时保存了 WordPress 主题、站点文档和 Astro 静态站。本文所说的自动化更新管线,只作用于 hostweb/aiguidance-astro,不会自动修改或发布 WordPress 主题,也不会处理同目录下的其他工程。

这套管线不是传统的云端 CI/CD。它由本地脚本、Codex 定时调研、Gitee Issue 和 Pull Request、人工审批以及 SSH 部署共同组成。自动化可以推进到草稿 PR,但合并和生产发布仍由站长决定。

完整链路如下。

定时调研或主动需求
  -> 候选迭代
  -> 站长批准开发
  -> 创建 I-XXX 迭代记录
  -> 修改代码或内容
  -> 本地质量门禁
  -> Gitee 分支和草稿 PR
  -> QA 与站长审查
  -> 站长批准发布
  -> 线上快照
  -> 同步构建产物
  -> URL 健康检查
  -> 成功完成,或失败后自动回滚

这套设计解决的重点不是无人值守发布,而是四个工程问题。

  1. 每次修改都有来源、动机和验收标准。
  2. 进入评审前必须完成可重复的构建与检查。
  3. 生产目录被覆盖前必须保留可识别的快照。
  4. 自动化权限有明确边界,调研、开发、QA 和发布不能互相越权。

一、先确认运行环境

进入 Astro 工程并安装依赖。

cd /workspace/hostweb/aiguidance-astro
npm install

本地需要以下命令。

Node.js 与 npm   运行 Astro、SEO 检查和调研脚本
Git              管理分支、提交和远端
curl             调用 Gitee API 和执行 URL 健康检查
jq               解析 Gitee API 响应
ssh              登录部署服务器
rsync            上传构建产物、创建快照和恢复版本

可以先检查版本。

node --version
npm --version
git --version
curl --version
jq --version
ssh -V
rsync --version

仓库中的主要入口如下。

automation/README.md                         管线角色与审批边界
automation/RUNBOOK.md                        主动请求和定时任务使用手册
automation/iterations/README.md              迭代主线与版本索引
automation/roles/                            五类角色的工作合同
automation/templates/                        需求、测试和迭代记录模板
automation/research/weekly-product-research.json
                                               每周调研的来源与候选配置
scripts/check.sh                              完整质量门禁
scripts/check-iterations.sh                   迭代记录一致性检查
scripts/new-iteration.sh                      创建下一条 I-XXX 记录
scripts/weekly-product-research.mjs            生成结构化调研报告
scripts/gitee-api.sh                          Gitee 鉴权、Issue 和 PR 操作
scripts/gitee-pr.sh                           检查、提交、推送和创建 PR
scripts/deploy.sh                             构建、备份、部署、检查和回滚

二、配置 Gitee 访问

管线默认从项目目录外的 ../gitee 读取私人令牌。以当前目录结构计算,实际位置是 hostweb/gitee。

令牌文件只保存一行 token,不加变量名,不写注释。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

限制文件权限,然后验证账号。

chmod 600 ../gitee
npm run gitee:auth

scripts/gitee-api.sh 会拒绝以下情况。

  • 文件不存在。
  • 权限不是 600 或 400。
  • 文件包含多条非空内容。
  • Git 远端不是可解析的 Gitee 仓库地址。

HTTPS 推送时,scripts/gitee-askpass.sh 会按需把 Gitee 仓库所有者作为用户名,把令牌作为密码交给 Git。令牌不会作为命令参数显示,也不应该写入 .env.deploy。

查看当前工作队列。

npm run gitee:issues
npm run gitee:prs

根据已填写的产品简报创建真实 Issue。

npm run gitee:issue -- "需求标题" path/to/filled-product-brief.md

这条命令会直接修改 Gitee 远端状态。提交前要确认简报不是空模板,并且不包含服务器地址、令牌或用户隐私信息。

三、配置生产部署

复制部署模板到项目根目录。

cp scripts/deploy.env.example .env.deploy

.env.deploy 已被 .gitignore 忽略。最小配置如下。

DEPLOY_USER=ubuntu
DEPLOY_HOST=example.com
DEPLOY_PORT=22
DEPLOY_SITE_DIR=/www/wwwroot/aiguidance.cn

建议同时明确临时目录、备份目录、健康检查地址和删除策略。

DEPLOY_TMP_DIR=/home/ubuntu/aiguidance-dist
DEPLOY_BACKUP_DIR=/home/ubuntu/aiguidance-backups
DEPLOY_SUDO=1
DEPLOY_DELETE=0
DEPLOY_HEALTHCHECK_URLS=https://aiguidance.cn/,https://aiguidance.cn/tools/,https://aiguidance.cn/404.html

各变量的作用如下。

变量作用使用建议
DEPLOY_TMP_DIR接收本地 dist/ 的远端临时目录必须与正式站点目录分开
DEPLOY_BACKUP_DIR保存每次发布前的线上快照定期清理旧快照,但保留最近可用版本
DEPLOY_SUDO是否用 sudo 写入宝塔站点目录普通部署用户没有写权限时设为 1
DEPLOY_DELETE正式安装时是否删除新构建中不存在的旧文件确认站点目录只存放 Astro 产物后再设为 1
DEPLOY_SSH_KEY指定 SSH 私钥优先使用密钥登录,不在配置中保存密码
DEPLOY_HEALTHCHECK_URLS部署后逐个检查的 URL至少覆盖首页、核心栏目和 404 页面

部署脚本上传到临时目录时始终使用 --delete,因为临时目录应该只保存本次构建。DEPLOY_DELETE 控制的是从临时目录安装到正式站点时是否删除旧文件,两者不要混淆。

先运行演练。

npm run deploy:dry-run

dry-run 会读取配置、运行 npm run check、检查本地命令和构建产物,并打印计划执行的远端命令,但不会连接服务器或修改远端文件。它不能证明 SSH、sudo、站点目录权限和线上 URL 一定可用。

四、建立调研入口

自动化更新有两个入口。

主动入口适合已经明确的需求,例如改善导航、增加教程或修正页面。请求中至少写清目标、动机和停止边界。

执行一次网站迭代
目标:改善工具导航页的筛选体验
动机:移动端查找工具步骤太多
完成边界:自动做到草稿 PR,不部署生产站

定时入口用于生成候选需求。仓库中的任务规格位于 automation/schedules/weekly-product-research.md,当前约定每周一 09:00、时区为 Asia/Shanghai、只读运行。

需要区分两个组件。

  • Codex 定时任务是真正的周期触发器。它需要在 Codex 中单独启用,负责按时读取仓库、Gitee、站点和近期公开信息。
  • automation/schedules/weekly-product-research.md 只是可审查的任务规格。把这个文件复制到其他仓库,不会自动创建系统定时任务。
  • scripts/weekly-product-research.mjs 是确定性的报告生成器。它读取 JSON 中已经配置好的来源、事实、推断和候选项,检查 URL 与关注词后输出 Markdown;它不会自行发现整个市场的新产品。

手动运行报告生成器。

npm run research:weekly

默认输出到下面的路径。

automation/reports/YYYY-MM-DD-weekly-product-research.md

指定日期和输出位置。

npm run research:weekly -- \
  --date 2026-08-12 \
  --output automation/reports/2026-08-12-weekly-product-research.md

在不能联网的环境中,只验证报告结构。

npm run research:weekly -- \
  --date 2026-08-12 \
  --skip-fetch \
  --output /tmp/aiguidance-weekly-research.md

--skip-fetch 产生的结果只能说明脚本可以生成报告,不能说明来源已核验。报告中会明确标记为跳过联网核验。

调研报告只负责提出候选。没有站长明确批准时,不应创建开发分支、修改代码或部署生产站。

五、创建一次正式迭代

站长批准需求后,创建下一条迭代记录。

npm run iteration:new -- "自动化管线教程" automated-pipeline-guide

脚本会扫描 automation/iterations/ 中已有的编号,并创建下一条 I-XXX-automated-pipeline-guide.md。新记录包括以下固定部分。

修改动机
主线关系
计划范围
实际修改
验证与结果
偏离与决策
后续引导

创建文件后还必须手动完成两件事。

  1. 填写动机、主线关系、范围和验收结果,不能保留模板占位内容。
  2. 把新记录加入 automation/iterations/README.md 的版本表,并保持状态一致。

检查记录。

npm run iteration:check

允许的状态只有 planned、in-progress、in-review、released 和 closed。检查脚本还会验证标题编号、固定章节、主线链接和索引状态。

推荐的状态更新时机如下。

节点状态
已记录但尚未批准开发planned
已批准并开始实施in-progress
PR 已创建,等待 QA 或站长审查in-review
已部署并完成线上验证released
已取消、合并或不再发布closed

六、修改内容并运行质量门禁

开发只修改已批准范围内的文件。新增文章放在 src/content/posts/,工作流放在 src/content/workflows/,工具条目放在 src/content/tools/,页面代码放在 src/pages/。

完成修改后运行完整检查。

npm run check

当前质量门禁按下面的顺序执行。

  1. 运行 scripts/check-iterations.sh,检查每条 I-XXX 记录和主线索引。
  2. 使用 --skip-fetch 在 /tmp 生成一份调研报告,确认关键章节仍存在。
  3. 运行 astro build,校验内容 schema 并生成静态页面。
  4. 检查首页、404、栏目页、工具页和工作流页等必要构建产物是否存在且非空。
  5. 运行 scripts/seo-audit.mjs,检查页面的 SEO 基础项。
  6. 检查关键文案和工具页官方更新日志入口,避免已上线能力意外消失。
  7. 检查项目外的 ../gitee 没有被 Git 跟踪,并扫描疑似硬编码 token。

单独运行 npm run build 只能证明 Astro 可以构建,不等于通过完整质量门禁。准备提交或发布时应使用 npm run check。

页面改动还需要人工检查。

npm run dev

默认访问 http://localhost:4321。至少检查桌面端、移动端、文章详情页、对应栏目页和 404 页面。自动构建无法发现所有排版、溢出、点击区域和可读性问题。

七、推送分支并创建草稿 PR

确认工作区只包含本次迭代的改动,再执行。

git status --short
git diff --check
git diff

默认命令如下。

npm run gitee:pr -- "新增 hostweb 自动化更新管线教程"

脚本会执行这些动作。

npm run check
创建 pr/时间戳-提交信息 分支
git add -A
git commit
git push -u origin 新分支
打印 Gitee 手动建 PR 的链接

这里最需要注意的是 git add -A。它会暂存当前仓库中的全部改动,包括未跟踪文件。工作区存在其他任务或个人文件时,不要直接运行该命令,应先拆分改动或手动提交。

指定稳定的分支名。

GITEE_BRANCH=pr/automated-pipeline-guide \
  npm run gitee:pr -- "新增 hostweb 自动化更新管线教程"

同时调用 Gitee API 创建草稿 PR。

GITEE_CREATE_PR=1 \
GITEE_BRANCH=pr/automated-pipeline-guide \
  npm run gitee:pr -- "新增 hostweb 自动化更新管线教程"

SKIP_BUILD=1 可以跳过提交前的 npm run check,但不应作为常规用法。它只适用于已经在相同提交内容上完成检查,并且能够保留验证证据的场景。

PR 中至少记录以下内容。

  • 关联 Issue 和 I-XXX 记录。
  • 实际修改范围。
  • npm run check 结果。
  • 人工页面检查结果。
  • 未验证项与残余风险。
  • 是否涉及部署配置、路径或回滚策略变化。

八、QA 与发布批准

QA 不能只看构建是否通过。automation/templates/review-report.md 要求同时核对需求验收标准、页面效果、链接、元数据、敏感信息、意外的大范围改动和迭代记录。

只有同时满足以下条件,才能进入发布阶段。

需求已由站长批准
PR 改动范围与需求一致
npm run check 通过
页面人工检查完成
测试报告结论为 qa-passed
迭代记录已更新为 in-review
站长明确批准指定 PR 发布

如果请求中没有明确写出批准发布,默认停止在草稿 PR。不要把批准开发理解为批准生产部署。

九、执行备份发布

发布前再次确认当前分支和构建内容与已批准 PR 一致,然后运行演练。

npm run deploy:dry-run

确认输出中的 SSH 目标、正式站点目录、临时目录、备份目录、删除策略和健康检查 URL。任何目标不符合预期都应停止。

正式发布。

npm run deploy

脚本按以下顺序执行。

  1. 运行 npm run check 并生成最新 dist/。
  2. 用 rsync -az --delete 把 dist/ 上传到远端临时目录。
  3. 以 UTC 时间生成发布编号,例如 20260812T091530Z。
  4. 把当前正式站点完整复制到对应快照目录,并确认快照中存在 index.html。
  5. 把远端临时目录同步到正式站点目录。
  6. 依次请求 DEPLOY_HEALTHCHECK_URLS 中的 URL,每个请求最多等待 20 秒。
  7. 全部通过后输出部署完成信息和回滚快照路径。

如果任一健康检查失败,脚本会执行带 --delete 的恢复同步,用发布前快照覆盖正式站点,并以非零状态退出。

自动回滚成立有一个前提,必须配置 DEPLOY_HEALTHCHECK_URLS。如果该变量为空,脚本会完成文件同步,但不会验证线上页面,也不会因页面异常自动回滚。

十、手动回滚

健康检查只能发现 URL 无法正常返回,无法识别文案错误、视觉错位或业务内容不正确。遇到这类问题时,需要使用部署日志最后输出的快照路径手动回滚。

先确认具体快照,不能对备份根目录使用模糊匹配。假设需要恢复的快照是:

/home/ubuntu/aiguidance-backups/20260812T091530Z

登录服务器并恢复。

ssh ubuntu@example.com
sudo rsync -a --delete \
  /home/ubuntu/aiguidance-backups/20260812T091530Z/ \
  /www/wwwroot/aiguidance.cn/

恢复后重新检查关键 URL,并把回滚原因、快照路径、时间和验证结果写入对应 I-XXX 记录。不要删除失败版本的提交和记录,后续修复需要这些证据。

十一、常见故障定位

npm run iteration:check 失败

常见原因是新 I-XXX 文件没有加入主线索引、文件内状态与索引状态不同、标题编号不匹配,或缺少固定章节。按报错中的文件名修正,不要绕过检查。

npm run check 在构建阶段失败

先单独运行 npm run build 查看 Astro 的完整错误。常见原因包括 Markdown frontmatter 字段缺失、日期格式错误、内容引用路径错误和页面语法错误。

npm run gitee:auth 拒绝令牌文件

检查文件位置、权限和内容行数。

ls -l ../gitee
chmod 600 ../gitee
awk 'NF { count += 1 } END { print count + 0 }' ../gitee

最后一条命令应该输出 1。不要把令牌内容打印到终端或日志。

推送成功但没有 PR

默认 npm run gitee:pr 只推送分支并打印手动创建 PR 的地址。需要自动创建草稿 PR 时,显式增加 GITEE_CREATE_PR=1。

dry-run 通过但正式部署失败

dry-run 不连接服务器。继续检查 SSH 登录、端口、私钥、远端临时目录写权限、sudo rsync 权限和正式站点目录是否存在。

部署成功但旧页面仍然存在

检查 DEPLOY_DELETE。设为 0 时,正式安装不会删除新 dist/ 中不存在的旧文件。只有确认站点目录专属于 Astro 构建产物,才能改为 1。

页面返回 200,但内容不正确

当前健康检查只使用 curl -fsSL 判断请求是否成功,不校验页面正文、哈希或截图。重要发布可以增加发布后 HTML 哈希比较或关键文本断言,但仍应保留人工页面检查。

十二、维护这条管线

管线稳定运行依赖持续维护,不是配置一次后永久有效。

每次新增关键页面时,检查是否需要把构建产物加入 scripts/check.sh 的 required_outputs。修改页面信息架构时,同步调整 SEO 审计和关键文案断言。新增内容类型时,更新 src/content.config.ts 的 schema 和对应页面入口。

调研侧需要定期更新 automation/research/weekly-product-research.json 中的来源、日期、关注词、事实和候选项。已过期的配置不会自动变成新结论,URL 可访问也不代表内容仍然新鲜。

部署侧需要定期检查备份占用空间、恢复命令是否仍可用、SSH key 是否过期、宝塔站点目录是否变化,以及所有健康检查 URL 是否覆盖当前核心路径。

最后保留一条固定原则:自动化负责减少重复操作,审批、证据和回滚负责限制错误影响。只有当调研、PR、发布和恢复连续运行稳定后,才适合评估自动合并或无人值守生产发布。