loading...

Publishing a JavaScript Package to NPM automatically with Github Actions

aleccool213 profile image Alec Brunelle Updated on ใƒป5 min read

Want more great content like this? Sign up for my newsletter, visit: alec.coffee/signup

Maintaining an open-source package can be a time-consuming task. Issues to be triaged, pull requests to be reviewed and changelogs to write. Publishing new versions of the code is usually done manually and making it automated is often on the back-burner of the maintainers' to-do list. There are a couple of key features of a rock-solid release process, the changelog, Git tags, NPM versions, and enforcing Semantic Versioning. Keeping all these in sync makes it so users understand changes in a release and understand how to keep up-to-date. Maintainers who fail to perform all of these steps will have a hard time triaging issues, which leads to more time debugging and less time spent coding. I recently came across a combo of tools, semantic-release and Github Actions, which made the entire release process automated, transparent, and simple to understand.

GitHub logo semantic-release / semantic-release

๐Ÿ“ฆ๐Ÿš€ Fully automated version management and package publishing

๐Ÿ“ฆ๐Ÿš€ semantic-release

Fully automated version management and package publishing

Join the community on Spectrum Travis Codecov Greenkeeper semantic-release

npm latest version npm next version npm beta version

semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes and publishing the package.

This removes the immediate connection between human emotions and version numbers, strictly following the Semantic Versioning specification.

Trust us, this will change your workflow for the better. โ€“ egghead.io

Highlights

How does it work?

Commit message format

semantic-release uses the commit messages toโ€ฆ

How It Works

Before we talk about implementation, it's important to understand what work our tools will perform. That way, if there are problems or modifications, we can fix them. semantic-release is going to do the majority of the work here, they say it best on their README.

It automates the whole package release workflow including determining the next version number, generating the release notes and publishing the package.

The Next Version Number

During a release, to determine the next version number, the tool reads commits since the last release. It knows your last release by looking at your Git tags. Based on the type of commit, it can determine how to bump up the version of the package. For this to work, commits need to be written in a certain way. By default, semantic-release uses the Angular Commit Message Conventions. This is critical because consumers of the package need to know if a new version releases a new feature, introduces breaking changes or both. For example, if someone commits fix(pencil): stop graphite breaking when too much pressure applied, semantic-release knows this contains a fix and to create a patch release. This will increase the version in the minor version range (0.0.x).

Never seen this type of versioning before? Check out Semantic Versioning.

After analyzing all the commits, it takes the highest priority type of change and makes sure that is the one that is applied. For example, if two commits were introduced since the last release, one breaking (x.0.0) and one minor (0.0.x), it would know to just up the version by breaking range.

Generating Release Notes

Once it has done finding out what type of release the next version is, changelog notes are generated based on the commits. semantic-release doesn't use conventional CHANGELOG.md file to notify users of what has changed, it does so with a Github Release which is attached to a Git tag.

An example of a Github Release that semantic-release generates and pushes on builds.

Automating With Github Actions

So semantic-release will be the tool to perform most of the work, but we still need a service to run the tool on. That is where Github Actions comes into play. When pull-requests are merged into master (or any base branch you configure), Github Actions will run a job that simply runs semantic-release with your configuration. All of the work we described previously will be performed.

An example of a Github Actions run using semantic-release to publish a new release.

Steps to Take

We will be using as many defaults as possible to make configuration dead simple. semantic-release uses a plugins system to enhance functionality. Here are the default plugins semantic-release uses.

Let's go over the steps which will make this all run smoothly.

  1. Add a dummy version property to the package.json of package. Released code will have the proper version written to this file by semantic-release.
        "version": "0.0.0-development",
  1. Add a new property to the package.json, publishConfig. This will be the home of our semantic-release configuration.
        "publishConfig": { "access": "public", "branches": ['master'] }
  1. The last step is to create a Github Action YAML file. This will tell Github Actions what to do when a commit is made to the repository.
        # .github/workflows/test-and-release.yaml

        name: Test and Release
        on: [push]

        jobs:
        test-and-release:
            name: Run tests and release
            runs-on: ubuntu-18.04
            steps:
            - name: Checkout
                uses: actions/checkout@v1
            - name: Setup Node.js
                uses: actions/setup-node@v1
                with:
                node-version: 12
            - name: Install dependencies
                run: npm ci
            - name: Run tests
                run: npm test
            - name: Release
                env:
                GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
                NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
                run: npm run semantic-release
  1. Add NPM_TOKEN to the secrets in the Github repos settings page. You can generate one of these from your NPM account at https://www.npmjs.com/settings//tokens

    screenshot of github repo settings screen

And that's it! You have a fully automated package release process ๐ŸŽ‰

Bonus

I implemented this on a repo we recently open-sourced at Yolk AI. It's named next-utils and everything described here can be found there.

GitHub logo Yolk-HQ / next-utils

๐Ÿฅฉ ๐Ÿณ A set of Next.js HoC utilities to make your life easier

next-utils

A set of Next.js utilities to make your life easier.


Actions Status version downloads MIT License

All Contributors PRs Welcome Code of Conduct

Tweet


Overview

React Higher-Order Components for use with Next.js, enabling simple, server-side-render-compatible configuration of functionality such as:

Table of Contents

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's dependencies:

npm install @yolkai/next-utils

Note

NOTE: Using any of these Higher-Order-Components will disable Automatic Static Optimization (statically built pages), since the Higher-Order-Component forces every page to implement getInitialProps.

๐Ÿ”ฎ Apollo Client

appWithApolloClient

Example Usage

Code

React higher-order component (HoC) which wraps the App component and:

  • Performs the page's initial GraphQL request on the server, and serializes the result to be used as the initial Apollo state once the client mounts.
  • Passes the Apollo client to theโ€ฆ

Another great thing about using semantic-release with Github Actions is that it has out-of-the-box support for bot comments. It will go into every issue and pull-request closed since the last release and comment to make sure everyone is aware. Here is an example:

#

๐ŸŽ‰ This issue has been resolved in version 1.0.0 ๐ŸŽ‰

The release is available on:

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

If you liked this post, check out more at https://blog.alec.coffee and signup for my newsletter

Posted on Mar 25 by:

aleccool213 profile

Alec Brunelle

@aleccool213

Thoughts and Words on JavaScript, Privacy, The Web, Remote Working

Discussion

markdown guide