WEBアプリのビルド情報・変更履歴を手っ取り早く確認したい（git＋node.js＋angular）

はじめに
---
WEBサイトの開発で、修正が実行環境に取り込まれているか不安になることが多いので、確認するためのAPIを作ってみました。
git＋angular＋node.js の構成を前提としています。

node.jsサーバからgit logコマンドを打って、結果を返すようにしています。

gitコマンド
---
node.js の Child process を使用して git log を取得します。
[Child process](https://nodejs.org/api/child_process.html)

gitコマンドは、今回は以下のオプションで実行しています。
`git log --no-merges --pretty=format:"[%ad] %h %an : %s" --date=format:"%Y/%m/%d %H:%M:%S"`

--no-merges
　マージしたときのコミットを除いて表示する

--pretty=format:"[%ad] %h %an : %s"：
　表示する情報を指定できる。

　%ad：作成日
　%h：省略されたコミットハッシュ
　%an：作成者名
　%s：件名

--date=format:"%Y/%m/%d %H:%M:%S"：
　日付部分のフォーマット。
　（デフォルトだと、[Sun Aug 22 11:05:52 2021 +0900]のような形式で表示されます。）

実行すると、以下のような形式で git log が取得されます。

```
[2021/08/22 11:05:52] 08bcd01 kyv28v : プロフィール画面の権限部分のサイズを調整
[2021/08/22 11:00:54] fd001a1 kyv28v : システム情報の表示を追加
```

※ その他、オプションの詳細は、以下参照。
　 [Git log のコマンドリファレンス](https://tracpath.com/docs/git-log/)

ビルド日時
---
ビルドを実行した日時も知りたいので、distフォルダにできたビルドファイルの日時を取得するようにしました。
原始的ですが、fs でファイル取得しています。

ソースコード
---
最終的に完成したソース（API側）は、以下の通りです。

```typescript
import { NextFunction, Request, Response } from 'express';

const express = require('express');
const router = express.Router();

const { execSync } = require('child_process');
const fs = require('fs');
const moment = require("moment-timezone");
const path = require('path');

router.get('/systemInfo', async function(req: Request, res: Response, next: NextFunction) {
    try {
        console.log('get systemInfo() start');

        // get client build dt.
        let clientBuildDt = getFileUpdateDt(path.join(__dirname, '../../../../front/dist/index.html'));

        // get server build dt.
        let serverBuildDt = getFileUpdateDt(path.join(__dirname, '../../../../server/dist/app.js'));

        // get git log.
        let gitLog = getGitLog();

        console.log('get systemInfo() end');
        res.json({
            clientBuildDt: clientBuildDt,
            serverBuildDt: serverBuildDt,
            gitLog: gitLog?.toString(),
        });
    } catch (e) {
        console.log(e.stack);
        res.json({ message: e.message });
    }
});

// get file update dt.
function getFileUpdateDt(path: string) {
    try {
        const file = fs.statSync(path);
        const fileDt = moment(file.mtime).tz("Asia/Tokyo").format("YYYY/MM/DD HH:mm:ss");
        // console.log('file update dt:' + fileDt);
        return fileDt;
    } catch(e) {
        console.log(e.toString());
        return null;
    }
}

// get git log.
function getGitLog() {
    try {
        const gitLog = execSync('git log --no-merges --pretty=format:"[%ad] %h %an : %s" --date=format:"%Y/%m/%d %H:%M:%S"')
        // console.log(`git log: ${gitLog.toString()}`)
        return gitLog;
    } catch(e) {
        console.log(e.toString());
        return null;
    }
}

module.exports = router;

```

画面
---
完成したAPIを画面から呼び出して表示するようにしました。
以下のように、変更履歴とビルド時間が表示されるようになるので、ビルドミスなどは減るのではないでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285246/a7f87274-465f-f610-90b2-9aa13d7e8c38.png)

その他
---
・git logを取得するので、実行環境でソースをプルしてビルドするような構成が前提になります。

・画面側は、単にAPIの結果を表示するだけなので、angularでなくても同じように対応できると思います。
　ただ、ビルド日時を取得するためには、ビルド後に生成されるファイル日時を取得できることが前提ですが。

・ビルドした後にgit pullしてしまうと、実際に取り込まれていない変更が履歴表示されてしまう危険がありますので、git pull→ビルドをまとめて行うようなシェルなどを作成したほうが確実だと思います。

・herokuでも動かしてみましたが、残念ながらgit logは取得できませんでした。
　`not a git repository (or any parent up to mount point /)`
　のエラーになったので、.gitフォルダが存在していないのかもしれません。
　（ちゃんと調べてませんが。）

・[web-page-manager-limited](https://github.com/kyv28v/web-page-manager-limited)
　に、今回試したWEBアプリを公開しています。
　今回作成したAPIの本体は、
　web-page-manager-limited/server/src/api/common/system.ts
　にあります。