Merge remote-tracking branch 'origin/main' into hediet/unicode-highlighting

This commit is contained in:
Alex Dima
2021-11-22 20:36:30 +01:00
519 changed files with 13758 additions and 9629 deletions
+2 -1
View File
@@ -951,6 +951,7 @@
"**/test/automation/**",
"@vscode/*",
"@parcel/*",
"playwright-core/**",
"*" // node modules
]
},
@@ -1064,7 +1065,7 @@
{
"files": [
"**/vscode.d.ts",
"**/vscode.proposed.d.ts"
"**/vscode.proposed.*.d.ts"
],
"rules": {
"vscode-dts-create-func": "warn",
+33
View File
@@ -75,9 +75,20 @@ jobs:
- name: Run Unit Tests (Browser)
run: yarn test-browser --browser chromium
- name: Compile Integration Tests
run: yarn --cwd test/integration/browser compile
- name: Run Integration Tests (Electron)
run: .\scripts\test-integration.bat
- name: Run Integration Tests (Browser)
timeout-minutes: 10
run: .\resources\server\test\test-web-integration.bat --browser firefox
- name: Run Remote Integration Tests (Electron)
timeout-minutes: 10
run: .\resources\server\test\test-remote-integration.bat
linux:
name: Linux
runs-on: ubuntu-latest
@@ -140,10 +151,22 @@ jobs:
id: browser-unit-tests
run: DISPLAY=:10 yarn test-browser --browser chromium
- name: Compile Integration Tests
run: yarn --cwd test/integration/browser compile
- name: Run Integration Tests (Electron)
id: electron-integration-tests
run: DISPLAY=:10 ./scripts/test-integration.sh
- name: Run Integration Tests (Browser)
id: browser-integration-tests
run: DISPLAY=:10 ./resources/server/test/test-web-integration.sh --browser chromium
- name: Run Remote Integration Tests (Electron)
id: electron-remote-integration-tests
timeout-minutes: 7
run: DISPLAY=:10 ./resources/server/test/test-remote-integration.sh
darwin:
name: macOS
runs-on: macos-latest
@@ -202,9 +225,19 @@ jobs:
- name: Run Unit Tests (Browser)
run: DISPLAY=:10 yarn test-browser --browser chromium
- name: Compile Integration Tests
run: yarn --cwd test/integration/browser compile
- name: Run Integration Tests (Electron)
run: DISPLAY=:10 ./scripts/test-integration.sh
- name: Run Integration Tests (Browser)
run: DISPLAY=:10 ./resources/server/test/test-web-integration.sh --browser webkit
- name: Run Remote Integration Tests (Electron)
timeout-minutes: 7
run: DISPLAY=:10 ./resources/server/test/test-remote-integration.sh
hygiene:
name: Hygiene, Layering and Monaco Editor
runs-on: ubuntu-latest
+2 -2
View File
@@ -18,7 +18,7 @@ See the [Feedback Channels](https://github.com/microsoft/vscode/wiki/Feedback-Ch
## Reporting Issues
Have you identified a reproducible problem in VS Code? Have a feature request? We want to hear about it! Here's how you can make reporting your issue as effective as possible.
Have you identified a reproducible problem in VS Code? Have a feature request? We want to hear about it! Here's how you can report your issue as effectively as possible.
### Identify Where to Report
@@ -43,7 +43,7 @@ If you cannot find an existing issue that describes your bug or feature, create
File a single issue per problem and feature request. Do not enumerate multiple bugs or feature requests in the same issue.
Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes.
Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar but have different causes.
The more information you can provide, the more likely someone will be successful at reproducing the issue and finding a fix.
+3 -3
View File
@@ -13,7 +13,7 @@ This repository ("`Code - OSS`") is where we (Microsoft) develop the [Visual Stu
<img alt="VS Code in action" src="https://user-images.githubusercontent.com/35271042/118224532-3842c400-b438-11eb-923d-a5f66fa6785a.png">
</p>
[Visual Studio Code](https://code.visualstudio.com) is a distribution of the `Code - OSS` repository with Microsoft specific customizations released under a traditional [Microsoft product license](https://code.visualstudio.com/License/).
[Visual Studio Code](https://code.visualstudio.com) is a distribution of the `Code - OSS` repository with Microsoft-specific customizations released under a traditional [Microsoft product license](https://code.visualstudio.com/License/).
[Visual Studio Code](https://code.visualstudio.com) combines the simplicity of a code editor with what developers need for their core edit-build-debug cycle. It provides comprehensive code editing, navigation, and understanding support along with lightweight debugging, a rich extensibility model, and lightweight integration with existing tools.
@@ -49,11 +49,11 @@ See our [wiki](https://github.com/microsoft/vscode/wiki/Feedback-Channels) for a
## Related Projects
Many of the core components and extensions to VS Code live in their own repositories on GitHub. For example, the [node debug adapter](https://github.com/microsoft/vscode-node-debug) and the [mono debug adapter](https://github.com/microsoft/vscode-mono-debug) have their own repositories. For a complete list, please visit the [Related Projects](https://github.com/microsoft/vscode/wiki/Related-Projects) page on our [wiki](https://github.com/microsoft/vscode/wiki).
Many of the core components and extensions to VS Code live in their own repositories on GitHub. For example, the [node debug adapter](https://github.com/microsoft/vscode-node-debug) and the [mono debug adapter](https://github.com/microsoft/vscode-mono-debug) repositories are separate from each other. For a complete list, please visit the [Related Projects](https://github.com/microsoft/vscode/wiki/Related-Projects) page on our [wiki](https://github.com/microsoft/vscode/wiki).
## Bundled Extensions
VS Code includes a set of built-in extensions located in the [extensions](extensions) folder, including grammars and snippets for many languages. Extensions that provide rich language support (code completion, Go to Definition) for a language have the suffix `language-features`. For example, the `json` extension provides coloring for `JSON` and the `json-language-features` provides rich language support for `JSON`.
VS Code includes a set of built-in extensions located in the [extensions](extensions) folder, including grammars and snippets for many languages. Extensions that provide rich language support (code completion, Go to Definition) for a language have the suffix `language-features`. For example, the `json` extension provides coloring for `JSON` and the `json-language-features` extension provides rich language support for `JSON`.
## Development Container
+1 -1
View File
@@ -1 +1 @@
2021-08-20T17:19:02.924Z
2021-11-19T08:23:35Z
+3 -3
View File
@@ -51,8 +51,6 @@ spdlog/test/**
spdlog/*.yml
!spdlog/build/Release/*.node
jschardet/dist/**
windows-foreground-love/binding.gyp
windows-foreground-love/build/**
windows-foreground-love/src/**
@@ -132,7 +130,9 @@ node-addon-api/**/*
**/*.ts
!typescript/**/*.d.ts
jschardet/dist/**
jschardet/index.js
jschardet/src/**
jschardet/dist/jschardet.js
es6-promise/lib/**
+23 -30
View File
@@ -5,11 +5,11 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const url = require("url");
const crypto = require("crypto");
const azure = require("azure-storage");
const storage_blob_1 = require("@azure/storage-blob");
const mime = require("mime");
const cosmos_1 = require("@azure/cosmos");
const identity_1 = require("@azure/identity");
const retry_1 = require("./retry");
if (process.argv.length !== 8) {
console.error('Usage: node createAsset.js PRODUCT OS ARCH TYPE NAME FILE');
@@ -118,20 +118,6 @@ function hashStream(hashName, stream) {
.on('close', () => c(shasum.digest('hex')));
});
}
async function doesAssetExist(blobService, quality, blobName) {
const existsResult = await new Promise((c, e) => blobService.doesBlobExist(quality, blobName, (err, r) => err ? e(err) : c(r)));
return existsResult.exists;
}
async function uploadBlob(blobService, quality, blobName, filePath, fileName) {
const blobOptions = {
contentSettings: {
contentType: mime.lookup(filePath),
contentDisposition: `attachment; filename="${fileName}"`,
cacheControl: 'max-age=31536000, public'
}
};
await new Promise((c, e) => blobService.createBlockBlobFromLocalFile(quality, blobName, filePath, blobOptions, err => err ? e(err) : c()));
}
function getEnv(name) {
const result = process.env[name];
if (typeof result === 'undefined') {
@@ -155,28 +141,35 @@ async function main() {
console.log('SHA1:', sha1hash);
console.log('SHA256:', sha256hash);
const blobName = commit + '/' + fileName;
const storageAccount = process.env['AZURE_STORAGE_ACCOUNT_2'];
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2'])
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
const blobExists = await doesAssetExist(blobService, quality, blobName);
const storagePipelineOptions = { retryOptions: { retryPolicyType: storage_blob_1.StorageRetryPolicyType.EXPONENTIAL, maxTries: 6, tryTimeoutInMs: 10 * 60 * 1000 } };
const credential = new identity_1.ClientSecretCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_CLIENT_SECRET']);
const blobServiceClient = new storage_blob_1.BlobServiceClient(`https://vscode.blob.core.windows.net`, credential, storagePipelineOptions);
const containerClient = blobServiceClient.getContainerClient(quality);
const blobClient = containerClient.getBlockBlobClient(blobName);
const blobExists = await blobClient.exists();
if (blobExists) {
console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`);
return;
}
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY'], `${storageAccount}.blob.core.chinacloudapi.cn`)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
// mooncake is fussy and far away, this is needed!
blobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
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),
blobContentDisposition: `attachment; filename="${fileName}"`,
blobCacheControl: 'max-age=31536000, public'
}
};
await (0, retry_1.retry)(() => Promise.all([
uploadBlob(blobService, quality, blobName, filePath, fileName),
uploadBlob(mooncakeBlobService, quality, blobName, filePath, fileName)
blobClient.uploadFile(filePath, blobOptions),
mooncakeBlobClient.uploadFile(filePath, blobOptions)
]));
console.log('Blobs successfully uploaded.');
// TODO: Understand if blobName and blobPath are the same and replace blobPath with blobName if so.
const assetUrl = `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`;
const blobPath = url.parse(assetUrl).path;
const blobPath = new URL(assetUrl).pathname;
const mooncakeUrl = `${process.env['MOONCAKE_CDN_URL']}${blobPath}`;
const asset = {
platform,
@@ -192,7 +185,7 @@ async function main() {
asset.supportsFastUpdate = true;
}
console.log('Asset:', JSON.stringify(asset, null, ' '));
const client = new cosmos_1.CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT'], key: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const client = new cosmos_1.CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT'], aadCredentials: credential });
const scripts = client.database('builds').container(quality).scripts;
await (0, retry_1.retry)(() => scripts.storedProcedure('createAsset').execute('', [commit, asset, true]));
console.log(` Done ✔️`);
+24 -34
View File
@@ -6,12 +6,12 @@
'use strict';
import * as fs from 'fs';
import * as url from 'url';
import { Readable } from 'stream';
import * as crypto from 'crypto';
import * as azure from 'azure-storage';
import { BlobServiceClient, BlockBlobParallelUploadOptions, StoragePipelineOptions, StorageRetryPolicyType } from '@azure/storage-blob';
import * as mime from 'mime';
import { CosmosClient } from '@azure/cosmos';
import { ClientSecretCredential } from '@azure/identity';
import { retry } from './retry';
interface Asset {
@@ -137,23 +137,6 @@ function hashStream(hashName: string, stream: Readable): Promise<string> {
});
}
async function doesAssetExist(blobService: azure.BlobService, quality: string, blobName: string): Promise<boolean | undefined> {
const existsResult = await new Promise<azure.BlobService.BlobResult>((c, e) => blobService.doesBlobExist(quality, blobName, (err, r) => err ? e(err) : c(r)));
return existsResult.exists;
}
async function uploadBlob(blobService: azure.BlobService, quality: string, blobName: string, filePath: string, fileName: string): Promise<void> {
const blobOptions: azure.BlobService.CreateBlockBlobRequestOptions = {
contentSettings: {
contentType: mime.lookup(filePath),
contentDisposition: `attachment; filename="${fileName}"`,
cacheControl: 'max-age=31536000, public'
}
};
await new Promise<void>((c, e) => blobService.createBlockBlobFromLocalFile(quality, blobName, filePath, blobOptions, err => err ? e(err) : c()));
}
function getEnv(name: string): string {
const result = process.env[name];
@@ -186,37 +169,44 @@ async function main(): Promise<void> {
console.log('SHA256:', sha256hash);
const blobName = commit + '/' + fileName;
const storageAccount = process.env['AZURE_STORAGE_ACCOUNT_2']!;
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2']!)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
const storagePipelineOptions: StoragePipelineOptions = { retryOptions: { retryPolicyType: StorageRetryPolicyType.EXPONENTIAL, maxTries: 6, tryTimeoutInMs: 10 * 60 * 1000 } };
const blobExists = await doesAssetExist(blobService, quality, blobName);
const credential = new ClientSecretCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, process.env['AZURE_CLIENT_SECRET']!);
const blobServiceClient = new BlobServiceClient(`https://vscode.blob.core.windows.net`, credential, storagePipelineOptions);
const containerClient = blobServiceClient.getContainerClient(quality);
const blobClient = containerClient.getBlockBlobClient(blobName);
const blobExists = await blobClient.exists();
if (blobExists) {
console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`);
return;
}
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY']!, `${storageAccount}.blob.core.chinacloudapi.cn`)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
// mooncake is fussy and far away, this is needed!
blobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
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),
blobContentDisposition: `attachment; filename="${fileName}"`,
blobCacheControl: 'max-age=31536000, public'
}
};
await retry(() => Promise.all([
uploadBlob(blobService, quality, blobName, filePath, fileName),
uploadBlob(mooncakeBlobService, quality, blobName, filePath, fileName)
blobClient.uploadFile(filePath, blobOptions),
mooncakeBlobClient.uploadFile(filePath, blobOptions)
]));
console.log('Blobs successfully uploaded.');
// TODO: Understand if blobName and blobPath are the same and replace blobPath with blobName if so.
const assetUrl = `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`;
const blobPath = url.parse(assetUrl).path;
const blobPath = new URL(assetUrl).pathname;
const mooncakeUrl = `${process.env['MOONCAKE_CDN_URL']}${blobPath}`;
const asset: Asset = {
@@ -236,7 +226,7 @@ async function main(): Promise<void> {
console.log('Asset:', JSON.stringify(asset, null, ' '));
const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, key: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, aadCredentials: credential });
const scripts = client.database('builds').container(quality).scripts;
await retry(() => scripts.storedProcedure('createAsset').execute('', [commit, asset, true]));
+3 -1
View File
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const identity_1 = require("@azure/identity");
const cosmos_1 = require("@azure/cosmos");
const retry_1 = require("./retry");
if (process.argv.length !== 3) {
@@ -38,7 +39,8 @@ async function main() {
assets: [],
updates: {}
};
const client = new cosmos_1.CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT'], key: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const aadCredentials = new identity_1.ClientSecretCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_CLIENT_SECRET']);
const client = new cosmos_1.CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT'], aadCredentials });
const scripts = client.database('builds').container(quality).scripts;
await (0, retry_1.retry)(() => scripts.storedProcedure('createBuild').execute('', [Object.assign(Object.assign({}, build), { _partitionKey: '' })]));
}
+3 -1
View File
@@ -5,6 +5,7 @@
'use strict';
import { ClientSecretCredential } from '@azure/identity';
import { CosmosClient } from '@azure/cosmos';
import { retry } from './retry';
@@ -47,7 +48,8 @@ async function main(): Promise<void> {
updates: {}
};
const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, key: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const aadCredentials = new ClientSecretCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, process.env['AZURE_CLIENT_SECRET']!);
const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, aadCredentials });
const scripts = client.database('builds').container(quality).scripts;
await retry(() => scripts.storedProcedure('createBuild').execute('', [{ ...build, _partitionKey: '' }]));
}
+3 -1
View File
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const identity_1 = require("@azure/identity");
const cosmos_1 = require("@azure/cosmos");
const retry_1 = require("./retry");
function getEnv(name) {
@@ -30,7 +31,8 @@ async function getConfig(client, quality) {
async function main() {
const commit = getEnv('BUILD_SOURCEVERSION');
const quality = getEnv('VSCODE_QUALITY');
const client = new cosmos_1.CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT'], key: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const aadCredentials = new identity_1.ClientSecretCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_CLIENT_SECRET']);
const client = new cosmos_1.CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT'], aadCredentials });
const config = await getConfig(client, quality);
console.log('Quality config:', config);
if (config.frozen) {
+3 -1
View File
@@ -5,6 +5,7 @@
'use strict';
import { ClientSecretCredential } from '@azure/identity';
import { CosmosClient } from '@azure/cosmos';
import { retry } from './retry';
@@ -46,7 +47,8 @@ async function main(): Promise<void> {
const commit = getEnv('BUILD_SOURCEVERSION');
const quality = getEnv('VSCODE_QUALITY');
const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, key: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const aadCredentials = new ClientSecretCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, process.env['AZURE_CLIENT_SECRET']!);
const client = new CosmosClient({ endpoint: process.env['AZURE_DOCUMENTDB_ENDPOINT']!, aadCredentials });
const config = await getConfig(client, quality);
console.log('Quality config:', config);
@@ -8,6 +8,8 @@
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
@@ -4,11 +4,5 @@
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>
@@ -8,7 +8,7 @@ steps:
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: 'github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key,ticino-storage-key'
SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key"
- task: DownloadPipelineArtifact@2
inputs:
@@ -48,23 +48,23 @@ steps:
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
mkdir -p .build
node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash
displayName: Prepare yarn cache flags
# - script: |
# mkdir -p .build
# node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash
# displayName: Prepare yarn cache flags
- task: Cache@2
inputs:
key: "nodeModules | $(Agent.OS) | .build/yarnlockhash"
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache
# - task: Cache@2
# inputs:
# key: "nodeModules | $(Agent.OS) | .build/yarnlockhash"
# path: .build/node_modules_cache
# cacheHitVar: NODE_MODULES_RESTORED
# displayName: Restore node_modules cache
- script: |
set -e
tar -xzf .build/node_modules_cache/cache.tgz
condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Extract node_modules cache
# - script: |
# set -e
# tar -xzf .build/node_modules_cache/cache.tgz
# condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Extract node_modules cache
- script: |
set -e
@@ -101,13 +101,13 @@ steps:
displayName: Install dependencies
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
- script: |
set -e
node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
mkdir -p .build/node_modules_cache
tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Create node_modules archive
# - script: |
# set -e
# node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
# mkdir -p .build/node_modules_cache
# tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
# condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Create node_modules archive
# This script brings in the right resources (images, icons, etc) based on the quality (insiders, stable, exploration)
- script: |
@@ -224,7 +224,7 @@ steps:
APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)
APP_NAME="`ls $APP_ROOT | head -n 1`"
yarn smoketest-no-compile --build "$APP_ROOT/$APP_NAME" --screenshots $(Build.SourcesDirectory)/.build/logs/smoke-tests
timeoutInMinutes: 5
timeoutInMinutes: 10
displayName: Run smoke tests (Electron)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
@@ -234,7 +234,7 @@ steps:
APP_NAME="`ls $APP_ROOT | head -n 1`"
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin" \
yarn smoketest-no-compile --build "$APP_ROOT/$APP_NAME" --remote --screenshots $(Build.SourcesDirectory)/.build/logs/smoke-tests-remote
timeoutInMinutes: 5
timeoutInMinutes: 10
displayName: Run smoke tests (Remote)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
@@ -242,7 +242,7 @@ steps:
set -e
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-darwin" \
yarn smoketest-no-compile --web --headless
timeoutInMinutes: 5
timeoutInMinutes: 10
displayName: Run smoke tests (Browser)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
@@ -301,10 +301,25 @@ steps:
displayName: Publish web server archive
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), ne(variables['VSCODE_PUBLISH'], 'false'))
- task: AzureCLI@2
inputs:
azureSubscription: "vscode-builds-subscription"
scriptType: pscore
scriptLocation: inlineScript
addSpnToEnvironment: true
inlineScript: |
Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey"
- script: |
AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \
set -e
AZURE_STORAGE_ACCOUNT="ticino" \
AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \
AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \
AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \
VSCODE_ARCH="$(VSCODE_ARCH)" \
yarn gulp upload-vscode-configuration
node build/azure-pipelines/upload-configuration
displayName: Upload configuration (for Bing settings search)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), ne(variables['VSCODE_PUBLISH'], 'false'))
continueOnError: true
+1 -1
View File
@@ -18,7 +18,7 @@ steps:
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: 'github-distro-mixin-password'
SecretsFilter: "github-distro-mixin-password"
- script: |
set -e
+1 -1
View File
@@ -14,7 +14,7 @@ steps:
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: 'github-distro-mixin-password'
SecretsFilter: "github-distro-mixin-password"
- script: |
set -e
@@ -3,16 +3,12 @@ steps:
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: 'github-distro-mixin-password'
SecretsFilter: "github-distro-mixin-password"
- task: DownloadPipelineArtifact@2
inputs:
@@ -51,23 +47,23 @@ steps:
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
mkdir -p .build
node build/azure-pipelines/common/computeNodeModulesCacheKey.js "alpine" $ENABLE_TERRAPIN > .build/yarnlockhash
displayName: Prepare yarn cache flags
# - script: |
# mkdir -p .build
# node build/azure-pipelines/common/computeNodeModulesCacheKey.js "alpine" $ENABLE_TERRAPIN > .build/yarnlockhash
# displayName: Prepare yarn cache flags
- task: Cache@2
inputs:
key: 'nodeModules | $(Agent.OS) | .build/yarnlockhash'
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache
# - task: Cache@2
# inputs:
# key: "nodeModules | $(Agent.OS) | .build/yarnlockhash"
# path: .build/node_modules_cache
# cacheHitVar: NODE_MODULES_RESTORED
# displayName: Restore node_modules cache
- script: |
set -e
tar -xzf .build/node_modules_cache/cache.tgz
condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Extract node_modules cache
# - script: |
# set -e
# tar -xzf .build/node_modules_cache/cache.tgz
# condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Extract node_modules cache
- script: |
set -e
@@ -93,13 +89,13 @@ steps:
displayName: Install dependencies
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
- script: |
set -e
node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
mkdir -p .build/node_modules_cache
tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Create node_modules archive
# - script: |
# set -e
# node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
# mkdir -p .build/node_modules_cache
# tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
# condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Create node_modules archive
- script: |
set -e
@@ -107,7 +103,7 @@ steps:
displayName: Mix in quality
- script: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
displayName: 'Register Docker QEMU'
displayName: "Register Docker QEMU"
condition: eq(variables['VSCODE_ARCH'], 'arm64')
- script: |
@@ -3,16 +3,12 @@ steps:
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,builds-docdb-key-readwrite,vscode-storage-key,ESRP-PKI,esrp-aad-username,esrp-aad-password"
SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password"
- task: DownloadPipelineArtifact@2
inputs:
@@ -42,23 +38,23 @@ steps:
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
mkdir -p .build
node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash
displayName: Prepare yarn cache flags
# - script: |
# mkdir -p .build
# node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash
# displayName: Prepare yarn cache flags
- task: Cache@2
inputs:
key: "nodeModules | $(Agent.OS) | .build/yarnlockhash"
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache
# - task: Cache@2
# inputs:
# key: "nodeModules | $(Agent.OS) | .build/yarnlockhash"
# path: .build/node_modules_cache
# cacheHitVar: NODE_MODULES_RESTORED
# displayName: Restore node_modules cache
- script: |
set -e
tar -xzf .build/node_modules_cache/cache.tgz
condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Extract node_modules cache
# - script: |
# set -e
# tar -xzf .build/node_modules_cache/cache.tgz
# condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Extract node_modules cache
- script: |
set -e
@@ -114,13 +110,13 @@ steps:
displayName: Install dependencies
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
- script: |
set -e
node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
mkdir -p .build/node_modules_cache
tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Create node_modules archive
# - script: |
# set -e
# node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
# mkdir -p .build/node_modules_cache
# tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
# condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Create node_modules archive
- script: |
set -e
@@ -212,7 +208,7 @@ steps:
set -e
APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)
yarn smoketest-no-compile --build "$APP_PATH" --electronArgs="--disable-dev-shm-usage --use-gl=swiftshader" --screenshots $(Build.SourcesDirectory)/.build/logs/smoke-tests
timeoutInMinutes: 5
timeoutInMinutes: 10
displayName: Run smoke tests (Electron)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
@@ -221,7 +217,7 @@ steps:
APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \
yarn smoketest-no-compile --build "$APP_PATH" --remote --electronArgs="--disable-dev-shm-usage --use-gl=swiftshader" --screenshots $(Build.SourcesDirectory)/.build/logs/smoke-tests-remote
timeoutInMinutes: 5
timeoutInMinutes: 10
displayName: Run smoke tests (Remote)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
@@ -229,7 +225,7 @@ steps:
set -e
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \
yarn smoketest-no-compile --web --headless --electronArgs="--disable-dev-shm-usage --use-gl=swiftshader"
timeoutInMinutes: 5
timeoutInMinutes: 10
displayName: Run smoke tests (Browser)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
@@ -293,9 +289,6 @@ steps:
- script: |
set -e
AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \
AZURE_STORAGE_ACCESS_KEY_2="$(vscode-storage-key)" \
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
VSCODE_ARCH="$(VSCODE_ARCH)" \
./build/azure-pipelines/linux/prepare-publish.sh
displayName: Prepare for Publish
@@ -3,10 +3,6 @@ steps:
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: DownloadPipelineArtifact@0
displayName: "Download Pipeline Artifact"
inputs:
@@ -22,6 +18,13 @@ steps:
# Make sure we get latest packages
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install -y curl apt-transport-https ca-certificates
# Yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update
sudo apt-get install -y yarn
# Define variables
REPO="$(pwd)"
+197 -204
View File
@@ -113,10 +113,6 @@ variables:
value: https://az764295.vo.msecnd.net
- name: AZURE_DOCUMENTDB_ENDPOINT
value: https://vscode.documents.azure.com:443/
- name: AZURE_STORAGE_ACCOUNT
value: ticino
- name: AZURE_STORAGE_ACCOUNT_2
value: vscode
- name: MOONCAKE_CDN_URL
value: https://vscode.cdn.azure.cn
- name: VSCODE_MIXIN_REPO
@@ -152,212 +148,209 @@ stages:
- template: product-compile.yml
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_WINDOWS'], true)) }}:
- stage: Windows
dependsOn:
- Compile
pool:
vmImage: VS2017-Win2016
jobs:
- stage: Windows
dependsOn:
- Compile
pool:
vmImage: VS2017-Win2016
jobs:
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- job: Windows
timeoutInMinutes: 90
variables:
VSCODE_ARCH: x64
steps:
- template: win32/product-build-win32.yml
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- job: Windows
timeoutInMinutes: 90
variables:
VSCODE_ARCH: x64
steps:
- template: win32/product-build-win32.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_32BIT, true)) }}:
- job: Windows32
timeoutInMinutes: 90
variables:
VSCODE_ARCH: ia32
steps:
- template: win32/product-build-win32.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_32BIT, true)) }}:
- job: Windows32
timeoutInMinutes: 90
variables:
VSCODE_ARCH: ia32
steps:
- template: win32/product-build-win32.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}:
- job: WindowsARM64
timeoutInMinutes: 90
variables:
VSCODE_ARCH: arm64
steps:
- template: win32/product-build-win32.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}:
- job: WindowsARM64
timeoutInMinutes: 90
variables:
VSCODE_ARCH: arm64
steps:
- template: win32/product-build-win32.yml
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_LINUX'], true)) }}:
- stage: Linux
dependsOn:
- Compile
pool:
vmImage: "Ubuntu-18.04"
jobs:
- ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}:
- job: Linux
container: vscode-x64
variables:
VSCODE_ARCH: x64
NPM_ARCH: x64
DISPLAY: ":10"
steps:
- template: linux/product-build-linux.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX, true), ne(variables['VSCODE_PUBLISH'], 'false')) }}:
- job: LinuxSnap
dependsOn:
- Linux
container: snapcraft
variables:
VSCODE_ARCH: x64
steps:
- template: linux/snap-build-linux.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true)) }}:
- job: LinuxArmhf
container: vscode-armhf
variables:
VSCODE_ARCH: armhf
NPM_ARCH: armv7l
steps:
- template: linux/product-build-linux.yml
# TODO@joaomoreno: We don't ship ARM snaps for now
- ${{ if and(false, eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true)) }}:
- job: LinuxSnapArmhf
dependsOn:
- LinuxArmhf
container: snapcraft
variables:
VSCODE_ARCH: armhf
steps:
- template: linux/snap-build-linux.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}:
- job: LinuxArm64
container: vscode-arm64
variables:
VSCODE_ARCH: arm64
NPM_ARCH: arm64
steps:
- template: linux/product-build-linux.yml
# TODO@joaomoreno: We don't ship ARM snaps for now
- ${{ if and(false, eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}:
- job: LinuxSnapArm64
dependsOn:
- LinuxArm64
container: snapcraft
variables:
VSCODE_ARCH: arm64
steps:
- template: linux/snap-build-linux.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true)) }}:
- job: LinuxAlpine
variables:
VSCODE_ARCH: x64
steps:
- template: linux/product-build-alpine.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true)) }}:
- job: LinuxAlpineArm64
variables:
VSCODE_ARCH: arm64
steps:
- template: linux/product-build-alpine.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WEB, true)) }}:
- job: LinuxWeb
variables:
VSCODE_ARCH: x64
steps:
- template: web/product-build-web.yml
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_MACOS'], true)) }}:
- stage: macOS
dependsOn:
- Compile
pool:
vmImage: macOS-latest
jobs:
- ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}:
- job: macOS
timeoutInMinutes: 90
variables:
VSCODE_ARCH: x64
steps:
- template: darwin/product-build-darwin.yml
- ${{ if ne(variables['VSCODE_PUBLISH'], 'false') }}:
- job: macOSSign
dependsOn:
- macOS
timeoutInMinutes: 90
variables:
VSCODE_ARCH: x64
steps:
- template: darwin/product-build-darwin-sign.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true)) }}:
- job: macOSARM64
timeoutInMinutes: 90
variables:
VSCODE_ARCH: arm64
steps:
- template: darwin/product-build-darwin.yml
- ${{ if ne(variables['VSCODE_PUBLISH'], 'false') }}:
- job: macOSARM64Sign
dependsOn:
- macOSARM64
timeoutInMinutes: 90
variables:
VSCODE_ARCH: arm64
steps:
- template: darwin/product-build-darwin-sign.yml
- ${{ if eq(variables['VSCODE_BUILD_MACOS_UNIVERSAL'], true) }}:
- job: macOSUniversal
dependsOn:
- macOS
- macOSARM64
timeoutInMinutes: 90
variables:
VSCODE_ARCH: universal
steps:
- template: darwin/product-build-darwin.yml
- ${{ if ne(variables['VSCODE_PUBLISH'], 'false') }}:
- job: macOSUniversalSign
dependsOn:
- macOSUniversal
timeoutInMinutes: 90
variables:
VSCODE_ARCH: universal
steps:
- template: darwin/product-build-darwin-sign.yml
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), ne(variables['VSCODE_PUBLISH'], 'false')) }}:
- stage: Publish
dependsOn:
- Compile
pool:
vmImage: "Ubuntu-18.04"
variables:
- name: BUILDS_API_URL
value: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/
jobs:
- job: PublishBuild
timeoutInMinutes: 180
displayName: Publish Build
steps:
- template: product-publish.yml
- ${{ if or(eq(parameters.VSCODE_RELEASE, true), and(in(parameters.VSCODE_QUALITY, 'insider', 'exploration'), eq(variables['VSCODE_SCHEDULEDBUILD'], true))) }}:
- stage: Release
- stage: Linux
dependsOn:
- Publish
- Compile
pool:
vmImage: "Ubuntu-18.04"
jobs:
- job: ReleaseBuild
displayName: Release Build
- ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}:
- job: Linux
container: vscode-x64
variables:
VSCODE_ARCH: x64
NPM_ARCH: x64
DISPLAY: ":10"
steps:
- template: linux/product-build-linux.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX, true), ne(variables['VSCODE_PUBLISH'], 'false')) }}:
- job: LinuxSnap
dependsOn:
- Linux
container: snapcraft
variables:
VSCODE_ARCH: x64
steps:
- template: linux/snap-build-linux.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true)) }}:
- job: LinuxArmhf
container: vscode-armhf
variables:
VSCODE_ARCH: armhf
NPM_ARCH: armv7l
steps:
- template: linux/product-build-linux.yml
# TODO@joaomoreno: We don't ship ARM snaps for now
- ${{ if and(false, eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true)) }}:
- job: LinuxSnapArmhf
dependsOn:
- LinuxArmhf
container: snapcraft
variables:
VSCODE_ARCH: armhf
steps:
- template: linux/snap-build-linux.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}:
- job: LinuxArm64
container: vscode-arm64
variables:
VSCODE_ARCH: arm64
NPM_ARCH: arm64
steps:
- template: linux/product-build-linux.yml
# TODO@joaomoreno: We don't ship ARM snaps for now
- ${{ if and(false, eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}:
- job: LinuxSnapArm64
dependsOn:
- LinuxArm64
container: snapcraft
variables:
VSCODE_ARCH: arm64
steps:
- template: linux/snap-build-linux.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true)) }}:
- job: LinuxAlpine
variables:
VSCODE_ARCH: x64
steps:
- template: linux/product-build-alpine.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true)) }}:
- job: LinuxAlpineArm64
variables:
VSCODE_ARCH: arm64
steps:
- template: linux/product-build-alpine.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WEB, true)) }}:
- job: LinuxWeb
variables:
VSCODE_ARCH: x64
steps:
- template: web/product-build-web.yml
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_MACOS'], true)) }}:
- stage: macOS
dependsOn:
- Compile
pool:
vmImage: macOS-latest
jobs:
- ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}:
- job: macOS
timeoutInMinutes: 90
variables:
VSCODE_ARCH: x64
steps:
- template: darwin/product-build-darwin.yml
- ${{ if ne(variables['VSCODE_PUBLISH'], 'false') }}:
- job: macOSSign
dependsOn:
- macOS
timeoutInMinutes: 90
variables:
VSCODE_ARCH: x64
steps:
- template: darwin/product-build-darwin-sign.yml
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true)) }}:
- job: macOSARM64
timeoutInMinutes: 90
variables:
VSCODE_ARCH: arm64
steps:
- template: darwin/product-build-darwin.yml
- ${{ if ne(variables['VSCODE_PUBLISH'], 'false') }}:
- job: macOSARM64Sign
dependsOn:
- macOSARM64
timeoutInMinutes: 90
variables:
VSCODE_ARCH: arm64
steps:
- template: darwin/product-build-darwin-sign.yml
- ${{ if eq(variables['VSCODE_BUILD_MACOS_UNIVERSAL'], true) }}:
- job: macOSUniversal
dependsOn:
- macOS
- macOSARM64
timeoutInMinutes: 90
variables:
VSCODE_ARCH: universal
steps:
- template: darwin/product-build-darwin.yml
- ${{ if ne(variables['VSCODE_PUBLISH'], 'false') }}:
- job: macOSUniversalSign
dependsOn:
- macOSUniversal
timeoutInMinutes: 90
variables:
VSCODE_ARCH: universal
steps:
- template: darwin/product-build-darwin-sign.yml
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), ne(variables['VSCODE_PUBLISH'], 'false')) }}:
- stage: Publish
dependsOn:
- Compile
pool:
vmImage: "Ubuntu-18.04"
variables:
- name: BUILDS_API_URL
value: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/
jobs:
- job: PublishBuild
timeoutInMinutes: 180
displayName: Publish Build
steps:
- template: product-release.yml
- template: product-publish.yml
- ${{ if or(eq(parameters.VSCODE_RELEASE, true), and(in(parameters.VSCODE_QUALITY, 'insider', 'exploration'), eq(variables['VSCODE_SCHEDULEDBUILD'], true))) }}:
- stage: Release
dependsOn:
- Publish
pool:
vmImage: "Ubuntu-18.04"
jobs:
- job: ReleaseBuild
displayName: Release Build
steps:
- template: product-release.yml
+39 -29
View File
@@ -3,16 +3,12 @@ steps:
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: 'github-distro-mixin-password,ticino-storage-key'
SecretsFilter: "github-distro-mixin-password"
- script: |
set -e
@@ -31,24 +27,24 @@ steps:
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
mkdir -p .build
node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash
displayName: Prepare yarn cache flags
# - script: |
# mkdir -p .build
# node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash
# displayName: Prepare yarn cache flags
# using `genericNodeModules` instead of `nodeModules` here to avoid sharing the cache with builds running inside containers
- task: Cache@2
inputs:
key: "genericNodeModules | $(Agent.OS) | .build/yarnlockhash"
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache
# # using `genericNodeModules` instead of `nodeModules` here to avoid sharing the cache with builds running inside containers
# - task: Cache@2
# inputs:
# key: "genericNodeModules | $(Agent.OS) | .build/yarnlockhash"
# path: .build/node_modules_cache
# cacheHitVar: NODE_MODULES_RESTORED
# displayName: Restore node_modules cache
- script: |
set -e
tar -xzf .build/node_modules_cache/cache.tgz
condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Extract node_modules cache
# - script: |
# set -e
# tar -xzf .build/node_modules_cache/cache.tgz
# condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Extract node_modules cache
- script: |
set -e
@@ -81,13 +77,13 @@ steps:
displayName: Install dependencies
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
- script: |
set -e
node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
mkdir -p .build/node_modules_cache
tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Create node_modules archive
# - script: |
# set -e
# node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
# mkdir -p .build/node_modules_cache
# tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
# condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Create node_modules archive
# Mixin must run before optimize, because the CSS loader will inline small SVGs
- script: |
@@ -107,9 +103,23 @@ steps:
displayName: Compile test suites
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- task: AzureCLI@2
inputs:
azureSubscription: "vscode-builds-subscription"
scriptType: pscore
scriptLocation: inlineScript
addSpnToEnvironment: true
inlineScript: |
Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey"
- script: |
set -e
AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \
AZURE_STORAGE_ACCOUNT="ticino" \
AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \
AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \
AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \
node build/azure-pipelines/upload-sourcemaps
displayName: Upload sourcemaps
condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false'))
+33 -11
View File
@@ -3,16 +3,12 @@ steps:
inputs:
versionSpec: "12.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: 'builds-docdb-key-readwrite,github-distro-mixin-password,ticino-storage-key,vscode-storage-key,vscode-mooncake-storage-key'
SecretsFilter: "github-distro-mixin-password"
- pwsh: |
. build/azure-pipelines/win32/exec.ps1
@@ -21,9 +17,31 @@ steps:
displayName: Install dependencies
- download: current
patterns: '**/artifacts_processed_*.txt'
patterns: "**/artifacts_processed_*.txt"
displayName: Download all artifacts_processed text files
- task: AzureCLI@2
inputs:
azureSubscription: "vscode-builds-subscription"
scriptType: pscore
scriptLocation: inlineScript
addSpnToEnvironment: true
inlineScript: |
Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey"
- task: AzureCLI@2
inputs:
azureSubscription: "vscode-builds-mooncake-subscription"
scriptType: pscore
scriptLocation: inlineScript
addSpnToEnvironment: true
inlineScript: |
Write-Host "##vso[task.setvariable variable=AZURE_MOONCAKE_TENANT_ID]$env:tenantId"
Write-Host "##vso[task.setvariable variable=AZURE_MOONCAKE_CLIENT_ID]$env:servicePrincipalId"
Write-Host "##vso[task.setvariable variable=AZURE_MOONCAKE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey"
- pwsh: |
. build/azure-pipelines/win32/exec.ps1
@@ -32,7 +50,9 @@ steps:
return
}
$env:AZURE_DOCUMENTDB_MASTERKEY = "$(builds-docdb-key-readwrite)"
$env:AZURE_TENANT_ID = "$(AZURE_TENANT_ID)"
$env:AZURE_CLIENT_ID = "$(AZURE_CLIENT_ID)"
$env:AZURE_CLIENT_SECRET = "$(AZURE_CLIENT_SECRET)"
$VERSION = node -p "require('./package.json').version"
Write-Host "Creating build with version: $VERSION"
exec { node build/azure-pipelines/common/createBuild.js $VERSION }
@@ -40,10 +60,12 @@ steps:
- pwsh: |
$env:VSCODE_MIXIN_PASSWORD = "$(github-distro-mixin-password)"
$env:AZURE_DOCUMENTDB_MASTERKEY = "$(builds-docdb-key-readwrite)"
$env:AZURE_STORAGE_ACCESS_KEY = "$(ticino-storage-key)"
$env:AZURE_STORAGE_ACCESS_KEY_2 = "$(vscode-storage-key)"
$env:MOONCAKE_STORAGE_ACCESS_KEY = "$(vscode-mooncake-storage-key)"
$env:AZURE_TENANT_ID = "$(AZURE_TENANT_ID)"
$env:AZURE_CLIENT_ID = "$(AZURE_CLIENT_ID)"
$env:AZURE_CLIENT_SECRET = "$(AZURE_CLIENT_SECRET)"
$env:AZURE_MOONCAKE_TENANT_ID = "$(AZURE_MOONCAKE_TENANT_ID)"
$env:AZURE_MOONCAKE_CLIENT_ID = "$(AZURE_MOONCAKE_CLIENT_ID)"
$env:AZURE_MOONCAKE_CLIENT_SECRET = "$(AZURE_MOONCAKE_CLIENT_SECRET)"
build/azure-pipelines/product-publish.ps1
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+11 -11
View File
@@ -3,21 +3,21 @@ steps:
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
- task: AzureCLI@2
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: 'builds-docdb-key-readwrite'
scriptType: pscore
scriptLocation: inlineScript
addSpnToEnvironment: true
inlineScript: |
Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey"
- script: |
set -e
(cd build ; yarn)
AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \
AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \
AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \
AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \
node build/azure-pipelines/common/releaseBuild.js
@@ -14,10 +14,6 @@ steps:
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- bash: |
TAG_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`)
CHANNEL="C1C14HJ2F"
+174 -182
View File
@@ -32,209 +32,201 @@ variables:
value: x64
stages:
- stage: Windows
condition: eq(variables.SCAN_WINDOWS, 'true')
pool:
vmImage: VS2017-Win2016
jobs:
- job: WindowsJob
timeoutInMinutes: 0
steps:
- task: CredScan@3
continueOnError: true
inputs:
scanFolder: '$(Build.SourcesDirectory)'
outputFormat: 'pre'
- task: NodeTool@0
inputs:
versionSpec: "14.x"
- stage: Windows
condition: eq(variables.SCAN_WINDOWS, 'true')
pool:
vmImage: VS2017-Win2016
jobs:
- job: WindowsJob
timeoutInMinutes: 0
steps:
- task: CredScan@3
continueOnError: true
inputs:
scanFolder: "$(Build.SourcesDirectory)"
outputFormat: "pre"
- task: NodeTool@0
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password"
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
"machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
"machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII
exec { git config user.email "vscode@microsoft.com" }
exec { git config user.name "VSCode" }
displayName: Prepare tooling
exec { git config user.email "vscode@microsoft.com" }
exec { git config user.name "VSCode" }
displayName: Prepare tooling
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") }
displayName: Merge distro
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") }
displayName: Merge distro
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npx https://aka.ms/enablesecurefeed standAlone }
timeoutInMinutes: 5
condition: and(succeeded(), eq(variables['ENABLE_TERRAPIN'], 'true'))
displayName: Switch to Terrapin packages
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npx https://aka.ms/enablesecurefeed standAlone }
timeoutInMinutes: 5
condition: and(succeeded(), eq(variables['ENABLE_TERRAPIN'], 'true'))
displayName: Switch to Terrapin packages
- task: Semmle@1
inputs:
sourceCodeDirectory: "$(Build.SourcesDirectory)"
language: "cpp"
buildCommandsString: "yarn --frozen-lockfile"
querySuite: "Required"
timeout: "1800"
ram: "16384"
addProjectDirToScanningExclusionList: true
env:
npm_config_arch: "$(NPM_ARCH)"
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: CodeQL
- task: Semmle@1
inputs:
sourceCodeDirectory: '$(Build.SourcesDirectory)'
language: 'cpp'
buildCommandsString: 'yarn --frozen-lockfile'
querySuite: 'Required'
timeout: '1800'
ram: '16384'
addProjectDirToScanningExclusionList: true
env:
npm_config_arch: "$(NPM_ARCH)"
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: CodeQL
- powershell: |
. build/azure-pipelines/win32/exec.ps1
. build/azure-pipelines/win32/retry.ps1
$ErrorActionPreference = "Stop"
retry { exec { yarn --frozen-lockfile } }
env:
npm_config_arch: "$(NPM_ARCH)"
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
CHILD_CONCURRENCY: 1
displayName: Install dependencies
- powershell: |
. build/azure-pipelines/win32/exec.ps1
. build/azure-pipelines/win32/retry.ps1
$ErrorActionPreference = "Stop"
retry { exec { yarn --frozen-lockfile } }
env:
npm_config_arch: "$(NPM_ARCH)"
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
CHILD_CONCURRENCY: 1
displayName: Install dependencies
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { yarn gulp "vscode-symbols-win32-$(VSCODE_ARCH)" }
displayName: Download Symbols
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { yarn gulp "vscode-symbols-win32-$(VSCODE_ARCH)" }
displayName: Download Symbols
- task: BinSkim@4
inputs:
InputType: "Basic"
Function: "analyze"
TargetPattern: "guardianGlob"
AnalyzeTargetGlob: '$(agent.builddirectory)\scanbin\**.dll;$(agent.builddirectory)\scanbin\**.exe;$(agent.builddirectory)\scanbin\**.node'
AnalyzeLocalSymbolDirectories: '$(agent.builddirectory)\scanbin\VSCode-win32-$(VSCODE_ARCH)\pdb'
- task: BinSkim@4
inputs:
InputType: 'Basic'
Function: 'analyze'
TargetPattern: 'guardianGlob'
AnalyzeTargetGlob: '$(agent.builddirectory)\scanbin\**.dll;$(agent.builddirectory)\scanbin\**.exe;$(agent.builddirectory)\scanbin\**.node'
AnalyzeLocalSymbolDirectories: '$(agent.builddirectory)\scanbin\VSCode-win32-$(VSCODE_ARCH)\pdb'
- task: TSAUpload@2
inputs:
GdnPublishTsaOnboard: true
GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)\build\azure-pipelines\.gdntsa'
- task: TSAUpload@2
inputs:
GdnPublishTsaOnboard: true
GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)\build\azure-pipelines\.gdntsa'
- stage: Linux
dependsOn: []
condition: eq(variables.SCAN_LINUX, 'true')
pool:
vmImage: "Ubuntu-18.04"
jobs:
- job: LinuxJob
steps:
- task: CredScan@2
inputs:
toolMajorVersion: "V2"
- task: NodeTool@0
inputs:
versionSpec: "14.x"
- stage: Linux
dependsOn: []
condition: eq(variables.SCAN_LINUX, 'true')
pool:
vmImage: "Ubuntu-18.04"
jobs:
- job: LinuxJob
steps:
- task: CredScan@2
inputs:
toolMajorVersion: 'V2'
- task: NodeTool@0
inputs:
versionSpec: "14.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(github-distro-mixin-password)
EOF
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password"
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
displayName: Prepare tooling
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(github-distro-mixin-password)
EOF
- script: |
set -e
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
displayName: Prepare tooling
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
timeoutInMinutes: 5
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
displayName: Switch to Terrapin packages
- script: |
set -e
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
set -e
yarn --cwd build
yarn --cwd build compile
displayName: Compile build tools
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
timeoutInMinutes: 5
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
displayName: Switch to Terrapin packages
- script: |
set -e
export npm_config_arch=$(NPM_ARCH)
- script: |
set -e
yarn --cwd build
yarn --cwd build compile
displayName: Compile build tools
if [ -z "$CC" ] || [ -z "$CXX" ]; then
# Download clang based on chromium revision used by vscode
curl -s https://raw.githubusercontent.com/chromium/chromium/91.0.4472.164/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux
# Download libcxx headers and objects from upstream electron releases
DEBUG=libcxx-fetcher \
VSCODE_LIBCXX_OBJECTS_DIR=$PWD/.build/libcxx-objects \
VSCODE_LIBCXX_HEADERS_DIR=$PWD/.build/libcxx_headers \
VSCODE_LIBCXXABI_HEADERS_DIR=$PWD/.build/libcxxabi_headers \
VSCODE_ARCH="$(NPM_ARCH)" \
node build/linux/libcxx-fetcher.js
# Set compiler toolchain
export CC=$PWD/.build/CR_Clang/bin/clang
export CXX=$PWD/.build/CR_Clang/bin/clang++
export CXXFLAGS="-nostdinc++ -D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit"
export LDFLAGS="-stdlib=libc++ -fuse-ld=lld -flto=thin -fsplit-lto-unit -L$PWD/.build/libcxx-objects -lc++abi"
fi
- script: |
set -e
export npm_config_arch=$(NPM_ARCH)
if [ "$VSCODE_ARCH" == "x64" ]; then
export VSCODE_REMOTE_CC=$(which gcc-4.8)
export VSCODE_REMOTE_CXX=$(which g++-4.8)
fi
if [ -z "$CC" ] || [ -z "$CXX" ]; then
# Download clang based on chromium revision used by vscode
curl -s https://raw.githubusercontent.com/chromium/chromium/91.0.4472.164/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux
# Download libcxx headers and objects from upstream electron releases
DEBUG=libcxx-fetcher \
VSCODE_LIBCXX_OBJECTS_DIR=$PWD/.build/libcxx-objects \
VSCODE_LIBCXX_HEADERS_DIR=$PWD/.build/libcxx_headers \
VSCODE_LIBCXXABI_HEADERS_DIR=$PWD/.build/libcxxabi_headers \
VSCODE_ARCH="$(NPM_ARCH)" \
node build/linux/libcxx-fetcher.js
# Set compiler toolchain
export CC=$PWD/.build/CR_Clang/bin/clang
export CXX=$PWD/.build/CR_Clang/bin/clang++
export CXXFLAGS="-nostdinc++ -D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit"
export LDFLAGS="-stdlib=libc++ -fuse-ld=lld -flto=thin -fsplit-lto-unit -L$PWD/.build/libcxx-objects -lc++abi"
fi
for i in {1..3}; do # try 3 times, for Terrapin
yarn --frozen-lockfile && break
if [ $i -eq 3 ]; then
echo "Yarn failed too many times" >&2
exit 1
fi
echo "Yarn failed $i, trying again..."
done
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Install dependencies
if [ "$VSCODE_ARCH" == "x64" ]; then
export VSCODE_REMOTE_CC=$(which gcc-4.8)
export VSCODE_REMOTE_CXX=$(which g++-4.8)
fi
- script: |
set -e
yarn gulp vscode-symbols-linux-$(VSCODE_ARCH)
displayName: Build
for i in {1..3}; do # try 3 times, for Terrapin
yarn --frozen-lockfile && break
if [ $i -eq 3 ]; then
echo "Yarn failed too many times" >&2
exit 1
fi
echo "Yarn failed $i, trying again..."
done
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Install dependencies
- task: BinSkim@3
inputs:
toolVersion: Latest
InputType: CommandLine
arguments: analyze $(agent.builddirectory)\scanbin\exe\*.* --recurse --local-symbol-directories $(agent.builddirectory)\scanbin\VSCode-linux-$(VSCODE_ARCH)\pdb
- script: |
set -e
yarn gulp vscode-symbols-linux-$(VSCODE_ARCH)
displayName: Build
- task: BinSkim@3
inputs:
toolVersion: Latest
InputType: CommandLine
arguments: analyze $(agent.builddirectory)\scanbin\exe\*.* --recurse --local-symbol-directories $(agent.builddirectory)\scanbin\VSCode-linux-$(VSCODE_ARCH)\pdb
- task: TSAUpload@2
inputs:
GdnPublishTsaConfigFile: '$(Build.SourceDirectory)\build\azure-pipelines\.gdntsa'
- task: TSAUpload@2
inputs:
GdnPublishTsaConfigFile: '$(Build.SourceDirectory)\build\azure-pipelines\.gdntsa'
+27 -18
View File
@@ -10,26 +10,35 @@ const vfs = require("vinyl-fs");
const util = require("../lib/util");
const filter = require("gulp-filter");
const gzip = require("gulp-gzip");
const identity_1 = require("@azure/identity");
const azure = require('gulp-azure-storage');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const credential = new identity_1.ClientSecretCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_CLIENT_SECRET']);
function main() {
return vfs.src('**', { cwd: '../vscode-web', base: '../vscode-web', dot: true })
.pipe(filter(f => !f.isDirectory()))
.pipe(gzip({ append: false }))
.pipe(es.through(function (data) {
console.log('Uploading CDN file:', data.relative); // debug
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: process.env.VSCODE_QUALITY,
prefix: commit + '/',
contentSettings: {
contentEncoding: 'gzip',
cacheControl: 'max-age=31536000, public'
}
}));
return new Promise((c, e) => {
vfs.src('**', { cwd: '../vscode-web', base: '../vscode-web', dot: true })
.pipe(filter(f => !f.isDirectory()))
.pipe(gzip({ append: false }))
.pipe(es.through(function (data) {
console.log('Uploading CDN file:', data.relative); // debug
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
credential,
container: process.env.VSCODE_QUALITY,
prefix: commit + '/',
contentSettings: {
contentEncoding: 'gzip',
cacheControl: 'max-age=31536000, public'
}
}))
.on('end', () => c())
.on('error', (err) => e(err));
});
}
main();
main().catch(err => {
console.error(err);
process.exit(1);
});
+28 -19
View File
@@ -12,29 +12,38 @@ import * as vfs from 'vinyl-fs';
import * as util from '../lib/util';
import * as filter from 'gulp-filter';
import * as gzip from 'gulp-gzip';
import { ClientSecretCredential } from '@azure/identity';
const azure = require('gulp-azure-storage');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const credential = new ClientSecretCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, process.env['AZURE_CLIENT_SECRET']!);
function main() {
return vfs.src('**', { cwd: '../vscode-web', base: '../vscode-web', dot: true })
.pipe(filter(f => !f.isDirectory()))
.pipe(gzip({ append: false }))
.pipe(es.through(function (data: Vinyl) {
console.log('Uploading CDN file:', data.relative); // debug
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: process.env.VSCODE_QUALITY,
prefix: commit + '/',
contentSettings: {
contentEncoding: 'gzip',
cacheControl: 'max-age=31536000, public'
}
}));
function main(): Promise<void> {
return new Promise((c, e) => {
vfs.src('**', { cwd: '../vscode-web', base: '../vscode-web', dot: true })
.pipe(filter(f => !f.isDirectory()))
.pipe(gzip({ append: false }))
.pipe(es.through(function (data: Vinyl) {
console.log('Uploading CDN file:', data.relative); // debug
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
credential,
container: process.env.VSCODE_QUALITY,
prefix: commit + '/',
contentSettings: {
contentEncoding: 'gzip',
cacheControl: 'max-age=31536000, public'
}
}))
.on('end', () => c())
.on('error', (err: any) => e(err));
});
}
main();
main().catch(err => {
console.error(err);
process.exit(1);
});
@@ -0,0 +1,112 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSettingsSearchBuildId = exports.shouldSetupSettingsSearch = void 0;
const path = require("path");
const os = require("os");
const cp = require("child_process");
const vfs = require("vinyl-fs");
const util = require("../lib/util");
const identity_1 = require("@azure/identity");
const azure = require('gulp-azure-storage');
const packageJson = require("../../package.json");
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
function generateVSCodeConfigurationTask() {
return new Promise((resolve, reject) => {
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
if (!buildDir) {
return reject(new Error('$AGENT_BUILDDIRECTORY not set'));
}
if (!shouldSetupSettingsSearch()) {
console.log(`Only runs on main and release branches, not ${process.env.BUILD_SOURCEBRANCH}`);
return resolve(undefined);
}
if (process.env.VSCODE_QUALITY !== 'insider' && process.env.VSCODE_QUALITY !== 'stable') {
console.log(`Only runs on insider and stable qualities, not ${process.env.VSCODE_QUALITY}`);
return resolve(undefined);
}
const result = path.join(os.tmpdir(), 'configuration.json');
const userDataDir = path.join(os.tmpdir(), 'tmpuserdata');
const extensionsDir = path.join(os.tmpdir(), 'tmpextdir');
const arch = process.env['VSCODE_ARCH'];
const appRoot = path.join(buildDir, `VSCode-darwin-${arch}`);
const appName = process.env.VSCODE_QUALITY === 'insider' ? 'Visual\\ Studio\\ Code\\ -\\ Insiders.app' : 'Visual\\ Studio\\ Code.app';
const appPath = path.join(appRoot, appName, 'Contents', 'Resources', 'app', 'bin', 'code');
const codeProc = cp.exec(`${appPath} --export-default-configuration='${result}' --wait --user-data-dir='${userDataDir}' --extensions-dir='${extensionsDir}'`, (err, stdout, stderr) => {
clearTimeout(timer);
if (err) {
console.log(`err: ${err} ${err.message} ${err.toString()}`);
reject(err);
}
if (stdout) {
console.log(`stdout: ${stdout}`);
}
if (stderr) {
console.log(`stderr: ${stderr}`);
}
resolve(result);
});
const timer = setTimeout(() => {
codeProc.kill();
reject(new Error('export-default-configuration process timed out'));
}, 12 * 1000);
codeProc.on('error', err => {
clearTimeout(timer);
reject(err);
});
});
}
function shouldSetupSettingsSearch() {
const branch = process.env.BUILD_SOURCEBRANCH;
return !!(branch && (/\/main$/.test(branch) || branch.indexOf('/release/') >= 0));
}
exports.shouldSetupSettingsSearch = shouldSetupSettingsSearch;
function getSettingsSearchBuildId(packageJson) {
try {
const branch = process.env.BUILD_SOURCEBRANCH;
const branchId = branch.indexOf('/release/') >= 0 ? 0 :
/\/main$/.test(branch) ? 1 :
2; // Some unexpected branch
const out = cp.execSync(`git rev-list HEAD --count`);
const count = parseInt(out.toString());
// <version number><commit count><branchId (avoid unlikely conflicts)>
// 1.25.1, 1,234,567 commits, main = 1250112345671
return util.versionStringToNumber(packageJson.version) * 1e8 + count * 10 + branchId;
}
catch (e) {
throw new Error('Could not determine build number: ' + e.toString());
}
}
exports.getSettingsSearchBuildId = getSettingsSearchBuildId;
async function main() {
const configPath = await generateVSCodeConfigurationTask();
if (!configPath) {
return;
}
const settingsSearchBuildId = getSettingsSearchBuildId(packageJson);
if (!settingsSearchBuildId) {
throw new Error('Failed to compute build number');
}
const credential = new identity_1.ClientSecretCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_CLIENT_SECRET']);
return new Promise((c, e) => {
vfs.src(configPath)
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
credential,
container: 'configuration',
prefix: `${settingsSearchBuildId}/${commit}/`
}))
.on('end', () => c())
.on('error', (err) => e(err));
});
}
if (require.main === module) {
main().catch(err => {
console.error(err);
process.exit(1);
});
}
@@ -0,0 +1,132 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as path from 'path';
import * as os from 'os';
import * as cp from 'child_process';
import * as vfs from 'vinyl-fs';
import * as util from '../lib/util';
import { ClientSecretCredential } from '@azure/identity';
const azure = require('gulp-azure-storage');
import * as packageJson from '../../package.json';
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
function generateVSCodeConfigurationTask(): Promise<string | undefined> {
return new Promise((resolve, reject) => {
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
if (!buildDir) {
return reject(new Error('$AGENT_BUILDDIRECTORY not set'));
}
if (!shouldSetupSettingsSearch()) {
console.log(`Only runs on main and release branches, not ${process.env.BUILD_SOURCEBRANCH}`);
return resolve(undefined);
}
if (process.env.VSCODE_QUALITY !== 'insider' && process.env.VSCODE_QUALITY !== 'stable') {
console.log(`Only runs on insider and stable qualities, not ${process.env.VSCODE_QUALITY}`);
return resolve(undefined);
}
const result = path.join(os.tmpdir(), 'configuration.json');
const userDataDir = path.join(os.tmpdir(), 'tmpuserdata');
const extensionsDir = path.join(os.tmpdir(), 'tmpextdir');
const arch = process.env['VSCODE_ARCH'];
const appRoot = path.join(buildDir, `VSCode-darwin-${arch}`);
const appName = process.env.VSCODE_QUALITY === 'insider' ? 'Visual\\ Studio\\ Code\\ -\\ Insiders.app' : 'Visual\\ Studio\\ Code.app';
const appPath = path.join(appRoot, appName, 'Contents', 'Resources', 'app', 'bin', 'code');
const codeProc = cp.exec(
`${appPath} --export-default-configuration='${result}' --wait --user-data-dir='${userDataDir}' --extensions-dir='${extensionsDir}'`,
(err, stdout, stderr) => {
clearTimeout(timer);
if (err) {
console.log(`err: ${err} ${err.message} ${err.toString()}`);
reject(err);
}
if (stdout) {
console.log(`stdout: ${stdout}`);
}
if (stderr) {
console.log(`stderr: ${stderr}`);
}
resolve(result);
}
);
const timer = setTimeout(() => {
codeProc.kill();
reject(new Error('export-default-configuration process timed out'));
}, 12 * 1000);
codeProc.on('error', err => {
clearTimeout(timer);
reject(err);
});
});
}
export function shouldSetupSettingsSearch(): boolean {
const branch = process.env.BUILD_SOURCEBRANCH;
return !!(branch && (/\/main$/.test(branch) || branch.indexOf('/release/') >= 0));
}
export function getSettingsSearchBuildId(packageJson: { version: string }) {
try {
const branch = process.env.BUILD_SOURCEBRANCH!;
const branchId = branch.indexOf('/release/') >= 0 ? 0 :
/\/main$/.test(branch) ? 1 :
2; // Some unexpected branch
const out = cp.execSync(`git rev-list HEAD --count`);
const count = parseInt(out.toString());
// <version number><commit count><branchId (avoid unlikely conflicts)>
// 1.25.1, 1,234,567 commits, main = 1250112345671
return util.versionStringToNumber(packageJson.version) * 1e8 + count * 10 + branchId;
} catch (e) {
throw new Error('Could not determine build number: ' + e.toString());
}
}
async function main(): Promise<void> {
const configPath = await generateVSCodeConfigurationTask();
if (!configPath) {
return;
}
const settingsSearchBuildId = getSettingsSearchBuildId(packageJson);
if (!settingsSearchBuildId) {
throw new Error('Failed to compute build number');
}
const credential = new ClientSecretCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, process.env['AZURE_CLIENT_SECRET']!);
return new Promise((c, e) => {
vfs.src(configPath)
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
credential,
container: 'configuration',
prefix: `${settingsSearchBuildId}/${commit}/`
}))
.on('end', () => c())
.on('error', (err: any) => e(err));
});
}
if (require.main === module) {
main().catch(err => {
console.error(err);
process.exit(1);
});
}
+78 -69
View File
@@ -10,79 +10,88 @@ const vfs = require("vinyl-fs");
const util = require("../lib/util");
const merge = require("gulp-merge-json");
const gzip = require("gulp-gzip");
const identity_1 = require("@azure/identity");
const azure = require('gulp-azure-storage');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const credential = new identity_1.ClientSecretCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_CLIENT_SECRET']);
function main() {
return es.merge(vfs.src('out-vscode-web-min/nls.metadata.json', { base: 'out-vscode-web-min' }), vfs.src('.build/extensions/**/nls.metadata.json', { base: '.build/extensions' }), vfs.src('.build/extensions/**/nls.metadata.header.json', { base: '.build/extensions' }), vfs.src('.build/extensions/**/package.nls.json', { base: '.build/extensions' }))
.pipe(merge({
fileName: 'combined.nls.metadata.json',
jsonSpace: '',
edit: (parsedJson, file) => {
let key;
if (file.base === 'out-vscode-web-min') {
return { vscode: parsedJson };
}
// Handle extensions and follow the same structure as the Core nls file.
switch (file.basename) {
case 'package.nls.json':
// put package.nls.json content in Core NlsMetadata format
// language packs use the key "package" to specify that
// translations are for the package.json file
parsedJson = {
messages: {
package: Object.values(parsedJson)
},
keys: {
package: Object.keys(parsedJson)
},
bundles: {
main: ['package']
return new Promise((c, e) => {
es.merge(vfs.src('out-vscode-web-min/nls.metadata.json', { base: 'out-vscode-web-min' }), vfs.src('.build/extensions/**/nls.metadata.json', { base: '.build/extensions' }), vfs.src('.build/extensions/**/nls.metadata.header.json', { base: '.build/extensions' }), vfs.src('.build/extensions/**/package.nls.json', { base: '.build/extensions' }))
.pipe(merge({
fileName: 'combined.nls.metadata.json',
jsonSpace: '',
edit: (parsedJson, file) => {
let key;
if (file.base === 'out-vscode-web-min') {
return { vscode: parsedJson };
}
// Handle extensions and follow the same structure as the Core nls file.
switch (file.basename) {
case 'package.nls.json':
// put package.nls.json content in Core NlsMetadata format
// language packs use the key "package" to specify that
// translations are for the package.json file
parsedJson = {
messages: {
package: Object.values(parsedJson)
},
keys: {
package: Object.keys(parsedJson)
},
bundles: {
main: ['package']
}
};
break;
case 'nls.metadata.header.json':
parsedJson = { header: parsedJson };
break;
case 'nls.metadata.json':
// put nls.metadata.json content in Core NlsMetadata format
const modules = Object.keys(parsedJson);
const json = {
keys: {},
messages: {},
bundles: {
main: []
}
};
for (const module of modules) {
json.messages[module] = parsedJson[module].messages;
json.keys[module] = parsedJson[module].keys;
json.bundles.main.push(module);
}
};
break;
case 'nls.metadata.header.json':
parsedJson = { header: parsedJson };
break;
case 'nls.metadata.json':
// put nls.metadata.json content in Core NlsMetadata format
const modules = Object.keys(parsedJson);
const json = {
keys: {},
messages: {},
bundles: {
main: []
}
};
for (const module of modules) {
json.messages[module] = parsedJson[module].messages;
json.keys[module] = parsedJson[module].keys;
json.bundles.main.push(module);
}
parsedJson = json;
break;
parsedJson = json;
break;
}
key = 'vscode.' + file.relative.split('/')[0];
return { [key]: parsedJson };
},
}))
.pipe(gzip({ append: false }))
.pipe(vfs.dest('./nlsMetadata'))
.pipe(es.through(function (data) {
console.log(`Uploading ${data.path}`);
// trigger artifact upload
console.log(`##vso[artifact.upload containerfolder=nlsmetadata;artifactname=combined.nls.metadata.json]${data.path}`);
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
credential,
container: 'nlsmetadata',
prefix: commit + '/',
contentSettings: {
contentEncoding: 'gzip',
cacheControl: 'max-age=31536000, public'
}
key = 'vscode.' + file.relative.split('/')[0];
return { [key]: parsedJson };
},
}))
.pipe(gzip({ append: false }))
.pipe(vfs.dest('./nlsMetadata'))
.pipe(es.through(function (data) {
console.log(`Uploading ${data.path}`);
// trigger artifact upload
console.log(`##vso[artifact.upload containerfolder=nlsmetadata;artifactname=combined.nls.metadata.json]${data.path}`);
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'nlsmetadata',
prefix: commit + '/',
contentSettings: {
contentEncoding: 'gzip',
cacheControl: 'max-age=31536000, public'
}
}));
}))
.on('end', () => c())
.on('error', (err) => e(err));
});
}
main();
main().catch(err => {
console.error(err);
process.exit(1);
});
+88 -77
View File
@@ -12,10 +12,12 @@ import * as vfs from 'vinyl-fs';
import * as util from '../lib/util';
import * as merge from 'gulp-merge-json';
import * as gzip from 'gulp-gzip';
import { ClientSecretCredential } from '@azure/identity';
const azure = require('gulp-azure-storage');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const credential = new ClientSecretCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, process.env['AZURE_CLIENT_SECRET']!);
interface NlsMetadata {
keys: { [module: string]: string },
@@ -23,85 +25,94 @@ interface NlsMetadata {
bundles: { [bundle: string]: string[] },
}
function main() {
return es.merge(
vfs.src('out-vscode-web-min/nls.metadata.json', { base: 'out-vscode-web-min' }),
vfs.src('.build/extensions/**/nls.metadata.json', { base: '.build/extensions' }),
vfs.src('.build/extensions/**/nls.metadata.header.json', { base: '.build/extensions' }),
vfs.src('.build/extensions/**/package.nls.json', { base: '.build/extensions' }))
.pipe(merge({
fileName: 'combined.nls.metadata.json',
jsonSpace: '',
edit: (parsedJson, file) => {
let key;
if (file.base === 'out-vscode-web-min') {
return { vscode: parsedJson };
}
function main(): Promise<void> {
return new Promise((c, e) => {
// Handle extensions and follow the same structure as the Core nls file.
switch (file.basename) {
case 'package.nls.json':
// put package.nls.json content in Core NlsMetadata format
// language packs use the key "package" to specify that
// translations are for the package.json file
parsedJson = {
messages: {
package: Object.values(parsedJson)
},
keys: {
package: Object.keys(parsedJson)
},
bundles: {
main: ['package']
es.merge(
vfs.src('out-vscode-web-min/nls.metadata.json', { base: 'out-vscode-web-min' }),
vfs.src('.build/extensions/**/nls.metadata.json', { base: '.build/extensions' }),
vfs.src('.build/extensions/**/nls.metadata.header.json', { base: '.build/extensions' }),
vfs.src('.build/extensions/**/package.nls.json', { base: '.build/extensions' }))
.pipe(merge({
fileName: 'combined.nls.metadata.json',
jsonSpace: '',
edit: (parsedJson, file) => {
let key;
if (file.base === 'out-vscode-web-min') {
return { vscode: parsedJson };
}
// Handle extensions and follow the same structure as the Core nls file.
switch (file.basename) {
case 'package.nls.json':
// put package.nls.json content in Core NlsMetadata format
// language packs use the key "package" to specify that
// translations are for the package.json file
parsedJson = {
messages: {
package: Object.values(parsedJson)
},
keys: {
package: Object.keys(parsedJson)
},
bundles: {
main: ['package']
}
};
break;
case 'nls.metadata.header.json':
parsedJson = { header: parsedJson };
break;
case 'nls.metadata.json':
// put nls.metadata.json content in Core NlsMetadata format
const modules = Object.keys(parsedJson);
const json: NlsMetadata = {
keys: {},
messages: {},
bundles: {
main: []
}
};
for (const module of modules) {
json.messages[module] = parsedJson[module].messages;
json.keys[module] = parsedJson[module].keys;
json.bundles.main.push(module);
}
};
break;
case 'nls.metadata.header.json':
parsedJson = { header: parsedJson };
break;
case 'nls.metadata.json':
// put nls.metadata.json content in Core NlsMetadata format
const modules = Object.keys(parsedJson);
const json: NlsMetadata = {
keys: {},
messages: {},
bundles: {
main: []
}
};
for (const module of modules) {
json.messages[module] = parsedJson[module].messages;
json.keys[module] = parsedJson[module].keys;
json.bundles.main.push(module);
}
parsedJson = json;
break;
parsedJson = json;
break;
}
key = 'vscode.' + file.relative.split('/')[0];
return { [key]: parsedJson };
},
}))
.pipe(gzip({ append: false }))
.pipe(vfs.dest('./nlsMetadata'))
.pipe(es.through(function (data: Vinyl) {
console.log(`Uploading ${data.path}`);
// trigger artifact upload
console.log(`##vso[artifact.upload containerfolder=nlsmetadata;artifactname=combined.nls.metadata.json]${data.path}`);
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
credential,
container: 'nlsmetadata',
prefix: commit + '/',
contentSettings: {
contentEncoding: 'gzip',
cacheControl: 'max-age=31536000, public'
}
key = 'vscode.' + file.relative.split('/')[0];
return { [key]: parsedJson };
},
}))
.pipe(gzip({ append: false }))
.pipe(vfs.dest('./nlsMetadata'))
.pipe(es.through(function (data: Vinyl) {
console.log(`Uploading ${data.path}`);
// trigger artifact upload
console.log(`##vso[artifact.upload containerfolder=nlsmetadata;artifactname=combined.nls.metadata.json]${data.path}`);
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'nlsmetadata',
prefix: commit + '/',
contentSettings: {
contentEncoding: 'gzip',
cacheControl: 'max-age=31536000, public'
}
}));
}))
.on('end', () => c())
.on('error', (err: any) => e(err));
});
}
main();
main().catch(err => {
console.error(err);
process.exit(1);
});
+21 -12
View File
@@ -10,9 +10,11 @@ const vfs = require("vinyl-fs");
const util = require("../lib/util");
// @ts-ignore
const deps = require("../lib/dependencies");
const identity_1 = require("@azure/identity");
const azure = require('gulp-azure-storage');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const credential = new identity_1.ClientSecretCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_CLIENT_SECRET']);
// optionally allow to pass in explicit base/maps to upload
const [, , base, maps] = process.argv;
function src(base, maps = `${base}/**/*.map`) {
@@ -40,16 +42,23 @@ function main() {
else {
sources.push(src(base, maps));
}
return es.merge(...sources)
.pipe(es.through(function (data) {
console.log('Uploading Sourcemap', data.relative); // debug
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'sourcemaps',
prefix: commit + '/'
}));
return new Promise((c, e) => {
es.merge(...sources)
.pipe(es.through(function (data) {
console.log('Uploading Sourcemap', data.relative); // debug
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
credential,
container: 'sourcemaps',
prefix: commit + '/'
}))
.on('end', () => c())
.on('error', (err) => e(err));
});
}
main();
main().catch(err => {
console.error(err);
process.exit(1);
});
+24 -14
View File
@@ -12,10 +12,12 @@ import * as vfs from 'vinyl-fs';
import * as util from '../lib/util';
// @ts-ignore
import * as deps from '../lib/dependencies';
import { ClientSecretCredential } from '@azure/identity';
const azure = require('gulp-azure-storage');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const credential = new ClientSecretCredential(process.env['AZURE_TENANT_ID']!, process.env['AZURE_CLIENT_ID']!, process.env['AZURE_CLIENT_SECRET']!);
// optionally allow to pass in explicit base/maps to upload
const [, , base, maps] = process.argv;
@@ -28,8 +30,8 @@ function src(base: string, maps = `${base}/**/*.map`) {
}));
}
function main() {
const sources = [];
function main(): Promise<void> {
const sources: any[] = [];
// vscode client maps (default)
if (!base) {
@@ -51,17 +53,25 @@ function main() {
sources.push(src(base, maps));
}
return es.merge(...sources)
.pipe(es.through(function (data: Vinyl) {
console.log('Uploading Sourcemap', data.relative); // debug
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'sourcemaps',
prefix: commit + '/'
}));
return new Promise((c, e) => {
es.merge(...sources)
.pipe(es.through(function (data: Vinyl) {
console.log('Uploading Sourcemap', data.relative); // debug
this.emit('data', data);
}))
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
credential,
container: 'sourcemaps',
prefix: commit + '/'
}))
.on('end', () => c())
.on('error', (err: any) => e(err));
});
}
main();
main().catch(err => {
console.error(err);
process.exit(1);
});
+47 -32
View File
@@ -3,16 +3,12 @@ steps:
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: 'github-distro-mixin-password,web-storage-account,web-storage-key,ticino-storage-key'
SecretsFilter: "github-distro-mixin-password"
- task: DownloadPipelineArtifact@2
inputs:
@@ -42,23 +38,23 @@ steps:
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
mkdir -p .build
node build/azure-pipelines/common/computeNodeModulesCacheKey.js "web" $ENABLE_TERRAPIN > .build/yarnlockhash
displayName: Prepare yarn cache flags
# - script: |
# mkdir -p .build
# node build/azure-pipelines/common/computeNodeModulesCacheKey.js "web" $ENABLE_TERRAPIN > .build/yarnlockhash
# displayName: Prepare yarn cache flags
- task: Cache@2
inputs:
key: 'nodeModules | $(Agent.OS) | .build/yarnlockhash'
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache
# - task: Cache@2
# inputs:
# key: "nodeModules | $(Agent.OS) | .build/yarnlockhash"
# path: .build/node_modules_cache
# cacheHitVar: NODE_MODULES_RESTORED
# displayName: Restore node_modules cache
- script: |
set -e
tar -xzf .build/node_modules_cache/cache.tgz
condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Extract node_modules cache
# - script: |
# set -e
# tar -xzf .build/node_modules_cache/cache.tgz
# condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Extract node_modules cache
- script: |
set -e
@@ -84,13 +80,13 @@ steps:
displayName: Install dependencies
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
- script: |
set -e
node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
mkdir -p .build/node_modules_cache
tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Create node_modules archive
# - script: |
# set -e
# node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt
# mkdir -p .build/node_modules_cache
# tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
# condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Create node_modules archive
- script: |
set -e
@@ -103,11 +99,24 @@ steps:
yarn gulp vscode-web-min-ci
displayName: Build
- task: AzureCLI@2
inputs:
azureSubscription: "vscode-builds-subscription"
scriptType: pscore
scriptLocation: inlineScript
addSpnToEnvironment: true
inlineScript: |
Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey"
- script: |
set -e
AZURE_STORAGE_ACCOUNT="$(web-storage-account)" \
AZURE_STORAGE_ACCESS_KEY="$(web-storage-key)" \
node build/azure-pipelines/upload-cdn.js
AZURE_STORAGE_ACCOUNT="vscodeweb" \
AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \
AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \
AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \
node build/azure-pipelines/upload-cdn
displayName: Upload to CDN
# upload only the workbench.web.api.js source maps because
@@ -115,13 +124,19 @@ steps:
# general task to upload source maps has already been run
- script: |
set -e
AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \
AZURE_STORAGE_ACCOUNT="ticino" \
AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \
AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \
AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \
node build/azure-pipelines/upload-sourcemaps out-vscode-web-min out-vscode-web-min/vs/workbench/workbench.web.api.js.map
displayName: Upload sourcemaps (Web)
- script: |
set -e
AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \
AZURE_STORAGE_ACCOUNT="ticino" \
AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \
AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \
AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \
node build/azure-pipelines/upload-nlsmetadata
displayName: Upload NLS Metadata
condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false'))
@@ -3,10 +3,6 @@ steps:
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: UsePythonVersion@0
inputs:
versionSpec: "2.x"
@@ -17,7 +13,7 @@ steps:
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,vscode-storage-key,builds-docdb-key-readwrite,ESRP-PKI,esrp-aad-username,esrp-aad-password"
SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password"
- task: DownloadPipelineArtifact@2
inputs:
@@ -46,25 +42,25 @@ steps:
exec { git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") }
displayName: Merge distro
- powershell: |
"$(VSCODE_ARCH)" | Out-File -Encoding ascii -NoNewLine .build\arch
"$env:ENABLE_TERRAPIN" | Out-File -Encoding ascii -NoNewLine .build\terrapin
node build/azure-pipelines/common/computeNodeModulesCacheKey.js > .build/yarnlockhash
displayName: Prepare yarn cache flags
# - powershell: |
# "$(VSCODE_ARCH)" | Out-File -Encoding ascii -NoNewLine .build\arch
# "$env:ENABLE_TERRAPIN" | Out-File -Encoding ascii -NoNewLine .build\terrapin
# node build/azure-pipelines/common/computeNodeModulesCacheKey.js > .build/yarnlockhash
# displayName: Prepare yarn cache flags
- task: Cache@2
inputs:
key: "nodeModules | $(Agent.OS) | .build/arch, .build/terrapin, .build/yarnlockhash"
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache
# - task: Cache@2
# inputs:
# key: "nodeModules | $(Agent.OS) | .build/arch, .build/terrapin, .build/yarnlockhash"
# path: .build/node_modules_cache
# cacheHitVar: NODE_MODULES_RESTORED
# displayName: Restore node_modules cache
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { 7z.exe x .build/node_modules_cache/cache.7z -aos }
condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Extract node_modules cache
# - powershell: |
# . build/azure-pipelines/win32/exec.ps1
# $ErrorActionPreference = "Stop"
# exec { 7z.exe x .build/node_modules_cache/cache.7z -aos }
# condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Extract node_modules cache
- powershell: |
. build/azure-pipelines/win32/exec.ps1
@@ -88,14 +84,14 @@ steps:
displayName: Install dependencies
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt }
exec { mkdir -Force .build/node_modules_cache }
exec { 7z.exe a .build/node_modules_cache/cache.7z -mx3 `@.build/node_modules_list.txt }
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
displayName: Create node_modules archive
# - powershell: |
# . build/azure-pipelines/win32/exec.ps1
# $ErrorActionPreference = "Stop"
# exec { node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt }
# exec { mkdir -Force .build/node_modules_cache }
# exec { 7z.exe a .build/node_modules_cache/cache.7z -mx3 `@.build/node_modules_list.txt }
# condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
# displayName: Create node_modules archive
- powershell: |
. build/azure-pipelines/win32/exec.ps1
@@ -208,7 +204,7 @@ steps:
$AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)"
exec { yarn smoketest-no-compile --build "$AppRoot" --screenshots $(Build.SourcesDirectory)\.build\logs\smoke-tests }
displayName: Run smoke tests (Electron)
timeoutInMinutes: 5
timeoutInMinutes: 10
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64'))
- powershell: |
@@ -218,7 +214,7 @@ steps:
$env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"
exec { yarn smoketest-no-compile --build "$AppRoot" --remote --screenshots $(Build.SourcesDirectory)\.build\logs\smoke-tests-remote }
displayName: Run smoke tests (Remote)
timeoutInMinutes: 5
timeoutInMinutes: 10
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64'))
- powershell: |
@@ -227,7 +223,7 @@ steps:
$env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-web-win32-$(VSCODE_ARCH)"
exec { yarn smoketest-no-compile --web --browser firefox --headless }
displayName: Run smoke tests (Browser)
timeoutInMinutes: 5
timeoutInMinutes: 10
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64'))
- task: PublishPipelineArtifact@0
@@ -310,9 +306,6 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$env:AZURE_STORAGE_ACCESS_KEY_2 = "$(vscode-storage-key)"
$env:AZURE_DOCUMENTDB_MASTERKEY = "$(builds-docdb-key-readwrite)"
$env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)"
.\build\azure-pipelines\win32\prepare-publish.ps1
displayName: Publish
condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false'))
+1 -107
View File
@@ -32,6 +32,7 @@ const createAsar = require('./lib/asar').createAsar;
const minimist = require('minimist');
const { compileBuildTask } = require('./gulpfile.compile');
const { compileExtensionsBuildTask } = require('./gulpfile.extensions');
const { getSettingsSearchBuildId, shouldSetupSettingsSearch } = require('./azure-pipelines/upload-configuration');
// Build
const vscodeEntryPoints = _.flatten([
@@ -475,110 +476,3 @@ gulp.task('vscode-translations-import', function () {
.pipe(vfs.dest(`./build/win32/i18n`));
}));
});
// This task is only run for the MacOS build
const generateVSCodeConfigurationTask = task.define('generate-vscode-configuration', () => {
return new Promise((resolve, reject) => {
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
if (!buildDir) {
return reject(new Error('$AGENT_BUILDDIRECTORY not set'));
}
if (process.env.VSCODE_QUALITY !== 'insider' && process.env.VSCODE_QUALITY !== 'stable') {
return resolve();
}
const userDataDir = path.join(os.tmpdir(), 'tmpuserdata');
const extensionsDir = path.join(os.tmpdir(), 'tmpextdir');
const arch = process.env['VSCODE_ARCH'];
const appRoot = path.join(buildDir, `VSCode-darwin-${arch}`);
const appName = process.env.VSCODE_QUALITY === 'insider' ? 'Visual\\ Studio\\ Code\\ -\\ Insiders.app' : 'Visual\\ Studio\\ Code.app';
const appPath = path.join(appRoot, appName, 'Contents', 'Resources', 'app', 'bin', 'code');
const codeProc = cp.exec(
`${appPath} --export-default-configuration='${allConfigDetailsPath}' --wait --user-data-dir='${userDataDir}' --extensions-dir='${extensionsDir}'`,
(err, stdout, stderr) => {
clearTimeout(timer);
if (err) {
console.log(`err: ${err} ${err.message} ${err.toString()}`);
reject(err);
}
if (stdout) {
console.log(`stdout: ${stdout}`);
}
if (stderr) {
console.log(`stderr: ${stderr}`);
}
resolve();
}
);
const timer = setTimeout(() => {
codeProc.kill();
reject(new Error('export-default-configuration process timed out'));
}, 12 * 1000);
codeProc.on('error', err => {
clearTimeout(timer);
reject(err);
});
});
});
const allConfigDetailsPath = path.join(os.tmpdir(), 'configuration.json');
gulp.task(task.define(
'upload-vscode-configuration',
task.series(
generateVSCodeConfigurationTask,
() => {
const azure = require('gulp-azure-storage');
if (!shouldSetupSettingsSearch()) {
const branch = process.env.BUILD_SOURCEBRANCH;
console.log(`Only runs on main and release branches, not ${branch}`);
return;
}
if (!fs.existsSync(allConfigDetailsPath)) {
throw new Error(`configuration file at ${allConfigDetailsPath} does not exist`);
}
const settingsSearchBuildId = getSettingsSearchBuildId(packageJson);
if (!settingsSearchBuildId) {
throw new Error('Failed to compute build number');
}
return gulp.src(allConfigDetailsPath)
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'configuration',
prefix: `${settingsSearchBuildId}/${commit}/`
}));
}
)
));
function shouldSetupSettingsSearch() {
const branch = process.env.BUILD_SOURCEBRANCH;
return branch && (/\/main$/.test(branch) || branch.indexOf('/release/') >= 0);
}
function getSettingsSearchBuildId(packageJson) {
try {
const branch = process.env.BUILD_SOURCEBRANCH;
const branchId = branch.indexOf('/release/') >= 0 ? 0 :
/\/main$/.test(branch) ? 1 :
2; // Some unexpected branch
const out = cp.execSync(`git rev-list HEAD --count`);
const count = parseInt(out.toString());
// <version number><commit count><branchId (avoid unlikely conflicts)>
// 1.25.1, 1,234,567 commits, main = 1250112345671
return util.versionStringToNumber(packageJson.version) * 1e8 + count * 10 + branchId;
} catch (e) {
throw new Error('Could not determine build number: ' + e.toString());
}
}
+1 -1
View File
@@ -183,7 +183,7 @@ function apiProposalNamesGenerator() {
try {
const t1 = Date.now();
const proposalNames = [];
for (let file of fs.readdirSync(dtsFolder)) {
for (let file of fs.readdirSync(dtsFolder).sort()) {
const match = pattern.exec(file);
if (match) {
proposalNames.push([match[1], `https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/${file}`]);
+1 -1
View File
@@ -224,7 +224,7 @@ function apiProposalNamesGenerator() {
const t1 = Date.now();
const proposalNames: [name: string, url: string][] = [];
for (let file of fs.readdirSync(dtsFolder)) {
for (let file of fs.readdirSync(dtsFolder).sort()) {
const match = pattern.exec(file);
if (match) {
proposalNames.push([match[1], `https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/${file}`]);
+6 -6
View File
@@ -3,14 +3,15 @@
"version": "1.0.0",
"license": "MIT",
"devDependencies": {
"@azure/cosmos": "^3.9.3",
"@azure/storage-blob": "^12.4.0",
"@azure/cosmos": "^3.14.1",
"@azure/identity": "^2.0.1",
"@azure/storage-blob": "^12.8.0",
"@electron/get": "^1.12.4",
"@types/ansi-colors": "^3.2.0",
"@types/azure": "0.9.19",
"@types/byline": "^4.2.32",
"@types/cssnano": "^4.0.0",
"@types/debounce": "^1.0.0",
"@types/debug": "4.1.5",
"@types/eslint": "4.16.1",
"@types/fancy-log": "^1.3.0",
"@types/fs-extra": "^9.0.12",
@@ -43,7 +44,6 @@
"@typescript-eslint/experimental-utils": "~2.13.0",
"@typescript-eslint/parser": "^3.3.0",
"applicationinsights": "1.0.8",
"azure-storage": "^2.1.0",
"byline": "^5.0.0",
"colors": "^1.4.0",
"commander": "^7.0.0",
@@ -54,7 +54,7 @@
"fs-extra": "^9.1.0",
"got": "11.8.1",
"gulp-merge-json": "^2.1.1",
"iconv-lite-umd": "0.6.8",
"iconv-lite-umd": "0.6.10",
"jsonc-parser": "^2.3.0",
"mime": "^1.4.1",
"mkdirp": "^1.0.4",
@@ -62,7 +62,7 @@
"plist": "^3.0.1",
"source-map": "0.6.1",
"tmp": "^0.2.1",
"typescript": "^4.6.0-dev.20211108",
"typescript": "^4.6.0-dev.20211115",
"vsce": "^1.100.0",
"vscode-universal-bundler": "^0.0.2"
},
+348 -454
View File
File diff suppressed because it is too large Load Diff
@@ -24,7 +24,7 @@
},
{
"type": "string",
"pattern": "^([a-z0-9\\-]+):(\\d{1,5})$"
"pattern": "^([a-z0-9-]+):(\\d{1,5})$"
}
]
}
@@ -32,7 +32,7 @@
"portsAttributes": {
"type": "object",
"patternProperties": {
"(^\\d+(\\-\\d+)?$)|(.+)": {
"(^\\d+(-\\d+)?$)|(.+)": {
"type": "object",
"description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.",
"properties": {
@@ -179,7 +179,7 @@
"description": "An array of extensions that should be installed into the container.",
"items": {
"type": "string",
"pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'."
}
},
@@ -116,7 +116,7 @@
"description": "An array of extensions that should be installed into the container.",
"items": {
"type": "string",
"pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'."
}
},
@@ -141,7 +141,7 @@
},
{
"type": "string",
"pattern": "^([a-z0-9\\-]+):(\\d{1,5})$"
"pattern": "^([a-z0-9-]+):(\\d{1,5})$"
}
]
}
@@ -149,7 +149,7 @@
"portsAttributes": {
"type": "object",
"patternProperties": {
"(^\\d+(\\-\\d+)?$)|(.+)": {
"(^\\d+(-\\d+)?$)|(.+)": {
"type": "object",
"description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.",
"properties": {
@@ -519,7 +519,7 @@
"description": "An array of extensions that should be installed into the container.",
"items": {
"type": "string",
"pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'."
}
},
@@ -544,7 +544,7 @@
},
{
"type": "string",
"pattern": "^([a-z0-9\\-]+):(\\d{1,5})$"
"pattern": "^([a-z0-9-]+):(\\d{1,5})$"
}
]
}
@@ -552,7 +552,7 @@
"portsAttributes": {
"type": "object",
"patternProperties": {
"(^\\d+(\\-\\d+)?$)|(.+)": {
"(^\\d+(-\\d+)?$)|(.+)": {
"type": "object",
"description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.",
"properties": {
@@ -888,7 +888,7 @@
"description": "An array of extensions that should be installed into the container.",
"items": {
"type": "string",
"pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'."
}
},
@@ -913,7 +913,7 @@
},
{
"type": "string",
"pattern": "^([a-z0-9\\-]+):(\\d{1,5})$"
"pattern": "^([a-z0-9-]+):(\\d{1,5})$"
}
]
}
@@ -921,7 +921,7 @@
"portsAttributes": {
"type": "object",
"patternProperties": {
"(^\\d+(\\-\\d+)?$)|(.+)": {
"(^\\d+(-\\d+)?$)|(.+)": {
"type": "object",
"description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.",
"properties": {
@@ -1231,7 +1231,7 @@
"description": "An array of extensions that should be installed into the container.",
"items": {
"type": "string",
"pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'."
}
},
@@ -1256,7 +1256,7 @@
},
{
"type": "string",
"pattern": "^([a-z0-9\\-]+):(\\d{1,5})$"
"pattern": "^([a-z0-9-]+):(\\d{1,5})$"
}
]
}
@@ -1264,7 +1264,7 @@
"portsAttributes": {
"type": "object",
"patternProperties": {
"(^\\d+(\\-\\d+)?$)|(.+)": {
"(^\\d+(-\\d+)?$)|(.+)": {
"type": "object",
"description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.",
"properties": {
@@ -1539,7 +1539,7 @@
"description": "An array of extensions that should be installed into the container.",
"items": {
"type": "string",
"pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'."
}
},
@@ -1564,7 +1564,7 @@
},
{
"type": "string",
"pattern": "^([a-z0-9\\-]+):(\\d{1,5})$"
"pattern": "^([a-z0-9-]+):(\\d{1,5})$"
}
]
}
@@ -1572,7 +1572,7 @@
"portsAttributes": {
"type": "object",
"patternProperties": {
"(^\\d+(\\-\\d+)?$)|(.+)": {
"(^\\d+(-\\d+)?$)|(.+)": {
"type": "object",
"description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.",
"properties": {
@@ -16,7 +16,7 @@
"description": "An array of extensions that should be installed into the container.",
"items": {
"type": "string",
"pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$",
"errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'."
}
},
@@ -41,7 +41,7 @@
},
{
"type": "string",
"pattern": "^([a-z0-9\\-]+):(\\d{1,5})$"
"pattern": "^([a-z0-9-]+):(\\d{1,5})$"
}
]
}
@@ -49,7 +49,7 @@
"portsAttributes": {
"type": "object",
"patternProperties": {
"(^\\d+(\\-\\d+)?$)|(.+)": {
"(^\\d+(-\\d+)?$)|(.+)": {
"type": "object",
"description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.",
"properties": {
@@ -9,6 +9,7 @@ import * as nls from 'vscode-nls';
import { provideInstalledExtensionProposals } from './extensionsProposals';
const localize = nls.loadMessageBundle();
const OVERRIDE_IDENTIFIER_REGEX = /\[([^\[\]]*)\]/g;
export class SettingsDocument {
@@ -186,61 +187,60 @@ export class SettingsDocument {
.then(languages => languages.map(l => this.newSimpleCompletionItem(formatFunc(l), range)));
}
private provideLanguageCompletionItemsForLanguageOverrides(_location: Location, range: vscode.Range, formatFunc: (string: string) => string = (l) => JSON.stringify(l)): Thenable<vscode.CompletionItem[]> {
return vscode.languages.getLanguages().then(languages => {
const completionItems = [];
const configuration = vscode.workspace.getConfiguration();
for (const language of languages) {
const inspect = configuration.inspect(`[${language}]`);
if (!inspect || !inspect.defaultValue) {
const item = new vscode.CompletionItem(formatFunc(language));
item.kind = vscode.CompletionItemKind.Property;
item.range = range;
completionItems.push(item);
}
}
return completionItems;
});
private async provideLanguageCompletionItemsForLanguageOverrides(_location: Location, range: vscode.Range): Promise<vscode.CompletionItem[]> {
const languages = await vscode.languages.getLanguages();
const completionItems = [];
for (const language of languages) {
const item = new vscode.CompletionItem(JSON.stringify(language));
item.kind = vscode.CompletionItemKind.Property;
item.range = range;
completionItems.push(item);
}
return completionItems;
}
private provideLanguageOverridesCompletionItems(location: Location, position: vscode.Position): vscode.ProviderResult<vscode.CompletionItem[]> {
if (location.path.length === 0) {
let range = this.document.getWordRangeAtPosition(position, /^\s*\[.*]?/) || new vscode.Range(position, position);
let text = this.document.getText(range);
if (text && text.trim().startsWith('[')) {
range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + text.indexOf('[')), range.end);
return this.provideLanguageCompletionItemsForLanguageOverrides(location, range, language => `"[${language}]"`);
}
range = this.document.getWordRangeAtPosition(position) || new vscode.Range(position, position);
text = this.document.getText(range);
let snippet = '"[${1:language}]": {\n\t"$0"\n}';
// Suggestion model word matching includes quotes,
// hence exclude the starting quote from the snippet and the range
// ending quote gets replaced
if (text && text.startsWith('"')) {
range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + 1), range.end);
snippet = snippet.substring(1);
}
return Promise.resolve([this.newSnippetCompletionItem({
label: localize('languageSpecificEditorSettings', "Language specific editor settings"),
documentation: localize('languageSpecificEditorSettingsDescription', "Override editor settings for language"),
snippet,
range
})]);
}
private async provideLanguageOverridesCompletionItems(location: Location, position: vscode.Position): Promise<vscode.CompletionItem[]> {
if (location.path.length === 1 && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) {
// Suggestion model word matching includes closed sqaure bracket and ending quote
// Hence include them in the proposal to replace
const range = this.document.getWordRangeAtPosition(position) || new vscode.Range(position, position);
return this.provideLanguageCompletionItemsForLanguageOverrides(location, range, language => `"[${language}]"`);
const startPosition = this.document.positionAt(location.previousNode.offset + 1);
const endPosition = startPosition.translate(undefined, location.previousNode.value.length);
const donotSuggestLanguages: string[] = [];
const languageOverridesRanges: vscode.Range[] = [];
let matches = OVERRIDE_IDENTIFIER_REGEX.exec(location.previousNode.value);
let lastLanguageOverrideRange: vscode.Range | undefined;
while (matches?.length) {
lastLanguageOverrideRange = new vscode.Range(this.document.positionAt(location.previousNode.offset + 1 + matches.index), this.document.positionAt(location.previousNode.offset + 1 + matches.index + matches[0].length));
languageOverridesRanges.push(lastLanguageOverrideRange);
/* Suggest the configured language if the position is in the match range */
if (!lastLanguageOverrideRange.contains(position)) {
donotSuggestLanguages.push(matches[1].trim());
}
matches = OVERRIDE_IDENTIFIER_REGEX.exec(location.previousNode.value);
}
const lastLanguageOverrideEndPosition = lastLanguageOverrideRange ? lastLanguageOverrideRange.end : startPosition;
if (lastLanguageOverrideEndPosition.isBefore(endPosition)) {
languageOverridesRanges.push(new vscode.Range(lastLanguageOverrideEndPosition, endPosition));
}
const languageOverrideRange = languageOverridesRanges.find(range => range.contains(position));
/**
* Skip if suggestsions are for first language override range
* Since VSCode registers language overrides to the schema, JSON language server does suggestions for first language override.
*/
if (languageOverrideRange && !languageOverrideRange.isEqual(languageOverridesRanges[0])) {
const languages = await vscode.languages.getLanguages();
const completionItems = [];
for (const language of languages) {
if (!donotSuggestLanguages.includes(language)) {
const item = new vscode.CompletionItem(`[${language}]`);
item.kind = vscode.CompletionItemKind.Property;
item.range = languageOverrideRange;
completionItems.push(item);
}
}
return completionItems;
}
}
return Promise.resolve([]);
return [];
}
private providePortsAttributesCompletionItem(range: vscode.Range): vscode.CompletionItem[] {
@@ -5,7 +5,6 @@
},
"include": [
"src/**/*",
"../../../src/vscode-dts/vscode.d.ts",
"../../../src/vscode-dts/vscode.proposed.d.ts",
"../../../src/vscode-dts/vscode.d.ts"
]
}
@@ -17,7 +17,6 @@
],
"main": "./client/out/node/cssClientMain",
"browser": "./client/dist/browser/cssClientMain",
"enableProposedApi": true,
"capabilities": {
"virtualWorkspaces": true,
"untrustedWorkspaces": {
+3 -1
View File
@@ -18,7 +18,9 @@
"supported": true
}
},
"enableProposedApi": true,
"enabledApiProposals": [
"terminalDataWriteEvent"
],
"main": "./out/extension",
"scripts": {
"compile": "gulp compile-extension:debug-server-ready",
+1 -1
View File
@@ -10,6 +10,6 @@
"include": [
"src/**/*",
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.d.ts",
"../../src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts",
]
}
+2
View File
@@ -0,0 +1,2 @@
build/**
cgmanifest.json
+32
View File
@@ -0,0 +1,32 @@
{
"registrations": [
{
"component": {
"type": "git",
"git": {
"name": "textmate/diff.tmbundle",
"repositoryUrl": "https://github.com/textmate/diff.tmbundle",
"commitHash": "0593bb775eab1824af97ef2172fd38822abd97d7"
}
},
"licenseDetail": [
"Copyright (c) textmate-diff.tmbundle project authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
],
"license": "TextMate Bundle License",
"version": "0.0.0"
}
],
"version": 1
}
@@ -8,4 +8,4 @@
["[", "]"],
["(", ")"]
]
}
}
+38
View File
@@ -0,0 +1,38 @@
{
"name": "diff",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "0.10.x"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin textmate/diff.tmbundle Syntaxes/Diff.plist ./syntaxes/diff.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "diff",
"aliases": [
"Diff",
"diff"
],
"extensions": [
".diff",
".patch",
".rej"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "diff",
"scopeName": "source.diff",
"path": "./syntaxes/diff.tmLanguage.json"
}
]
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"displayName": "Diff Language Basics",
"description": "Provides syntax highlighting & bracket matching in Diff files."
}
+1 -18
View File
@@ -41,24 +41,7 @@
"onCommand:editor.emmet.action.decrementNumberByTen",
"onCommand:editor.emmet.action.reflectCSSValue",
"onCommand:workbench.action.showEmmetCommands",
"onLanguage:html",
"onLanguage:haml",
"onLanguage:blade",
"onLanguage:css",
"onLanguage:sass",
"onLanguage:scss",
"onLanguage:less",
"onLanguage:stylus",
"onLanguage:slim",
"onLanguage:stylus",
"onLanguage:jade",
"onLanguage:pug",
"onLanguage:javascriptreact",
"onLanguage:typescriptreact",
"onLanguage:php",
"onLanguage:vue",
"onLanguage:xsl",
"onLanguage:xml"
"onStartupFinished"
],
"main": "./out/node/emmetNodeMain",
"browser": "./dist/browser/emmetBrowserMain",
+2
View File
@@ -0,0 +1,2 @@
build/**
cgmanifest.json
@@ -8,9 +8,3 @@ var updateGrammar = require('vscode-grammar-updater');
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Commit%20Message.tmLanguage', './syntaxes/git-commit.tmLanguage.json');
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Rebase%20Message.tmLanguage', './syntaxes/git-rebase.tmLanguage.json');
updateGrammar.update('textmate/diff.tmbundle', 'Syntaxes/Diff.plist', './syntaxes/diff.tmLanguage.json');
@@ -33,34 +33,7 @@
],
"license": "MIT",
"version": "0.0.0"
},
{
"component": {
"type": "git",
"git": {
"name": "textmate/diff.tmbundle",
"repositoryUrl": "https://github.com/textmate/diff.tmbundle",
"commitHash": "0593bb775eab1824af97ef2172fd38822abd97d7"
}
},
"licenseDetail": [
"Copyright (c) textmate-diff.tmbundle project authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
],
"license": "TextMate Bundle License",
"version": "0.0.0"
}
],
"version": 1
}
}
+70
View File
@@ -0,0 +1,70 @@
{
"name": "git-base",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "0.10.x"
},
"scripts": {
"update-grammar": "node ./build/update-grammars.js"
},
"contributes": {
"languages": [
{
"id": "git-commit",
"aliases": [
"Git Commit Message",
"git-commit"
],
"filenames": [
"COMMIT_EDITMSG",
"MERGE_MSG"
],
"configuration": "./languages/git-commit.language-configuration.json"
},
{
"id": "git-rebase",
"aliases": [
"Git Rebase Message",
"git-rebase"
],
"filenames": [
"git-rebase-todo"
],
"configuration": "./languages/git-rebase.language-configuration.json"
},
{
"id": "ignore",
"aliases": [
"Ignore",
"ignore"
],
"extensions": [
".gitignore_global",
".gitignore"
],
"configuration": "./languages/ignore.language-configuration.json"
}
],
"grammars": [
{
"language": "git-commit",
"scopeName": "text.git-commit",
"path": "./syntaxes/git-commit.tmLanguage.json"
},
{
"language": "git-rebase",
"scopeName": "text.git-rebase",
"path": "./syntaxes/git-rebase.tmLanguage.json"
},
{
"language": "ignore",
"scopeName": "source.ignore",
"path": "./syntaxes/ignore.tmLanguage.json"
}
]
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"displayName": "Git Base",
"description": "Git static contributions and pickers."
}
-1
View File
@@ -4,5 +4,4 @@ out/**
tsconfig.json
build/**
extension.webpack.config.js
cgmanifest.json
yarn.lock
+11 -76
View File
@@ -9,7 +9,14 @@
"vscode": "^1.5.0"
},
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"enableProposedApi": true,
"enabledApiProposals": [
"diffCommand",
"contribViewsWelcome",
"scmActionButton",
"scmSelectedProvider",
"scmValidation",
"timeline"
],
"categories": [
"Other"
],
@@ -23,7 +30,6 @@
"compile": "gulp compile-extension:git",
"watch": "gulp watch-extension:git",
"update-emoji": "node ./build/update-emoji.js",
"update-grammar": "node ./build/update-grammars.js",
"test": "node ../../node_modules/mocha/bin/mocha"
},
"capabilities": {
@@ -75,7 +81,8 @@
"command": "git.openChange",
"title": "%command.openChange%",
"category": "Git",
"icon": "$(compare-changes)"
"icon": "$(compare-changes)",
"enablement": "scmActiveResourceHasChanges"
},
{
"command": "git.openAllChanges",
@@ -2290,78 +2297,6 @@
}
}
],
"languages": [
{
"id": "git-commit",
"aliases": [
"Git Commit Message",
"git-commit"
],
"filenames": [
"COMMIT_EDITMSG",
"MERGE_MSG"
],
"configuration": "./languages/git-commit.language-configuration.json"
},
{
"id": "git-rebase",
"aliases": [
"Git Rebase Message",
"git-rebase"
],
"filenames": [
"git-rebase-todo"
],
"configuration": "./languages/git-rebase.language-configuration.json"
},
{
"id": "diff",
"aliases": [
"Diff",
"diff"
],
"extensions": [
".diff",
".patch",
".rej"
],
"configuration": "./languages/diff.language-configuration.json"
},
{
"id": "ignore",
"aliases": [
"Ignore",
"ignore"
],
"extensions": [
".gitignore_global",
".gitignore"
],
"configuration": "./languages/ignore.language-configuration.json"
}
],
"grammars": [
{
"language": "git-commit",
"scopeName": "text.git-commit",
"path": "./syntaxes/git-commit.tmLanguage.json"
},
{
"language": "git-rebase",
"scopeName": "text.git-rebase",
"path": "./syntaxes/git-rebase.tmLanguage.json"
},
{
"language": "diff",
"scopeName": "source.diff",
"path": "./syntaxes/diff.tmLanguage.json"
},
{
"language": "ignore",
"scopeName": "source.ignore",
"path": "./syntaxes/ignore.tmLanguage.json"
}
],
"configurationDefaults": {
"[git-commit]": {
"editor.rulers": [
@@ -2431,7 +2366,7 @@
"dependencies": {
"byline": "^5.0.0",
"file-type": "^7.2.0",
"iconv-lite-umd": "0.6.8",
"iconv-lite-umd": "0.6.10",
"jschardet": "3.0.0",
"vscode-extension-telemetry": "0.4.3",
"vscode-nls": "^4.0.0",
+2 -2
View File
@@ -1944,8 +1944,8 @@ export class Repository implements Disposable {
} else {
actionButton = {
command: 'git.publish',
title: localize('scm button publish title', "$(cloud-upload) Publish Changes"),
tooltip: localize('scm button publish tooltip', "Publish Changes"),
title: localize('scm button publish title', "$(cloud-upload) Publish Branch"),
tooltip: localize('scm button publish tooltip', "Publish Branch"),
arguments: [this._sourceControl],
};
}
+1 -1
View File
@@ -154,7 +154,7 @@ class SyncStatusBar {
} else {
icon = '$(cloud-upload)';
command = 'git.publish';
tooltip = localize('publish changes', "Publish Changes");
tooltip = localize('publish branch', "Publish Branch");
}
} else {
command = '';
+3 -6
View File
@@ -166,8 +166,7 @@ export class GitTimelineProvider implements TimelineProvider {
if (showAuthor) {
item.description = c.authorName;
}
// allow-any-unicode-next-line
item.detail = `${c.authorName} (${c.authorEmail}) — ${c.hash.substr(0, 8)}\n${dateFormatter.format(date)}\n\n${message}`;
item.detail = `${c.authorName} (${c.authorEmail}) \u2014 ${c.hash.substr(0, 8)}\n${dateFormatter.format(date)}\n\n${message}`;
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
@@ -192,8 +191,7 @@ export class GitTimelineProvider implements TimelineProvider {
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new ThemeIcon('git-commit');
item.description = '';
// allow-any-unicode-next-line
item.detail = localize('git.timeline.detail', '{0} — {1}\n{2}\n\n{3}', you, localize('git.index', 'Index'), dateFormatter.format(date), Resource.getStatusText(index.type));
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.index', 'Index'), dateFormatter.format(date), Resource.getStatusText(index.type));
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
@@ -215,8 +213,7 @@ export class GitTimelineProvider implements TimelineProvider {
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new ThemeIcon('git-commit');
item.description = '';
// allow-any-unicode-next-line
item.detail = localize('git.timeline.detail', '{0} — {1}\n{2}\n\n{3}', you, localize('git.workingTree', 'Working Tree'), dateFormatter.format(date), Resource.getStatusText(working.type));
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.workingTree', 'Working Tree'), dateFormatter.format(date), Resource.getStatusText(working.type));
const cmd = this.commands.resolveTimelineOpenDiffCommand(item, uri);
if (cmd) {
-1
View File
@@ -1 +0,0 @@
--ui tdd out/test
+5 -1
View File
@@ -10,7 +10,11 @@
"include": [
"src/**/*",
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.d.ts",
"../../src/vscode-dts/vscode.proposed.diffCommand.d.ts",
"../../src/vscode-dts/vscode.proposed.scmActionButton.d.ts",
"../../src/vscode-dts/vscode.proposed.scmSelectedProvider.d.ts",
"../../src/vscode-dts/vscode.proposed.scmValidation.d.ts",
"../../src/vscode-dts/vscode.proposed.timeline.d.ts",
"../types/lib.textEncoder.d.ts"
]
}
+4 -4
View File
@@ -46,10 +46,10 @@ file-type@^7.2.0:
resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74"
integrity sha1-ETz+1S4daVmrgCSJBuLyWozcy3Q=
iconv-lite-umd@0.6.8:
version "0.6.8"
resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz#5ad310ec126b260621471a2d586f7f37b9958ec0"
integrity sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A==
iconv-lite-umd@0.6.10:
version "0.6.10"
resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.10.tgz#faec47521e095b8e3a7175ae08e1b4ae0359a735"
integrity sha512-8NtgTa/m1jVq7vdywmD5+SqIlZsB59wtsjaylQuExyCojMq1tHVQxmHjeqVSYwKwnmQbH4mZ1Dxx1eqDkPgaqA==
isexe@^2.0.0:
version "2.0.0"
@@ -9,7 +9,6 @@
"vscode": "^1.41.0"
},
"icon": "images/icon.png",
"enableProposedApi": true,
"categories": [
"Other"
],
@@ -9,7 +9,6 @@
},
"include": [
"src/**/*",
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.d.ts"
"../../src/vscode-dts/vscode.d.ts"
]
}
-1
View File
@@ -9,7 +9,6 @@
"vscode": "^1.41.0"
},
"icon": "images/icon.png",
"enableProposedApi": true,
"categories": [
"Other"
],
+1 -2
View File
@@ -9,7 +9,6 @@
},
"include": [
"src/**/*",
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.d.ts"
"../../src/vscode-dts/vscode.d.ts"
]
}
@@ -5,7 +5,6 @@
},
"include": [
"src/**/*",
"../../../src/vscode-dts/vscode.d.ts",
"../../../src/vscode-dts/vscode.proposed.d.ts"
"../../../src/vscode-dts/vscode.d.ts"
]
}
@@ -1,5 +1,4 @@
{
"enableProposedApi": true,
"name": "html-language-features",
"displayName": "%displayName%",
"description": "%description%",
-1
View File
@@ -9,7 +9,6 @@
"version": "1.0.0",
"publisher": "vscode",
"icon": "icon.png",
"enableProposedApi": true,
"license": "MIT",
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"engines": {
+1 -2
View File
@@ -6,7 +6,6 @@
},
"include": [
"src/**/*",
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.d.ts"
"../../src/vscode-dts/vscode.d.ts"
]
}
+23 -20
View File
@@ -8,7 +8,10 @@
"engines": {
"vscode": "^1.57.0"
},
"enableProposedApi": true,
"enabledApiProposals": [
"notebookEditor",
"notebookEditorEdit"
],
"activationEvents": [
"onNotebook:jupyter-notebook"
],
@@ -29,23 +32,23 @@
{
"id": "jupyter",
"aliases": [
"Jupyter"
"Jupyter (JSON)"
],
"extensions": [
".ipynb"
]
}
],
"grammars": [
{
"language": "jupyter",
"scopeName": "source.jupyter",
"path": "./syntaxes/jupyter.tmLanguage.json",
"embeddedLanguages": {
"source.json": "json"
}
}
],
"grammars": [
{
"language": "jupyter",
"scopeName": "source.jupyter",
"path": "./syntaxes/jupyter.tmLanguage.json",
"embeddedLanguages": {
"source.json": "json"
}
}
],
"notebooks": [
{
"type": "jupyter-notebook",
@@ -59,10 +62,10 @@
}
]
},
"scripts": {
"compile": "npx gulp compile-extension:ipynb",
"watch": "npx gulp watch-extension:ipynb"
},
"scripts": {
"compile": "npx gulp compile-extension:ipynb",
"watch": "npx gulp watch-extension:ipynb"
},
"dependencies": {
"@enonic/fnv-plus": "^1.3.0",
"detect-indent": "^6.0.0",
@@ -72,8 +75,8 @@
"@jupyterlab/coreutils": "^3.1.0",
"@types/uuid": "^8.3.1"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}
+2 -1
View File
@@ -9,6 +9,7 @@
"include": [
"src/**/*",
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.d.ts"
"../../src/vscode-dts/vscode.proposed.notebookEditor.d.ts",
"../../src/vscode-dts/vscode.proposed.notebookEditorEdit.d.ts",
]
}
@@ -5,9 +5,8 @@
import { ExtensionContext, Uri } from 'vscode';
import { LanguageClientOptions } from 'vscode-languageclient';
import { startClient, LanguageClientConstructor } from '../jsonClient';
import { startClient, LanguageClientConstructor, SchemaRequestService } from '../jsonClient';
import { LanguageClient } from 'vscode-languageclient/browser';
import { RequestService } from '../requests';
declare const Worker: {
new(stringUrl: string): any;
@@ -24,7 +23,7 @@ export function activate(context: ExtensionContext) {
return new LanguageClient(id, name, clientOptions, worker);
};
const http: RequestService = {
const schemaRequests: SchemaRequestService = {
getContent(uri: string) {
return fetch(uri, { mode: 'cors' })
.then(function (response: any) {
@@ -32,7 +31,8 @@ export function activate(context: ExtensionContext) {
});
}
};
startClient(context, newLanguageClient, { http });
startClient(context, newLanguageClient, { schemaRequests });
} catch (e) {
console.log(e);
@@ -6,6 +6,8 @@ import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
export type JSONLanguageStatus = { schemas: string[] };
import {
workspace, window, languages, commands, ExtensionContext, extensions, Uri,
Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken,
@@ -18,7 +20,7 @@ import {
} from 'vscode-languageclient';
import { hash } from './utils/hash';
import { RequestService, joinPath } from './requests';
import { createLanguageStatusItem } from './languageStatus';
namespace VSCodeContentRequest {
export const type: RequestType<string, string, any> = new RequestType('vscode/content');
@@ -32,6 +34,11 @@ namespace ForceValidateRequest {
export const type: RequestType<string, Diagnostic[], any> = new RequestType('json/validate');
}
namespace LanguageStatusRequest {
export const type: RequestType<string, JSONLanguageStatus, any> = new RequestType('json/languageStatus');
}
export interface ISchemaAssociations {
[pattern: string]: string[];
}
@@ -88,10 +95,16 @@ export interface TelemetryReporter {
export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => CommonLanguageClient;
export interface Runtime {
http: RequestService;
schemaRequests: SchemaRequestService;
telemetry?: TelemetryReporter
}
export interface SchemaRequestService {
getContent(uri: string): Promise<string>;
}
export const languageServerDescription = localize('jsonserver.name', 'JSON Language Server');
export function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime) {
const toDispose = context.subscriptions;
@@ -190,7 +203,7 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
};
// Create the language client and start the client.
const client = newLanguageClient('json', localize('jsonserver.name', 'JSON Language Server'), clientOptions);
const client = newLanguageClient('json', languageServerDescription, clientOptions);
client.registerProposedFeatures();
const disposable = client.start();
@@ -220,7 +233,7 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
*/
runtime.telemetry.sendTelemetryEvent('json.schema', { schemaURL: uriPath });
}
return runtime.http.getContent(uriPath).catch(e => {
return runtime.schemaRequests.getContent(uriPath).catch(e => {
return Promise.reject(new ResponseError(4, e.toString()));
});
} else {
@@ -314,6 +327,8 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
}
});
toDispose.push(createLanguageStatusItem(documentSelector, (uri: string) => client.sendRequest(LanguageStatusRequest.type, uri)));
function updateFormatterRegistration() {
const formatEnabled = workspace.getConfiguration().get(SettingIds.enableFormatter);
if (!formatEnabled && rangeFormatting) {
@@ -376,7 +391,7 @@ function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[]
if (Array.isArray(fileMatch) && typeof url === 'string') {
let uri: string = url;
if (uri[0] === '.' && uri[1] === '/') {
uri = joinPath(extension.extensionUri, uri).toString();
uri = Uri.joinPath(extension.extensionUri, uri).toString();
}
fileMatch = fileMatch.map(fm => {
if (fm[0] === '%') {
@@ -497,7 +512,7 @@ function getSchemaId(schema: JSONSchemaSettings, folderUri?: Uri): string | unde
url = schema.schema.id || `vscode://schemas/custom/${encodeURIComponent(hash(schema.schema).toString(16))}`;
}
} else if (folderUri && (url[0] === '.' || url[0] === '/')) {
url = joinPath(folderUri, url).toString();
url = Uri.joinPath(folderUri, url).toString();
}
return url;
}
@@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { window, languages, Uri, LanguageStatusSeverity, Disposable, commands, QuickPickItem, extensions, workspace } from 'vscode';
import { JSONLanguageStatus } from './jsonClient';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
type ShowSchemasInput = {
schemas: string[];
uri: string;
};
interface ShowSchemasItem extends QuickPickItem {
uri: Uri;
}
function equalsIgnoreCase(a: string, b: string): boolean {
return a.length === b.length && a.toLowerCase().localeCompare(b.toLowerCase()) === 0;
}
function isEqualAuthority(a1: string | undefined, a2: string | undefined) {
return a1 === a2 || (a1 !== undefined && a2 !== undefined && equalsIgnoreCase(a1, a2));
}
function findExtension(uri: Uri) {
for (const ext of extensions.all) {
const parent = ext.extensionUri;
if (uri.scheme === parent.scheme && isEqualAuthority(uri.authority, parent.authority) && uri.path.startsWith(parent.path + '/')) {
return ext;
}
}
return undefined;
}
function findWorkspaceFolder(uri: Uri) {
if (workspace.workspaceFolders) {
for (const wf of workspace.workspaceFolders) {
const parent = wf.uri;
if (uri.scheme === parent.scheme && isEqualAuthority(uri.authority, parent.authority) && uri.path.startsWith(parent.path + '/')) {
return wf;
}
}
}
return undefined;
}
function renderShowSchemasItem(schema: string): ShowSchemasItem {
const uri = Uri.parse(schema);
const extension = findExtension(uri);
if (extension) {
return { label: extension.id, description: uri.path.substring(extension.extensionUri.path.length + 1), uri };
}
const wf = findWorkspaceFolder(uri);
if (wf) {
return { label: uri.path.substring(wf.uri.path.length + 1), description: 'Workspace', uri };
}
if (uri.scheme === 'file') {
return { label: uri.fsPath, uri };
} else if (uri.scheme === 'vscode') {
return { label: schema, description: 'internally generated', uri };
}
return { label: schema, uri };
}
export function createLanguageStatusItem(documentSelector: string[], statusRequest: (uri: string) => Promise<JSONLanguageStatus>): Disposable {
const statusItem = languages.createLanguageStatusItem('json.projectStatus', documentSelector);
statusItem.name = localize('statusItem.name', "JSON Validation Status");
statusItem.severity = LanguageStatusSeverity.Information;
const showSchemasCommand = commands.registerCommand('_json.showAssociatedSchemaList', (arg: ShowSchemasInput) => {
const items: ShowSchemasItem[] = arg.schemas.sort().map(renderShowSchemasItem);
const quickPick = window.createQuickPick<ShowSchemasItem>();
quickPick.title = localize('schemaPicker.title', 'JSON Schemas used for {0}', arg.uri.toString());
quickPick.placeholder = localize('schemaPicker.placeholder', 'Select the schema to open');
quickPick.items = items;
quickPick.show();
quickPick.onDidAccept(() => {
commands.executeCommand('vscode.open', quickPick.selectedItems[0].uri);
quickPick.dispose();
});
});
const activeEditorListener = window.onDidChangeActiveTextEditor(() => {
updateLanguageStatus();
});
async function updateLanguageStatus() {
const document = window.activeTextEditor?.document;
if (document && documentSelector.indexOf(document.languageId) !== -1) {
try {
statusItem.text = '$(loading~spin)';
statusItem.detail = localize('pending.detail', 'Loading JSON info');
statusItem.command = undefined;
const schemas = (await statusRequest(document.uri.toString())).schemas;
statusItem.detail = undefined;
if (schemas.length === 0) {
statusItem.text = localize('status.noSchema', 'Validated without JSON schema');
} else if (schemas.length === 1) {
const item = renderShowSchemasItem(schemas[0]);
statusItem.text = localize('status.singleSchema', 'Validated with JSON schema');
statusItem.command = {
command: 'vscode.open',
title: localize('status.openSchemaLink', 'Open Schema'),
tooltip: item.description ? `${item.label} - ${item.description}` : item.label,
arguments: [item.uri]
};
} else {
statusItem.text = localize('status.multipleSchema', 'Validated with multiple JSON schemas');
statusItem.command = {
command: '_json.showAssociatedSchemaList',
title: localize('status.openSchemasLink', 'Show Schemas'),
arguments: [{ schemas, uri: document.uri.toString() } as ShowSchemasInput]
};
}
} catch (e) {
statusItem.text = localize('status.error', 'Unable to compute used schemas');
statusItem.detail = undefined;
statusItem.command = undefined;
console.log(e);
}
} else {
statusItem.text = localize('status.notJSON', 'Not a JSON editor');
statusItem.detail = undefined;
statusItem.command = undefined;
}
}
updateLanguageStatus();
return Disposable.from(statusItem, activeEditorListener, showSchemasCommand);
}
@@ -3,24 +3,26 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionContext } from 'vscode';
import { startClient, LanguageClientConstructor } from '../jsonClient';
import { ExtensionContext, OutputChannel, window, workspace } from 'vscode';
import { startClient, LanguageClientConstructor, SchemaRequestService, languageServerDescription } from '../jsonClient';
import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient } from 'vscode-languageclient/node';
import * as fs from 'fs';
import { xhr, XHRResponse, getErrorStatusDescription } from 'request-light';
import { promises as fs } from 'fs';
import * as path from 'path';
import { xhr, XHRResponse, getErrorStatusDescription, Headers } from 'request-light';
import TelemetryReporter from 'vscode-extension-telemetry';
import { RequestService } from '../requests';
import { JSONSchemaCache } from './schemaCache';
let telemetry: TelemetryReporter | undefined;
// this method is called when vs code is activated
export function activate(context: ExtensionContext) {
const clientPackageJSON = getPackageInfo(context);
export async function activate(context: ExtensionContext) {
const clientPackageJSON = await getPackageInfo(context);
telemetry = new TelemetryReporter(clientPackageJSON.name, clientPackageJSON.version, clientPackageJSON.aiKey);
const outputChannel = window.createOutputChannel(languageServerDescription);
const serverMain = `./server/${clientPackageJSON.main.indexOf('/dist/') !== -1 ? 'dist' : 'out'}/node/jsonServerMain`;
const serverModule = context.asAbsolutePath(serverMain);
@@ -35,10 +37,15 @@ export function activate(context: ExtensionContext) {
};
const newLanguageClient: LanguageClientConstructor = (id: string, name: string, clientOptions: LanguageClientOptions) => {
clientOptions.outputChannel = outputChannel;
return new LanguageClient(id, name, serverOptions, clientOptions);
};
const log = getLog(outputChannel);
context.subscriptions.push(log);
startClient(context, newLanguageClient, { http: getHTTPRequestService(), telemetry });
const schemaRequests = await getSchemaRequestService(context, log);
startClient(context, newLanguageClient, { schemaRequests, telemetry });
}
export function deactivate(): Promise<any> {
@@ -52,23 +59,88 @@ interface IPackageInfo {
main: string;
}
function getPackageInfo(context: ExtensionContext): IPackageInfo {
async function getPackageInfo(context: ExtensionContext): Promise<IPackageInfo> {
const location = context.asAbsolutePath('./package.json');
try {
return JSON.parse(fs.readFileSync(location).toString());
return JSON.parse((await fs.readFile(location)).toString());
} catch (e) {
console.log(`Problems reading ${location}: ${e}`);
return { name: '', version: '', aiKey: '', main: '' };
}
}
function getHTTPRequestService(): RequestService {
interface Log {
trace(message: string): void;
dispose(): void;
}
const traceSetting = 'json.trace.server';
function getLog(outputChannel: OutputChannel): Log {
let trace = workspace.getConfiguration().get(traceSetting) === 'verbose';
const configListener = workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(traceSetting)) {
trace = workspace.getConfiguration().get(traceSetting) === 'verbose';
}
});
return {
getContent(uri: string, _encoding?: string): Promise<string> {
const headers = { 'Accept-Encoding': 'gzip, deflate' };
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
return response.responseText;
}, (error: XHRResponse) => {
trace(message: string) {
if (trace) {
outputChannel.appendLine(message);
}
},
dispose: () => configListener.dispose()
};
}
const retryTimeoutInDays = 2; // 2 days
const retryTimeoutInMs = retryTimeoutInDays * 24 * 60 * 60 * 1000;
async function getSchemaRequestService(context: ExtensionContext, log: Log): Promise<SchemaRequestService> {
let cache: JSONSchemaCache | undefined = undefined;
const globalStorage = context.globalStorageUri;
if (globalStorage.scheme === 'file') {
const schemaCacheLocation = path.join(globalStorage.fsPath, 'json-schema-cache');
await fs.mkdir(schemaCacheLocation, { recursive: true });
cache = new JSONSchemaCache(schemaCacheLocation, context.globalState);
log.trace(`[json schema cache] initial state: ${JSON.stringify(cache.getCacheInfo(), null, ' ')}`);
}
const isXHRResponse = (error: any): error is XHRResponse => typeof error?.status === 'number';
const request = async (uri: string, etag?: string): Promise<string> => {
const headers: Headers = { 'Accept-Encoding': 'gzip, deflate' };
if (etag) {
headers['If-None-Match'] = etag;
}
try {
log.trace(`[json schema cache] Requesting schema ${uri} etag ${etag}...`);
const response = await xhr({ url: uri, followRedirects: 5, headers });
if (cache) {
const etag = response.headers['etag'];
if (typeof etag === 'string') {
log.trace(`[json schema cache] Storing schema ${uri} etag ${etag} in cache`);
await cache.putSchema(uri, etag, response.responseText);
} else {
log.trace(`[json schema cache] Response: schema ${uri} no etag`);
}
}
return response.responseText;
} catch (error: unknown) {
if (isXHRResponse(error)) {
if (error.status === 304 && etag && cache) {
log.trace(`[json schema cache] Response: schema ${uri} unchanged etag ${etag}`);
const content = await cache.getSchema(uri, etag);
if (content) {
log.trace(`[json schema cache] Get schema ${uri} etag ${etag} from cache`);
return content;
}
return request(uri);
}
let status = getErrorStatusDescription(error.status);
if (status && error.responseText) {
status = `${status}\n${error.responseText.substring(0, 200)}`;
@@ -76,8 +148,24 @@ function getHTTPRequestService(): RequestService {
if (!status) {
status = error.toString();
}
return Promise.reject(status);
});
log.trace(`[json schema cache] Respond schema ${uri} error ${status}`);
throw status;
}
throw error;
}
};
return {
getContent: async (uri: string) => {
if (cache && /^https?:\/\/json\.schemastore\.org\//.test(uri)) {
const content = await cache.getSchemaIfAccessedSince(uri, retryTimeoutInMs);
if (content) {
log.trace(`[json schema cache] Schema ${uri} from cache without request (last accessed less than ${retryTimeoutInDays} days ago)`);
return content;
}
}
return request(uri, cache?.getETag(uri));
}
};
}
@@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { promises as fs } from 'fs';
import * as path from 'path';
import { createHash } from 'crypto';
import { Memento } from 'vscode';
interface CacheEntry {
etag: string;
fileName: string;
accessTime: number;
}
interface CacheInfo {
[schemaUri: string]: CacheEntry;
}
const MEMENTO_KEY = 'json-schema-cache';
export class JSONSchemaCache {
private readonly cacheInfo: CacheInfo;
constructor(private readonly schemaCacheLocation: string, private readonly globalState: Memento) {
this.cacheInfo = globalState.get<CacheInfo>(MEMENTO_KEY, {});
}
getETag(schemaUri: string): string | undefined {
return this.cacheInfo[schemaUri]?.etag;
}
async putSchema(schemaUri: string, etag: string, schemaContent: string): Promise<void> {
try {
const fileName = getCacheFileName(schemaUri);
await fs.writeFile(path.join(this.schemaCacheLocation, fileName), schemaContent);
const entry: CacheEntry = { etag, fileName, accessTime: new Date().getTime() };
this.cacheInfo[schemaUri] = entry;
} catch (e) {
delete this.cacheInfo[schemaUri];
} finally {
await this.updateMemento();
}
}
async getSchemaIfAccessedSince(schemaUri: string, expirationDuration: number): Promise<string | undefined> {
const cacheEntry = this.cacheInfo[schemaUri];
if (cacheEntry && cacheEntry.accessTime + expirationDuration >= new Date().getTime()) {
return this.loadSchemaFile(schemaUri, cacheEntry);
}
return undefined;
}
async getSchema(schemaUri: string, etag: string): Promise<string | undefined> {
const cacheEntry = this.cacheInfo[schemaUri];
if (cacheEntry) {
if (cacheEntry.etag === etag) {
return this.loadSchemaFile(schemaUri, cacheEntry);
} else {
this.deleteSchemaFile(schemaUri, cacheEntry);
}
}
return undefined;
}
private async loadSchemaFile(schemaUri: string, cacheEntry: CacheEntry): Promise<string | undefined> {
const cacheLocation = path.join(this.schemaCacheLocation, cacheEntry.fileName);
try {
const content = (await fs.readFile(cacheLocation)).toString();
cacheEntry.accessTime = new Date().getTime();
return content;
} catch (e) {
delete this.cacheInfo[schemaUri];
return undefined;
} finally {
await this.updateMemento();
}
}
private async deleteSchemaFile(schemaUri: string, cacheEntry: CacheEntry): Promise<void> {
const cacheLocation = path.join(this.schemaCacheLocation, cacheEntry.fileName);
delete this.cacheInfo[schemaUri];
await this.updateMemento();
try {
await fs.rm(cacheLocation);
} catch (e) {
// ignore
}
}
// for debugging
public getCacheInfo() {
return this.cacheInfo;
}
private async updateMemento() {
try {
await this.globalState.update(MEMENTO_KEY, this.cacheInfo);
} catch (e) {
// ignore
}
}
}
function getCacheFileName(uri: string): string {
return `${createHash('MD5').update(uri).digest('hex')}.schema.json`;
}
@@ -1,68 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Uri } from 'vscode';
export interface RequestService {
getContent(uri: string, encoding?: string): Promise<string>;
}
export function getScheme(uri: string) {
return uri.substr(0, uri.indexOf(':'));
}
export function dirname(uri: string) {
const lastIndexOfSlash = uri.lastIndexOf('/');
return lastIndexOfSlash !== -1 ? uri.substr(0, lastIndexOfSlash) : '';
}
export function basename(uri: string) {
const lastIndexOfSlash = uri.lastIndexOf('/');
return uri.substr(lastIndexOfSlash + 1);
}
const Slash = '/'.charCodeAt(0);
const Dot = '.'.charCodeAt(0);
export function isAbsolutePath(path: string) {
return path.charCodeAt(0) === Slash;
}
export function resolvePath(uri: Uri, path: string): Uri {
if (isAbsolutePath(path)) {
return uri.with({ path: normalizePath(path.split('/')) });
}
return joinPath(uri, path);
}
export function normalizePath(parts: string[]): string {
const newParts: string[] = [];
for (const part of parts) {
if (part.length === 0 || part.length === 1 && part.charCodeAt(0) === Dot) {
// ignore
} else if (part.length === 2 && part.charCodeAt(0) === Dot && part.charCodeAt(1) === Dot) {
newParts.pop();
} else {
newParts.push(part);
}
}
if (parts.length > 1 && parts[parts.length - 1].length === 0) {
newParts.push('');
}
let res = newParts.join('/');
if (parts[0].length === 0) {
res = '/' + res;
}
return res;
}
export function joinPath(uri: Uri, ...paths: string[]): Uri {
const parts = uri.path.split('/');
for (let path of paths) {
parts.push(...path.split('/'));
}
return uri.with({ path: normalizePath(parts) });
}
@@ -6,6 +6,6 @@
"include": [
"src/**/*",
"../../../src/vscode-dts/vscode.d.ts",
"../../../src/vscode-dts/vscode.proposed.d.ts"
"../../../src/vscode-dts/vscode.proposed.languageStatus.d.ts",
]
}
@@ -16,13 +16,15 @@
],
"main": "./client/out/node/jsonClientMain",
"browser": "./client/dist/browser/jsonClientMain",
"enableProposedApi": true,
"capabilities": {
"virtualWorkspaces": true,
"untrustedWorkspaces": {
"supported": true
}
},
"enabledApiProposals": [
"languageStatus"
],
"scripts": {
"compile": "npx gulp compile-extension:json-language-features-client compile-extension:json-language-features-server",
"watch": "npx gulp watch-extension:json-language-features-client watch-extension:json-language-features-server",
@@ -14,7 +14,7 @@
"dependencies": {
"jsonc-parser": "^3.0.0",
"request-light": "^0.5.4",
"vscode-json-languageservice": "^4.1.9",
"vscode-json-languageservice": "^4.2.0-next.1",
"vscode-languageserver": "^7.0.0",
"vscode-uri": "^3.0.2"
},
@@ -12,10 +12,12 @@ import {
import { formatError, runSafe, runSafeAsync } from './utils/runner';
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Diagnostic, Range, Position } from 'vscode-json-languageservice';
import { getLanguageModelCache } from './languageModelCache';
import { RequestService, basename, resolvePath } from './requests';
import { Utils, URI } from 'vscode-uri';
type ISchemaAssociations = Record<string, string[]>;
type JSONLanguageStatus = { schemas: string[] };
namespace SchemaAssociationNotification {
export const type: NotificationType<ISchemaAssociations | SchemaConfiguration[]> = new NotificationType('json/schemaAssociations');
}
@@ -36,14 +38,22 @@ namespace ForceValidateRequest {
export const type: RequestType<string, Diagnostic[], any> = new RequestType('json/validate');
}
namespace LanguageStatusRequest {
export const type: RequestType<string, JSONLanguageStatus, any> = new RequestType('json/languageStatus');
}
const workspaceContext = {
resolveRelativePath: (relativePath: string, resource: string) => {
const base = resource.substr(0, resource.lastIndexOf('/') + 1);
return resolvePath(base, relativePath);
const base = resource.substring(0, resource.lastIndexOf('/') + 1);
return Utils.resolvePath(URI.parse(base), relativePath).toString();
}
};
export interface RequestService {
getContent(uri: string): Promise<string>;
}
export interface RuntimeEnvironment {
file?: RequestService;
http?: RequestService
@@ -179,7 +189,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
const showLimitedNotification = (uri: string, resultLimit: number) => {
const warning = pendingWarnings[uri];
connection.sendNotification(ResultLimitReachedNotification.type, `${basename(uri)}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
connection.sendNotification(ResultLimitReachedNotification.type, `${Utils.basename(URI.parse(uri))}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
warning.timeout = undefined;
};
@@ -255,7 +265,11 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
// A schema has changed
connection.onNotification(SchemaContentChangeNotification.type, uri => {
languageService.resetSchema(uri);
if (languageService.resetSchema(uri)) {
for (const doc of documents.all()) {
triggerValidation(doc);
}
}
});
// Retry schema validation on all open documents
@@ -273,6 +287,16 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
});
});
connection.onRequest(LanguageStatusRequest.type, async uri => {
const document = documents.get(uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.getLanguageStatus(document, jsonDocument);
} else {
return { schemas: [] };
}
});
function updateConfiguration() {
const languageSettings = {
validate: true,
@@ -5,8 +5,7 @@
import { createConnection, Connection, Disposable } from 'vscode-languageserver/node';
import { formatError } from '../utils/runner';
import { RuntimeEnvironment, startServer } from '../jsonServer';
import { RequestService } from '../requests';
import { RequestService, RuntimeEnvironment, startServer } from '../jsonServer';
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
import { URI as Uri } from 'vscode-uri';
@@ -1,87 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vscode-uri';
export interface RequestService {
getContent(uri: string, encoding?: string): Promise<string>;
}
export function getScheme(uri: string) {
return uri.substr(0, uri.indexOf(':'));
}
export function dirname(uri: string) {
const lastIndexOfSlash = uri.lastIndexOf('/');
return lastIndexOfSlash !== -1 ? uri.substr(0, lastIndexOfSlash) : '';
}
export function basename(uri: string) {
const lastIndexOfSlash = uri.lastIndexOf('/');
return uri.substr(lastIndexOfSlash + 1);
}
const Slash = '/'.charCodeAt(0);
const Dot = '.'.charCodeAt(0);
export function extname(uri: string) {
for (let i = uri.length - 1; i >= 0; i--) {
const ch = uri.charCodeAt(i);
if (ch === Dot) {
if (i > 0 && uri.charCodeAt(i - 1) !== Slash) {
return uri.substr(i);
} else {
break;
}
} else if (ch === Slash) {
break;
}
}
return '';
}
export function isAbsolutePath(path: string) {
return path.charCodeAt(0) === Slash;
}
export function resolvePath(uriString: string, path: string): string {
if (isAbsolutePath(path)) {
const uri = URI.parse(uriString);
const parts = path.split('/');
return uri.with({ path: normalizePath(parts) }).toString();
}
return joinPath(uriString, path);
}
export function normalizePath(parts: string[]): string {
const newParts: string[] = [];
for (const part of parts) {
if (part.length === 0 || part.length === 1 && part.charCodeAt(0) === Dot) {
// ignore
} else if (part.length === 2 && part.charCodeAt(0) === Dot && part.charCodeAt(1) === Dot) {
newParts.pop();
} else {
newParts.push(part);
}
}
if (parts.length > 1 && parts[parts.length - 1].length === 0) {
newParts.push('');
}
let res = newParts.join('/');
if (parts[0].length === 0) {
res = '/' + res;
}
return res;
}
export function joinPath(uriString: string, ...paths: string[]): string {
const uri = URI.parse(uriString);
const parts = uri.path.split('/');
for (let path of paths) {
parts.push(...path.split('/'));
}
return uri.with({ path: normalizePath(parts) }).toString();
}
@@ -22,10 +22,10 @@ request-light@^0.5.4:
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.4.tgz#497a98c6d8ae49536417a5e2d7f383b934f3e38c"
integrity sha512-t3566CMweOFlUk7Y1DJMu5OrtpoZEb6aSTsLQVT3wtrIEJ5NhcY9G/Oqxvjllzl4a15zXfFlcr9q40LbLVQJqw==
vscode-json-languageservice@^4.1.9:
version "4.1.9"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.1.9.tgz#fb48edc69e37167c3cafd447c3fa898052d87b61"
integrity sha512-kxNHitUy2fCxmP6vAp0SRLrUSuecUYzzxlC+85cC3jJlFHWmvtCJOzikC+kcUnIdls9fQSB8n0yHs8Sl6taxJw==
vscode-json-languageservice@^4.2.0-next.1:
version "4.2.0-next.1"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.2.0-next.1.tgz#31a8c3be04c87d5aa593c11b98d84258b173a22f"
integrity sha512-aQvkkuZpeSPv86QLzyMdKTCgvXR+qSO39nSgj/XGaOcuHmTt7vMZB7ymYGGkQ4cAaQdHs/2G6a479LQybIGSbg==
dependencies:
jsonc-parser "^3.0.0"
vscode-languageserver-textdocument "^1.0.1"
@@ -5,7 +5,6 @@
"version": "1.0.0",
"icon": "icon.png",
"publisher": "vscode",
"enableProposedApi": true,
"license": "MIT",
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"engines": {
@@ -10,18 +10,26 @@ import { joinLines } from './util';
const testFileA = workspaceFile('a.md');
const debug = false;
function debugLog(...args: any[]) {
if (debug) {
console.log(...args);
}
}
function workspaceFile(...segments: string[]) {
return vscode.Uri.joinPath(vscode.workspace.workspaceFolders![0].uri, ...segments);
}
async function getLinksForFile(file: vscode.Uri): Promise<vscode.DocumentLink[]> {
console.log('getting links', file.toString(), Date.now());
debugLog('getting links', file.toString(), Date.now());
const r = (await vscode.commands.executeCommand<vscode.DocumentLink[]>('vscode.executeLinkProvider', file))!;
console.log('got links', file.toString(), Date.now());
debugLog('got links', file.toString(), Date.now());
return r;
}
suite('Markdown Document links', () => {
(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('Markdown Document links', () => {
setup(async () => {
// the tests make the assumption that link providers are already registered
@@ -149,21 +157,21 @@ function assertActiveDocumentUri(expectedUri: vscode.Uri) {
}
async function withFileContents(file: vscode.Uri, contents: string): Promise<void> {
console.log('openTextDocument', file.toString(), Date.now());
debugLog('openTextDocument', file.toString(), Date.now());
const document = await vscode.workspace.openTextDocument(file);
console.log('showTextDocument', file.toString(), Date.now());
debugLog('showTextDocument', file.toString(), Date.now());
const editor = await vscode.window.showTextDocument(document);
console.log('editTextDocument', file.toString(), Date.now());
debugLog('editTextDocument', file.toString(), Date.now());
await editor.edit(edit => {
edit.replace(new vscode.Range(0, 0, 1000, 0), contents);
});
console.log('opened done', vscode.window.activeTextEditor?.document.toString(), Date.now());
debugLog('opened done', vscode.window.activeTextEditor?.document.toString(), Date.now());
}
async function executeLink(link: vscode.DocumentLink) {
console.log('executeingLink', link.target?.toString(), Date.now());
debugLog('executeingLink', link.target?.toString(), Date.now());
const args = JSON.parse(decodeURIComponent(link.target!.query));
await vscode.commands.executeCommand(link.target!.path, args);
console.log('executedLink', vscode.window.activeTextEditor?.document.toString(), Date.now());
debugLog('executedLink', vscode.window.activeTextEditor?.document.toString(), Date.now());
}

Some files were not shown because too many files have changed in this diff Show More