How to Automate Continuous Integration and Development, Versioning and Publishing
Using GitHub, CircleCI and Semantic Release
One of the most important tools in developing great software is the ability to automate. Imagine every time you need to release code to production, you have to repeat the same manual steps such as running tests, tagging/versioning your code changes and then manually provisioning or updating software or the configuration of your infrastructure, which can easily become the stuff of nightmares and create several horrific scenarios.
Imagine the cost in developer time, resources and also the fact that manual testing can become very complicated as code becomes more complex which can increase the chances of bugs and errors slipping through into production. Automating the process will save time and improve code quality, as you only need to focus on the quality of your code and errors can be detected before they get into production. Running automated tests every time code is deployed, ensures that bugs are caught quickly and fixed promptly.
An automated process also ensures that we can implement and test new features quickly and also fix bugs multiple times. An automated build process allows us to have a single source of truth in terms of how our code looks and how it works.
When we create and publish packages to NPM, we want to be able to automate how we track GIT changes and publishing of our package. This saves time from manually managing versions of the package.
There are a few tools that help simplify this process and I will be focusing on how I use the following tools:
- GitHub and CircleCI — to automate deployment and work flow
- Semantic release — to automate version management and package publishing to NPM.
Continuous Integration and Development, Versioning and Publishing
Being able to automate how we track GIT changes, versioning and publishing of our package aids our Continuous Integration and Continuous Development process.
Semantic Release provides us with the ability to automate version management and the publishing of our package to NPM.
Installing semantic-release-cli
as a dev dependency and running semantic-release-cli setup
to configure our CI/CD process allows us to automate the Semantic release setup process and sets up all default configurations.
With semantic-release-cli
, we can do the following:
semantic-release-cli steps
Next, we can use an existing an GitHub repository or create a remote repository in GitHub and push our project to the remote repository. You can read more about getting started with GitHub and how to create a repository.
I usually opt to manually setup my CI by setting up a new project in the CircleCI Dashboard. You can read more about how to set up CircleCI.
Next, CircleCI requires a configuration file in the project. We have to create a .circleci
folder and config.yml
which will include our jobs and workflows:
// Create CircleCI configuration folder
$ mkdir .circleci// Create configuration file
$ touch .circleci/config.yml
Set up all authentication tokens and environmental variables for your project such as GH_TOKEN
/ GITHUB_TOKEN
and NPM_TOKEN
in the CI or in this case, CircleCI. Read Creating a personal access token on how to create an access token on GitHub. Also, you must have an account on NPM to create an access token.
To add environmental variables, click on the Add Variable
button.
Install semantic-release
as a dev dependency, which automates the package release workflow including: determining the next version number, generating the release notes and publishing the package to NPM.
// Install Semantic release
$ yarn add -D semantic-release
Semantic Release expects commits to be in the conventional GIT commit format likefeat: add feature X
or fix: fix bug Y
that perform minor
and patch
version bumps respectively.
Next, because Semantic Release will set the version automatically, we set the version
property to 0.0.0-development
and add a semantic-release
command to the scripts
property in package.json
// package.json"version": "0.0.0-development",
...
"scripts": {
...
"semantic-release": "semantic-release"
},
All the manual steps above can be set up automatically running semantic-release-cli setup
command.
Next, you update your CircleCI config.yml
file as follows:
The CircleCI configuration is triggered on every push to our remote repository on GitHub. These steps are run in sequence, so this means that every time we trigger a deploy it runs the following steps as part of our workflow -
yarn install
— installs our dependencies;yarn lint
— lints and tests our code style;yarn test
— runs feature testsyarn build
— runs the build process of compiling our code from Typescript to JavaScriptyarn semantic-release
— creates a version tag and publishes the code to NPM
If any of the steps fail, then the entire build process will fail and nothing is released to production.
You can also drill down on the error to identify what caused the build to fail
To trigger a deployment, create a GIT commit and push to the master branch:
$ git commit -m "fix: xxx"$ git push origin master
This will trigger a new release in NPM:
To use, import the latest version of the library into any of your projects.
Wrap Up
Automating our code release process ensures that we ship quickly, save on costs and time, and improve our code quality and it should always be our core focus when architecting a new system / product.
I hope this article gives you a good foundation to automate your workflow, manage versioning and publish your package to NPM using the tools outlined above.
I have included a Github repository with the implementation described in this article. Feel free to clone, fork or star it if it helps you.