Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to include git revision into angular-cli application?

I need to display git revision on my angular2 application's about page. The project is based on angular-cli.

How can build be extended so git revision is put for example into environment.ts or other place accessible to application?

like image 382
Vilmantas Baranauskas Avatar asked Feb 10 '17 08:02

Vilmantas Baranauskas


People also ask

Is git necessary for angular?

If you want to collaborate with your team on the same Angular project or you just want to keep a remote copy of your project's source code, then you need to add a remote GitHub repository to your Git repository which will allow you to push, pull and synchronize the code between the local and remote repositories at any ...

What is revision and version in Git?

It uses what is called an extended SHA1 syntax, [and includes] various ways to spell object names. So "revision" refers to the id you can use as a parameter to reference an object in git (usually a commit). HEAD@{5 minutes ago} is a revision which reference the commit present 5 minutes ago.


2 Answers

As suggested by @Yuri, I was able to solve this by using npm scripting.

  1. Defined git.version.ts in the root of the angular-cli project:
import { Observable, combineLatest } from 'rxjs'  declare var require: any; declare var process: any;  const fs = require('fs'); const exec = require('child_process').exec;  const revision = new Observable<string>(s => {     exec('git rev-parse --short HEAD',         (error: Error, stdout, stderr) => {             if (error !== null) {                 console.log('git error: ' + error + stderr);             }             s.next(stdout.toString().trim());             s.complete();         }); });  const branch = new Observable<string>(s => {     exec('git rev-parse --abbrev-ref HEAD',         (error: Error, stdout, stderr) => {             if (error !== null) {                 console.log('git error: ' + error + stderr);             }             s.next(stdout.toString().trim());             s.complete();         }); });  combineLatest(revision, branch)     .subscribe(([revision, branch]) => {         console.log(`version: '${process.env.npm_package_version}', revision: '${revision}', branch: '${branch}'`);          const content = '// this file is automatically generated by git.version.ts script\n' +             `export const versions = {version: '${process.env.npm_package_version}', revision: '${revision}', branch: '${branch}'};`;          fs.writeFileSync(             'src/environments/versions.ts',             content,             {encoding: 'utf8'}         );     });  
  1. Added pre-build hook in package.json:
"scripts": {     "ng": "ng",     ...     "start": "ng serve --proxy proxy-config.json",     "prebuild.prod": "ts-node -O \"{\\\"module\\\":\\\"commonjs\\\"}\" git.version.ts",     "build.prod": "ng build -prod",     ... } 
  1. Use the generated src/environments/versions.ts in the application.

    UPDATE 10/2018: Here is the more-readable version of the script, rxjs-version-agnostic:

import { writeFileSync } from 'fs'; import { dedent } from 'tslint/lib/utils'; import { promisify } from 'util'; import * as child from 'child_process'; const exec = promisify(child.exec);  async function createVersionsFile(filename: string) {   const revision = (await exec('git rev-parse --short HEAD')).stdout.toString().trim();   const branch = (await exec('git rev-parse --abbrev-ref HEAD')).stdout.toString().trim();    console.log(`version: '${process.env.npm_package_version}', revision: '${revision}', branch: '${branch}'`);    const content = dedent`       // this file is automatically generated by git.version.ts script       export const versions = {         version: '${process.env.npm_package_version}',         revision: '${revision}',         branch: '${branch}'       };`;    writeFileSync(filename, content, {encoding: 'utf8'}); }  createVersionsFile('src/environments/versions.ts');   

Note, when using angular-cli v7.0.6, I also had to change script invocation in the package.json:

"scripts": {     ...     "prebuild.prod": "ts-node -O '{\"module\": \"commonjs\"}' git.version.ts",     ... } 
like image 191
Vilmantas Baranauskas Avatar answered Oct 07 '22 13:10

Vilmantas Baranauskas


The other answers were helpful, but I preferred a more simple, direct approach. Here's mine.

Run npm install git-describe --save-dev. Then add git-version.js to the root:

// This script runs operations *synchronously* which is normally not the best // approach, but it keeps things simple, readable, and for now is good enough.  const { gitDescribeSync } = require('git-describe'); const { writeFileSync } = require('fs');  const gitInfo = gitDescribeSync(); const versionInfoJson = JSON.stringify(gitInfo, null, 2);  writeFileSync('git-version.json', versionInfoJson); 

Optionally you can add /git-version.json to your .gitignore file.

Update your package.json to do something like this:

"scripts": {   "build": "node git-version.js && ng build" } 

Then add version-info.ts to the root of your project:

export const versionInfo = (() => {   try {     // tslint:disable-next-line:no-var-requires     return require('../../git-version.json');   } catch {     // In dev the file might not exist:     return { tag: 'v0.0.0', hash: 'dev' };   } })(); 

And import the versionInfo in your app.component.ts or anywhere else you'd want to use it.

like image 30
Jeroen Avatar answered Oct 07 '22 13:10

Jeroen