From 1349cb2c95ece861faa0e6214593db8c521df208 Mon Sep 17 00:00:00 2001 From: mustard Date: Wed, 20 Jul 2022 16:56:04 +0800 Subject: [PATCH 1/3] Add in product changelog --- package.json | 8 ++ src/extension.ts | 3 + src/releaseNotes.ts | 318 ++++++++++++++++++++++++++++++++++++++++++++ yarn.lock | 5 + 4 files changed, 334 insertions(+) create mode 100644 src/releaseNotes.ts diff --git a/package.json b/package.json index d5eeace7..a7d9726d 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "onCommand:gitpod.syncProvider.remove", "onCommand:gitpod.exportLogs", "onCommand:gitpod.api.autoTunnel", + "onCommand:gitpod.showReleaseNotes", "onAuthenticationRequest:gitpod", "onUri" ], @@ -92,6 +93,11 @@ "command": "gitpod.exportLogs", "category": "Gitpod", "title": "Export all logs" + }, + { + "command": "gitpod.showReleaseNotes", + "category": "Gitpod", + "title": "Show Release Notes" } ] }, @@ -109,6 +115,7 @@ "@types/analytics-node": "^3.1.9", "@types/crypto-js": "4.1.1", "@types/google-protobuf": "^3.7.4", + "@types/js-yaml": "^4.0.5", "@types/node": "16.x", "@types/node-fetch": "^2.5.12", "@types/semver": "^7.3.10", @@ -135,6 +142,7 @@ "@gitpod/local-app-api-grpcweb": "main", "@improbable-eng/grpc-web-node-http-transport": "^0.14.0", "analytics-node": "^6.0.0", + "js-yaml": "^4.1.0", "node-fetch": "2.6.7", "pkce-challenge": "^3.0.0", "semver": "^7.3.7", diff --git a/src/extension.ts b/src/extension.ts index 02f8055f..cd74b81b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,6 +12,7 @@ import { enableSettingsSync, updateSyncContext } from './settingsSync'; import { GitpodServer } from './gitpodServer'; import TelemetryReporter from './telemetryReporter'; import { exportLogs } from './exportLogs'; +import { registerReleaseNotesView } from './releaseNotes'; const EXTENSION_ID = 'gitpod.gitpod-desktop'; const FIRST_INSTALL_KEY = 'gitpod-desktop.firstInstall'; @@ -89,6 +90,8 @@ export async function activate(context: vscode.ExtensionContext) { await context.globalState.update(FIRST_INSTALL_KEY, true); telemetry.sendTelemetryEvent('gitpod_desktop_installation', { kind: 'install' }); } + + registerReleaseNotesView(context); } export async function deactivate() { diff --git a/src/releaseNotes.ts b/src/releaseNotes.ts new file mode 100644 index 00000000..d0c651bc --- /dev/null +++ b/src/releaseNotes.ts @@ -0,0 +1,318 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Gitpod. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import fetch from 'node-fetch'; +import * as vscode from 'vscode'; +import { load } from 'js-yaml'; + +const LAST_READ_RELEASE_NOTES_ID = 'gitpod.lastReadReleaseNotesId'; + +export function registerReleaseNotesView(context: vscode.ExtensionContext) { + + async function shouldShowReleaseNotes(lastReadId: string | undefined) { + const releaseId = await getLastPublish(); + console.log(`gitpod release notes lastReadId: ${lastReadId}, latestReleaseId: ${releaseId}`); + return releaseId !== lastReadId; + } + + context.subscriptions.push( + vscode.commands.registerCommand('gitpod.showReleaseNotes', () => { + ReleaseNotesPanel.createOrShow(context); + }) + ); + + // sync between machines + context.globalState.setKeysForSync([LAST_READ_RELEASE_NOTES_ID]); + + const lastReadId = context.globalState.get(LAST_READ_RELEASE_NOTES_ID); + shouldShowReleaseNotes(lastReadId).then(shouldShow => { + if (shouldShow) { + ReleaseNotesPanel.createOrShow(context); + } + }); +} + +async function getLastPublish() { + const resp = await fetch(`${websiteHost}/changelog/latest`); + if (!resp.ok) { + throw new Error(`Getting latest releaseId failed: ${resp.statusText}`); + } + const { releaseId } = JSON.parse(await resp.text()); + return releaseId as string; +} + +const websiteHost = 'https://www.gitpod.io'; + +class ReleaseNotesPanel { + public static currentPanel: ReleaseNotesPanel | undefined; + public static readonly viewType = 'gitpodReleaseNotes'; + private readonly panel: vscode.WebviewPanel; + private lastReadId: string | undefined; + private _disposables: vscode.Disposable[] = []; + + private async loadChangelog(releaseId: string) { + const resp = await fetch(`${websiteHost}/changelog/raw-markdown?releaseId=${releaseId}`); + if (!resp.ok) { + throw new Error(`Getting raw markdown content failed: ${resp.statusText}`); + } + const md = await resp.text(); + + const parseInfo = (md: string) => { + if (!md.startsWith('---')) { + return; + } + const lines = md.split('\n'); + const end = lines.indexOf('---', 1); + const content = lines.slice(1, end).join('\n'); + return load(content) as { title: string; date: string; image: string; alt: string; excerpt: string }; + }; + const info = parseInfo(md); + + const content = md + .replace(/---.*?---/gms, '') + .replace(/