1

I have an Angular (v12) project that gets updated regularly. Sometimes we do a build two or three times in a single day.

The client wants to display the current version of the application in the format YYYY.MM.DD.x, x being the build number for the day e.g. v2022.03.14.3 would be the version number for the third build of today.

In the environments I do have a property for this, which I then use in the relevant component, but currently I have to update it manually every time I run ng build and then commit the change to the git repository for next time.

I was hoping I could find a way to automate this, even if I only get the date.

SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41
Lukho Mdingi
  • 518
  • 1
  • 5
  • 18

4 Answers4

2

You can use git tags or releases to send as arg to compile docker, this way you will know exactly which commit was deployed:

// package.json

{
  "name": "dashboard",
  "version": "0.0.1",
  "scripts": {
    ...
    "build:dashboard:production": "ng build dashboard --configuration=production",
    "build:dashboard:staging": "ng build dashboard --configuration=staging",
  }
...
}
// environment.prod.ts

export const environment = {
  release: '<VERSION>',
  production: true,
  apiHost: 'https://example.app',
};
# Dockerfile

# Stage 0, "build-stage", based on Node.js, to build and compile the frontend
FROM node:16.14.0 as build

WORKDIR /app

ARG config
ARG version

COPY / /app
RUN sed -i "s|<VERSION>|\"${version}\"|" ./projects/dashboard/src/environments/environment.${config}.ts

RUN npm install
RUN npm run build:dashboard:${config}

...
Chris
  • 2,117
  • 13
  • 18
  • 1
    This is the best solution if building with docker. If building on docker hub, you can even use a hook to pass the latest git hash and a date as arguments! – Luke Kroon Dec 06 '22 at 19:06
1

In your tsconfig.app.json file, add node to the types array. If there is not a already types array, add it under compilerOptions in the json root.

  "compilerOptions": {
    "types": ["node"]
  }
}

Step 2 - Adding environment variables Find your environment constant in src/environments. You should see two files, one for prod, environment.prod.ts, and one for not-prod, environment.ts. In production, I keep it simple and add the appVersion variable without any changes.

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

In the non-production environment though, I like to add a dev tag.

appVersion: require('../../package.json').version + '--dev';

This helps me remember if I'm in a non production environment, because there is nothing worse than troubleshooting a problem in the wrong environment.

Step 3 - Adding the version to an Angular component Likewise this is easier than it sounds. Now that the node types and version variable are available, they just need to be accessed and displayed somewhere in the app. I prefer to add this to the bootstrapped component, which is usually AppComponent. This best way I've found to do this is with a host binding.

Note: You do not need to specify prod vs non-prod in your environment import. When Angular builds, it will use the production environment if the --prod build flag is used.

import { Component, HostBinding } from '@angular/core';
import { environment } from 'src/environments/environment';

@Component({
  ...
})
export class AppComponent {
  @HostBinding('attr.app-version') appVersionAttr = environment.appVersion;
}
Step 5 - Adding npm version to your pipeline
If your pipeline stack offers automatically created version numbers, just make sure they are compliant with normalized SEMVER2. Once you have add a task in your pipeline to run the npm command
npm version $(build.buildNumber)

Last Thoughts Now that you've added a version number, build, build, build and check the check your work. You should see an html attribute on whatever html element you added the host binding to. For me it looks like this:

<app-root app-version="3.1.28-master"></app-root>
0

In the past I have added a key to my package.json file called something like dateVersion (since npm is semver only). I then leverage json-loader in webpack, which will allow you to simply: import { dateVersion } from './../package.json' into the part of the application you wish to display your version.

I bet you can come up with a way to update the package file at the same moment you update the environment file.

There may be a more ng way to do this, but the above is what I have done in the past and continue to do in most of my frontends.

Levi
  • 1,552
  • 1
  • 11
  • 10
0

Step 1

(to show the version from package.json)

Add appVersion param to your enviorment.ts.

export const environment = {
    appVersion: require('../../package.json').version;
};

Import environment to your component and access appVersion and use it on your template.

import { environment } from 'src/environments/environment';

currentVersion : string = environment.appVersion;
today: Date = new Date();

In html

<div>Current version: {{today | date : 'YYYY.MM.DD'}} {{currentVersion}}</div>

If you want the date to be date when build was done then follow this: https://medium.com/@izzatnadiri/how-to-inject-and-display-an-angular-build-timestamp-and-application-environment-details-in-67a312f80656

Step 2

(to auto-increment version on build)

Lets use npm version patch to change it. We bump the version number up on npm run build.

Add to package.json scripts

"prebuild": "npm --no-git-tag-version version patch"

pacakge.json before build

{
  "name": "application-versioning",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "prebuild": "npm --no-git-tag-version version patch",
    "build": "ng build --prod --aot",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
...

Then run command

npm run build

After build notice version change

{
  "name": "application-versioning",
  "version": "0.0.1",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "prebuild": "npm --no-git-tag-version version patch",
    "build": "ng build --prod --aot",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  }
...

https://docs.npmjs.com/cli/v8/commands/npm-version

Joosep Parts
  • 5,372
  • 2
  • 8
  • 33
  • In Step 1, `today` will always be the current date and not the last build's date. If the last build was on Monday, it should show 2022.03.21. – Lukho Mdingi Mar 25 '22 at 09:51
  • Yeah, that's true. I didn't specially read out that it was supposed to be the date of the build - but I guess that makes sense. – Joosep Parts Mar 25 '22 at 09:57