- GitHub
- GitHub Actions
When you implement continuous integration and continuous delivery in your projects, if you are using the same technology, you probably noticed that the workflows are similar or identical, and as you know duplicate is not a good thing at all!
Why are we trying to mutualize workflows?
So the question is, how to reuse your workflows and be more efficient between your projects instead of duplicate your workflows?
Let’s suppose you have a workflow to build a dotnet
project called DemoReusableTemplates
. This project needs a specific version of dotnet
to build. So the workflow will looks like this:
name: Main
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build_dotnet:
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@v2
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
- run: dotnet restore src/DemoReusableTemplates.csproj
- run: dotnet build src/DemoReusableTemplates.csproj
This kind of workflow can be easily reused between your dotnet
projects, if you can pass these inputs as parameters:
dotnet
version to useThis is where the composite
actions come in!
Let’s create a reusable action using the composite
actions to build our dotnet
application.
In a new GitHub repository let’s create a folder called dotnet-build
and let’s add in it a file called action.yml
. The name of the file must be action.yml
or action.yaml
. If your file does not respect this convention, your GitHub Action will not work.
name: "Build dotnet"
description: "Build dotnet..."
inputs:
dotnet-version:
description: 'The dotnet version to use'
default: '2.1.x'
required: false
project-path:
description: 'The path to the project'
required: true
runs:
using: "composite"
steps:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ inputs.dotnet-version }}
- run: dotnet restore ${{ inputs.project-path }}
shell: bash
- run: dotnet build ${{ inputs.project-path }}
shell: bash
As you can see above we have the project path and the dotnet
version defined as input parameters. We pass them using $
and $
. Then we use the composite
keyword to be able to reuse this action and we add the list of all previous commands afterwards.
Because it’s a composite action we don’t specify a
runner
so we need to add the shell parameter to eachrun
action. If you don’t do it you will have this kind of error message: Required property is missing: shell.
As you have probably already noticed, the dotnet-version
has a default value set to 2.1.x
so it’s not required.
To reference a composite
in your different workflows and projects, it must be save in a specific repository. This common repository will contain different composites
with different versions of it:
You can have one project referencing the composite
action in the version v0.0.1
and another referencing the version v0.0.2
.
With that in mind, let’s commit and push this composite
action in a dedicated repository. Then add a tag
for instance: v0.0.1
.
The idea now is to update our first workflow with our new action:
name: Main
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build_dotnet:
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@v2
- name: Build dotnet
uses: damienaicheh/demo-action-composite/dotnet-build@v0.0.1
with:
dotnet-version: 5.0.x
project-path: src/DemoReusableTemplates.csproj
As you can see above we reference the dotnet-build
action using the name of the repository with the entire path to the folder that contain the action.yml
. Also, to specify the version of this composite
action we want to use, we add the number of the tag at the end. Here it’s @v0.0.1
.
As you saw it’s really easy to reuse your workflows between your projects and avoid duplication. Feel free to create your own repositories of composite
action! You will find the two GitHub repository for this article available here:
Happy coding!