Section 2 - Composite Custom Actions
Last updated
Last updated
Composite custom actions allow you to define a series of steps that can be run as a single workflow job step. Similar to reusable workflows, composite actions let you group multiple steps together, but with one key difference: while reusable workflows encapsulate an entire workflow and cannot be called from a single step, composite actions wrap a sequence of steps into a single step that can be called within a workflow.
Additionally, when a reusable workflow runs, the full workflow is displayed in the GitHub Actions UI. In contrast, composite actions are treated as a single step, making them more streamlined and focused on specific tasks.
To make this concept clearer, let’s dive into an example. We’ll define the get-labels action as a composite action.
Composite actions are defined in an action.yaml file. For this example, we will define our composite action in the . While custom actions are usually defined in their own repository, for simplicity and to demonstrate how we can encapsulate multiple actions and workflows in a single repository, we will define it here rather than creating a new repo.
Let’s start by creating the directories and the action.yaml file:
This action reads a label from a pull request (PR) to determine the type of release we want to create. For example:
bump:patch (e.i v0.0.1 --> v0.0.2)
bump:minor (e.i v0.0.1 --> v0.1.0)
bump:major (e.i v0.0.1 --> v1.0.0)
In these examples, the action will search for a label in the form and output the label’s value.
Now, let’s start defining the composite action in the action.yaml file by specifying its name, description, inputs, and outputs:
The inputs make this action versatile, allowing it to handle various label formats, not just bump:<value>
. If no label is found, the action defaults to input.default-label-value
as the label value. Here’s what each input does:
label-key: The key of the label to read (e.g., <key>:<value>).
default-label-value: The default value to output if no label is found.
github-token: A token required to access the PR, specifically for non-pull request events (e.g., push events).
The output, label-value, allows the value of the label to be passed to subsequent steps in the workflow, making it accessible for further decisions. In the case of releases the value is passed to decide what kind of bump to use in the version update for the release.
The composite action logic is composed of several steps. Since the purpose of the action is to retrieve pull request (PR) labels, we divide the logic into two separate steps: one for pull request events and another for push events.
For PR events, the labels are already available in the github.event parameter since they are part of the pull request itself.
For push events, however, labels are not directly available because a push event is not associated with a PR. Therefore, we need to make an API call to GitHub to retrieve the PR based on the commit hash and extract the associated labels.
The third step is responsible for setting the output label value by determining which previous step successfully found the label and setting it accordingly.
Here’s how the logic comes together:
Summary of Steps:
Step 1 - Get the Push Event Label (only runs for push events)
This step makes a curl request to the GitHub API to retrieve the PR associated with the commit. If multiple PRs are associated, the value remains empty. This can be updated to be more sophisticated, but in most cases, a single PR is associated with the commit, so this approach works well.
Step 2 - Get the Pull Request Event Label (only runs for pull request events)
This step uses the github.event parameter to find the label. Since it is a pull request event, the labels are available in github.event.pull_request.labels. If no label is found, the value defaults to empty.
Step 3 - Set the Output Label Value
This step determines the final output label value. It checks if either Step 1 or Step 2 has set a value, and if so, uses that value. If neither step sets a value, it defaults to the default_label_value.
You can find the full source code for the composite action here:
To use the action, you can refer to it in a workflow step as follows:
Alternatively, if the action lives in its own repository, you could release it in a similar fashion to how we did demonstrated in Release workflow example in Chapter 1, Section 3.
.
As we discussed in Chapter 3, Section 5: Releasing the Reusable Workflow, we added logic to release custom actions. This logic essentially looks for any custom actions defined under the .github/actions/ directory and makes a release for them in the repository.