From 010d604475f7f6b7b29a8bd3f64502682bdfcfdd Mon Sep 17 00:00:00 2001 From: Nightt <87569709+nightt5879@users.noreply.github.com> Date: Fri, 27 Mar 2026 14:26:53 +0800 Subject: [PATCH] build: harden 1.1.2 verification flow --- .github/workflows/ci.yml | 15 ++---------- CHANGELOG.md | 7 ++++++ README.md | 17 ++++++------- README_EN.md | 18 +++++++------- content-map.md | 5 ++-- docs/content-edit-guide.md | 4 +-- docs/content-ops-checklist.md | 8 ++---- docs/hand-off-summary.md | 6 ++--- docs/local-preview.md | 2 +- docs/release-baseline-checklist.md | 13 +++++----- docs/roadmap.md | 11 +++++++-- docs/zero-code-ops-playbook.md | 4 +-- package-lock.json | 4 +-- package.json | 7 +++--- scripts/build-site.mjs | 31 ++++++++++++++++++++++++ scripts/verify.mjs | 39 ++++++++++++++++++++++++++++++ verify.bat | 28 +++------------------ 17 files changed, 129 insertions(+), 90 deletions(-) create mode 100644 scripts/build-site.mjs create mode 100644 scripts/verify.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 353965d..41a1a9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,8 +9,6 @@ on: jobs: verify: runs-on: ubuntu-latest - env: - ASTRO_TELEMETRY_DISABLED: '1' steps: - name: Checkout uses: actions/checkout@v4 @@ -24,14 +22,5 @@ jobs: - name: Install dependencies run: npm ci - - name: Validate content - run: npm run validate:content - - - name: Build site - run: npm run build - - - name: Smoke test built routes - run: npm run test:smoke - - - name: Verify SEO and locale alternates - run: npm run test:seo + - name: Run full verification + run: npm run verify diff --git a/CHANGELOG.md b/CHANGELOG.md index b253a16..6384e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## [1.1.2] - 2026-03-27 + +### Changed +- Unified the verification entrypoint around `npm run verify` and `verify.bat` to keep local, Windows, and CI checks aligned. +- Tightened the build flow so verification uses clean build output instead of relying on existing `dist/` artifacts. +- Updated the release and ops documentation to describe `1.1.2` as stability hardening, without adding outward site features. + ## [1.1.1] - 2026-03-26 ### Added diff --git a/README.md b/README.md index a29f235..c216581 100644 --- a/README.md +++ b/README.md @@ -29,10 +29,7 @@ git clone https://github.com/nightt5879/doubleducklab.git cd doubleducklab npm install -npm run validate:content -npm run build -npm run test:smoke -npm run test:seo +npm run verify npm run preview ``` @@ -161,18 +158,19 @@ venue: "Conference Name" ## 验证链路 +- `npm run verify` + - 推荐的一键验收入口,依次执行 `validate:content`、`build`、`test:smoke`、`test:seo` + - 统一本地、Windows 和 CI 的稳定性检查流程 - `npm run validate:content` - 校验站点文案、成员、项目、论文、新闻、招生与合作的文件结构 - `npm run build` - - 生成静态站点 + - 生成静态站点,并默认清理旧 `dist/` 与关闭 Astro telemetry - `npm run test:smoke` - 检查 `/`、`/en/`、`/members`、`/projects`、`/papers`、`/news` 的构建结果 - `npm run test:seo` - 检查 canonical、Open Graph、hreflang、404 noindex 与当前页语言互跳 - `verify.bat` - - 依次执行 `validate:content`、`build`、`test:smoke`、`test:seo` - - 自动设置 `ASTRO_TELEMETRY_DISABLED=1` - - 适合 Windows 下双击或命令行一键验收 + - Windows 下的一键验收入口,与 `npm run verify` 保持一致 ## 文档入口 @@ -186,7 +184,8 @@ venue: "Conference Name" - `1.0.1`:基线修复,修乱码、收真源、补 CI / smoke - `1.1.0`:生产域名、SEO 元信息、当前页中英互跳与构建后 SEO 校验 -- `1.1.1`:review follow-up,修 alternate 可用性、内部链接 URL 一致性与 `test:seo` 站点地址读取 +- `1.1.1`:review follow-up,修 alternate 可用性、内部链接 URL 一致性与 `test:seo` 站点地址读取,已完成 +- `1.1.2`:稳定性硬化,统一 `verify` 入口、干净构建与发布验收流程 - `1.2.0`:先给 `news` 接 CMS ## License diff --git a/README_EN.md b/README_EN.md index 537a9c2..a343631 100644 --- a/README_EN.md +++ b/README_EN.md @@ -29,10 +29,7 @@ A bilingual Astro template for academic lab websites, built around a local-first git clone https://github.com/nightt5879/doubleducklab.git cd doubleducklab npm install -npm run validate:content -npm run build -npm run test:smoke -npm run test:seo +npm run verify npm run preview ``` @@ -161,18 +158,20 @@ venue: "Conference Name" ## Validation Pipeline +- `npm run verify` + - Recommended one-click verification entrypoint + - Runs `validate:content`, `build`, `test:smoke`, and `test:seo` in order + - Keeps local, Windows, and CI verification aligned - `npm run validate:content` - Validates site copy and all content collections - `npm run build` - - Produces the static site + - Produces the static site with a clean `dist/` and telemetry disabled by default - `npm run test:smoke` - Checks the built `/`, `/en/`, `/members`, `/projects`, `/papers`, and `/news` routes - `npm run test:seo` - Checks canonical tags, Open Graph metadata, hreflang alternates, 404 noindex, and current-page locale switching - `verify.bat` - - Runs `validate:content`, `build`, `test:smoke`, and `test:seo` in order - - Sets `ASTRO_TELEMETRY_DISABLED=1` automatically - - Useful for a one-click verification pass on Windows + - Windows one-click verification entrypoint kept in sync with `npm run verify` ## Docs @@ -186,7 +185,8 @@ venue: "Conference Name" - `1.0.1`: baseline hardening, encoding fix, source-of-truth cleanup, CI and smoke coverage - `1.1.0`: production site URL, SEO metadata, current-page locale switching, and post-build SEO checks -- `1.1.1`: review follow-up for alternate availability, internal URL consistency, and `test:seo` site URL loading +- `1.1.1`: review follow-up for alternate availability, internal URL consistency, and `test:seo` site URL loading, completed +- `1.1.2`: stability hardening, unified verification entrypoint, and clean-build guardrails - `1.2.0`: CMS pilot for `news` ## License diff --git a/content-map.md b/content-map.md index 7575241..72229e5 100644 --- a/content-map.md +++ b/content-map.md @@ -92,6 +92,7 @@ ## 8. 验证链路 +- 推荐一键验收:`npm run verify` - 内容校验:`npm run validate:content` - 构建:`npm run build` - 构建后 smoke:`npm run test:smoke` @@ -101,6 +102,4 @@ 1. 不再使用 `src/data/content/*`。 2. 改内容优先改 `src/data/site.*.json` 或 `src/content/*`,不要先改页面模板硬编码。 3. 改完内容后至少跑一次: - - `npm run validate:content` - - `npm run build` - - `npm run test:smoke` + - `npm run verify` diff --git a/docs/content-edit-guide.md b/docs/content-edit-guide.md index 94fae51..1cd15ce 100644 --- a/docs/content-edit-guide.md +++ b/docs/content-edit-guide.md @@ -126,9 +126,7 @@ venue: "Conference Name" 在项目根目录执行: ```bash -npm run validate:content -npm run build -npm run test:smoke +npm run verify ``` ## 5. 如何预览 diff --git a/docs/content-ops-checklist.md b/docs/content-ops-checklist.md index 3cd2d0f..455adfe 100644 --- a/docs/content-ops-checklist.md +++ b/docs/content-ops-checklist.md @@ -22,9 +22,7 @@ git checkout -b content/YYYYMMDD-topic 3. 运行检查 ```bash -npm run validate:content -npm run build -npm run test:smoke +npm run verify ``` 4. 本地预览确认 @@ -75,8 +73,6 @@ git push origin content/YYYYMMDD-topic ## C. 交付前 30 秒检查 - [ ] 内容改动只落在 `src/data/site.*.json` 或 `src/content/*` -- [ ] `npm run validate:content` 通过 -- [ ] `npm run build` 通过 -- [ ] `npm run test:smoke` 通过 +- [ ] `npm run verify` 通过 - [ ] 中英文页面都看过 - [ ] PR 描述写清楚影响范围 diff --git a/docs/hand-off-summary.md b/docs/hand-off-summary.md index f809f17..b68bb9f 100644 --- a/docs/hand-off-summary.md +++ b/docs/hand-off-summary.md @@ -18,10 +18,8 @@ - 招生与合作:`src/content/join/recruitment/` ### 3. 工程验证 -- `npm run validate:content` -- `npm run build` -- `npm run test:smoke` -- GitHub Actions CI:PR / `main` 自动跑校验、构建、smoke +- `npm run verify` +- GitHub Actions CI:PR / `main` 自动跑统一验收链路(内容校验、构建、smoke、SEO) ## 二、1.0.1 做了什么 diff --git a/docs/local-preview.md b/docs/local-preview.md index 41b1e30..87683f7 100644 --- a/docs/local-preview.md +++ b/docs/local-preview.md @@ -13,7 +13,7 @@ npm run dev ## 3. 生产构建验证 ```bash -npm run build +npm run verify npm run preview ``` diff --git a/docs/release-baseline-checklist.md b/docs/release-baseline-checklist.md index b661044..1f88b15 100644 --- a/docs/release-baseline-checklist.md +++ b/docs/release-baseline-checklist.md @@ -1,4 +1,4 @@ -# Release Baseline Checklist(1.1.0) +# Release Baseline Checklist(1.1.2) ## 0. 环境要求 - Node.js 18+ @@ -8,10 +8,7 @@ ```bash npm install -npm run validate:content -npm run build -npm run test:smoke -npm run test:seo +npm run verify ``` Windows 可直接运行: @@ -36,6 +33,7 @@ verify.bat ## 3. 通过标准 +- [ ] `verify` 通过 - [ ] `validate:content` 通过 - [ ] `build` 通过 - [ ] `test:smoke` 通过 @@ -47,8 +45,9 @@ verify.bat ## 4. 失败排查 +- `verify` 失败:先看卡在哪一步,再对应下方各项逐一排查 - `validate:content` 失败:优先检查 frontmatter、语言配对、文件路径 -- `build` 失败:检查页面 import、字段拼写、内容集合命名 +- `build` 失败:检查页面 import、字段拼写、内容集合命名,以及是否有旧 `dist/` 干扰 - `test:smoke` 失败:优先检查页面静态文案是否被误删或再次出现乱码 - `test:seo` 失败:优先检查 `PUBLIC_SITE_URL`、语言路由映射与布局层 meta 输出 -- `verify.bat` 失败:先看停在哪一步,再对应上面三项逐一排查 +- `verify.bat` 失败:先看停在哪一步,再对应上面各项逐一排查 diff --git a/docs/roadmap.md b/docs/roadmap.md index 4e7ddb2..756daaa 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # Roadmap -更新时间:2026-03-26(1.1.1 follow-up) +更新时间:2026-03-27(1.1.2 stability hardening) ## 1.0.1 基线修复 @@ -19,13 +19,20 @@ - 当前页面中英互跳 - build 后补 SEO / i18n 校验 -## 1.1.1 SEO / URL follow-up(进行中) +## 1.1.1 SEO / URL follow-up(已完成) 计划项: - alternate / hreflang 按对侧页面存在性输出 - 站内内部链接统一为 canonical 尾斜杠形式 - `test:seo` 与 build 共用站点 URL 解析逻辑 +## 1.1.2 Stability hardening + +已完成: +- 统一 `verify` 作为本地、Windows 和 CI 的验收入口 +- 让构建流程默认走干净产物,避免旧 `dist/` 影响验收 +- 收口发布验收与文档叙事,保持对外行为不变 + ## 1.2.0 CMS 试点 计划项: diff --git a/docs/zero-code-ops-playbook.md b/docs/zero-code-ops-playbook.md index 52a9bc9..ca932b3 100644 --- a/docs/zero-code-ops-playbook.md +++ b/docs/zero-code-ops-playbook.md @@ -37,9 +37,7 @@ ## 2. 每次修改后的标准验证 ```bash -npm run validate:content -npm run build -npm run test:smoke +npm run verify ./run.sh ``` diff --git a/package-lock.json b/package-lock.json index 0ef5d78..1494922 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "double-duck-lab", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "double-duck-lab", - "version": "1.1.1", + "version": "1.1.2", "devDependencies": { "astro": "^5.13.0", "vite": "^6.4.1" diff --git a/package.json b/package.json index 40bd24a..d1ca5e5 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,17 @@ { "name": "double-duck-lab", "type": "module", - "version": "1.1.1", + "version": "1.1.2", "private": true, "scripts": { "dev": "astro dev", - "build": "astro build", + "build": "node scripts/build-site.mjs", "preview": "astro preview", "astro": "astro", "validate:content": "node scripts/validate-content.mjs", "test:smoke": "node scripts/smoke-build.mjs", - "test:seo": "node scripts/verify-seo-i18n.mjs" + "test:seo": "node scripts/verify-seo-i18n.mjs", + "verify": "node scripts/verify.mjs" }, "devDependencies": { "astro": "^5.13.0", diff --git a/scripts/build-site.mjs b/scripts/build-site.mjs new file mode 100644 index 0000000..1684efb --- /dev/null +++ b/scripts/build-site.mjs @@ -0,0 +1,31 @@ +#!/usr/bin/env node +import { spawnSync } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; + +const distDir = path.resolve('dist'); +const astroEntry = path.resolve('node_modules/astro/astro.js'); + +fs.rmSync(distDir, { recursive: true, force: true }); + +if (process.env.ASTRO_TELEMETRY_DISABLED === undefined) { + process.env.ASTRO_TELEMETRY_DISABLED = '1'; +} + +const result = spawnSync(process.execPath, [astroEntry, 'build'], { + stdio: 'inherit', + env: process.env, + shell: false, +}); + +if (result.error) { + console.error(result.error.message); + process.exit(1); +} + +if (result.signal) { + console.error(`Build interrupted by signal ${result.signal}`); + process.exit(1); +} + +process.exit(result.status ?? 1); diff --git a/scripts/verify.mjs b/scripts/verify.mjs new file mode 100644 index 0000000..719afd3 --- /dev/null +++ b/scripts/verify.mjs @@ -0,0 +1,39 @@ +#!/usr/bin/env node +import { spawnSync } from 'node:child_process'; + +const npmExecPath = process.env.npm_execpath; +const steps = [ + 'validate:content', + 'build', + 'test:smoke', + 'test:seo', +]; + +if (!npmExecPath) { + console.error('[verify] npm_execpath is not set. Run this script via `npm run verify`.'); + process.exit(1); +} + +steps.forEach((scriptName, index) => { + console.log(`[verify] step ${index + 1}/${steps.length}: npm run ${scriptName}`); + + const result = spawnSync(process.execPath, [npmExecPath, 'run', scriptName], { + stdio: 'inherit', + shell: false, + env: process.env, + }); + + if (result.error) { + console.error(`[verify] failed to start npm run ${scriptName}: ${result.error.message}`); + process.exit(1); + } + + if (result.signal) { + console.error(`[verify] interrupted during npm run ${scriptName}: ${result.signal}`); + process.exit(1); + } + + if ((result.status ?? 1) !== 0) { + process.exit(result.status ?? 1); + } +}); diff --git a/verify.bat b/verify.bat index e537f79..0ea850d 100644 --- a/verify.bat +++ b/verify.bat @@ -19,36 +19,14 @@ if not exist node_modules ( ) ) -echo [verify.bat] step 1/4: validate content -call npm.cmd run validate:content +echo [verify.bat] running npm run verify +call npm.cmd run verify if errorlevel 1 ( set "EXIT_CODE=%ERRORLEVEL%" goto finish ) -echo [verify.bat] step 2/4: build site -set "ASTRO_TELEMETRY_DISABLED=1" -call npm.cmd run build -if errorlevel 1 ( - set "EXIT_CODE=%ERRORLEVEL%" - goto finish -) - -echo [verify.bat] step 3/4: smoke test built routes -call npm.cmd run test:smoke -if errorlevel 1 ( - set "EXIT_CODE=%ERRORLEVEL%" - goto finish -) - -echo [verify.bat] step 4/4: verify SEO and locale alternates -call npm.cmd run test:seo -if errorlevel 1 ( - set "EXIT_CODE=%ERRORLEVEL%" - goto finish -) - -echo [verify.bat] success: validation, build, smoke test, and SEO checks all passed. +echo [verify.bat] success: npm run verify completed successfully. :finish if not "%EXIT_CODE%"=="0" (