loading...
Cover image for Setup automatic versioning in a Javascript/Nativescript project

Setup automatic versioning in a Javascript/Nativescript project

valentinprgnd profile image Valentin Prugnaud 🦊 (he / him) Originally published at whatdafox.com on ・4 min read

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:

$ npm install commitizen -g 
Enter fullscreen mode Exit fullscreen mode

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

$ commitizen init cz-conventional-changelog --save-dev --save-exact 
Enter fullscreen mode Exit fullscreen mode

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

$ git cz 
Enter fullscreen mode Exit fullscreen mode

Install Commitlint

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

$ npm install --save-dev @commitlint/cli @commitlint/config-conventional 
Enter fullscreen mode Exit fullscreen mode

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

module.exports = {extends: ['@commitlint/config-conventional']} 
Enter fullscreen mode Exit fullscreen mode

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

$ echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js 
Enter fullscreen mode Exit fullscreen mode

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:

$ npm install husky --save-dev 
Enter fullscreen mode Exit fullscreen mode

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

{ "hooks": { "commit-msg": "commitlint -e $GIT_PARAMS" } } 
Enter fullscreen mode Exit fullscreen mode

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:

$ npm i --save-dev standard-version 
Enter fullscreen mode Exit fullscreen mode

Then to generate your initial release version automatically, run:

$ standard-version --first-release 
Enter fullscreen mode Exit fullscreen mode

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:

$ standard-version 
Enter fullscreen mode Exit fullscreen mode

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:

"scripts": { "release": "standard-version" } 
Enter fullscreen mode Exit fullscreen mode

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:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="__PACKAGE__" 
    android:versionCode="220000" 
    android:versionName="2.2.0"
>
Enter fullscreen mode Exit fullscreen mode

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:


<plist version="1.0">
  <dict>
    <key>CFBundleShortVersionString</key>
    <string>2.2.0</string>
    <key>CFBundleVersion</key>
    <string>2.2.0</string>
  </dict>
</plist>
Enter fullscreen mode Exit fullscreen mode

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 & Info.plist files, we need to install a few tools to manipulate XML and PList files:

$ npm install --save-dev xml-js xml-beautifier plist
Enter fullscreen mode Exit fullscreen mode

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:

"scripts": {
  "pre-release": "node standard-version.js &amp;&amp; git add --all",
  "release": "standard-version -a"
}
Enter fullscreen mode Exit fullscreen mode

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:
"scripts": {
  "pre-release": "node standard-version.js &amp;&amp; git add --all",
  "release": "npm run pre-release &amp;&amp; standard-version -a"
}
Enter fullscreen mode Exit fullscreen mode
  1. Update our package.json with a Standard Version post-bump hook:
"standard-version": {
  "scripts": {
    "postbump": "npm run pre-release"
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

$ git push --follow-tags
Enter fullscreen mode Exit fullscreen mode

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

Discussion

pic
Editor guide