1
0
mirror of synced 2025-12-19 18:10:59 -05:00
Files
docs/content/actions/reference/workflows-and-actions/reusing-workflow-configurations.md

242 lines
14 KiB
Markdown

---
title: Reusing workflow configurations
shortTitle: Reusing workflow configurations
intro: Find information about avoiding duplication when creating a workflow by reusing existing workflows{% ifversion fpt or ghec %} and using YAML anchors and aliases{% endif %}.
versions:
fpt: '*'
ghec: '*'
ghes: '*'
redirect_from:
- /actions/reference/reusable-workflows-reference
- /actions/reference/workflows-and-actions/reusable-workflows
---
## Reusable workflows
Reference information for reusable workflows.
### Access to reusable workflows
A reusable workflow can be used by another workflow if any of the following is true:
* Both workflows are in the same repository.
* The called workflow is stored in a public repository{% ifversion ghes %} on {% data variables.product.prodname_ghe_server %}.
You cannot directly use reusable workflows defined on {% data variables.product.prodname_dotcom_the_website %}. Instead store a copy of the reusable workflow on {% data variables.location.product_location %}, and call the workflow from that path.
{% elsif actions-workflow-policy %}, and your {% ifversion ghec %}enterprise{% else %}organization{% endif %} allows you to use public reusable workflows.{% endif %}{% ifversion ghes or ghec %}
* The called workflow is stored in an internal repository and the settings for that repository allow it to be accessed. For more information, see [AUTOTITLE](/actions/creating-actions/sharing-actions-and-workflows-with-your-enterprise).{% endif %}
* The called workflow is stored in a private repository and the settings for that repository allow it to be accessed. For more information, see {% ifversion ghes or ghec %}[AUTOTITLE](/actions/creating-actions/sharing-actions-and-workflows-with-your-enterprise).{% else %}[AUTOTITLE](/actions/creating-actions/sharing-actions-and-workflows-with-your-organization) and [AUTOTITLE](/actions/creating-actions/sharing-actions-and-workflows-from-your-private-repository).{% endif %}
The following table shows the accessibility of reusable workflows to a caller workflow, depending on the visibility of the host repository.
| Caller repository | Accessible workflows repositories |
|----|----|
| `private` | `private`{% ifversion ghes or ghec %}, `internal`,{% endif %} and `public` |
| {% ifversion ghes or ghec %} |
| `internal` | `internal`, and `public` |
| {% endif %} |
| `public` | `public` |
The **Actions permissions** on the callers repository's Actions settings page must be configured to allow the use of actions and reusable workflows - see [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#allowing-select-actions-and-reusable-workflows-to-run).
For {% ifversion ghes or ghec %}internal or {% endif %}private repositories, the **Access** policy on the Actions settings page of the called workflow's repository must be explicitly configured to allow access from repositories containing caller workflows - see [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#allowing-access-to-components-in-a-private-repository).
{% data reusables.actions.actions-redirects-workflows %}
### Limitations of reusable workflows
* You can connect up to {% ifversion fpt or ghec %}ten {% else %}four {% endif %}levels of workflows. For more information, see [Nesting reusable workflows](/actions/how-tos/sharing-automations/reuse-workflows#nesting-reusable-workflows).
* You can call a maximum of {% ifversion fpt or ghec %}50 {% else %}20 {% endif %}unique reusable workflows from a single workflow file. This limit includes any trees of nested reusable workflows that may be called starting from your top-level caller workflow file.
For example, _top-level-caller-workflow.yml__called-workflow-1.yml__called-workflow-2.yml_ counts as 2 reusable workflows.
* Any environment variables set in an `env` context defined at the workflow level in the caller workflow are not propagated to the called workflow. For more information, see [AUTOTITLE](/actions/learn-github-actions/variables) and [AUTOTITLE](/actions/learn-github-actions/contexts#env-context).
* Similarly, environment variables set in the `env` context, defined in the called workflow, are not accessible in the `env` context of the caller workflow. Instead, you must use outputs of the reusable workflow. For more information, see [Using outputs from a reusable workflow](/actions/how-tos/sharing-automations/reuse-workflows#using-outputs-from-a-reusable-workflow).
* To reuse variables in multiple workflows, set them at the organization, repository, or environment levels and reference them using the `vars` context. For more information see [AUTOTITLE](/actions/learn-github-actions/variables) and [AUTOTITLE](/actions/learn-github-actions/contexts#vars-context).
* Reusable workflows are called directly within a job, and not from within a job step. You cannot, therefore, use `GITHUB_ENV` to pass values to job steps in the caller workflow.
### Supported keywords for jobs that call a reusable workflow
When you call a reusable workflow, you can only use the following keywords in the job containing the call:
* [`jobs.<job_id>.name`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname)
* [`jobs.<job_id>.uses`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_iduses)
* [`jobs.<job_id>.with`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idwith)
* [`jobs.<job_id>.with.<input_id>`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idwithinput_id)
* [`jobs.<job_id>.secrets`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsecrets)
* [`jobs.<job_id>.secrets.<secret_id>`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsecretssecret_id)
* [`jobs.<job_id>.secrets.inherit`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsecretsinherit)
* [`jobs.<job_id>.strategy`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategy)
* [`jobs.<job_id>.needs`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds)
* [`jobs.<job_id>.if`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idif)
* [`jobs.<job_id>.concurrency`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idconcurrency)
* [`jobs.<job_id>.permissions`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idpermissions)
> [!NOTE]
>
> * If `jobs.<job_id>.permissions` is not specified in the calling job, the called workflow will have the default permissions for the `GITHUB_TOKEN`. For more information, see [AUTOTITLE](/actions/reference/workflow-syntax-for-github-actions#permissions).
> * The `GITHUB_TOKEN` permissions passed from the caller workflow can be only downgraded (not elevated) by the called workflow.
> * If you use `jobs.<job_id>.concurrency.cancel-in-progress: true`, don't use the same value for `jobs.<job_id>.concurrency.group` in the called and caller workflows as this will cause the workflow that's already running to be cancelled. A called workflow uses the name of its caller workflow in {% raw %}${{ github.workflow }}{% endraw %}, so using this context as the value of `jobs.<job_id>.concurrency.group` in both caller and called workflows will cause the caller workflow to be cancelled when the called workflow runs.
### How reusable workflows use runners
#### {% data variables.product.github %}-hosted runners
The assignment of {% data variables.product.prodname_dotcom %}-hosted runners is always evaluated using only the caller's context. Billing for {% data variables.product.prodname_dotcom %}-hosted runners is always associated with the caller. The caller workflow cannot use {% data variables.product.prodname_dotcom %}-hosted runners from the called repository. For more information, see [AUTOTITLE](/actions/using-github-hosted-runners/about-github-hosted-runners).
#### Self-hosted runners
Called workflows that are owned by the same user or organization{% ifversion ghes or ghec %} or enterprise{% endif %} as the caller workflow can access self-hosted runners from the caller's context. This means that a called workflow can access self-hosted runners that are:
* In the caller repository
* In the caller repository's organization{% ifversion ghes or ghec %} or enterprise{% endif %}, provided that the runner has been made available to the caller repository
### Access and permissions for nested workflows
A workflow that contains nested reusable workflows will fail if any of the nested workflows is inaccessible to the initial caller workflow. For more information, see [Access to reusable workflows](#access-to-reusable-workflows).
`GITHUB_TOKEN` permissions can only be the same or more restrictive in nested workflows. For example, in the workflow chain A > B > C, if workflow A has `package: read` token permission, then B and C cannot have `package: write` permission. For more information, see [AUTOTITLE](/actions/security-guides/automatic-token-authentication).
For information on how to use the API to determine which workflow files were involved in a particular workflow run, see [AUTOTITLE](/actions/how-tos/sharing-automations/reuse-workflows#monitoring-which-workflows-are-being-used).
### Behavior of reusable workflows when re-running jobs
{% data reusables.actions.partial-reruns-with-reusable %}
### `github` context
When a reusable workflow is triggered by a caller workflow, the `github` context is always associated with the caller workflow. The called workflow is automatically granted access to `github.token` and `secrets.GITHUB_TOKEN`. For more information about the `github` context, see [AUTOTITLE](/actions/learn-github-actions/contexts#github-context).
## Workflow templates
Reference information to use when creating workflow templates for your organization.
### Workflow template availability
You can use templates in repositories that match or have more restricted visibility than the template repository.
* Workflow templates in a public `.github` repository are available to all repository types.
* Workflow templates in an internal `.github` repository are only available to internal and private repositories.
* Workflow templates in a private `.github` repository are only available to private repositories.
{% ifversion ghec %}
Because public workflow templates require a public `.github` repository, they are not available for {% data variables.product.prodname_emus %}.
{% endif %}
### Granting access for private/internal repositories
If you're using a private or internal `.github` repository, you need to grant Read access to users or teams who should be able to use the templates.
### The `$default-branch` placeholder
If you need to refer to a repository's default branch, you can use the `$default-branch` placeholder in your workflow template. When a workflow is created the placeholder will be automatically replaced with the name of the repository's default branch.
{% ifversion ghes %}
### Placeholder values in the `runs-on` key
The following values in the `runs-on` key are also treated as placeholders:
* `ubuntu-latest` is replaced with `[ self-hosted ]`
* `windows-latest` is replaced with `[ self-hosted, windows ]`
* `macos-latest"` is replaced with `[ self-hosted, macOS ]`
{% endif %}
### Example workflow template file
This file named `octo-organization-ci.yml` demonstrates a basic workflow.
```yaml copy
name: Octo Organization CI
on:
push:
branches: [ $default-branch ]
pull_request:
branches: [ $default-branch ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: {% data reusables.actions.action-checkout %}
- name: Run a one-line script
run: echo Hello from Octo Organization
```
### Metadata file requirements
The metadata file must have the same name as the workflow file, but instead of the `.yml` extension, it must be appended with `.properties.json`. For example, this file named `octo-organization-ci.properties.json` contains the metadata for a workflow file named `octo-organization-ci.yml`:
{% data reusables.actions.workflow-templates-metadata-example %}
{% data reusables.actions.workflow-templates-metadata-keys %}
{% ifversion fpt or ghec %}
## YAML anchors and aliases
You can use YAML anchors and aliases to reduce repetition in your workflows. An anchor (marked with `&`) identifies a piece of content that you want to reuse, while an alias (marked with `*`) repeats that content in another location.
For detailed information about anchors and aliases, see [Node Anchors and Aliases in the YAML specification](https://yaml.org/spec/1.2.2/#3222-anchors-and-aliases).
Here's an example that uses YAML anchors and aliases with environment variables:
```yaml
jobs:
job1:
env: &env_vars # Define the anchor on first use
NODE_ENV: production
DATABASE_URL: {% raw %}${{ secrets.DATABASE_URL }}{% endraw %}
steps:
- run: echo "Using production settings"
job2:
env: *env_vars # Reuse the environment variables
steps:
- run: echo "Same environment variables here"
```
This is equivalent to writing the following YAML without anchors and aliases:
```yaml
jobs:
job1:
env:
NODE_ENV: production
DATABASE_URL: {% raw %}${{ secrets.DATABASE_URL }}{% endraw %}
steps:
- run: echo "Using production settings"
job2:
env:
NODE_ENV: production
DATABASE_URL: {% raw %}${{ secrets.DATABASE_URL }}{% endraw %}
steps:
- run: echo "Same environment variables here"
```
You can also use anchors for more complex configurations, such as reusing an entire job configuration:
```yaml
jobs:
test: &base_job # Define the anchor on first use
runs-on: ubuntu-latest
timeout-minutes: 30
env:
NODE_VERSION: '18'
steps:
- uses: {% data reusables.actions.action-checkout %}
- name: Set up Node.js
uses: {% data reusables.actions.action-setup-node %}
with:
node-version: {% raw %}${{ env.NODE_VERSION }}{% endraw %}
- run: npm test
alt-test: *base_job # Reuse the entire job configuration
```
{% endif %}