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.
semantic-release / semantic-release
๐ฆ๐ Fully automated version management and package publishing
๐ฆ ๐ semantic-release
Fully automated version management and package publishing
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 and communicating the impact of changes to consumers.
Trust us, this will change your workflow for the better. โ egghead.io
Highlights
- Fully automated release
- Enforce Semantic Versioning specification
- New features and fixes are immediately available to users
- Notify maintainers and users of new releases
- Use formalized commit message convention to document changes in the codebase
- Publish on different distribution channels (such as npm dist-tags) based on git merges
- Integrate with your continuous integration workflow
- Avoid potential errors associated with manual releases
- Support any package managers and languages via plugins
- Simple and reusable configuration via shareable configurations
How does it work?
Commit
โฆ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.
- 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",
- Add a new property to the package.json,
publishConfig
. This will be the home of our semantic-release configuration.
"publishConfig": { "access": "public", "branches": ['master'] }
- 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
-
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
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.
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.
ATTENTION: This project is no longer maintained.
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
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โฆ
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:
Comment for #12
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
Top comments (1)
That's amazing, thanks for the tutorial it really helped me out setting ci for my library for the first time.