Ivan's Blog 2026
Ivan's Blog 2026 是 Ivan 博客平台的公开开源镜像,由 Astro public site、Vite/React admin SPA 和 Bun gateway/API 组成。README.md、astro.config.mjs、apps/admin/、src/server/ 和 package.
- Progressive web app
- Worktree bootstrap
目录
技术栈
运行与交付
- CI 工作流
- ci.yml
- e2e.yml
- manual-product-release.yml
- notify-release-failure.yml
- playbook-content-rollback.yml
- playbook-content-update.yml
- product-release.yml
- release-merge-followup.yml
- 能力标记
- bun_lock
- docker_compose
- dockerfile
- github_actions
- package_json
依赖与工具
- package.json
- 开发依赖
- @astrojs/react
- @babel/parser
- @biomejs/biome
- @commitlint/cli
- 生产依赖
- @astrojs/markdown-remark
- @astrojs/mdx
- @astrojs/node
- @codemirror/autocomplete
- 项目脚本
- admin:build
- admin:build:compiled
- admin:dev
- admin:preview
配置与质量
- 配置文件
- .dockerignore
- .gitignore
- biome.jsonc
- bunfig.toml
- docker-compose.yml
- lefthook.yml
- package.json
- tsconfig.json
{
"ci_workflows": [
"ci.yml",
"e2e.yml",
"manual-product-release.yml",
"notify-release-failure.yml",
"playbook-content-rollback.yml",
"playbook-content-update.yml",
"product-release.yml",
"release-merge-followup.yml"
],
"configs_root": [
".dockerignore",
".gitignore",
"biome.jsonc",
"bunfig.toml",
"docker-compose.yml",
"lefthook.yml",
"package.json",
"tsconfig.json"
],
"markers_present": [
"bun_lock",
"docker_compose",
"dockerfile",
"github_actions",
"package_json"
],
"package_json": {
"deps_dev": [
"@astrojs/react",
"@babel/parser",
"@biomejs/biome",
"@commitlint/cli",
"@commitlint/config-conventional",
"@happy-dom/global-registrator",
"@iconify-json/line-md",
"@iconify-json/tabler",
"@mdx-js/mdx",
"@storybook/addon-docs",
"@storybook/react-vite",
"@tailwindcss/postcss",
"@tailwindcss/typography",
"@tailwindcss/vite",
"@testing-library/react",
"@types/bun",
"@types/jsdom",
"@types/node",
"@types/react",
"@types/react-dom"
],
"deps_prod": [
"@astrojs/markdown-remark",
"@astrojs/mdx",
"@astrojs/node",
"@codemirror/autocomplete",
"@codemirror/commands",
"@codemirror/lang-yaml",
"@codemirror/state",
"@codemirror/view",
"@earendil-works/chord",
"@earendil-works/pi-ai",
"@earendil-works/pi-durable",
"@fingerprintjs/fingerprintjs",
"@fontsource-variable/inter",
"@iconify-json/bxl",
"@iconify-json/carbon",
"@iconify-json/cib",
"@iconify-json/fa6-brands",
"@iconify-json/game-icons",
"@iconify-json/material-symbols",
"@iconify-json/simple-icons"
],
"scripts": [
"admin:build",
"admin:build:compiled",
"admin:dev",
"admin:preview",
"backend:build",
"backend:dist",
"build",
"build-storybook",
"build:compiled",
"check",
"check:public-no-daisy",
"console:build",
"console:start",
"content:migrate-api-links",
"content:scan-api-links",
"db:migrations:validate",
"db:which",
"demo:memo-list",
"dev",
"dev-data:clean"
]
}
}Purpose
Ivan's Blog 2026 是 Ivan 博客平台的公开开源镜像,由 Astro public site、Vite/React admin SPA 和 Bun gateway/API 组成。README.md、astro.config.mjs、apps/admin/、src/server/ 和 package.json 共同证明这些 runtime 与本地文件内容系统仍然共存;旧的 legacy Next runtime 不再是当前仓库边界。
Taxonomy
- Tags: Progressive web app, Worktree bootstrap
Repository map
site/与astro.config.mjs:Astro public site,output: static、srcDir: ./site、outDir: ./site-dist。apps/admin/:Vite/React admin SPA,admin:dev、admin:build、admin:preview是独立脚本。src/server/与src/lib/:Bun gateway/API、内容服务、版本信息和 release library。public/site.webmanifest与site/layouts/BaseLayout.astro:public site 的 install metadata、apple-touch-icon与rel="manifest"linkage。drizzle/、drizzle.config.ts、scripts/:SQLite migrations、dev data、content sync、gateway、Docker build/release helpers。.github/release-contract.json、scripts/product-release.ts与src/lib/release/:manual version policy、release ledger、双产品 artifact、publication 和 recovery boundary。docs/adr/0015-manual-version-release-delivery.md、docs/adr/0016-signed-release-ledger-and-frozen-products.md、docs/runbooks/manual-version-release.md与docs/specs/manual-version-release/:发布合同、操作手册和实现证据。
Runtime and delivery
本地开发是 Bun-first。README.md 与 AGENTS.md 把 ./scripts/setup.sh / bun run setup 定义为 fresh checkout 或新 worktree 的必需恢复入口;默认入口安装依赖与 hooks、创建 .env.local、租用 worktree-local ports,并准备 dev data,linked worktree 还通过 Lefthook 触发同一 bootstrap。bun run dev 组合 Astro、Admin 和 Bun Gateway;端口由 PORT、SITE_PORT、ADMIN_PORT 管理。交付不是单 artifact:build 拆成 site:build、admin:build:compiled、console:build、backend:dist,Docker 使用 /app/data/sqlite.db。截至 2026-10-10,release delivery 已切换为 manual two-product contract:.github/workflows/manual-product-release.yml 从 main 手动接收 stable/alpha/beta/rc 或 forward-only SemVer,并负责 reservation 与 signed VERSION-only PR;.github/workflows/product-release.yml 在精确 release merge 通过 CI/E2E 后恢复冻结输入、构建 static frontend 与 full-feature Docker image,并按 prerelease/stable 路径发布;.github/workflows/release-merge-followup.yml 负责 release branch 的 exact-main gate follow-up。当前实现状态是 active / partial:full platform validation 与真实 alpha acceptance 仍待完成,本快照不把它们表述为 production 或 alpha 已验收。公开站仍显式挂出 site.webmanifest 并声明 display: standalone,但当前 manifest 的 icons 仍为空数组,install metadata 尚未收口。
Architecture notes
最稳妥的架构记忆是“三个 runtime + 一个 gateway + 一个 SQLite content/settings core + 一个 manual release ledger”。Astro public rendering、Admin editor UI、Bun gateway/API 和 local-file content sync 都是当前事实。AI-backed features 由 OPENAI_API_KEY、CHAT_COMPLETION_MODEL、EMBEDDING_MODEL_NAME 和加密 key 配置;content sync 依赖 local files。发布链把统一版本 identity 绑定到 static frontend 与 full-feature Docker image,保留冻结输入、artifact retention 和同 identity recovery 的边界。
Workflow and quality gates
.github/workflows/ci.yml、e2e.yml、manual-product-release.yml、product-release.yml、release-merge-followup.yml 与 notify-release-failure.yml 把 lint/unit/build/e2e、manual release preparation、product publication、merge follow-up 和 failure notification 拆开;.github/quality-gates.json、docs/version-impact/manual-product-release.json 以及 tests/lib/manual-release-*.test.ts 提供 release policy、impact 和 recovery 证据。package.json 本地门禁包括 Biome、Bun tests、Playwright、DB migration validation、public-no-daisy 和 Storybook build。full platform validation 与真实 alpha acceptance 仍是开放门禁,不应由现有 unit/fixture evidence 推断完成。
Reusable decisions
- 不要用
Astro site、React app或TypeScript web单标签吞掉所有 runtime;public site、Admin SPA、Bun gateway 和 release library 仍需按边界分别维护。 - 新 worktree 不一定需要隐式 hook 自动恢复;当
README.md与AGENTS.md明确要求运行同一个 repo-owned setup,且默认入口统一依赖、hooks、端口检查与 dev DB seed,并通过显式 flag 提供可选 E2E browser runtime 时,也构成可审查的Worktree bootstrapcontract(scripts/setup.sh)。 - 版本发布应以
Manual version release delivery为当前 Topic:手动输入、唯一 release identity、受保护的VERSION-only PR、冻结双产品 artifact 和同 identity recovery 分阶段验证;不能从 PR 元数据或历史流程推导版本真相(.github/release-contract.json、scripts/product-release.ts)。 - release failure notification 作为 sidecar workflow,避免污染 release build logic。
- 公开站如果要保留 install surface,
site.webmanifest应和实际 layout 入口一起维护;否则最容易出现“有 manifest 但没有完整 icons/runtime contract”的半成品状态。
Risks and open questions
- route/env/API 改动要同时验证 Astro、Admin 和 Bun Gateway。
- release implementation 目前是
active / partial;full platform validation、真实 alpha acceptance、外部发布目标和 recovery 的实际平台演练仍需单独完成。 - static frontend 与 full-feature image 必须共享 release identity 和冻结输入;任一 artifact 或平台步骤失败时,应沿 ledger recovery 路径处理,不能把单个 workflow 绿色当成完整交付证明。
- Storybook 当前证明 admin component docs/QA;没有 Storybook a11y addon 证据时,不能把它过度命名为 accessibility。
- 当前
public/site.webmanifest的icons为空数组,说明 PWA install metadata 尚未收口完成;后续若真要支持安装体验,需要先补齐 icons 与更明确的运行时边界。
Evidence index
README.mdAGENTS.mdpackage.jsonscripts/setup.shlefthook.ymlastro.config.mjssite/layouts/BaseLayout.astroapps/admin/site/src/drizzle.config.tsDockerfiledocker-compose.ymlplaywright.config.ts.storybook/main.tssrc/server/public/site.webmanifest.github/quality-gates.json.github/release-contract.json.github/workflows/ci.yml.github/workflows/e2e.yml.github/workflows/manual-product-release.yml.github/workflows/product-release.yml.github/workflows/release-merge-followup.yml.github/workflows/notify-release-failure.ymlscripts/product-release.tssrc/lib/release/docs/adr/0015-manual-version-release-delivery.mddocs/adr/0016-signed-release-ledger-and-frozen-products.mddocs/runbooks/manual-version-release.mddocs/specs/manual-version-release/SPEC.mddocs/specs/manual-version-release/IMPLEMENTATION.mddocs/version-impact/manual-product-release.jsonhttps://github.com/IvanLi-CN/blog-26/commit/f383c2ba2c81cc330670fea44eff17442f02bc9ehttps://github.com/IvanLi-CN/blog-26/commit/260692f8be487574ee6227c81f65be4a576a2f6a