How to include git revision into angular-cli application?

前端 未结 9 2178
甜味超标
甜味超标 2021-01-31 16:40

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 exampl

相关标签:
9条回答
  • 2021-01-31 16:42
    1. Add git-version.js to the root.This code will execute git commands and write the output to the git-version.json file.
    const childProcess = require('child_process');
    const { writeFileSync } = require('fs');
    
    const longSHA = childProcess.execSync("git rev-parse HEAD").toString().trim();
    const shortSHA = childProcess.execSync("git rev-parse --short HEAD").toString().trim();
    const branch = childProcess.execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
    const authorName = childProcess.execSync("git log -1 --pretty=format:'%an'").toString().trim();
    const commitTime = childProcess.execSync("git log -1 --pretty=format:'%cd'").toString().trim();
    const commitMsg = childProcess.execSync("git log -1 --pretty=%B").toString().trim();
    const totalCommitCount = childProcess.execSync("git rev-list --count HEAD").toString().trim();
    
    const versionInfo = {
        shortSHA: shortSHA,
        SHA : longSHA,
        branch: branch,
        lastCommitAuthor: authorName,
        lastCommitTime: commitTime,
        lastCommitMessage: commitMsg,
        lastCommitNumber: totalCommitCount
    }
    
    const versionInfoJson = JSON.stringify(versionInfo, null, 2);
    
    writeFileSync('/src/git-version.json', versionInfoJson);
    

    This code will generate the git-version.json file :-

    {
      "shortSHA": "0e786d4",
      "SHA": "0e786d4ad3778463f6f30c28f254cc85c24eb4b3",
      "branch": "master",
      "lastCommitAuthor": "'saurabh'",
      "lastCommitTime": "'Thu Apr 9 12:59:16 2020 +0530'",
      "lastCommitMessage": "Commit message",
      "lastCommitNumber": "200"
    }
    

    Modify above code as per your requirements.

    Run: node git-version.js This will generate the git-version.json into src directory.

    1. To run this code before or after the build. add a new script to package.json
    "scripts": {
       "ng": "ng",
       "start": "ng serve",
       "build": "ng build",
       "test": "ng test",
       "lint": "ng lint",
       "e2e": "ng e2e",
       "build.prod": "node git-version.js && ng build --prod"
     }
    
    1. Run:- npm run build.prod

    suggestions for code improvement are welcome :)

    0 讨论(0)
  • 2021-01-31 16:46

    Use gulp task using gulp-replace and git-rev-sync to add the hash and branch on build :

    1) Create the gulp task

    var gulp            =    require('gulp'),
        replace         =    require('gulp-replace'),
        git             =    require('git-rev-sync'),
    
    gulp.task('git', function () {
        gulp.src('src/index.html')
            .pipe(replace('{{git-branch}}', git.branch()))
            .pipe(replace('{{git-hash}}', git.short()))
            .pipe(gulp.dest('src/'))
    });
    
    // Build Tasks
    gulp.task('build', ['git']);
    

    2) Add the following code to index.html :

    {{git-branch}}@{{git-hash}}
    

    3) Run

    gulp build
    
    0 讨论(0)
  • 2021-01-31 16:47

    I went with a modified version of Vilmantas Baranauskas

    I moved src/index.html to src/index.base.html and added an empty <meta name="revision" content=""> inside the HEAD

    Example:

    <head>
        <meta charset="utf-8">
        <title>MySuperAwesome Angular</title>
        <base href="/">
    
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="revision" content="">
        <link rel="icon" type="image/x-icon" href="favicon.ico">
    

    Then modified git.version.ts like this:

    import 'rxjs/add/observable/combineLatest';
    
    import { readFileSync, writeFileSync } from 'fs';
    import { join } from 'path';
    import { Observable } from 'rxjs/Observable';
    
    const indexBasePath = join(__dirname, 'src');
    
    const exec = require('child_process').exec;
    
    const revObs = new Observable<string>(s => {
        exec('git rev-parse --short HEAD',
        function (error: Error, stdout: Buffer, stderr: Buffer) {
            if (error !== null) {
                console.log('git error: ' + error + stderr);
            }
            s.next(stdout.toString().trim());
            s.complete();
        });
    });
    
    const branchObs = new Observable<string>(s => {
        exec('git rev-parse --abbrev-ref HEAD',
        function (error: Error, stdout: Buffer, stderr: Buffer) {
            if (error !== null) {
                console.log('git error: ' + error + stderr);
            }
            s.next(stdout.toString().trim());
            s.complete();
        });
    });
    
    Observable
        .combineLatest(revObs, branchObs)
        .subscribe(([revision, branch]) => {
            console.log(`revision: '${revision}', branch: '${branch}'`);
    
            const baseHTML = readFileSync(join(indexBasePath, 'index.base.html'), 'utf8');
            const html = baseHTML
              .replace('<meta name="revision" content="">', `<meta name="revision" content="${ revision }">`);
    
            writeFileSync(
              join(indexBasePath, 'index.html'),
              html,
              { encoding: 'utf8' }
            );
        });
    

    In this example I only put revision, but you can be more thorough and put branch and version inside your html HEAD section

    0 讨论(0)
  • 2021-01-31 16:52

    Display branch name and commit hash

    I have a little different approach, inspired by answers repo Seba Arce and Jeroen , in main project directory:

    • execute: npm install git-rev-sync --save (this lib give acces to hash and branch name)
    • add file git-version-gen.js with following body

    const git  = require('git-rev-sync');
    const { writeFileSync } = require('fs');
    
    const gitInfo = { commit: git.short(), commitLong: git.long(), branch: git.branch() };
    const ts = 'export const gitVersion = ' + JSON.stringify(gitInfo, null, 2);
    
    writeFileSync('src/environments/git-version.ts', ts);

    • in package.json in scripts add "build": "node git-version-gen.js && ng build ..."
    • in your main app file e.g. app.component.ts use it as follows

    import { gitVersion } from '../../../environments/git-version';
    
    // ...
    
      constructor() {
        console.log(`GIT branch:`,gitVersion.branch);
        console.log(`GIT commit:`,gitVersion.commit);
      }

    What are advantages of use this?

    • we create here src/environments/git-version.ts file so this is TypeScript, not .json - similar like you environments files - this will turn on support from your code editor (e.g VSCode)

    • you have acces to commit hash nad branch name (lib git-describe not gives acces to branch name)

    • if you commit generated git-version.ts file instead put it to .gitignore then project will run without build (e.g. by ng serve ...) and fresh developers will not be confused that there is missing some 'mystic' file... - however choice is up to you.

    • cross platform - tested on Azure (windows), MacOs (~linux-like)

    0 讨论(0)
  • 2021-01-31 16:52

    I've done it by generating prebuild script run on postinstall and run before any angular related script

    const fs =  require('fs');
    const git = require('git-rev-sync');
    var mkdirp = require('mkdirp');
    
    const releaseTag = git.tag();
    const template = `export const gitTag = '${releaseTag}';\n`;
    
    mkdirp('./generated', function(err) {
        fs.writeFileSync('./generated/git-tag.ts', template, { encoding: 'UTF-8' });
    });
    
    

    which generated git-tag.ts file:

    export const gitTag = 'xxxxxxx';
    

    and now u just use in component

    import { gitTag } from '[pathToRoot]/generated/git-tag';
    

    also add .gitignore

    generated

    0 讨论(0)
  • 2021-01-31 16:59

    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",
        ...
    }
    
    0 讨论(0)
提交回复
热议问题