Merge pull request #447 from mempool/simon/frontend-commit-hash-hostname
Backend and frontend commit, version and hostname displayed on the about page
This commit is contained in:
		
						commit
						fa9ba582a0
					
				@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "mempool-backend",
 | 
			
		||||
  "version": "2.0.0",
 | 
			
		||||
  "version": "2.2-dev",
 | 
			
		||||
  "description": "Bitcoin mempool visualizer and blockchain explorer backend",
 | 
			
		||||
  "license": "GNU Affero General Public License v3.0",
 | 
			
		||||
  "homepage": "https://mempool.space",
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,24 @@
 | 
			
		||||
import * as fs from 'fs';
 | 
			
		||||
import * as os from 'os';
 | 
			
		||||
import logger from '../logger';
 | 
			
		||||
import { IBackendInfo } from '../mempool.interfaces';
 | 
			
		||||
 | 
			
		||||
class BackendInfo {
 | 
			
		||||
  gitCommitHash = '';
 | 
			
		||||
  hostname = '';
 | 
			
		||||
  private gitCommitHash = '';
 | 
			
		||||
  private hostname = '';
 | 
			
		||||
  private version = '';
 | 
			
		||||
 | 
			
		||||
  constructor() {
 | 
			
		||||
    this.setLatestCommitHash();
 | 
			
		||||
    this.setVersion();
 | 
			
		||||
    this.hostname = os.hostname();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public getBackendInfo() {
 | 
			
		||||
  public getBackendInfo(): IBackendInfo {
 | 
			
		||||
    return {
 | 
			
		||||
      'hostname': this.hostname,
 | 
			
		||||
      'git-commit': this.gitCommitHash,
 | 
			
		||||
      hostname: this.hostname,
 | 
			
		||||
      gitCommit: this.gitCommitHash,
 | 
			
		||||
      version: this.version,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -29,6 +33,15 @@ class BackendInfo {
 | 
			
		||||
      logger.err('Could not load git commit info: ' + e.message || e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private setVersion(): void {
 | 
			
		||||
    try {
 | 
			
		||||
      const packageJson = fs.readFileSync('package.json').toString();
 | 
			
		||||
      this.version = JSON.parse(packageJson).version;
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      throw new Error(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new BackendInfo();
 | 
			
		||||
 | 
			
		||||
@ -159,8 +159,7 @@ class WebsocketHandler {
 | 
			
		||||
      'conversions': fiatConversion.getConversionRates(),
 | 
			
		||||
      'mempool-blocks': mempoolBlocks.getMempoolBlocks(),
 | 
			
		||||
      'transactions': memPool.getLatestTransactions(),
 | 
			
		||||
      'git-commit': backendInfo.gitCommitHash,
 | 
			
		||||
      'hostname': backendInfo.hostname,
 | 
			
		||||
      'backendInfo': backendInfo.getBackendInfo(),
 | 
			
		||||
      'loadingIndicators': loadingIndicators.getLoadingIndicators(),
 | 
			
		||||
      ...this.extraInitProperties
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -160,3 +160,9 @@ interface RequiredParams {
 | 
			
		||||
 | 
			
		||||
export interface ILoadingIndicators { [name: string]: number; }
 | 
			
		||||
export interface IConversionRates { [currency: string]: number; }
 | 
			
		||||
 | 
			
		||||
export interface IBackendInfo {
 | 
			
		||||
  hostname: string;
 | 
			
		||||
  gitCommit: string;
 | 
			
		||||
  version: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,8 @@ const GENERATED_CONFIG_FILE_NAME = 'generated-config.js';
 | 
			
		||||
 | 
			
		||||
let settings = [];
 | 
			
		||||
let configContent = {};
 | 
			
		||||
let gitCommitHash = '';
 | 
			
		||||
let packetJsonVersion = '';
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
  const rawConfig = fs.readFileSync(CONFIG_FILE_NAME);
 | 
			
		||||
@ -15,6 +17,13 @@ try {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
  const packageJson = fs.readFileSync('package.json');
 | 
			
		||||
  packetJsonVersion = JSON.parse(packageJson).version;
 | 
			
		||||
} catch (e) {
 | 
			
		||||
  throw new Error(e);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
for (setting in configContent) {
 | 
			
		||||
  settings.push({
 | 
			
		||||
    key: setting,
 | 
			
		||||
@ -22,9 +31,17 @@ for (setting in configContent) {
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
  gitCommitHash = fs.readFileSync('../.git/refs/heads/master').toString().trim();
 | 
			
		||||
} catch (e) {
 | 
			
		||||
  console.log('Could not load git commit info: ' + e.message || e);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const code = `(function (window) {
 | 
			
		||||
  window.__env = window.__env || {};${settings.reduce((str, obj) => `${str}
 | 
			
		||||
    window.__env.${obj.key} = ${ typeof obj.value === 'string' ? `'${obj.value}'` : obj.value };`, '')}
 | 
			
		||||
    window.__env.GIT_COMMIT_HASH = '${gitCommitHash}';
 | 
			
		||||
    window.__env.PACKAGE_JSON_VERSION = '${packetJsonVersion}';
 | 
			
		||||
  }(global || this));`;
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "mempool-frontend",
 | 
			
		||||
  "version": "2.0.0",
 | 
			
		||||
  "version": "2.2-dev",
 | 
			
		||||
  "description": "Bitcoin mempool visualizer and blockchain explorer backend",
 | 
			
		||||
  "license": "GNU Affero General Public License v3.0",
 | 
			
		||||
  "homepage": "https://mempool.space",
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,4 @@
 | 
			
		||||
{
 | 
			
		||||
  "/api/v1/donations": {
 | 
			
		||||
    "target": "http://localhost:9000/",
 | 
			
		||||
    "secure": false
 | 
			
		||||
  },
 | 
			
		||||
  "/api/v1": {
 | 
			
		||||
    "target": "http://localhost:8999/",
 | 
			
		||||
    "secure": false
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,13 @@
 | 
			
		||||
    <br>
 | 
			
		||||
    <img src="./resources/mempool-logo-bigger.png" height="62.5" width="250">
 | 
			
		||||
    <br>
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
    <div class="text-small text-center offset-md-1">
 | 
			
		||||
      v2.2-dev ({{ gitCommit$ | async }})
 | 
			
		||||
    <div class="text-small">
 | 
			
		||||
      Frontend:
 | 
			
		||||
      v{{ packetJsonVersion }} ({{ frontendGitCommitHash }}) [{{ hostname }}]
 | 
			
		||||
      <br>
 | 
			
		||||
      Backend: v{{ (backendInfo$ | async ).version }} ({{ (backendInfo$ | async ).gitCommit | slice:0:8 }}) [{{ (backendInfo$ | async).hostname }}]
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 | 
			
		||||
import { ApiService } from 'src/app/services/api.service';
 | 
			
		||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
 | 
			
		||||
import { delay, map, retryWhen, switchMap, tap } from 'rxjs/operators';
 | 
			
		||||
import { IBackendInfo } from 'src/app/interfaces/websocket.interface';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-about',
 | 
			
		||||
@ -14,7 +15,7 @@ import { delay, map, retryWhen, switchMap, tap } from 'rxjs/operators';
 | 
			
		||||
  styleUrls: ['./about.component.scss'],
 | 
			
		||||
})
 | 
			
		||||
export class AboutComponent implements OnInit, OnDestroy {
 | 
			
		||||
  gitCommit$: Observable<string>;
 | 
			
		||||
  backendInfo$: Observable<IBackendInfo>;
 | 
			
		||||
  donationForm: FormGroup;
 | 
			
		||||
  paymentForm: FormGroup;
 | 
			
		||||
  donationStatus = 1;
 | 
			
		||||
@ -22,6 +23,9 @@ export class AboutComponent implements OnInit, OnDestroy {
 | 
			
		||||
  contributors$: Observable<any>;
 | 
			
		||||
  donationObj: any;
 | 
			
		||||
  sponsorsEnabled = this.stateService.env.OFFICIAL_MEMPOOL_SPACE;
 | 
			
		||||
  frontendGitCommitHash = this.stateService.env.GIT_COMMIT_HASH.substr(0, 8);
 | 
			
		||||
  packetJsonVersion = this.stateService.env.PACKAGE_JSON_VERSION;
 | 
			
		||||
  hostname = document.location.hostname;
 | 
			
		||||
  sponsors = null;
 | 
			
		||||
  contributors = null;
 | 
			
		||||
  requestSubscription: Subscription | undefined;
 | 
			
		||||
@ -36,7 +40,7 @@ export class AboutComponent implements OnInit, OnDestroy {
 | 
			
		||||
  ) { }
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    this.gitCommit$ = this.stateService.gitCommit$.pipe(map((str) => str.substr(0, 8)));
 | 
			
		||||
    this.backendInfo$ = this.stateService.backendInfo$;
 | 
			
		||||
    this.seoService.setTitle($localize`:@@004b222ff9ef9dd4771b777950ca1d0e4cd4348a:About`);
 | 
			
		||||
    this.websocketService.want(['blocks']);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ export interface WebsocketResponse {
 | 
			
		||||
  rbfTransaction?: Transaction;
 | 
			
		||||
  transactions?: TransactionStripped[];
 | 
			
		||||
  loadingIndicators?: ILoadingIndicators;
 | 
			
		||||
  backendInfo?: IBackendInfo;
 | 
			
		||||
  'track-tx'?: string;
 | 
			
		||||
  'track-address'?: string;
 | 
			
		||||
  'track-asset'?: string;
 | 
			
		||||
@ -49,3 +50,8 @@ export interface TransactionStripped {
 | 
			
		||||
  value: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IBackendInfo {
 | 
			
		||||
  hostname: string;
 | 
			
		||||
  gitCommit: string;
 | 
			
		||||
  version: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
 | 
			
		||||
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable } from 'rxjs';
 | 
			
		||||
import { Block, Transaction } from '../interfaces/electrs.interface';
 | 
			
		||||
import { MempoolBlock, MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface';
 | 
			
		||||
import { IBackendInfo, MempoolBlock, MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface';
 | 
			
		||||
import { OptimizedMempoolStats } from '../interfaces/node-api.interface';
 | 
			
		||||
import { Router, NavigationStart } from '@angular/router';
 | 
			
		||||
import { isPlatformBrowser } from '@angular/common';
 | 
			
		||||
@ -27,6 +27,8 @@ export interface Env {
 | 
			
		||||
  NGINX_PROTOCOL?: string;
 | 
			
		||||
  NGINX_HOSTNAME?: string;
 | 
			
		||||
  NGINX_PORT?: string;
 | 
			
		||||
  GIT_COMMIT_HASH: string;
 | 
			
		||||
  PACKAGE_JSON_VERSION: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const defaultEnv: Env = {
 | 
			
		||||
@ -41,6 +43,8 @@ const defaultEnv: Env = {
 | 
			
		||||
  'NGINX_PROTOCOL': 'http',
 | 
			
		||||
  'NGINX_HOSTNAME': '127.0.0.1',
 | 
			
		||||
  'NGINX_PORT': '80',
 | 
			
		||||
  'GIT_COMMIT_HASH': '',
 | 
			
		||||
  'PACKAGE_JSON_VERSION': '',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
@ -65,7 +69,7 @@ export class StateService {
 | 
			
		||||
  isLoadingWebSocket$ = new ReplaySubject<boolean>(1);
 | 
			
		||||
  vbytesPerSecond$ = new ReplaySubject<number>(1);
 | 
			
		||||
  lastDifficultyAdjustment$ = new ReplaySubject<number>(1);
 | 
			
		||||
  gitCommit$ = new ReplaySubject<string>(1);
 | 
			
		||||
  backendInfo$ = new ReplaySubject<IBackendInfo>(1);
 | 
			
		||||
  loadingIndicators$ = new ReplaySubject<ILoadingIndicators>(1);
 | 
			
		||||
 | 
			
		||||
  live2Chart$ = new Subject<OptimizedMempoolStats>();
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
 | 
			
		||||
import { WebsocketResponse } from '../interfaces/websocket.interface';
 | 
			
		||||
import { WebsocketResponse, IBackendInfo } from '../interfaces/websocket.interface';
 | 
			
		||||
import { StateService } from './state.service';
 | 
			
		||||
import { Block, Transaction } from '../interfaces/electrs.interface';
 | 
			
		||||
import { Subscription } from 'rxjs';
 | 
			
		||||
@ -236,13 +236,13 @@ export class WebsocketService {
 | 
			
		||||
      this.stateService.bsqPrice$.next(response['bsq-price']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (response['git-commit']) {
 | 
			
		||||
      this.stateService.gitCommit$.next(response['git-commit']);
 | 
			
		||||
    if (response.backendInfo) {
 | 
			
		||||
      this.stateService.backendInfo$.next(response.backendInfo);
 | 
			
		||||
 | 
			
		||||
      if (!this.latestGitCommit) {
 | 
			
		||||
        this.latestGitCommit = response['git-commit'];
 | 
			
		||||
        this.latestGitCommit = response.backendInfo.gitCommit;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (this.latestGitCommit !== response['git-commit']) {
 | 
			
		||||
        if (this.latestGitCommit !== response.backendInfo.gitCommit) {
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            window.location.reload();
 | 
			
		||||
          }, Math.floor(Math.random() * 60000) + 60000);
 | 
			
		||||
@ -283,7 +283,7 @@ export class WebsocketService {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (response['git-commit']) {
 | 
			
		||||
      this.stateService.gitCommit$.next(response['git-commit']);
 | 
			
		||||
      this.stateService.backendInfo$.next(response['git-commit']);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user