Path: blob/main/src/vs/workbench/contrib/emergencyAlert/electron-browser/emergencyAlert.contribution.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js';6import { IBannerService } from '../../../services/banner/browser/bannerService.js';7import { asJson, IRequestService } from '../../../../platform/request/common/request.js';8import { IProductService } from '../../../../platform/product/common/productService.js';9import { CancellationToken } from '../../../../base/common/cancellation.js';10import { ILogService } from '../../../../platform/log/common/log.js';11import { Codicon } from '../../../../base/common/codicons.js';12import { arch, platform } from '../../../../base/common/process.js';1314interface IEmergencyAlert {15readonly commit: string;16readonly platform?: string;17readonly arch?: string;18readonly message: string;19readonly actions?: [{20readonly label: string;21readonly href: string;22}];23}2425interface IEmergencyAlerts {26readonly alerts: IEmergencyAlert[];27}2829export class EmergencyAlert implements IWorkbenchContribution {3031static readonly ID = 'workbench.contrib.emergencyAlert';3233constructor(34@IBannerService private readonly bannerService: IBannerService,35@IRequestService private readonly requestService: IRequestService,36@IProductService private readonly productService: IProductService,37@ILogService private readonly logService: ILogService38) {39if (productService.quality !== 'insider') {40return; // only enabled in insiders for now41}4243const emergencyAlertUrl = productService.emergencyAlertUrl;44if (!emergencyAlertUrl) {45return; // no emergency alert configured46}4748this.fetchAlerts(emergencyAlertUrl);49}5051private async fetchAlerts(url: string): Promise<void> {52try {53await this.doFetchAlerts(url);54} catch (e) {55this.logService.error(e);56}57}5859private async doFetchAlerts(url: string): Promise<void> {60const requestResult = await this.requestService.request({ type: 'GET', url, disableCache: true }, CancellationToken.None);6162if (requestResult.res.statusCode !== 200) {63throw new Error(`Failed to fetch emergency alerts: HTTP ${requestResult.res.statusCode}`);64}6566const emergencyAlerts = await asJson<IEmergencyAlerts>(requestResult);67if (!emergencyAlerts) {68return;69}7071for (const emergencyAlert of emergencyAlerts.alerts) {72if (73(emergencyAlert.commit !== this.productService.commit) || // version mismatch74(emergencyAlert.platform && emergencyAlert.platform !== platform) || // platform mismatch75(emergencyAlert.arch && emergencyAlert.arch !== arch) // arch mismatch76) {77return;78}7980this.bannerService.show({81id: 'emergencyAlert.banner',82icon: Codicon.warning,83message: emergencyAlert.message,84actions: emergencyAlert.actions85});8687break;88}89}90}9192registerWorkbenchContribution2('workbench.emergencyAlert', EmergencyAlert, WorkbenchPhase.Eventually);939495