配了三年 reusable workflow,今天才发现 github.workflow_ref 从来不是 workflow 自己的——这件事今天被 GitHub 彻底原生化了
配了三年 reusable workflow,今天才发现 github.workflow_ref 从来不是 workflow 自己的——这件事今天被 GitHub 彻底原生化了
Reusable workflow 是个好东西。把 CI 逻辑抽到一个独立文件,主 workflow 调一下 uses: 就能复用,维护成本降一大截。但你有没有遇到过这种情况:你想在 reusable workflow 里做日志审计,想知道「这个 job 到底用的是哪个 workflow 文件定义的」——结果 github.workflow_ref 给你返回的是调用者的信息,而不是你自己。
这就是所谓「身份反转」问题。
旧方案的痛:你在自己的 workflow 里,却不知道你是谁
Reusable workflow 存在已久,但它的上下文属性一直有个设计问题:github.workflow_ref 和 github.workflow_sha 这两个属性,指向的是调用者(caller)的 workflow 文件,而不是被调用者(called/reusable)自己的 workflow 文件。
举个例子:你的主 workflow 是 A.yml,它调用了一个 reusable workflow B.yml。在 B.yml 的 job 里,github.workflow_ref 返回的是 A.yml 的路径,而不是 B.yml。如果 B.yml 需要知道「自己是谁」——比如做签名校验、打印自己所在的 commit——它拿到的信息是错的。
社区解决这个问题靠的是 canonical/get-workflow-version-action 这个第三方 action:手动获取 called workflow 的真实 ref 和 SHA。但这是一个带副作用的 workaround:多一个 action 依赖,多一个供应链风险点。
2025 年 3 月的 tj-actions 供应链攻击(CVE-2025-30066)就是典型——攻击者通过污染 GitHub Actions 生态里的一个热门 action,窃取了 23000+ 个仓库的 runner 内存中的 secrets。问题根源之一正是 over-permissioned tokens 和过多的第三方 action 依赖。
*GitHub 的原生修复:四个新的 job. 属性**
2026 年 9 月,GitHub 给 reusable workflow 补上了这四个新属性:
job.workflow_ref— 定义当前 job 的 workflow 文件的完整 refjob.workflow_sha— 定义当前 job 的 workflow 文件的 commit SHAjob.workflow_repository— 定义当前 job 的 workflow 文件所在仓库(owner/repo)job.workflow_file_path— 定义当前 job 的 workflow 文件相对于仓库根目录的路径
这四个属性才是 reusable workflow 真正需要知道的「我是谁」。
关键区别是:直接写在 workflow 里的 job,job.workflow_ref 等于 github.workflow_ref;而对于 reusable workflow,job.workflow_ref 指向被调用 workflow,两者才真正分开。
两个实际用法
第一个:reusable workflow 检出自己的代码,不用硬编码仓库路径。
旧写法(硬编码):
- uses: actions/checkout@v4
with:
repository: my-org/my-repo
ref: ${{ github.sha }}
新写法(动态自引用):
- uses: actions/checkout@v4
with:
repository: ${{ job.workflow_repository }}
ref: ${{ job.workflow_sha }}
这样 reusable workflow 本身不需要知道调用者是谁,天然支持跨仓库复用。
第二个(更重要):在 reusable workflow 开头打印 job.workflow_sha,为 SLSA 审计链条提供密码学证明。
- name: Log workflow identity for audit trail
run: echo "Running workflow SHA: ${{ job.workflow_sha }}"
GitHub 的 SLSA 工具链可以消费这个信息,让 workflow 自己证明自己的身份,而不是依赖调用者传入的数据。这个在出了供应链事故之后会特别有价值——你可以独立验证「到底是哪个版本的 workflow 在跑」。
一个限制:GitHub Enterprise Server 暂时没有
目前这四个属性只对 github.com 公开,GitHub Enterprise Server 还没上线。如果你的 CI 全跑在 GHES 上,暂时还用不了。
下一步:三个具体动作
-
立刻:如果你的 reusable workflow 还在用
canonical/get-workflow-version-action,查一下它的依赖情况,考虑迁移到原生job.workflow_sha。这个 action 已经 deprecated,但还没删除,越早换越安全。 -
本周:在所有 reusable workflow 的开头加一行
echo "job.workflow_sha: ${{ job.workflow_sha }}"——不需要任何额外 action,三行 YAML,审计链条就建立起来了。 -
长期:配合 GitHub 九月同批的
vulnerability-alerts: read权限(最小权限读 Dependabot alerts,不再需要contents: write),以及 runner deprecation REST API,三个改动加在一起,几小时工作,CI 安全基线明显提升。
Reusable workflow 的「身份反转」这个问题存在了很久,社区用第三方 action 打补丁也是一种工程判断。现在 GitHub 补上了原生能力,是时候把那个 workaround 卸掉了。
评论区
登录后可评论。