Setup automatic versioning in a Javascript/Nativescript project
Tags: nativescript, javascript, vue
Published: 2020-01-18 00:22:12

---
title: Setup automatic versioning in a Javascript/Nativescript project
slug: this-is-my-slug
published: true
tags: ['NativeScript', 'JavaScript', 'VueJS']
cover_image: https://whatdafox.com/assets/static/hero.07cc2b7.64f0f5e3f7dfdd48e5966d73cbf2718e.jpg
canonical_url: https://whatdafox.com/setup-automatic-versioning-in-a-javascript-nativescript-project/
description: "When developing with NativeScript, maintaining the version of your project can be time-consuming. Let’s explore the steps to improve this process."
---

When developing an application, maintaining the version of your project can be time-consuming. Let’s explore the steps to improve this process. # Use a commit message convention The very first step to versioning is to have a proper commit message convention. An easy way to get started is to leverage tools like Commitizen and Commitlint in your project and enforce them using Husky. 

## Install Commitizen 

> This is optional and will not enforce the commit style as Commitlint would. When you commit with Commitizen, you’ll be prompted to fill out any required commit fields at commit time. 

You can install Commitizen globally in one step: 

```bash 
$ npm install commitizen -g 
``` 

To initialize Commitizen for sensible defaults (using the cz-conventional-changelog convention), you can run this command: 

```bash 
$ commitizen init cz-conventional-changelog --save-dev --save-exact 
``` 

You can use Commitizen to help you build your commit message by typing this command and following the steps: 

```bash 
$ git cz 
```

## Install Commitlint 

Commitlint will help your team adhere to a commit convention. To install Commitlint in your project, run this command: 

```bash 
$ npm install --save-dev @commitlint/cli @commitlint/config-conventional 
``` 

To configure Commitlint to use our convention, create a `commitlint.config.js` file with the following content: 

```javascript 
module.exports = {extends: ['@commitlint/config-conventional']} 
``` 

For a one-liner, you can run this command in your terminal: 

```bash 
$ echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js 
``` 

## Install Husky 

Installing and configuring Husky in your project will enforce the commit style for each commit. To setup Husky in your project, run the following command: 

```bash 
$ npm install husky --save-dev 
``` 

Then create a `.huskyrc` file in the root of your project and add the following content: 

```javascript 
{ "hooks": { "commit-msg": "commitlint -e $GIT_PARAMS" } } 
``` 

This will run Commitlint before each commit and validate the commit message against your convention. If the commit message is invalid, the commit will be aborted. 

# Generate a changelog 

Now that we are following a commit message convention, we can easily generate a changelog for our project each time we issue a release. For that, I would recommend using Standard Version, which will help you automate versioning and `CHANGELOG` generation. 

To install Standard Version in your project, run: 

```bash 
$ npm i --save-dev standard-version 
``` 

Then to generate your initial release version automatically, run: 

```bash 
$ standard-version --first-release 
``` 

Standard Version will look at your commit history, generate the matching `CHANGELOG` file, commit the changes, and create a git tag. For subsequent releases, run: 

```bash 
$ standard-version 
``` 

This will not only generate/update the `CHANGELOG` file but also update your `package.json` file with the version number before committing the changes, and creating a git tag. 

--- 

You can also set up a npm script to generate your release version, by adding the following script to your `package.json`: 

```json 
"scripts": { "release": "standard-version" } 
``` 

--- 

# NativeScript-only: 

Automate the update of platform-specific manifests Now that we have an easy way to generate our changelog, our `package.json` reflecting the right version, we need to update the platform-specific manifests to reflect that version as well. 

For Android, the version is specified in the `AndroidManifest.xml` file. In a NativeScript project, you will typically find that file under the `app/App_Resources/Android/src/main` directory. 

Look for the `versionCode` and `versionName` attributes on the manifest tag: 

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="__PACKAGE__" 
    android:versionCode="220000" 
    android:versionName="2.2.0"
>
```

For iOS, the version is specified in the `Info.plist` file. In a NativeScript project, you will typically find that file under the `app/App_Resources/iOS` directory.
Look for the `CFBundleShortVersionString` and `CFBundleVersion` keys:

```xml

<plist version="1.0">
  <dict>
    <key>CFBundleShortVersionString</key>
    <string>2.2.0</string>
    <key>CFBundleVersion</key>
    <string>2.2.0</string>
  </dict>
</plist>
```

We need to create a script that can look for the version generated by Standard Version in our `package.json`, updates these two files accordingly and adds everything to the version commit automatically.

To update the `AndroidManifest.xml` &amp; `Info.plist` files, we need to install a few tools to manipulate XML and PList files:

```bash
$ npm install --save-dev xml-js xml-beautifier plist
```

Then create a `standard-version.js` file in the root directory of your project. We will use that file to open each file, update the version where appropriate and save the file back to the disk.

Now we can create a pre-release script to trigger this code, stage the files and update our release script to make ensure any staged files will be included in the version commit from Standard Version. Update your `package.json` like so:

```json
"scripts": {
  "pre-release": "node standard-version.js &amp;&amp; git add --all",
  "release": "standard-version -a"
}
```

> Having the pre-release npm script allows us to test our standard-version script without generating a release commit and tag.

Finally, to run our pre-release script every time we run our release script, we have two options:

1. Update the release script to run pre-release beforehand:

```json
"scripts": {
  "pre-release": "node standard-version.js &amp;&amp; git add --all",
  "release": "npm run pre-release &amp;&amp; standard-version -a"
}
```

2. Update our `package.json` with a Standard Version post-bump hook:

```json
"standard-version": {
  "scripts": {
    "postbump": "npm run pre-release"
  }
}
```

> Personally, I prefer the second option, as it will enforce the pre-release script even if I run Standard Version with the standalone standard-version command.

We can now push our new version to version control using:
 
```bash 
$ git push --follow-tags
``` 

and our version is updated in all the right places automagically.