From 8065712528e697a85a7d1ee4739530c0f8aae1b9 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 29 Aug 2019 13:06:29 -0700 Subject: [PATCH] Add publishing of webview content to pipeline (#80069) * Experimental publish step of webview contents * Move webview publish into product compile * Move test step first * More script after install * Move script after build * Debug * Add env var * Don't log env --- .../azure-pipelines/common/publish-webview.sh | 9 ++ .../azure-pipelines/common/publish-webview.ts | 87 +++++++++++++++++++ build/azure-pipelines/product-compile.yml | 6 ++ 3 files changed, 102 insertions(+) create mode 100755 build/azure-pipelines/common/publish-webview.sh create mode 100644 build/azure-pipelines/common/publish-webview.ts diff --git a/build/azure-pipelines/common/publish-webview.sh b/build/azure-pipelines/common/publish-webview.sh new file mode 100755 index 0000000000000..77e222258fea4 --- /dev/null +++ b/build/azure-pipelines/common/publish-webview.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e +REPO="$(pwd)" + +# Publish webview contents +PACKAGEJSON="$REPO/package.json" +VERSION=$(node -p "require(\"$PACKAGEJSON\").version") + +node build/azure-pipelines/common/publish-webview.js "$REPO/src/vs/workbench/contrib/webview/browser/pre/" diff --git a/build/azure-pipelines/common/publish-webview.ts b/build/azure-pipelines/common/publish-webview.ts new file mode 100644 index 0000000000000..143b61bb61abb --- /dev/null +++ b/build/azure-pipelines/common/publish-webview.ts @@ -0,0 +1,87 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as azure from 'azure-storage'; +import * as mime from 'mime'; +import * as minimist from 'minimist'; +import { basename, join } from 'path'; + +const fileNames = [ + 'fake.html', + 'host.js', + 'index.html', + 'main.js', + 'service-worker.js' +]; + +async function assertContainer(blobService: azure.BlobService, container: string): Promise { + await new Promise((c, e) => blobService.createContainerIfNotExists(container, { publicAccessLevel: 'blob' }, err => err ? e(err) : c())); +} + +async function doesBlobExist(blobService: azure.BlobService, container: string, blobName: string): Promise { + const existsResult = await new Promise((c, e) => blobService.doesBlobExist(container, blobName, (err, r) => err ? e(err) : c(r))); + return existsResult.exists; +} + +async function uploadBlob(blobService: azure.BlobService, container: string, blobName: string, file: string): Promise { + const blobOptions: azure.BlobService.CreateBlockBlobRequestOptions = { + contentSettings: { + contentType: mime.lookup(file), + cacheControl: 'max-age=31536000, public' + } + }; + + await new Promise((c, e) => blobService.createBlockBlobFromLocalFile(container, blobName, file, blobOptions, err => err ? e(err) : c())); +} + +async function publish(commit: string, files: readonly string[]): Promise { + + console.log('Publishing...'); + console.log('Commit:', commit); + const storageAccount = process.env['AZURE_WEBVIEW_STORAGE_ACCOUNT']!; + + const blobService = azure.createBlobService(storageAccount, process.env['AZURE_WEBVIEW_STORAGE_ACCESS_KEY']!) + .withFilter(new azure.ExponentialRetryPolicyFilter(20)); + + await assertContainer(blobService, commit); + + for (const file of files) { + const blobName = basename(file); + const blobExists = await doesBlobExist(blobService, commit, blobName); + if (blobExists) { + console.log(`Blob ${commit}, ${blobName} already exists, not publishing again.`); + continue; + } + console.log('Uploading blob to Azure storage...'); + await uploadBlob(blobService, commit, blobName, file); + } + + console.log('Blobs successfully uploaded.'); +} + +function main(): void { + const commit = process.env['BUILD_SOURCEVERSION']; + + if (!commit) { + console.warn('Skipping publish due to missing BUILD_SOURCEVERSION'); + return; + } + + const opts = minimist(process.argv.slice(2)); + const [directory] = opts._; + + const files = fileNames.map(fileName => join(directory, fileName)); + + publish(commit, files).catch(err => { + console.error(err); + process.exit(1); + }); +} + +if (process.argv.length < 3) { + console.error('Usage: node publish.js '); + process.exit(-1); +} +main(); diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 169dfe154fb85..10333b9847266 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -98,6 +98,12 @@ steps: displayName: Extract Telemetry condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) +- script: | + set -e + AZURE_WEBVIEW_STORAGE_ACCESS_KEY="$(vscode-webview-storage-key)" \ + ./build/azure-pipelines/common/publish-webview.sh + displayName: Publish Webview + - script: | set -e yarn gulp compile-build