跳到主要内容
版本:1.27-dev

作用域工作流

作用域工作流(Scoped Workflows)让你把 Actions 工作流集中维护在一个**源(source)**仓库中,并让它们自动在许多其他仓库上运行,而无需把工作流文件复制到每个仓库里。

提交到源仓库作用域工作流目录下的工作流文件,会在该源所适用的每个仓库(称为消费方(consuming)仓库)上运行。每次运行都在消费方仓库自身的上下文中执行:使用它的 runner、密钥、GITEA_TOKEN 和分支,而工作流内容则读取自源仓库。这适用于在组织或实例范围内强制推行共享 CI:代码检查、安全扫描、合规或策略检查等。

级别

源仓库可以在两个级别注册:

  • 所有者级别(Owner level):由组织或用户注册。该源的工作流会在该组织或用户拥有的每个仓库上运行。
  • 实例级别(Instance level):由站点管理员注册。该源的工作流会在实例上的每一个仓库上运行。

同一个仓库可以同时在两个级别注册;对于每个匹配的事件,它仍只会被评估一次。

备注

实例级别的源适用于实例上的每一个仓库,且被设为必需(required)的源无法被选择退出(opt out)。检测会在每个仓库的每次事件上运行。请谨慎注册。

配置

作用域工作流存放在一个与常规工作流分开的目录中,由 app.ini[actions] 段的 SCOPED_WORKFLOW_DIRS 控制:

[actions]
SCOPED_WORKFLOW_DIRS = .gitea/scoped_workflows
  • 默认值为 .gitea/scoped_workflows
  • 可以列出多个目录(以逗号分隔)。
  • 不得与 WORKFLOW_DIRS(常规工作流目录,默认为 .gitea/workflows.github/workflows重叠
  • 留空意味着没有任何目录存放作用域工作流,因此不会找到也不会运行任何作用域工作流。设置页面仍会显示、源仍可注册,但不会有任何作用域工作流运行。

把作用域工作流放在它们自己的目录中,意味着源仓库自身的 Actions 不受影响:只有 SCOPED_WORKFLOW_DIRS 下的文件才会被当作作用域工作流。

从一个仓库提供作用域工作流

  1. 在准备作为源的仓库中,把工作流文件提交到其默认分支上的作用域工作流目录下,例如 .gitea/scoped_workflows/lint.yaml

    name: Lint
    on: [push, pull_request]
    jobs:
    lint:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - run: echo "lint the consuming repository here"
  2. 将该仓库注册为源:

    • 组织组织设置 -> Actions -> 作用域工作流
    • 用户用户设置 -> Actions -> 作用域工作流
    • 实例(管理员)管理后台 -> Actions -> 作用域工作流

    搜索并添加该仓库。此后,它的作用域工作流便会适用于该级别下的消费方仓库。

源仓库也在它自己的作用域内,因此它会像其他消费方一样在自身上运行这些工作流。

作用域工作流如何运行

  • 该运行属于消费方仓库,使用它的 runner、密钥、GITEA_TOKEN 和 ref。它在那里的表现与普通运行一致,包括重跑、日志和提交状态。
  • 工作流内容读取自源仓库,并钉定在事件发生时源默认分支的 commit 上。
  • 检测使用消费方仓库的事件,因此工作流的 on: 触发器(例如 pushpull_request)必须与该事件匹配。

选择退出(Opting out)

消费方仓库可以在其 Actions 页面(该工作流会显示在其源之下)禁用一个它不想要的作用域工作流。已被标记为必需(required)(见下文)的工作流,消费方仓库永远无法将其禁用,也无法选择退出。

必需工作流与合并门禁

在作用域工作流设置页面上,你可以把单个工作流标记为必需(required),并为每个工作流给定一个或多个状态检查模式(status-check patterns)(每行一个 glob)。一个必需的作用域工作流:

  • 无法被消费方仓库禁用。
  • 会对合并请求(PR)形成合并门禁:消费方的 PR 只有在一个匹配每一个模式的提交状态都通过后才能合并(必须存在且通过,must-present-and-pass)。一个从不产生任何状态的必需检查会阻止合并,而不是被静默跳过,因此在消费方关闭 Actions 也无法绕过它。

作用域运行产生的状态检查 context 形如:

<源仓库全名>: <工作流显示名> / <job> (<event>)

设置页面会为每个工作流预览这些 “Expected status checks(预期状态检查)”,并标记出与你的模式匹配的项,便于你确认模式是否正确。一种常见模式是对 job 和 event 使用通配符,例如 my-org/ci-repo: Lint / *

强制范围:

  • 必需检查会在任何设有分支保护规则的目标分支上强制生效,即使该规则自身的状态检查处于关闭状态。
  • 没有保护规则的目标分支不受门禁约束。
注意

只有运行在会产生提交状态的事件(pushpull_requestpull_request_targetrelease)上的工作流才能被设为必需。仅运行在 workflow_dispatchscheduleworkflow_call 等事件上的工作流不会产生任何状态,因此把它设为必需会永久阻止每一个消费方 PR 的合并。设置页面在这种情况下会向你发出警告。

可复用工作流(uses:

作用域工作流可以调用可复用工作流:

  • 本地引用(uses: ./...)会相对于仓库解析:即调用方工作流内容的来源仓库,而非消费方仓库。
  • 跨仓库引用(uses: owner/repo/...@ref)会以消费方仓库的读取权限来解析。如果它指向一个私有仓库,请确保每个消费方仓库都能读取它,否则工作流会在那里失败。

可复用工作流可以放在源仓库的 SCOPED_WORKFLOW_DIRS(或 WORKFLOW_DIRS)之下。

安全注意事项

源仓库的工作流内容会在它所适用的每个仓库中执行,其步骤脚本及其输出会写入该仓库的 Actions 日志,任何能查看消费方仓库 Actions 的人都能读取这些日志。

  • 因此,将一个私有仓库注册为源,会通过这些日志泄露其工作流逻辑。只应注册那些其工作流内容可以与每个消费方仓库共享的仓库。

限制

  • 目前不支持将 on: scheduleon: workflow_run 作为作用域工作流触发器。
  • 作用域工作流内容读取自源的默认分支;源的其他分支不会被使用。