Github composite actions
Prerequisite
This article assumes basic knowledge of github actions.
If you are not familiar with it, read on here.
What’s new ?
If you have ever copied pasted some .yml workflow from one repository to the other, to get the same job done in your CI, then this may well be for you.
Github recently released a new feature to the already existing composite actions. As you may have guessed from the name, “composite actions” is a way to extract and create a new action that encapsulates several others.
Now this new feature allows you to compose github actions from the marketplace, alongside running your custom shell commands.
You can read more here.
The advantages are obvious:
- Encapsulate a series of fine-grained actions (like caching a file) into a reusable more abstract action
- Reduce the code size of your workflows by extracting and encapsulating jobs (or parts of it)
- Maintain your action code in one place instead of making upgrades everywhere because of the duplication (you’ll still need to update the version used in each workflow relying on the composite).
Example – Building and Publishing an NPM library
Say you have several libraries, each hosted in their own repository.
You probably have a job that looks like this:
# in my-library/workflows/release.yml jobs: release: name: release runs-on: ubuntu-latest steps: - name: Checks out the repository uses: actions/checkout@v2 - name: Sets up node JS v16 uses: actions/setup-node@v2 with: node-version: '16.x' - name: Install the dependencies run: yarn install --frozen-lockfile - name: Run the tests run: yarn test - name: Builds the assets run: yarn build - name: Publishes to NPM run: yarn publish
It’s a simple job that installs the packages -> runs the tests -> builds -> publishes the package.
Well thanks to Github composite action, assuming your process is always the same across your libraries, you can now encapsulate that jobs into à composite action:
# in my-github-publish-to-npm-composite-actionname: 'publish-to-npm-composite-action' description: 'installs, builds, tests, publishes to NPM' runs: using: "composite" steps: - name: Checkout repository uses: actions/checkout@v2 - name: Setup Nodejs uses: actions/setup-node@v2 with: node-version: 16.x - name: Install the dependencies run: yarn install --frozen-lockfile - name: Run the tests run: yarn test - name: Builds the assets run: yarn build - name: Publishes to NPM run: yarn publish
After publishing your action, you can now simply include it in your library workflow:
release: runs-on: ubuntu-latest steps: - uses: namespace/my-github-publish-to-npm-composite-action@v1.0.0
And voilà !
Customising your actions
If your workflows slightly differ, you can of course pass parameters / environment variables to your composite action so it can be tweaked, while still benefiting from having the action source code centralised in one place.
You can for example take your node version from the environment:
name: 'publish-to-npm-composite-action' description: 'installs, builds, tests, publishes to NPM' runs: using: "composite" steps: - name: Checkout repository uses: actions/checkout@v2 - name: Setup Nodejs uses: actions/setup-node@v2 with: node-version: ${{ env.NODE_VERSION }} - name: Install the dependencies run: yarn install --frozen-lockfile - name: Run the tests run: yarn test - name: Builds the assets run: yarn build - name: Publishes to NPM run: yarn publish
And in your library, pass the node version as an env variable
release: runs-on: ubuntu-latest steps: - uses: namespace/my-github-publish-to-npm-composite-action@v1.0.0 env: NODE_VERSION: 16