# 重用工作流

了解如何通过重用现有工作流程来避免在创建工作流程时重复。

## 创建可重用的工作流程

可重用工作流程是 YAML 格式的文件，与任何其他工作流程文件非常相似。 与其他工作流文件一样，可以在存储库的 `.github/workflows` 目录中找到可重用的工作流。 不支持 `workflows` 目录的子目录。

可以通过创建只能执行特定可重用工作流的自承载运行程序组来标准化部署。 有关详细信息，请参阅 [使用组管理对自托管运行程序的访问](/zh/enterprise-server@3.22/actions/how-tos/manage-runners/self-hosted-runners/manage-access)。

若要使工作流可重用，`on` 的值必须包括 `workflow_call`：

```yaml
on:
  workflow_call:
```

## 在可重用工作流程中使用输入和机密

您可以定义输入和机密，这些输入和机密可以从调用方工作流程传递，然后在被调用的工作流程中使用。 在可重用工作流程中使用输入或机密有三个阶段。

1. 在可重用工作流中，使用 `inputs` 和 `secrets` 关键字定义将从调用方工作流传递的输入或机密。

   ```yaml
   on:
     workflow_call:
       inputs:
         config-path:
           required: true
           type: string
       secrets:
         personal_access_token:
           required: true
   ```

   有关定义输入和机密的语法的详细信息，请参阅 [`on.workflow_call.inputs`](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_callinputs) 和 [`on.workflow_call.secrets`](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_callsecrets)。

2. 在可重用工作流中，引用在上一步的 `on` 键中定义的输入或机密。

   > \[!NOTE]
   > 如果在调用工作流中使用 `secrets: inherit` 继承机密，那么即使未在 `on` 键中显式定义机密，也可以引用它们。 有关详细信息，请参阅“[GitHub Actions 的工作流语法](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idsecretsinherit)”。

   ```yaml
   jobs:
     reusable_workflow_job:
       runs-on: ubuntu-latest
       steps:
       - uses: actions/labeler@v6
         with:
           repo-token: ${{ secrets.personal_access_token }}
           configuration-path: ${{ inputs.config-path }}
   ```

   在上面的示例中，`personal_access_token` 是在存储库或组织级别定义的机密。

   > \[!WARNING]
   > 无法从调用方工作流传递环境机密，因为 `on.workflow_call` 不支持 `environment` 关键字。 如果在作业级别的可重用工作流中包含 `environment`，则将使用环境机密，而不是从调用方工作流传递的机密。 有关详细信息，请参阅 [管理部署环境](/zh/enterprise-server@3.22/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments) 和 [GitHub Actions 的工作流语法](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_call)。

3. 传递来自调用方工作流程的输入或机密。

   若要将命名输入传递到调用的工作流，请在作业中使用 `with` 关键字。 使用 `secrets` 关键字传递命名机密。 对于输入，输入值的数据类型必须与调用的工作流中指定的类型（布尔值、数字或字符串）匹配。

   ```yaml
   jobs:
     call-workflow-passing-data:
       uses: octo-org/example-repo/.github/workflows/reusable-workflow.yml@main
       with:
         config-path: .github/labeler.yml
       secrets:
         personal_access_token: ${{ secrets.token }}
   ```

   在同一组织或企业中调用可重用工作流的工作流可以使用 `inherit` 关键字隐式传递机密。

   ```yaml
   jobs:
     call-workflow-passing-data:
       uses: octo-org/example-repo/.github/workflows/reusable-workflow.yml@main
       with:
         config-path: .github/labeler.yml
       secrets: inherit
   ```

### 示例可重用工作流程

