Semantic Version Your Web Extension
Preamble
If you’ve written any application that relies on auto release versioning, then you’ve probably had to decide on an objective method for deciding the version numbers associated with a new release.
There are a number of versioning schemes and for this project we will be using semantic versioning. If you do not yet know about semantic versioning you should take some time to read up on it, useful link here Semantic Versioning.
Overall, semantic versioning appeals to me because of the strict but easy to understand, for both authors and consumers, guidelines. When releasing a new version of my application, or in this case web extension a simple number tells the user updating what to expect and in this guide we will also touch on automatically creating versions and changelogs using semantic commits.
Without Further Ado!
The scope of this tutorial will be
- Adding node to your project
- Setting up GitHub actions CI
- Adding build and release steps
- Profit?
Prerequisites
We will be using the following tools, feel free to skip if you already have them or some alternative installed in your environment.
Ready, Set, Go!
Clone the starter repository, this includes a sample web extension for the purpose of this tutorial https://github.com/tophat/webext-training.
$ git clone git@github.com:tophat/webext-training.git
$ cd webext-training
Step 1: Create package.json
$ npm init
...
Is this OK? (yes) yes
This will give you a bunch of options you can fill in or ignore for now and at the end of the prompt you should have something like this
{
"name": "webext-training",
"version": "0.0.1",
"description": "Semantic versioning your web extension",
"main": "content.js",
"scripts": {
"test": "echo 'Good tests and continuous deployments make the world go round'"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tophat/webext-training.git"
},
"author": "iamogbz",
"license": "MIT",
"bugs": {
"url": "https://github.com/tophat/webext-training/issues"
},
"homepage": "https://github.com/tophat/webext-training#readme"
}
Note: The test script is a stub for now but can be easily configured to use any javascript testing framework.
Step 2: Add Dependencies
$ yarn add -D semantic-release @semantic-release/changelog semantic-release-chrome semantic-release-firefox-add-on
These are responsible for running the semantic release pipeline, with the second responsible for updating the repo changelog following the keepachangelog.com convention and the last 2, being plugins for Chrome and Firefox respectively.
Note: Remember to commit your changes after each step.
Step 3: Release Configuration
You will need to either configure semantic-release
by adding a release
section to your package.json
or creating a .releaserc
file, see options.
$ vim .releaserc.json
We will be specifying a few things
- Chrome extension ID
- Mozilla extension ID
- Location of packaged extension for each browser respectively
- Source and artifacts directory for
semantic-release-add-on
,semantic-release-chrome
defaults to the working directory which is suitable for now
{
"dryRun": true,
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
[
"semantic-release-chrome",
{
"extensionId": "ffifqrxowctbwefuzphbhgsreeltlrhw",
"asset": "webext-training.zip"
}
],
[
"semantic-release-firefox-add-on",
{
"artifactsDir": ".",
"extensionId": "biciwyjkdhcmbrkuugxdpxmsccxdiyib",
"sourceDir": ".",
"targetXpi": "webext-training.xpi"
}
],
[
"@semantic-release/github",
{
"assets": [
{
"path": "webext-training.zip"
},
{
"path": "webext-training.xpi"
}
]
}
]
]
}
Note: The dryRun
flag is useful to catch errors in your configuration before semantic-release
will attempt to publish the release.
Step 4: Enable Github Actions
Configure GitHub CI workflow to run tests and release on the master branch.
$ mkdir .github/workflow
$ vim .github/workflow/nodejs.yml
We will be specifying a few things
- The name of our workflow i.e.
Build
- When we want this workflow to be to run i.e. on
push
- The os environment using a docker image i.e
ubuntu-latest
- Checking out the repo branch commit code
- Setting up a version of node in the environment i.e.
12.x
- Installing the project dependencies i.e.
yarn install
- Running tests and coverage to confirm changes are good i.e.
yarn test
- When to run the deploy using
semantic-release
, in this case on master i.e.github.ref == 'ref/heads/master'
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: Install
run: |
yarn install
- name: Test
env:
CI: true
run: |
yarn test --ci --coverage
- name: Release
if: github.ref == 'refs/heads/master'
run: |
yarn semantic-release
See here for an introduction to github actions.
Note: After committing and pushing to GitHub, you should see the action run and publish a status. It will likely fail, but that’s where the next step comes in.
Step 5: Add CI Environment Variables
Some of the semantic-release
plugins need environment variables to be present before they can be successfully run. These can be added to your repository secrets and made available to the build GitHub action pipeline by visiting https://github.com/USER/REPO/webext-training/settings/secrets
.
@semantic-release/changelog
: Needs aGH_TOKEN
environment variable with push access to the repository set. Create a personal access token for releasing to GitHub https://github.com/settings/tokens.semantic-release-chrome
: Needs the environment variablesGOOGLE_CLIENT_ID
,GOOGLE_CLIENT_SECRET
, andGOOGLE_REFRESH_TOKEN
. More details here https://github.com/GabrielDuarteM/semantic-release-chrome#chrome-webstore-authentication.semantic-release-firefox-add-on
: Needs the environment variablesFIREFOX_API_KEY
andFIREFOX_SECRET_KEY
. More details here https://github.com/tophat/semantic-release-firefox-add-on#mozilla-add-on-authentication.
After adding these to your GitHub repo settings secrets, they can now be included in your GitHub action workflow pipeline.
Once you commit and push your CI should build successfully and the dry run release should complete with no hiccups. 🥳🎉
Once you feel comfortable with your current setup, remove the dryRun
flag from the release config and watch the magic happen.
Extras
Maybe you’re wondering how you can ensure your commits are semantic? Then look no further, you can easily extend your existing setup to lint commits and help with writing semantic commits.
Lint commits to ensure semantic correctness before they are written.
$ yarn add -D @commitlint/cli @commitlint/config-conventional husky
The first two handle linting the commit messages while the last is a useful package for running commands on git hooks.
Now all commit messages are checked to ensure maximum semanticity.
Construct semantically correct commits using semantic conventions.
yarn add -D commitizen cz-conventional-changelog
The first is the tool for writing commits while the second defines the prompts.
Now you can write semantic commits using yarn commit
.
Hope this was a good first or return expedition into the land of semantic versioning.