自动化 Git 时间戳:GitHub App 如何为每一次提交锚定时间
你推送了一次重要的提交——那是某个功能的核心,日后可能会有人要求你证明自己是最先构建它的人。在手动方式下,这一刻正是你的流程中断之时。你停下来,切换上下文,开始一套小小的仪式:调用本地工具、处理证明文件,把这次提交钉在某个时间点上。然后下一次提交你又得再来一遍,再下一次又一遍,直到有一天你忘了。
这就是手动打时间戳的陷阱。现有技术记录(prior-art records)的强度取决于其密度和规律性,而依赖人工流程的记录两者都不具备。开发者在赶工时跳过这一步,在新机器上配置错误,或者干脆没在真正重要的那个仓库上设置。链条中的缺口,正是对方律师或审计人员要找的东西。
本文讲的是如何通过 GitHub App 实现自动化 Git 时间戳,彻底把人类从这个循环中移除。一次安装,之后对受监控仓库的每一次提交都会被指纹化,并在每晚锚定进比特币——由机器按计划执行,无需任何人输入命令。
这是一篇自动化操作指南,不是密码学深度解析。关于为什么要这么做,请参阅《保护知识产权:软件开发人员指南》和《软件初创企业的现有技术保护:指南》。关于日后如何核验证明的机制,请参阅《无需共享源代码即可验证代码时间戳》。
(背景说明:原始做法是每次提交都手动运行 OpenTimestamps 工具,并自行管理日历服务器提交。那是硬核路线。下文所述全是自动化路径。)
一次性设置:安装 GitHub App,然后忘掉它
Timestamp GIT 是一个围绕 GitHub App 构建的托管式 SaaS。你只需针对一个仓库或整个组织安装一次,之后自动化就会接管。
有两种部署模式,你根据自己愿意授予多少访问权限来选择:
标准模式(GitHub App)。 GitHub App 只读取受监控仓库的 HEAD 提交哈希——每次推送时自动读取。证明文件会写入同一仓库的专用分支,或写入一个独立的影子仓库。由于 GitHub 的权限模型不提供“仅提交哈希”这一范围,此模式需要对源仓库的只读访问权限,以及对证明文件落地的目标仓库的读写访问权限。
企业 ZK 模式(GitHub Action)。 采集步骤移入你自己的 CI。一个 12 行的 GitHub Action 在你的 runner 上运行,提取 HEAD 哈希,并只把该哈希推送到 Timestamp GIT API。权衡很明确:读取权限留在你手里,Timestamp GIT 只需要对目标仓库的读写权限。源代码和仓库读取权限都绝不跨越边界。
关于设置,有两点值得注意:
- 开发者机器上什么都不装。 没有 CLI,没有本地守护进程,没有每台笔记本的配置漂移。App 运行在 GitHub 的基础设施和我们的后端上;Action 运行在 GitHub 托管或自托管的 runner 上。
- 没有持续的配置工作。 安装后,App 通过 webhook 检测新提交。没有人需要记住任何事。
安装后,你可以在你的仓库页面查看和管理哪些仓库受到监控。
自动化流水线:从提交到比特币锚定
App 安装完成后,从 git push 到不可篡改的证明文件出现在你的仓库中,实际发生的是以下过程。
1. 提交检测与批处理
有新提交时 webhook 会触发。App——或在企业 ZK 模式下由你的 Action——提取提交哈希,并将其放入内存键值存储。该存储是队列,不是账本;它存在的唯一目的就是累积哈希,直到夜间批处理运行。
只有哈希在流动。绝不会有 diff,绝不会有文件内容,绝不会有分支历史。
2. 午夜 cron worker
每晚,一个 worker 会取出所有待处理的哈希,并:
- 按仓库分组,为每个仓库写一个清单文件(
.txt)。 - 在该批次上原生构建一棵 Merkle 树。
- 使用公共日历服务器创建 OpenTimestamps 证明。
- 将 Merkle 根锚定进比特币区块链。
最后一步正是让记录不可篡改的关键。一旦根在某个比特币区块中得到确认,任何实体——包括 Timestamp GIT——都无法事后更改或伪造它。
3. 证明文件交付
锚定完成后,清单文件和对应的 .ots 收据文件会被推送回你的仓库,放在专用的 timestamps 分支或影子仓库中。
为此预留几个小时。比特币确认通常需要约 3 小时,所以证明文件一般在夜间运行后几小时才落地,而不是立即。
企业 ZK 模式:唯一带工作流文件的模式
这是你唯一会看到 YAML 的地方。设置向导会生成预填好端点和密钥的工作流;大致如下:
name: Timestamp commit hash
on: [push]
jobs:
anchor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Send HEAD hash to Timestamp GIT
env:
TSG_ENDPOINT: ${{ secrets.TIMESTAMPGIT_ENDPOINT }}
run: curl -fsS -X POST "$TSG_ENDPOINT" --data "$(git rev-parse HEAD)"
整个集成就这么点。如果你想深入了解这个模式,有一篇专门的指南:《用于提交时间戳的 GitHub Action:设置指南》。
自定义流水线:ZK Commit API
如果你需要把时间戳功能嵌入标准流程之外的地方,ZK Commit API 可以直接接收提交哈希。它使用 HMAC 认证——签名 URL 中的哈希值必须随请求一起提供——所以仅凭泄露的 URL 不足以写入你的账本。
对于只读自动化,公共状态端点更简单:
# Last anchored Bitcoin block for a repo
curl -s https://timestampgit.dev/api/statusLast/your-org/your-repo
# Total stamped commit count
curl -s https://timestampgit.dev/api/statusCount/your-org/your-repo
# Combined summary (what the Shields.io badge consumes)
curl -s https://timestampgit.dev/api/statusSummary/your-org/your-repo
监控与故障处理
你无法审计的自动化,不是你在纠纷中能信任的自动化。Timestamp GIT 在三个地方暴露你的证明链状态。
公共状态仪表盘
/status/{user}/{repo} 显示证明的存续时长、最早的锚定日期、每日规律性,以及每次锚定背后的比特币区块和交易数据。还有一个日历热力图,让缺口一目了然,另有可下载的审计 CSV 和 PDF 证书导出。
规律性是值得关注的指标。有洞的热力图,其现有技术说服力弱于一张密实的热力图。
验证徽章
你可以在 README 中嵌入 Shields.io 徽章,公开显示验证状态。/connected/{user}/{repo} 处的组件提供实时预览和 markdown 片段,/api/badgeLink/{user}/{repo} 则以编程方式返回徽章 URL 和片段。
私有仓库会在徽章和状态 URL 后附加一个加密的 HMAC,作用域限定于该服务器实例。这意味着徽章仍能渲染,而只有授权用户才能解析底层的状态数据。
当夜间运行失败时
最可能的失败是比特币网络拥堵导致确认延迟。系统会重试,而不是丢弃该批次。通过仪表盘查看状态,或者如果你要接入自己的告警系统,就通过 API 查看:
# Confirm the latest anchored block; a stale value means the last run didn't land
curl -s https://timestampgit.dev/api/statusLast/your-org/your-repo | jq .
如果你需要用于合规的时点证据,直接拉取产物:
# Full audit ledger as CSV
curl -sO https://timestampgit.dev/api/audit/your-org/your-repo
# PDF certificate for a specific date
curl -sO https://timestampgit.dev/api/report/your-org/your-repo/2026-10-04
任何人都还可以通过 /verification/{user}/{repo}/{date} 独立验证某一天的时间戳,完整的 Merkle 链计算在浏览器本地完成。没有人——包括 Timestamp GIT——能看到你验证了什么。
气隙环境
如果你的安全策略完全不允许使用托管服务,Timestamp GIT 也以 Docker 镜像形式发布。一个快速开始的 Docker Compose 配置大致如下:
services:
timestampgit:
image: rue1401/timestampgit:prod
ports:
- "8080:8080"
volumes:
- ./data:/app/data
restart: unless-stopped
valkey:
image: valkey/valkey:8
restart: unless-stopped
docker compose pull
docker compose up -d
docker compose logs -f timestampgit
启动后,应用可在 http://localhost:8080 访问,首次启动时会有设置向导引导你连接 GitHub App 并配置实例。用于评估的限时演示许可证可通过 Docker License 页面获取。《使用 Docker 自托管区块链时间戳》详细介绍了这条路径。
自动化时间戳的最佳实践
- 定期提交,块大小合理。 每一次提交都会为当天的 Merkle 树增加一片叶子。密集的链条比每季度四次巨型提交更有现有技术说服力。
- 写有意义的提交信息。 只有哈希会被打时间戳,但审计时你需要把证明与功能对应起来。好的提交信息让这种映射变得轻而易举。
- 为锚定过期配置告警。 绿色徽章应该意味着最近一次运行成功,而不是三月份运行过一次。
- 别动那个工作流。 自动化时间戳最大的风险就是有人去“改进”流水线。默认设置没有手动步骤是有原因的。
- 当源代码不能被读取时,采用企业 ZK 模式。 如果合规要求禁止向第三方授予仓库读取权限,就在你自己的 runner 上运行该 Action。
- 告诉你的团队这是自动的。 以为打时间戳是手动任务的工程师,最终会尝试手动去做,而重复或格式错误的条目就是这么来的。
你可以从 timestampgit.dev 开始——安装 App,连接一个仓库,让第一批夜间批处理跑起来。
常见问题
问:使用自动化时间戳需要改变我的 Git 工作流吗? 答:不需要。安装 Timestamp GIT GitHub App 后,它会通过 webhook 自动检测新提交,并在每晚为其打时间戳。你照常提交即可——无需额外命令或步骤。
问:如果我使用多个分支或多个仓库会怎样? 答:GitHub App 会监控你授予访问权限的仓库中的所有分支。你也可以配置监控哪些仓库。对于多个仓库,每个仓库都有自己的清单和证明文件。
问:我的源代码会暴露给 Timestamp GIT 吗? 答:不会。在标准模式下,App 只读取 HEAD 提交哈希——绝不读取你的源代码。在企业 ZK 模式下,你基础设施上的 GitHub Action 只把提交哈希推送到我们的 API,所以你的代码绝不离开你的环境。
问:一次提交需要多久才能被打上时间戳?
答:提交哈希每晚批量锚定进比特币一次。夜间运行后,比特币交易通常需要约 3 小时确认,之后 .ots 证明文件会被推送回你的仓库。
结语
手动打时间戳之所以失败,原因和所有手动合规一样:它依赖于一个人每一次、永远地记住。GitHub App 移除了这种依赖。安装一次,你受监控仓库中的每一次提交都会在夜间按计划被指纹化、批处理、构建 Merkle 根并锚定进比特币——背后还有徽章、公共状态仪表盘、审计 CSV、PDF 证书和浏览器本地验证作为支撑。
如果你是在为团队评估这套方案,先从一个私有仓库开始,看第一周的热力图逐渐填满。然后再决定推广到什么程度。
安装 GitHub App,连接你的第一个仓库,剩下的交给午夜 worker。