The image above is shown on the pageTest environment/development environmentVersion information.

I’ll talk about that later

The figure above shows each submissionGit CommitOf course, here I’m recording every commit, you can record every build.

So, let’s use Angular to implement it. React and Vue do the same thing.

Set up the environment

Since the focus here is not on scaffolding, we can generate a project directly using angular-CLI scaffolding.

Step 1: Install scaffold tools

npm install -g @angular/cli
Copy the code

Step 2: Create a project

# ng new PROJECT_NAME
ng new ng-commit
Copy the code

Step 3: Run the project

npm run start
Copy the code

The project is running, listening on port 4200 by default, just open http://localhost:4200/ in your browser.

If port 4200 is not occupied

The ng-commit project focus folder SRC consists of the following:

SRC ├ ─ ─ app / / application subject │ ├ ─ ─ app - routing. The module. The ts / / routing module │ │ └ ─ ─ app. The module. The ts / / application modules ├ ─ ─ assets/resources/static ├ ─ ─ the main, ts ├ ─ ├ ─ less.txt //Copy the code

We will add the services directory to the app directory and the version.json file to the assets directory.

Record the information submitted each time

Create a file version. TXT in the root directory to store the submitted information. Create a file in the root directory called commit.js to manipulate the commit information.

With the focus on commit.js, let’s dive right into the topic:

const execSync = require('child_process').execSync;
const fs = require('fs')
const versionPath = 'version.txt'
const buildPath = 'dist'
const autoPush = true;
const commit = execSync('git show -s --format=%H').toString().trim(); // The current version number

let versionStr = ' '; // Version string

if(fs.existsSync(versionPath)) {
  versionStr = fs.readFileSync(versionPath).toString() + '\n';
}

