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