此名为 `workflow-B.yml` 的可重用工作流文件（稍后将在[调用方工作流示例](#example-caller-workflow)中引用此文件）从调用方工作流中获取输入字符串和机密，并在操作中使用它们。

```yaml copy
name: Reusable workflow example

on:
  workflow_call:
    inputs:
      config-path:
        required: true
        type: string
    secrets:
      token:
        required: true

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/labeler@v6
      with:
        repo-token: ${{ secrets.token }}
        configuration-path: ${{ inputs.config-path }}
```

## 调用可重用工作流程

使用 `uses` 关键字调用可重用工作流。 与在工作流程中使用操作不同，您可以直接在作业中调用可重用工作流程，而不是从作业步骤中调用。

[`jobs.<job_id>.uses`](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_iduses)

可以使用以下语法之一引用可重用的工作流文件：

* `$/.github/workflows/{filename}` 用于同一存储库中的可重用工作流。 这是引用同一存储库中可重用工作流的建议语法。 此语法在 . 中 GitHub Enterprise Server不可用。
* ```
            可重用工作流的 `{owner}/{repo}/.github/workflows/{filename}@{ref}`，这些工作流位于公共、内部和私有存储库中。
  ```
* `./.github/workflows/{filename}` 用于同一存储库中的可重用工作流。

使用 <<c1/>a0/> 引用可重用工作流<c0 />时，<c2 />可以是 SHA、发布标记或分支名称。 如果发布标记和分支具有相同的名称，则发布标记优先于分支名称。 出于稳定性和安全性考虑，使用提交 SHA 是最稳妥的选项。 有关详细信息，请参阅“[安全使用指南](/zh/enterprise-server@3.22/actions/reference/security/secure-use#reusing-third-party-workflows)”。

使用或`$/`（不使用）`./``{owner}/{repo}`在同一存储库`@{ref}`中引用可重用工作流时，调用的工作流与调用方工作流的提交相同。 引用 <c0 /> 不得包含 <c1 /> 后缀， <c2 /> 且在 < a0/> 中 <c3 />不可用。 不允许使用 `refs/heads` 和 `refs/tags` 等引用前缀。 您不能在此关键词中使用上下文或表达式。

您可以调用多个工作流程，在单独的作业中引用每个工作流程。

```yaml
jobs:
  call-workflow-1-in-local-repo:
    uses: octo-org/this-repo/.github/workflows/workflow-1.yml@172239021f7ba04fe7327647b213799853a9eb89
  call-workflow-2-in-local-repo:
    uses: ./.github/workflows/workflow-2.yml
  # The `$/` syntax is not available in GitHub Enterprise Server.
  call-workflow-in-same-repo-at-running-commit:
    uses: $/.github/workflows/workflow-2.yml
  call-workflow-in-another-repo:
    uses: octo-org/another-repo/.github/workflows/workflow.yml@v1
```

### 示例调用方工作流程

此工作流程文件调用两个工作流程文件。 向其中的第二个文件 `workflow-B.yml`（如[可重用工作流示例](#example-reusable-workflow)中所示）传递了一个输入 (`config-path`) 和一个机密 (`token`)。

```yaml copy
name: Call a reusable workflow

on:
  pull_request:
    branches:
      - main

jobs:
  call-workflow:
    uses: octo-org/example-repo/.github/workflows/workflow-A.yml@v1

  call-workflow-passing-data:
    permissions:
      contents: read
      pull-requests: write
    uses: octo-org/example-repo/.github/workflows/workflow-B.yml@main
    with:
      config-path: .github/labeler.yml
    secrets:
      token: ${{ secrets.GITHUB_TOKEN }}
```

## 将输入和机密传递到可重用的工作流程

若要将命名输入传递到调用的工作流，请在作业中使用 `with` 关键字。 使用 `secrets` 关键字传递命名机密。 对于输入，输入值的数据类型必须与调用的工作流中指定的类型（布尔值、数字或字符串）匹配。

```yaml
jobs:
  call-workflow-passing-data:
    uses: octo-org/example-repo/.github/workflows/reusable-workflow.yml@main
    with:
      config-path: .github/labeler.yml
    secrets:
      personal_access_token: ${{ secrets.token }}
```

在同一组织或企业中调用可重用工作流的工作流可以使用 `inherit` 关键字隐式传递机密。

```yaml
jobs:
  call-workflow-passing-data:
    uses: octo-org/example-repo/.github/workflows/reusable-workflow.yml@main
    with:
      config-path: .github/labeler.yml
    secrets: inherit
```

## 将矩阵策略与可重用工作流配合使用

使用矩阵策略的作业可以调用可重用工作流。

使用矩阵策略，可以在单个作业定义中使用变量自动创建基于变量组合的多个作业运行。 例如，可以使用矩阵策略将不同输入传递给可重用工作流。 有关矩阵的详细信息，请参阅“[在工作流中运行作业变体](/zh/enterprise-server@3.22/actions/how-tos/write-workflows/choose-what-workflows-do/run-job-variations)”。

以下示例作业调用可重用工作流，并通过使用值 `target` 定义变量 `[dev, stage, prod]` 来引用矩阵上下文。 它将运行三个作业，变量中的每个值对应一个作业。

```yaml copy
jobs:
  ReusableMatrixJobForDeployment:
    strategy:
      matrix:
        target: [dev, stage, prod]
    uses: octocat/octo-repo/.github/workflows/deployment.yml@main
    with:
      target: ${{ matrix.target }}
```

## 嵌套可重用工作流

最多可以连接十 四个级别的工作流 - 即顶级调用方工作流和最多三个可重用工作流级别。 例如：*caller-workflow\.yml\_\_→called-workflow-1.yml\_→\_called-workflow-2.yml→\_\_called-workflow-3.yml*。

不允许工作流树中存在循环。

> \[!NOTE] 嵌套的可重用工作流要求链中的所有工作流都可供调用方访问，并且在整个链中，权限只能保持不变或降低，而不能提升。 有关详细信息，请参阅“[重用工作流配置](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/reusing-workflow-configurations)”。

在可重用工作流中，可以调用另一个可重用工作流。

```yaml copy
name: Reusable workflow

on:
  workflow_call:

jobs:
  call-another-reusable:
    uses: octo-org/example-repo/.github/workflows/another-reusable.yml@v1
```

## 将机密传递给嵌套工作流

可以在调用工作流中使用 `jobs.<job_id>.secrets` 将命名机密传递给直接调用的工作流。 或者，可以使用 `jobs.<job_id>.secrets.inherit` 将调用工作流的所有机密传递给直接调用的工作流。 有关详细信息，请参阅上面的 [重用工作流](/zh/enterprise-server@3.22/actions/how-tos/reuse-automations/reuse-workflows#passing-inputs-and-secrets-to-a-reusable-workflow) 部分和参考文章 [GitHub Actions 的工作流语法](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idsecretsinherit)。 机密仅传递给直接调用的工作流，因此在工作流链 A > B > C 中，工作流 C 仅从 A 接收从 A 传递给 B，然后从 B 传递给 C 的机密。

在以下示例中，工作流 A 使用 `inherit` 关键字将其所有机密传递给工作流 B，但工作流 B 仅将一个机密传递给工作流 C。传递给工作流 B 的任何其他机密都不可供工作流 C 使用。

```yaml
jobs:
  workflowA-calls-workflowB:
    uses: octo-org/example-repo/.github/workflows/B.yml@main
    secrets: inherit # pass all secrets
```

```yaml
jobs:
  workflowB-calls-workflowC:
    uses: different-org/example-repo/.github/workflows/C.yml@main
    secrets:
      repo-token: ${{ secrets.personal_access_token }} # pass just this secret
```

## 使用可重用工作流程的输出

可重用工作流程可能会生成要在调用方工作流程中使用的数据。 要使用这些输出，必须将它们指定为可重用工作流的输出。

如果设置输出的可重用工作流使用矩阵策略来执行，则输出会是由矩阵的最后一个成功完成且实际设置值的可重用工作流设置的输出。
这意味着，如果最后一个成功完成可重用工作流为其输出设置空字符串，而倒数第二个成功完成可重用工作流为其输出设置实际值，则输出会包含倒数第二个完成可重用工作流的值。

以下可重用工作流程具有包含两个步骤的单个作业。 在每个步骤中，我们设置一个单词作为输出："hello" 和 "world"。 在作业的 `outputs` 部分，我们将这些步骤输出映射到名为 `output1` 和 `output2` 的作业输出。 然后，在 `on.workflow_call.outputs` 部分中，为工作流本身定义两个输出，一个称为 `firstword`，映射到 `output1`，另一个称为 `secondword`，映射到 `output2`。

必须将 `value` 设置为所调用工作流中作业级输出的值。 步骤级输出必须首先映射到作业级输出，如下所示。

有关详细信息，请参阅 [在作业之间传递信息](/zh/enterprise-server@3.22/actions/how-tos/write-workflows/choose-what-workflows-do/pass-job-outputs) 和 [GitHub Actions 的工作流语法](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_calloutputs)。

```yaml copy
name: Reusable workflow

on:
  workflow_call:
    # Map the workflow outputs to job outputs
    outputs:
      firstword:
        description: "The first output string"
        value: ${{ jobs.example_job.outputs.output1 }}
      secondword:
        description: "The second output string"
        value: ${{ jobs.example_job.outputs.output2 }}

jobs:
  example_job:
    name: Generate output
    runs-on: ubuntu-latest
    # Map the job outputs to step outputs
    outputs:
      output1: ${{ steps.step1.outputs.firstword }}
      output2: ${{ steps.step2.outputs.secondword }}
    steps:
      - id: step1
        run: echo "firstword=hello" >> $GITHUB_OUTPUT
      - id: step2
        run: echo "secondword=world" >> $GITHUB_OUTPUT
```

现在，我们可以在调用方工作流程中使用输出，就像使用同一工作流程中作业的输出一样。 我们使用在可重用工作流中的工作流级别定义的名称引用输出：`firstword` 和 `secondword`。 在此工作流中，`job1` 调用可重用工作流，`job2` 将可重用工作流的输出（“hello world”）呈现在工作流日志的标准输出中。

```yaml copy
name: Call a reusable workflow and use its outputs

on:
  workflow_dispatch:

jobs:
  job1:
    uses: octo-org/example-repo/.github/workflows/called-workflow.yml@v1

  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
      - run: echo ${{ needs.job1.outputs.firstword }} ${{ needs.job1.outputs.secondword }}
```

有关使用作业输出的详细信息，请参阅 [GitHub Actions 的工作流语法](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idoutputs)。 如果要在工作流之间共享变量以外的内容（例如生成工件），请参阅 [使用工作流工件存储和共享数据](/zh/enterprise-server@3.22/actions/tutorials/store-and-share-data)。

## 监控正在使用的工作流程

使用 GitHub Enterprise Cloud 的组织可以通过 REST API 与审核日志 GitHub 进行交互，以监视正在使用的工作流。 有关详细信息，请参阅[GitHub Enterprise Cloud文档](/zh/enterprise-cloud@latest/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/reviewing-the-audit-log-for-your-organization#using-the-audit-log-api)。

## 后续步骤

要查找有关工作流重用细节的信息，请参阅 [重用工作流配置](/zh/enterprise-server@3.22/actions/reference/workflows-and-actions/reusing-workflow-configurations)。