if(versionStr.indexOf(commit) ! = -1) {
  console.warn('\x1B[33m%s\x1b[0m'.Warming: The current Git version data already exists! \n')}else {
  let name = execSync('git show -s --format=%cn').toString().trim(); / / name
  let email = execSync('git show -s --format=%ce').toString().trim(); / / email
  let date = new Date(execSync('git show -s --format=%cd').toString()); / / date
  let message = execSync('git show -s --format=%s').toString().trim(); / / that
  versionStr = `git:${commit}\ n the author:${name}<${email}> \ n date:${date.getFullYear()+The '-'+(date.getMonth()+1) +The '-'+date.getDate()+' '+date.getHours()+':'+date.getMinutes()}\ n:${message}\nThe ${new Array(80).join(The '*')}\n${versionStr}`;
  fs.writeFileSync(versionPath, versionStr);
  // After the version information is written, it is automatically committed to the current branch of Git
  if(autoPush) { // This step can be written according to actual requirements
    execSync(`git add ${ versionPath }`);
    execSync(`git commit ${ versionPath }-m Automatically submits the version information);
    execSync(`git push origin ${ execSync('git rev-parse --abbrev-ref HEAD').toString().trim() }`)}}if(fs.existsSync(buildPath)) {
  fs.writeFileSync(`${ buildPath }/${ versionPath }`, fs.readFileSync(versionPath))
}
Copy the code

The above files can be accessed directly from Node commit.js. For easy management, we add a command line to package.json:

"scripts": {
  "commit": "node commit.js"
}
Copy the code

That way, use the NPM run commit equivalent to Node commit.js.

Generating Version Information

With that in mind, we can now generate version information in the specified format, version.json, from the commit information.

Create a new file, version.js, in the root directory to generate version data.

const execSync = require('child_process').execSync;
const fs = require('fs')
const targetFile = 'src/assets/version.json'; // The target file stored to

const commit = execSync('git show -s --format=%h').toString().trim(); // The current submitted version number, the first 7 bits of the hash value
let date = new Date(execSync('git show -s --format=%cd').toString()); / / date
let message = execSync('git show -s --format=%s').toString().trim(); / / that

let versionObj = {
  "commit": commit,
  "date": date,
  "message": message
};

const data = JSON.stringify(versionObj);

fs.writeFile(targetFile, data, (err) = > {
  if(err) {
    throw err
  }
  console.log('Stringify Json data is saved.')})Copy the code

We add a command line to package.json for easy management:

"scripts": {
  "version": "node version.js"
}
Copy the code

Generate version information based on the environment

Generate different version information for different environments. Suppose we have development environment, production environment and vehicle test environment.

  • The production environment version ismajor.minor.patch, such as: 1.1.0
  • The development environment version information ismajor.minor.patch:beta, such as: 1.1.0: beta
  • The test environment version information ismajor.minor.path-data:hash, such as: 1.1.0-2022.01.01:4 rtr5rg

To facilitate the management of different environments, we created a new file in the root directory of the project as follows:

├─ ├─ test.json // ├─ test.json // / ├─ test.json // // // // // // // // // // // / Test the environment configuration fileCopy the code

Relevant documents are as follows:

// development.json
{
  "env": "development"."version": "1.3.0"
}
Copy the code
// production.json
{
  "env": "production"."version": "1.3.0"
}
Copy the code
// test.json
{
  "env": "test"."version": "1.3.0"
}
Copy the code

Default. json Copy the configuration information of different environments based on the command line. In package.json:

"scripts": {
  "copyConfigProduction": "cp ./config/production.json ./config/default.json"."copyConfigDevelopment": "cp ./config/development.json ./config/default.json"."copyConfigTest": "cp ./config/test.json ./config/default.json",}Copy the code

Is easy Bro, right?

By integrating the content of generated version information, different version information can be generated according to different environments. The specific code is as follows:

const execSync = require('child_process').execSync;
const fs = require('fs')
const targetFile = 'src/assets/version.json'; // The target file stored to
const config = require('./config/default.json');

const commit = execSync('git show -s --format=%h').toString().trim(); // The version number of the current submission
let date = new Date(execSync('git show -s --format=%cd').toString()); / / date
let message = execSync('git show -s --format=%s').toString().trim(); / / that

let versionObj = {
  "env": config.env,
  "version": ""."commit": commit,
  "date": date,
  "message": message
};

// Format the date
const formatDay = (date) = > {
  let formatted_date = date.getFullYear() + "." + (date.getMonth()+1) + "." +date.getDate()
    return formatted_date;
}

if(config.env === 'production') {
  versionObj.version = config.version
}

if(config.env === 'development') {
  versionObj.version = `${ config.version }:beta`
}

if(config.env === 'test') {
  versionObj.version = `${ config.version }-${ formatDay(date) }:${ commit }`
}

const data = JSON.stringify(versionObj);

fs.writeFile(targetFile, data, (err) = > {
  if(err) {
    throw err
  }
  console.log('Stringify Json data is saved.')})Copy the code

Add command lines for different environments to package.json:

"scripts": {
  "build:production": "npm run copyConfigProduction && npm run version"."build:development": "npm run copyConfigDevelopment && npm run version"."build:test": "npm run copyConfigTest && npm run version",}Copy the code

The generated version information is directly stored in assets in the SRC /assets/version.json path.

Display version information on the page with Angular

The final step is to display the version information on the page, in this case in conjunction with Angular.

Use ng generate service version to generate the Version service in the app/services directory. Add the request information to the generated version.service.ts file as follows:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class VersionService {

  constructor(
    private http: HttpClient
  ){}public getVersion():Observable<any> {
    return this.http.get('assets/version.json')}}Copy the code

To use the request, mount the HttpClientModule module in the app.module.ts file:

import { HttpClientModule } from '@angular/common/http';

// ...

imports: [
  HttpClientModule
],
Copy the code

Then call it from the component, here is the app.component.ts file:

import { Component } from '@angular/core';
import { VersionService } from './services/version.service'; // Import version services

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

  public version: string = '1.0.0'

  constructor(
    private readonly versionService: VersionService
  ) {}

  ngOnInit() {
    this.versionService.getVersion().subscribe({
      next: (data: any) = > {
        this.version = data.version // Change the version information
      },
      error: (error: any) = > {
        console.error(error)
      }
    })
  }
}
Copy the code

At this point, we are done with the version information. Let’s finally tweak the package.json command:

"scripts": {
  "start": "ng serve"."version": "node version.js"."commit": "node commit.js"."build": "ng build"."build:production": "npm run copyConfigProduction && npm run version && npm run build"."build:development": "npm run copyConfigDevelopment && npm run version && npm run build"."build:test": "npm run copyConfigTest && npm run version && npm run build"."copyConfigProduction": "cp ./config/production.json ./config/default.json"."copyConfigDevelopment": "cp ./config/development.json ./config/default.json"."copyConfigTest": "cp ./config/test.json ./config/default.json"
}
Copy the code

Scripts are used for ease of management, but for Jenkins to build easy to call. For Jenkins, those who are interested can try it on their own.

Reference & later

  • Node reads Git information
  • NG-ZORRO
  • First post – Github Blog