Ivan's Blog
项目实践

Dockrev

Dockrev 是 self-hosted Docker/Compose update manager。README.md 把根文档定位为快速入口,完整部署、使用、运维、排障和 API 文档在 docs-site/,这说明它是运维工具而不是普通 CRUD 管理台。

  • Responsive web UI
  • UI version display
  • Floating UI tooltip
  • GitHub Actions scheduling
  • Project docs site
  • Worktree bootstrap

目录

技术栈

运行与交付

CI 工作流
  • ci-pr.yml
  • docs-pages.yml
  • notify-failed-workflow.yml
  • notify-release-failure.yml
  • release-completion-pr.yml
  • release-preparation.yml
  • release.yml
  • review-policy.yml
能力标记
  • bun_lock
  • cargo_toml
  • dockerfile
  • github_actions
  • package_json
JSON

Purpose

Dockrev 是 self-hosted Docker/Compose update manager。README.md 把根文档定位为快速入口,完整部署、使用、运维、排障和 API 文档在 docs-site/,这说明它是运维工具而不是普通 CRUD 管理台。

Taxonomy

  • Tags: Responsive web UI, UI version display, Floating UI tooltip, GitHub Actions scheduling, Project docs site, Worktree bootstrap

Repository map

  • src/ 和 crates/ 承载 Rust service/domain;Cargo.toml 是 Axum/ops 服务入口。
  • web/ 是 React/Vite 管理 UI,包含大量 web/tests/*.test.ts(x)、Storybook daemon 和 screenshot capture scripts。
  • docs-site/ 是 Rspress 文档站,docs-pages.yml 负责发布。
  • Dockerfile 与 deploy/ 说明 Dockerized delivery 是核心路径。

Runtime and delivery

文档站脚本由根 package.json 暴露 docs:dev、docs:build、docs:preview,默认端口 50885 可用 DOCS_PORT 覆盖。Web 子项目有 Storybook daemon、screenshot capture、test-storybook 和 Vite build。Dockerfile 把服务作为 deployable artifact 构建。新 linked worktree 的开发前提由 README.md 与 docs-site/docs/quick-start.md 固定为 bun run hooks:install 后执行 bun run bootstrap:worktree;shared post-checkout 会恢复根目录、web/、docs-site/ 的 Bun 依赖并预热 cargo fetch --locked,但不替维护者安装 Bun、Rust、Playwright 或系统包。

Architecture notes

产品模型围绕 Docker/Compose target discovery、digest snapshot、candidate version、release drawer、supervisor health 和 webhook/status。React UI 嵌入在 Rust 服务旁,既是操作台也是状态解释层;floating UI / tooltip 相关依赖说明复杂状态说明不是纯表格文本。

证据锚点:README.md。

Workflow and quality gates

ci-main.yml、ci-pr.yml、docs-pages.yml、release-preparation.yml、release-completion-pr.yml、release.yml、review-policy.yml、notify-release-failure.yml 和 notify-failed-workflow.yml 拆分 PR、main、docs、release、review 和 failure-notification gates。.github/manual-version-release.json 声明唯一发布策略;Release Preparation 只接受必填字符串 version,每次从 main 根 VERSION 计算目标,缺失或无效时失败关闭。它创建只改根 VERSION 的签名身份、冻结来源与目标,并用不可变 reservation 约束同版本身份;创建身份 PR 后还会复查基准,若基准已变化则关闭过期 PR,避免它阻塞下一次准备。.github/quality-gates.json 声明 Review Policy Gate 与 Manual Version Release Completion,并记录精确的旧/目标检查集合及目标工作流契约。.github/scripts/check-live-quality-gates.py 只接受精确的旧规则集或目标规则集;旧集合显式报告为迁移未完成,并从 main 检查目标 workflow 的 pull_request_target、github.workflow_sha checkout 和目标 check 名称。当前 live ruleset 已切换到目标集合 Review Policy Gate 与 Manual Version Release Completion;目标 workflow 已可信地进入 main,GitHub 会在每个 PR 合并前要求这两个检查成功。release-completion-pr.yml 只使用 pull_request_target,并检出 github.workflow_sha 对应的工作流版本,只监听 opened、synchronize、reopened 和 ready_for_review,不监听 edited;项目 contract test 固定这组事件,避免 PR 合并或关闭后的元数据编辑重新触发 required completion gate。Stable、alpha、beta 与 RC 的序号/晋升由 .github/scripts/release_policy.py 校验;major/minor/patch 始终按 main 最新 VERSION 的数值核心计算,预发布输入按同核心通道顺序推进,且不会推进 GHCR latest。.github/workflows/release.yml 为同一身份构建一个包含 Linux binaries、archives、checksums 与文件清单的 bundle;发布前验证清单文件 hash 和 GitHub artifact SHA-256。失败通知携带 identity 与 artifact digest;若身份上下文 artifact 无法下载,则只发送标明身份未验证的运行上下文,不伪造版本身份。同身份恢复复用已完成 bundle。Release Preparation 只负责准备受保护 main PR,当前流程不调用 merge 或 auto-merge;PR 合并后,release.yml 由 main 的 push 自动完成发布。已验证样本是 PR #432 修复 edited 触发、PR #433 合并后的 Release run 和 v0.81.4-beta.1;它们均绑定 merge SHA fbebdb27b9cde15a5fa63faacfdf5e480b969dd8。GITHUB_TOKEN 相关 workflow-run approval 不作为每次发布的固定人工步骤或本项目的 universal blocker 记录。

Reusable decisions

  • 运维工具把完整 docs-site 作为主要文档入口,README 保持短入口。
  • 任何被声明为 expected-success 的 workflow 都必须对最终 failure 可达通知;业务 workflow 负责业务上下文,通用 sidecar 只消费 workflow_run metadata,不能把普通 CI/Docs failure 伪装成 release identity。
  • Storybook 用于 component QA;没有 accessibility addon 证据时不要命名为 accessibility。
  • Docker/Compose update manager 的发布失败必须有通知,因为部署用户依赖 image/artifact 可用性。
  • 手动发版只保留一个 version 决策入口,主干根 VERSION 同时作为身份文件和下一次分配基准;release tag、package manifest 与历史发布记录不能替代它。
  • 预发布序列按 alpha -> beta -> rc -> stable 前进;stable baseline 可直接开始 beta,RC 必须来自相同 numeric core 的 beta lineage,任何跳级或回退都应在分配时拒绝。
  • required-check 迁移必须保留可信执行边界;不得把由待合并改动自行提供的 workflow 当作受信任保护检查。
  • required-check 过渡态要声明旧集合与目标集合;CI 仅容忍精确的已知旧集合,并单独报告 main 上目标 workflow 的可信状态。切换后,目标 check 必须对每个 PR 成功,GitHub 才允许合并。
  • 手动版本发布由 Release Preparation 准备受保护的 VERSION-only 身份 PR,当前 workflow 不自动合并;PR 合并后 main push 触发 Release 发布,workflow_dispatch 只用于同一 merge identity 的恢复。
  • required PR completion gate 的事件集合固定为 opened、synchronize、reopened 和 ready_for_review;edited 默认不参与该 gate,避免合并/关闭后的 PR 元数据编辑制造迟到或错误的 required check。
  • 发布恢复必须固定同一个 merge identity 与已完成 artifact digest;bundle 缺失时才可为同一身份重建,不能重算或替换版本。
  • 把 linked-worktree 依赖恢复收敛在 scripts/bootstrap-worktree.sh,以 lockfile hash 做幂等 stamp,并用 scripts/test-worktree-bootstrap.sh 覆盖首次恢复、缓存命中、跳过开关和缺失工具失败路径。
  • 失败通知配置、workflow 名称和 notification exclusion 必须一起更新并由 contract test 校验;OIDC/Oidrune 的外部 allowlist 仍属于维护者配置,不写进 caller workflow 的 secret。

Risks and open questions

  • live ruleset 是仓库外部配置,可能与 .github/quality-gates.json 漂移;调整必需检查后,应运行 .github/scripts/check-live-quality-gates.py 验证目标集合和 main 上的可信 workflow 状态。
  • 更新动作可能影响真实容器,UI guard 和 backend guard 必须同步。
  • Digest freshness/candidate inference 一旦误判会引导错误升级。
  • docs-site 端口和服务端口要遵守 port lease,不要直接复用默认值。
  • bootstrap 只恢复仓库内依赖,不应把安装 Bun、Rust、Playwright 或系统包混入 checkout hook;缺工具时应给出可操作错误或 skip 开关(scripts/bootstrap-worktree.sh、README.md)。

Evidence index

  • README.md
  • Cargo.toml
  • Dockerfile
  • deploy/
  • docs-site/package.json
  • web/package.json
  • web/.storybook/main.ts
  • web/scripts/capture-storybook-screenshots.mjs
  • web/tests/
  • .github/workflows/ci-main.yml
  • .github/workflows/ci-pr.yml
  • .github/workflows/docs-pages.yml
  • .github/workflows/release-preparation.yml
  • .github/workflows/release-completion-pr.yml
  • .github/workflows/release.yml
  • .github/manual-version-release.json
  • .github/scripts/release_policy.py
  • .github/scripts/check-live-quality-gates.py
  • .github/scripts/release_preparation.py
  • .github/scripts/release_completion.py
  • .github/scripts/release_identity.py
  • .github/scripts/release_artifact_bundle.py
  • .github/scripts/release_recovery_artifact.py
  • .github/workflows/notify-release-failure.yml
  • .github/workflows/notify-failed-workflow.yml
  • .github/release-failure-notification.json
  • .github/scripts/workflow_failure_context.py
  • .github/scripts/test_workflow_failure_notification_contract.py
  • .github/scripts/test_manual_version_release.py
  • .github/scripts/test_release_workflow_contract.py
  • https://github.com/IvanLi-CN/dockrev/pull/432
  • https://github.com/IvanLi-CN/dockrev/pull/433
  • https://github.com/IvanLi-CN/dockrev/actions/runs/37331154606
  • https://github.com/IvanLi-CN/dockrev/releases/tag/v0.81.4-beta.1
  • docs/specs/workflow-failure-notification/SPEC.md
  • docs/specs/release-channel-promotion/SPEC.md
  • docs/release.md
  • scripts/install-hooks.sh
  • scripts/bootstrap-worktree.sh
  • scripts/test-worktree-bootstrap.sh
  • docs-site/docs/quick-start.md