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.
- Astro site
- TypeScript web
- React app
- Progressive web app
- Playwright e2e
- Dockerized dev
- SQLite
- Manual version release delivery
- Release failure notification
- Storybook component QA
- 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: Astro site, TypeScript web, React app, Progressive web app, Playwright e2e, Dockerized dev, SQLite, Manual version release delivery, Release failure notification, Storybook component QA, Worktree bootstrap
- Why / evidence: 这些 tags 来自 checked-out repo 和 catalog record。主要证据包括
README.md、AGENTS.md、package.json、scripts/setup.sh、lefthook.yml、astro.config.mjs、apps/admin/、site/、src/server/、src/lib/release/、drizzle.config.ts、site/layouts/BaseLayout.astro、public/site.webmanifest、.github/release-contract.json、.github/workflows/manual-product-release.yml、.github/workflows/product-release.yml、.github/workflows/release-merge-followup.yml。Topic token 的大小写以对应技术/工作流的官方写法为准;slug 只作为稳定 ID,不直接充当项目标题。
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
相关内容
Astro site
主题Astro site 用于标记把 Astro 作为 public/static site 交付面的项目。它不等同于“整个仓库都是 Astro 应用”:在当前代表项目里,Astro 负责面向读者的 public content rendering 和 static export,而 admin SPA、gateway、API 或 legacy runtime 由其他边界承担。关键证据通常包括 astro.config.
Dockerized dev
主题Dockerized dev 标记 Dockerfile、Compose 或 container build 是本地开发、集成验证或部署交付的一等路径。它不表示“仓库里偶然有 Dockerfile”,而是 Docker 影响运行环境、数据卷、端口、build args、嵌入式前端产物或 release artifact。
Next.js app
主题Next.js app 在当前 playbook 中表示 Next.js 仍承担项目的 current runtime、API、preview 或 compatibility surface。它不一定意味着整个项目是纯 Next.js;在 Ivan 博客项目中,它是 legacy internal runtime,与 Astro public site 和 React admin SPA 共存。
Playwright e2e
主题Playwright e2e 指仓库把真实浏览器里的关键用户流程当成正式质量门禁,而不是“顺手写了几条页面脚本”。它强调的是产品行为验证:路由、认证、交互链路、浏览器 API、嵌入式控制台或多 runtime 页面组合,必须在接近真实使用路径的浏览器环境里被证明可用(projects/blog-26.md、projects/proxy-broker.md、projects/octo-rill.
PR label release
主题PR label release 是逐 PR 的产品发布协议:PR labels 只提供经过 gate 验证的发布操作与发布阶段;最高的合格 final vX.Y.Z Git release tag 是唯一数字版本基线,VERSION 只锁定 trusted preparation 已决定的精确产品版本。label 不能计算、覆盖或为版本提供 fallback。
Progressive web app
主题Progressive web app 在这套 playbook 里不是“网页顺手带个 manifest”的统称,而是“把一个 Web surface 当成可安装应用去维护”的工程模式。
React app
主题React app 标记 React 是主要用户界面、管理台、控制台或嵌入式操作面 runtime。这里关心的是 route、component tree、client state、表单流、dashboard 交互和前端构建后的真实运行边界,而不是“项目依赖里有 React”。 这个 Topic 用来回答“用户实际操作的是不是一个 React runtime,以及它在系统里承担什么职责”。
README content contract
主题README content contract 是面向项目入口文档的可审查规范:README 先让目标读者理解产品、边界和下一步,再提供可复现的 Quick Start、集成 contract、交付语义、文档真相源、许可证入口、有限产品 preview,以及有来源的 Logo 和 Badge 入口。
Release failure notification
主题Release failure notification 指一个仓库为所有“预期成功但最终以 failure 结束”的交付 workflow 建立显式、可审查的告警路径。范围包括 release、deploy、CI、Docs Pages 和 required gate,但必须由 checked-in allowlist 声明;成功、skipped、cancelled 和通知 workflow 自身不属于通知条件。
Service ports
主题Service ports 表示端口号、bind 地址、dev/prod 暴露方式和多组件端口分工本身就是仓库的稳定 contract。它不是“服务都会有端口”这种空泛事实,而是说端口设计会直接影响本地预览、反向代理、权限边界、自动化脚本和故障排查。 这个 Topic 关注的是端口作为系统边界的那一面。
SQLite
主题SQLite 表示项目把 SQLite 作为默认持久层、ledger、audit log、content/settings store 或低运维 embedded database,并围绕它建立路径、schema、迁移、volume、备份和运行时 ownership 约定。它不是“依赖树里有 sqlite”这么宽,而是数据库文件本身已经成为系统 contract 的一部分。
Storybook component QA
主题Storybook component QA 表示仓库把 Storybook 当作组件级文档、状态枚举、视觉检查或 interaction smoke 的稳定入口。它不等同于 Storybook accessibility:只有项目明确引入 a11y addon 或等价 Axe sweep 时,才同时打 accessibility Topic。这个拆分用于避免“只要有 Storybook 就叫 a11y”的误判。
TypeScript web
主题TypeScript web 表示项目把 TypeScript 作为一个或多个 Web surface 的主语言,并围绕它建立 workspace scripts、typecheck、bundler、lint/format、env contract 和前端构建门禁。这里的主语不是“仓库里出现了 .ts 文件”,而是 TypeScript 已经决定了维护者怎样启动、构建、校验和交付实际 Web surface。
Worktree bootstrap
主题Worktree bootstrap 表示仓库把 linked worktree 的“首次进入可开发状态”当成正式 contract 来维护,而不是依赖维护者记忆、散落且无统一入口的手工 checklist,或假定只有主工作区才值得被照顾。