Note
GitHub-hosted runners are not currently supported on GitHub Enterprise Server. You can see more information about planned future support on the GitHub public roadmap.
Introduction
In this guide, you'll learn about the basic components needed to create and use a packaged composite action. To focus this guide on the components needed to package the action, the functionality of the action's code is minimal. The action prints "Hello World" and then "Goodbye", or if you provide a custom name, it prints "Hello [who-to-greet]" and then "Goodbye". The action also maps a random number to the random-number output variable, and runs a script named goodbye.sh.
Once you complete this project, you should understand how to build your own composite action and test it in a workflow.
Warning
When creating workflows and actions, you should always consider whether your code might execute untrusted input from possible attackers. Certain contexts should be treated as untrusted input, as an attacker could insert their own malicious content. For more information, see Security hardening for GitHub Actions.
Composite actions and reusable workflows
Composite actions allow you to collect a series of workflow job steps into a single action which you can then run as a single job step in multiple workflows. Reusable workflows provide another way of avoiding duplication, by allowing you to run a complete workflow from within other workflows. For more information, see Avoiding duplication.
Prerequisites
Before you begin, you'll create a repository on GitHub.
-
Create a new public repository on GitHub. You can choose any repository name, or use the following
hello-world-composite-actionexample. You can add these files after your project has been pushed to GitHub. For more information, see Creating a new repository. -
Clone your repository to your computer. For more information, see Cloning a repository.
-
From your terminal, change directories into your new repository.
Shell cd hello-world-composite-action
cd hello-world-composite-action -
In the
hello-world-composite-actionrepository, create a new file calledgoodbye.shwith example code:Shell echo "echo Goodbye" > goodbye.sh
echo "echo Goodbye" > goodbye.sh -
From your terminal, make
goodbye.shexecutable.Shell chmod +x goodbye.sh
chmod +x goodbye.shShell chmod +x goodbye.sh
chmod +x goodbye.shShell git add --chmod=+x -- goodbye.sh
git add --chmod=+x -- goodbye.sh -
From your terminal, check in your
goodbye.shfile.Shell git add goodbye.sh git commit -m "Add goodbye script" git push
git add goodbye.sh git commit -m "Add goodbye script" git pushShell git add goodbye.sh git commit -m "Add goodbye script" git push
git add goodbye.sh git commit -m "Add goodbye script" git pushShell git commit -m "Add goodbye script" git push
git commit -m "Add goodbye script" git push
Creating an action metadata file
-
In the
hello-world-composite-actionrepository, create a new file calledaction.ymland add the following example code. For more information about this syntax, see Metadata syntax for GitHub Actions.YAML name: 'Hello World' description: 'Greet someone' inputs: who-to-greet: # id of input description: 'Who to greet' required: true default: 'World' outputs: random-number: description: "Random number" value: ${{ steps.random-number-generator.outputs.random-number }} runs: using: "composite" steps: - name: Set Greeting run: echo "Hello $INPUT_WHO_TO_GREET." shell: bash env: INPUT_WHO_TO_GREET: ${{ inputs.who-to-greet }} - name: Random Number Generator id: random-number-generator run: echo "random-number=$(echo $RANDOM)" >> $GITHUB_OUTPUT shell: bash - name: Set GitHub Path run: echo "$GITHUB_ACTION_PATH" >> $GITHUB_PATH shell: bash env: GITHUB_ACTION_PATH: ${{ github.action_path }} - name: Run goodbye.sh run: goodbye.sh shell: bashname: 'Hello World' description: 'Greet someone' inputs: who-to-greet: # id of input description: 'Who to greet' required: true default: 'World' outputs: random-number: description: "Random number" value: ${{ steps.random-number-generator.outputs.random-number }} runs: using: "composite" steps: - name: Set Greeting run: echo "Hello $INPUT_WHO_TO_GREET." shell: bash env: INPUT_WHO_TO_GREET: ${{ inputs.who-to-greet }} - name: Random Number Generator id: random-number-generator run: echo "random-number=$(echo $RANDOM)" >> $GITHUB_OUTPUT shell: bash - name: Set GitHub Path run: echo "$GITHUB_ACTION_PATH" >> $GITHUB_PATH shell: bash env: GITHUB_ACTION_PATH: ${{ github.action_path }} - name: Run goodbye.sh run: goodbye.sh shell: bashThis file defines the
who-to-greetinput, maps the random generated number to therandom-numberoutput variable, adds the action's path to the runner system path (to locate thegoodbye.shscript during execution), and runs thegoodbye.shscript.For more information about managing outputs, see Metadata syntax for GitHub Actions.
For more information about how to use
github.action_path, see Accessing contextual information about workflow runs. -
From your terminal, check in your
action.ymlfile.Shell git add action.yml git commit -m "Add action" git push
git add action.yml git commit -m "Add action" git push -
From your terminal, add a tag. This example uses a tag called
v1. For more information, see About custom actions.Shell git tag -a -m "Description of this release" v1 git push --follow-tags
git tag -a -m "Description of this release" v1 git push --follow-tags
Testing out your action in a workflow
The following workflow code uses the completed hello world action that you made in Creating a composite action.
Copy the workflow code into a .github/workflows/main.yml file in another repository, replacing OWNER and SHA with the repository owner and the SHA of the commit you want to use, respectively. You can also replace the who-to-greet input with your name.
on: [push]
jobs:
hello_world_job:
runs-on: ubuntu-latest
name: A job to say hello
steps:
- uses: actions/checkout@v4
- id: foo
uses: OWNER/hello-world-composite-action@SHA
with:
who-to-greet: 'Mona the Octocat'
- run: echo random-number "$RANDOM_NUMBER"
shell: bash
env:
RANDOM_NUMBER: ${{ steps.foo.outputs.random-number }}
on: [push]
jobs:
hello_world_job:
runs-on: ubuntu-latest
name: A job to say hello
steps:
- uses: actions/checkout@v4
- id: foo
uses: OWNER/hello-world-composite-action@SHA
with:
who-to-greet: 'Mona the Octocat'
- run: echo random-number "$RANDOM_NUMBER"
shell: bash
env:
RANDOM_NUMBER: ${{ steps.foo.outputs.random-number }}
From your repository, click the Actions tab, and select the latest workflow run. The output should include: "Hello Mona the Octocat", the result of the "Goodbye" script, and a random number.
Example composite actions on GitHub
You can find many examples of composite actions on GitHub.