How to Add a Build Number to the Web Build in Angular
Tags: angular, build, version, deployment
Published: 2023-08-15 05:18:47

Have you ever found yourself wondering which version of a web build is running when you deploy your angular code? By adding some scripts to the angular build command I was able to solve this problem.

## Instructions

### Step 1 - Adding version in your environment file

In your `environment.ts` file, add a version property from the `package.json`

```typescript
export const environment = {
  production: true,
  version: require('../../package.json').version,
};
```

### Step 2 - Create a build number by using the current time and previous build number

Create a `build-version.js` file on the root folder and add the following:

```javascript
const { writeFileSync } = require('fs');
const { join } = require('path');

const BUILD_VERSION_PATH = join(__dirname, 'src/build-version.json');

function getTimestampBasedVersion() {
  return parseInt(new Date().getTime() / 1000);
}

let currentIteration = getTimestampBasedVersion();

try {
  currentIteration =
    require('./build-version.json')?.currentIteration ||
    getTimestampBasedVersion();
} catch (e) {
  currentIteration = getTimestampBasedVersion();
}

const buildVersion = {
  currentIteration: currentIteration + 1,
  buildVersion: `${
    require('./package.json')?.version
  }-build.${currentIteration}`,
};

writeFileSync(BUILD_VERSION_PATH, JSON.stringify(buildVersion, null, 2));
```
This will try to fetch the previous build number from the `build-version.json` file and increment it by 1, if this file is not found then it will use the current timestamp as the build number.

The **fs.writeFileSync()** creates a new file if the specified file does not exist.

The **path.join()** method is used to join a number of path-segments using the platform-specific delimiter to form a single path.

Add `build-version.json` to the `.gitignore` file so that it does not create a commit on the build generation.

If you don’t want the current timestamp as the build number then you can start with 1 as the initial build number.

```javascript
const { writeFileSync } = require('fs');
const { join } = require('path');

const BUILD_VERSION_PATH = join(__dirname, 'src/build-version.json');

let currentIteration = 1;

try {
  currentIteration =
    require('./build-version.json')?.currentIteration || currentIteration;
} catch (e) {
  currentIteration = 1;
}

const buildVersion = {
  currentIteration: currentIteration + 1,
  buildVersion: `${
    require('./package.json')?.version
  }-build.${currentIteration}`,
};

writeFileSync(BUILD_VERSION_PATH, JSON.stringify(buildVersion, null, 2));
```

> _This approach could fail if the deployment creates a new docker image every time, then the build number will always be 1. So in those cases, we can use the current timestamp as the build number._

### Step 3 - Adding bash script to generate the build number

Create a `build-version.sh` file and add the following:

```bash
node build-version.js
printf "\n\n"
cat src/build-version.json
printf "\n\n"
```
This will generate the build version and also print the build number on the console of the docker’s or Jenkin’s console.

### Step 4 - Showing the build number on the web browser

Add the following code snippet to the `app.component.ts` to show the build number on the console of the web browser

```typescript
import { Component } from '@angular/core';
import { environment } from 'src/environments/environment';
import * as build from '../build-version.json';

@Component({
  selector: 'ra-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {

  constructor() {
    this.displayBuildVersion();
  }

  /**
   * To display the current build version on the console
   */
  displayBuildVersion(): void {
    console.log(
      `%cCurrent version: ${environment.version}`,
      `background: #0082af; padding: 8px 12px; border-radius: 4px; color: #fafafa; font-size: x-large`
    );

    try {
      console.log(
        `%cCurrent build number: ${build?.buildVersion}`,
        `background: #0082af; padding: 8px 12px; border-radius: 4px; color: #fafafa; font-size: large`
      );
    } catch (e) {
      console.warn(e);
    }
  }
}
```

### Step 5 - Running the build version script along with the angular build commands

Add the build version script `build-version.sh` to the build commands in the `package.json`

```javascript
{
  ...
  "version": "1.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build:prod": "bash build-version.sh && ng build --configuration production --aot",
    "watch": "ng build --watch --configuration development",
    "test": "ng test --code-coverage",
    ...
  },
  ...
}
```

### Step 6 - Running your angular build and generating the build number

Once you run the build and deploy the code on the server you will be able to see the build numbers during the build in docker or Jenkins and also in the deployed website.

![Jenkin’s console output showing the current build number](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hn9rfd1dkk6dchnnlkq6.png)

![Web browser’s console log showing the current version and current build number](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f5654y4lieodurgpr5wv.png)

## Last thoughts
Now you’ve added the build numbers, build again and again to see the build version being incremented on each build.

Happy coding!