diff options
author | Joao Moreno <joao.moreno@microsoft.com> | 2022-03-25 12:57:11 +0300 |
---|---|---|
committer | Joao Moreno <joao.moreno@microsoft.com> | 2022-03-25 12:57:18 +0300 |
commit | aa3bf656ca5d712b041432b10f6ae5bc6ce4d1a4 (patch) | |
tree | cdd7f35e46d3c17b7821c741677d43d23227cd28 /build/azure-pipelines | |
parent | 4c79da6dd7601b8c77296efa61dc572be559ff74 (diff) |
make mooncake upload configurable
Diffstat (limited to 'build/azure-pipelines')
-rw-r--r-- | build/azure-pipelines/common/createAsset.js | 33 | ||||
-rw-r--r-- | build/azure-pipelines/common/createAsset.ts | 38 | ||||
-rw-r--r-- | build/azure-pipelines/common/retry.js | 9 | ||||
-rw-r--r-- | build/azure-pipelines/common/retry.ts | 10 | ||||
-rw-r--r-- | build/azure-pipelines/product-build.yml | 6 |
5 files changed, 68 insertions, 28 deletions
diff --git a/build/azure-pipelines/common/createAsset.js b/build/azure-pipelines/common/createAsset.js index 389a052f469..4c04ffb762a 100644 --- a/build/azure-pipelines/common/createAsset.js +++ b/build/azure-pipelines/common/createAsset.js @@ -155,11 +155,6 @@ async function main() { console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`); return; } - const mooncakeCredential = new identity_1.ClientSecretCredential(process.env['AZURE_MOONCAKE_TENANT_ID'], process.env['AZURE_MOONCAKE_CLIENT_ID'], process.env['AZURE_MOONCAKE_CLIENT_SECRET']); - const mooncakeBlobServiceClient = new storage_blob_1.BlobServiceClient(`https://vscode.blob.core.chinacloudapi.cn`, mooncakeCredential, storagePipelineOptions); - const mooncakeContainerClient = mooncakeBlobServiceClient.getContainerClient(quality); - const mooncakeBlobClient = mooncakeContainerClient.getBlockBlobClient(blobName); - console.log('Uploading blobs to Azure storage and Mooncake Azure storage...'); const blobOptions = { blobHTTPHeaders: { blobContentType: mime.lookup(filePath), @@ -167,11 +162,29 @@ async function main() { blobCacheControl: 'max-age=31536000, public' } }; - await (0, retry_1.retry)(() => Promise.all([ - blobClient.uploadFile(filePath, blobOptions), - mooncakeBlobClient.uploadFile(filePath, blobOptions) - ])); - console.log('Blobs successfully uploaded.'); + const uploadPromises = [ + (0, retry_1.retry)(async () => { + await blobClient.uploadFile(filePath, blobOptions); + console.log('Blob successfully uploaded to Azure storage.'); + }) + ]; + const shouldUploadToMooncake = /true/i.test(process.env['VSCODE_PUBLISH_TO_MOONCAKE'] ?? 'true'); + if (shouldUploadToMooncake) { + const mooncakeCredential = new identity_1.ClientSecretCredential(process.env['AZURE_MOONCAKE_TENANT_ID'], process.env['AZURE_MOONCAKE_CLIENT_ID'], process.env['AZURE_MOONCAKE_CLIENT_SECRET']); + const mooncakeBlobServiceClient = new storage_blob_1.BlobServiceClient(`https://vscode.blob.core.chinacloudapi.cn`, mooncakeCredential, storagePipelineOptions); + const mooncakeContainerClient = mooncakeBlobServiceClient.getContainerClient(quality); + const mooncakeBlobClient = mooncakeContainerClient.getBlockBlobClient(blobName); + uploadPromises.push((0, retry_1.retry)(async () => { + await mooncakeBlobClient.uploadFile(filePath, blobOptions); + console.log('Blob successfully uploaded to Mooncake Azure storage.'); + })); + console.log('Uploading blobs to Azure storage and Mooncake Azure storage...'); + } + else { + console.log('Uploading blobs to Azure storage...'); + } + await uploadPromises; + console.log('All blobs successfully uploaded.'); const assetUrl = `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`; const blobPath = new URL(assetUrl).pathname; const mooncakeUrl = `${process.env['MOONCAKE_CDN_URL']}${blobPath}`; diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index 07f833c39f6..8dca506d96c 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -187,13 +187,6 @@ async function main(): Promise<void> { return; } - const mooncakeCredential = new ClientSecretCredential(process.env['AZURE_MOONCAKE_TENANT_ID']!, process.env['AZURE_MOONCAKE_CLIENT_ID']!, process.env['AZURE_MOONCAKE_CLIENT_SECRET']!); - const mooncakeBlobServiceClient = new BlobServiceClient(`https://vscode.blob.core.chinacloudapi.cn`, mooncakeCredential, storagePipelineOptions); - const mooncakeContainerClient = mooncakeBlobServiceClient.getContainerClient(quality); - const mooncakeBlobClient = mooncakeContainerClient.getBlockBlobClient(blobName); - - console.log('Uploading blobs to Azure storage and Mooncake Azure storage...'); - const blobOptions: BlockBlobParallelUploadOptions = { blobHTTPHeaders: { blobContentType: mime.lookup(filePath), @@ -202,12 +195,33 @@ async function main(): Promise<void> { } }; - await retry(() => Promise.all([ - blobClient.uploadFile(filePath, blobOptions), - mooncakeBlobClient.uploadFile(filePath, blobOptions) - ])); + const uploadPromises: Promise<void>[] = [ + retry(async () => { + await blobClient.uploadFile(filePath, blobOptions); + console.log('Blob successfully uploaded to Azure storage.'); + }) + ]; + + const shouldUploadToMooncake = /true/i.test(process.env['VSCODE_PUBLISH_TO_MOONCAKE'] ?? 'true'); + + if (shouldUploadToMooncake) { + const mooncakeCredential = new ClientSecretCredential(process.env['AZURE_MOONCAKE_TENANT_ID']!, process.env['AZURE_MOONCAKE_CLIENT_ID']!, process.env['AZURE_MOONCAKE_CLIENT_SECRET']!); + const mooncakeBlobServiceClient = new BlobServiceClient(`https://vscode.blob.core.chinacloudapi.cn`, mooncakeCredential, storagePipelineOptions); + const mooncakeContainerClient = mooncakeBlobServiceClient.getContainerClient(quality); + const mooncakeBlobClient = mooncakeContainerClient.getBlockBlobClient(blobName); + + uploadPromises.push(retry(async () => { + await mooncakeBlobClient.uploadFile(filePath, blobOptions); + console.log('Blob successfully uploaded to Mooncake Azure storage.'); + })); + + console.log('Uploading blobs to Azure storage and Mooncake Azure storage...'); + } else { + console.log('Uploading blobs to Azure storage...'); + } - console.log('Blobs successfully uploaded.'); + await uploadPromises; + console.log('All blobs successfully uploaded.'); const assetUrl = `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`; const blobPath = new URL(assetUrl).pathname; diff --git a/build/azure-pipelines/common/retry.js b/build/azure-pipelines/common/retry.js index 41136b52b93..bd78d195abb 100644 --- a/build/azure-pipelines/common/retry.js +++ b/build/azure-pipelines/common/retry.js @@ -6,20 +6,23 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.retry = void 0; async function retry(fn) { + let lastError; for (let run = 1; run <= 10; run++) { try { return await fn(); } catch (err) { - if (!/ECONNRESET/.test(err.message)) { + if (!/ECONNRESET|CredentialUnavailableError|Audience validation failed/i.test(err.message)) { throw err; } + lastError = err; const millis = (Math.random() * 200) + (50 * Math.pow(1.5, run)); - console.log(`Failed with ECONNRESET, retrying in ${millis}ms...`); + console.log(`Request failed, retrying in ${millis}ms...`); // maximum delay is 10th retry: ~3 seconds await new Promise(c => setTimeout(c, millis)); } } - throw new Error('Retried too many times'); + console.log(`Too many retries, aborting.`); + throw lastError; } exports.retry = retry; diff --git a/build/azure-pipelines/common/retry.ts b/build/azure-pipelines/common/retry.ts index 1737676590d..0c766771da8 100644 --- a/build/azure-pipelines/common/retry.ts +++ b/build/azure-pipelines/common/retry.ts @@ -6,21 +6,25 @@ 'use strict'; export async function retry<T>(fn: () => Promise<T>): Promise<T> { + let lastError: Error | undefined; + for (let run = 1; run <= 10; run++) { try { return await fn(); } catch (err) { - if (!/ECONNRESET/.test(err.message)) { + if (!/ECONNRESET|CredentialUnavailableError|Audience validation failed/i.test(err.message)) { throw err; } + lastError = err; const millis = (Math.random() * 200) + (50 * Math.pow(1.5, run)); - console.log(`Failed with ECONNRESET, retrying in ${millis}ms...`); + console.log(`Request failed, retrying in ${millis}ms...`); // maximum delay is 10th retry: ~3 seconds await new Promise(c => setTimeout(c, millis)); } } - throw new Error('Retried too many times'); + console.log(`Too many retries, aborting.`); + throw lastError; } diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 551228f420b..f6eee5e5761 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -77,6 +77,10 @@ parameters: displayName: "Publish to builds.code.visualstudio.com" type: boolean default: true + - name: VSCODE_PUBLISH_TO_MOONCAKE + displayName: "Publish to Azure China" + type: boolean + default: true - name: VSCODE_RELEASE displayName: "Release build if successful" type: boolean @@ -107,6 +111,8 @@ variables: value: ${{ in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI') }} - name: VSCODE_PUBLISH value: ${{ and(eq(parameters.VSCODE_PUBLISH, true), eq(variables.VSCODE_CIBUILD, false)) }} + - name: VSCODE_PUBLISH_TO_MOONCAKE + value: ${{ eq(parameters.VSCODE_PUBLISH_TO_MOONCAKE, true) }} - name: VSCODE_SCHEDULEDBUILD value: ${{ eq(variables['Build.Reason'], 'Schedule') }} - name: VSCODE_STEP_ON_IT |