How to automate releases and publish packages to NPM using GitHub Actions

Nanthankumaran S
3 min readApr 7, 2023

--

In this article, we will take a look at how to automate releases and publish packages to NPM using GitHub Actions.

Step 1: Add tokens to GitHub

We need 2 tokens to accomplish this task of automating releases and publishing packages.

  • PA_TOKEN - Personal Access Token from GitHub
  • NPM_TOKEN - NPM Token for automation

PA_TOKEN

Head over to https://github.com/settings/tokens/new to generate a new Personal Access Token

If you wish to set expiration, make sure to check the token expiration before releases

NPM_TOKEN

Go to Settings > Access Tokens > Generate new token > Classic token

Make sure you have chosen Automation

Add them to GitHub

Open Settings of the repository. Under Security > Secrets > Action, click New Repository Secret and add your tokens

Make sure to be consistent in naming your Secrets in GitHub. Mine will be

PA_TOKEN for Personal Access Token and NPM_TOKEN for NPM Registry Token

Step 2: Create workflows

We are going to create 2 workflows

  1. releases.yml — To generate release whenever we commit
  2. publish.yml — To publish the package once the release is published

.github/workflows/release.yml

name: Releases
on:
push:
branches:
- main

jobs:
changelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Conventional Changelog Action
id: changelog
uses: TriPSs/conventional-changelog-action@v3.7.1
with:
github-token: ${{ secrets.PA_TOKEN }}
version-file: './package.json,./package-lock.json'
- name: create release
uses: actions/create-release@v1
if: ${{ steps.changelog.outputs.skipped == 'false' }}
env:
GITHUB_TOKEN: ${{ secrets.PA_TOKEN }}
with:
tag_name: ${{ steps.changelog.outputs.tag }}
release_name: ${{ steps.changelog.outputs.tag }}
body: ${{ steps.changelog.outputs.clean_changelog }}

.github/workflows/publish.yml

name: Publish to NPM
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '16'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies and build 🔧
run: npm ci
- name: Publish package on NPM 📦
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Explanation:

The first entry point will be release.yml, where while committing the code it will generate a new release based on the conventional commits (will see that in minutes).

After each proper commit, the release.yml will change the CHANGELOG.md, package.json & package-lock.json

Then once the release was created the publish.yml will publish the package with the generated release to NPM Registry

Conventional Commits

I have written a detailed article about conventional commits here. Do check it out for a better understanding

https://nanthakumaran.medium.com/conventional-commits-simplify-your-project-history-and-automate-tasks-29007273e198

A quick recap. These commit messages are based on semantic software versioning. To generate releases, we need to follow this conventional commit format

Based on this the commit message needs to be composed.

  • fix - Bug Fixes
    eg: git commit -m "fix: Fixed a typo in index.js"
  • feat - Features (Minor changes)
    eg: git commit -m "feat: Added payment feature"
  • BREAKING CHANGE - Major changes
    eg: git commit -m "BREAKING CHANGE: Migration from Node 12 to Node 16"

These are the basic conventional commit messages. There are some additional conventional commit messages too. They are,

docs:, style:, refractor:, chore: and much more.

Check out https://www.conventionalcommits.org/en/v1.0.0/ for more information about conventional commits

I hope you are clear with the detailed step-by-step guide to automate releases and publish packages to NPM using GitHub Actions. Thanks for reading

Follow Nanthakumaran on Twitter LinkedIn GitHub Medium

--

--

Nanthankumaran S

Associate Engineer at Presidio | Software, Cloud and Data Engineer | 2x AWs