NPM package deployment using YAML GitHub Actions
Wednesday, August 21, 2019
Recently GitHub announced that GitHub Actions will be moving away from the original HCL syntax in-favour of a YAML format similar to Travis CI and Bitbucket Pipelines. This means that HCL style actions will no longer work after September 30, 2019. It is possible to migrate using a migration script however in-some cases it may be required to reconfigure.
This particular issue occurred to me as actions which return a neutral result seem to fail the whole build with the YAML format. This means that using actions/bin/filter to trigger a deploy would fail the build unless a release tag was found. With this in mind, reconfiguring my GitHub Actions seemed like the best choice.
Desired Behaviour
My particular use of GitHub Actions is for deploying my small NPM packages.
To keep it simple I wanted the following to occur:
- Install dependencies, Build and Test package on each commit
- Publish package if a release tag was created
Creating the Action Configuration
Create the file .github/workflows/workflow.yml
Checking for Tag
This method simply builds and tests the package on any commit.
Then if it finds a tag starting with v, it will trigger a deploy.
So if a GitHub Release is created with the tag v2.3.4, it will trigger a deploy.
This is a bit naive however for my purposes I usually don't tag unless its a release.
One advantage of checking for a tag this way is that it cuts down on unneeded builds as a whole build can only ever run 1 or 2 times (2 in the case a build is deployed).
The GitHub Actions docs mentions being able to restrict actions to certain branches or tags however I could not get this to work.
name: build # Name Action Build
on: [push] # Trigger on push
jobs:
run:
runs-on: ubuntu-latest # Run on Ubuntu Docker image
steps:
- name: Checkout Repo # Checkout repo
uses: actions/checkout@v1
- name: Use Node.js # Configure Node.js
uses: actions/setup-node@v1
with:
node-version: '12.9' # Set Node.js Version
registry-url: 'https://registry.npmjs.org' # Set Node.js reigistry
- name: Deploy Info # Print GitHub Deploy info
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Install # Install dependancies
run: npm install
- name: Build # Build app if needed
run: npm run build --if-present
- name: Test
run: npm run test --if-present # Run tests if needed
- name: Publish
if: startsWith(github.ref, 'refs/tags/v') # Check if publish step should run
run: npm publish --access public # Publish package
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} # Set NPM auth token from GitHub Secrets
Checking for a Release
If you found the previous method too naive, you may want to check for a GitHub Release before triggering a deploy.
The drawback to this is that a few extraneous builds will be triggered as the release
event will fire both when the release is created
and published
. As far as I am aware this can not be restricted using the on
property.
To ensure we only deploy once, we will indicate to only run the Publish step when a release is published
.
name: build
on:
push: # Run build on push (commit in most cases)
tag: [] # Only run build if not tagged
release: # Run build on release
tag:
- v* # Check for release tag
jobs:
run:
runs-on: ubuntu-latest # Run on Ubuntu Docker image
steps:
- name: Checkout Repo # Checkout repo
uses: actions/checkout@v1
- name: Use Node.js # Configure Node.js
uses: actions/setup-node@v1
with:
node-version: '12.9' # Set Node.js Version
registry-url: 'https://registry.npmjs.org' # Set Node.js reigistry
- name: Deploy Info # Print GitHub Deploy info
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Install # Install dependancies
run: npm install
- name: Build # Build app if needed
run: npm run build --if-present
- name: Test
run: npm run test --if-present # Run tests if needed
- name: Publish
if: github.event_name == 'release' && github.event.action == 'published' # Check if publish step should run
run: npm publish --access public # Publish package
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} # Set NPM auth token from GitHub Secrets
Setting NPM Auth Token Secret
Simply go to your repo Settings and select the Secrets tab.
Then Add a new secret with the Name of NPM_AUTH_TOKEN
and set the Value to your NPM token.
Adding the GitHub Actions badge
GitHub now offers an undocumented API which will return nice Travis CI like status badge.
An example can be seen on the actions/toolkit repo.
The format for the API is as follows:
https://github.com/<user|org>/<repo>/<action_name>/badge.svg
The action_name
propery is the name
field in the YAML which in this case is build
.
An example of this would be:
https://github.com/woofers/ludum-dare-badges/workflows/build/badge.svg
To make it even nicer we can link the badge to our repo's actions page:
[![img](https://github.com/woofers/ludum-dare-badges/workflows/build/badge.svg)](https://github.com/woofers/ludum-dare-badges/actions)
It will look something like this: