Semantic Release Automation - Part 2 - Setup Semantic Release Package
Tags: javascript, devops, github, webdev
Published: 2020-05-20 05:00:03

Previously I talked about semantic version and why it is important to follow the guidelines for versioning, in this part of the series i will talk about how to maintain the package versioning automatically using [semantic release package](https://github.com/semantic-release/semantic-release).

Here is a short description about semantic release from the authors: 
>semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes and publishing the package.

Semantic release is relying on the **commit format** to determine the next release based on it. You can configure any format you want, the default format is [angular message format](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines). for example if we have a package version `1.0.0`, a commit message with this format:
- `feat: added new feature` will bump the version to 1.1.0 
- `fix: added more config` will bump the version to 1.0.1 

For more details about how semantic release works you can find it [here](https://github.com/semantic-release/semantic-release#how-does-it-work).

**Note:** If you didn't follow the naming conventions, semantic release package won't be able to determine the next release version. Also it would be a problem when you have a large team and you want all of them to follow the rules, luckily there are packages for this, we will talk about them shortly.

I will use semantic release in a simple [react] (https://reactjs.org/docs/create-a-new-react-app.html) project and will use [Github actions](https://github.com/features/actions) along with [Github packages](https://github.com/features/packages) to automate our workflow.

You can find a full example that we want to achieve at the end of this series [here](https://github.com/abdelrahmanahmed/semantic-release-example). Get Ready 🔥

### **Table Of Contents**
* [Prerequisites 📋](#Prerequisites)
* [Installing semantic release package 📦](#installing-semantic-release-package)
* [Configure Semantic Release package ⚙️](#configure-semantic-release-package)
* [Pipeline Setup ▶️](#pipeline-setup)
* [See the workflow in action 🧪](#see-the-workflow-in-action)


### **Prerequisites** 📋 <a name="prerequisites"></a>
- Basic knowledge of CI/CD workflow, you can refer to my 2 mins [article](https://dev.to/abdelrahmanahmed/continuous-integration-continuous-delivery-and-continuous-deployment-in-a-nutshell-1018) about this topic.
- Installed [npm](https://www.npmjs.com) >=5.2.0
- Installed [Git](https://git-scm.com/).
- Fresh repository hosted on [Github](https://github.com/).
- Create [Github token](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line), this will be used by semantic release package.


### **Installing semantic release package** 📦 <a name="installing-semantic-release-package"></a>
We will use [sematnic release CLI](https://github.com/semantic-release/cli) package for quick installation. This will help us to configure multiple things:
 - Git repository.
 - Package Manager repository **(Github packages)**
 - Continuous Integration platform **(Github actions)**
Use this command to configure our workflow:  
```sh
npx semantic-release-cli setup
```
You will be asked several questions about your credentials and configuration
 
![CLI](https://dev-to-uploads.s3.amazonaws.com/i/nsiya41ueo4dnrsy19k0.png)

  - **NPM registry** the registry which you will store your package on it, in our case this we will use Github packages, so copy this url `https://npm.pkg.github.com/` and press enter.
  - **Authentication Method** Choose token based authentication.
  - **NPM username** here we will configure our Github packages credentials, so you need to enter your github username.
  - **NPM password** this will be the github token which you have generated it earlier.
  - **Github username** this will be the same as username you enterd in NPM username, so enter it again 😅.
  - **Github password** wrtie your Github password.
  - **Which CI** we will be using Github actions, so choose the last option (other).

If everything goes Ok, the CLI will print out `GH_TOKEN` and `NPM_TOKEN`. These values will be used by our CI (Github actions), to be able to push automated commits and publish your package to Github packages.

Now we are going to use `GH_TOKEN` and `NPM_TOKEN` and we will create new secrets in Github, which will be used by our pipelines.Go to your repository settings -> find **secrets** tab in the left panel -> create two secrets, one for `GH_TOKEN` and the other for`NPM_TOKEN`. See below image:

![github secrets](https://dev-to-uploads.s3.amazonaws.com/i/0xihfqxs84ilx28chlr4.png)

Edit your `package.json` file and add our [publish config](https://docs.npmjs.com/files/package.json#publishconfig): 
```javascript
	"publishConfig": {
		"registry": "https://npm.pkg.github.com/",
		"pkgRoot": "build"
	}
```
`pkgRoot` key is a path to your build directory, here we are using `create-react-app` to build our package and produce the result to build directory. With these configations we will able to publish our package to Github packages.

Also change the version value of your `package.json` file and let it start with `1.0.0` 
```javascript
"version":"1.0.0"
```

### **Configure Semantic Release package** ⚙️ <a name="configure-semantic-release-package"></a>

Semantic Release has several configuration out of the box, we will use some of them to build our workflow:
- Create a new file (`.releaserc.json`) in your root directory (there are [other ways](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#configuration-file) to create this file.
-  copy the content of this gist to your `.releaserc.json` file and change `repositoryUrl` to your repository url.

{% gist https://gist.github.com/abdelrahmanahmed/3ac96476bb7b0b50024d786eccc32971 %}

You may want to follow the [documentation](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#options) for more clarification. 


The default [plugins](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/plugins.md) used be semantic release package are `['@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator', '@semantic-release/npm', '@semantic-release/github']`

I added two more external plugins [@semantic-release/changelog](https://github.com/semantic-release/changelog) (to create an automated [changelog file](https://github.com/abdelrahmanahmed/semantic-release-example/blob/master/CHANGELOG.md)) and [@semantic-release/git](https://github.com/semantic-release/git) (to bump version in package.json and package-lock.json files and create a new commit with this change)

Dont forget to install them in your dev dependencies   
```sh
npm install @semantic-release/git -D && npm install @semantic-release/changelog -D
```  

### **Pipeline Setup** ▶️ <a name="pipeline-setup"></a>
To Define your Github actions, create `.github` folder in your root project path and add `workflows` folder inside it. After that create your action, for example : `ci.yml`. A full path should be like this `.github/workflows/ci.yml`. 

Here is a full example of basic CI using semantic release command, copy this example to your action file and replace `SEMANTIC_RELEASE_GH_TOKEN` and `SEMANTIC_RELEASE_NPM_TOKEN` with your secrets name.

{% gist https://gist.github.com/abdelrahmanahmed/f82458d7d1320c2f7f24ce98c0fb1a8e.js %}


You may noticed that we add this condition the build process `if: "!contains(github.event.head_commit.message, 'skip ci')"`, this means that any commit message contains skip ci will not trigger complete the process of the pipelines, this is useful you wish to pervert unnecessary pipelines triggers for some commit messages. 

### **See the workflow in action** 🧪 <a name="see-the-workflow-in-action"></a>

Now push your commits to your repository and navigate to actions tab in your repository and watch your pipelines  progress. If everything goes well you should see a green indicators in all of action's steps. 

![successful-piplines](https://dev-to-uploads.s3.amazonaws.com/i/jcpvphknnlz3l58hg86t.png)

Semantic release package has created a new release, you can view it in releases tab. Also you can view your deployed package at packages tab

![packages and releases tabs](https://dev-to-uploads.s3.amazonaws.com/i/wkqtkgdued0r1w13lo3h.png)

Configurations🎉 now you have a built a basic automated workflow with github actions and semantic release package. Next we will continue our setup and implement the **continues deployment** part to deploy our app to [Github pages](https://pages.github.com/).



Thanks to freepik platform, i was able to build my article covered using their awesome designs. 
<a href="https://www.freepik.com/free-photos-vectors/business">Business vector created by macrovector - www.freepik.com</a>