Merge remote-tracking branch 'origin/main' into connor4312/cli-self-update

This commit is contained in:
Connor Peet
2022-10-14 14:23:41 -07:00
1157 changed files with 24739 additions and 16506 deletions
+6 -6
View File
@@ -1,6 +1,6 @@
# Code - OSS Development Container
[![Open in Remote - Containers](https://img.shields.io/static/v1?label=Remote%20-%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode)
[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode)
This repository includes configuration for a development container for working with Code - OSS in a local container or using [GitHub Codespaces](https://github.com/features/codespaces).
@@ -8,7 +8,7 @@ This repository includes configuration for a development container for working w
## Quick start - local
If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. Clicking these links will cause VS Code to automatically install the Remote - Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
1. Install Docker Desktop or Docker for Linux on your local machine. (See [docs](https://aka.ms/vscode-remote/containers/getting-started) for additional details.)
@@ -16,13 +16,13 @@ If you already have VS Code and Docker installed, you can click the badge above
> **Note:** The [Resource Monitor](https://marketplace.visualstudio.com/items?itemName=mutantdino.resourcemonitor) extension is included in the container so you can keep an eye on CPU/Memory in the status bar.
3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Remote - Containers](https://aka.ms/vscode-remote/download/containers) extension.
3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Dev Containers](https://aka.ms/vscode-remote/download/containers) extension.
![Image of Remote - Containers extension](https://microsoft.github.io/vscode-remote-release/images/remote-containers-extn.png)
![Image of Dev Containers extension](https://microsoft.github.io/vscode-remote-release/images/remote-containers-extn.png)
> **Note:** The Remote - Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details.
> **Note:** The Dev Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details.
4. Press <kbd>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or <kbd>F1</kbd> and select **Remote-Containers: Clone Repository in Container Volume...**.
4. Press <kbd>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or <kbd>F1</kbd> and select **Dev Containers: Clone Repository in Container Volume...**.
> **Tip:** While you can use your local source tree instead, operations like `yarn install` can be slow on macOS or when using the Hyper-V engine on Windows. We recommend the "clone repository in container" approach instead since it uses "named volume" rather than the local filesystem.
+2
View File
@@ -6,6 +6,7 @@
**/extensions/css-language-features/server/test/pathCompletionFixtures/**
**/extensions/html-language-features/server/lib/jquery.d.ts
**/extensions/html-language-features/server/src/test/pathCompletionFixtures/**
**/extensions/ipynb/notebook-out/**
**/extensions/markdown-language-features/media/**
**/extensions/markdown-language-features/notebook-out/**
**/extensions/markdown-math/notebook-out/**
@@ -27,4 +28,5 @@
**/src/vs/base/test/common/filters.perf.data.js
**/src/vs/loader.js
**/test/unit/assert.js
**/test/automation/out/**
**/typings/**
+4 -4
View File
@@ -13,10 +13,10 @@ Does this issue occur when all extensions are disabled?: Yes/No
<!-- 🪓 If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. -->
<!-- 📣 Issues caused by an extension need to be reported directly to the extension publisher. The 'Help > Report Issue' dialog can assist with this. -->
- VS Code Version:
- OS Version:
- VS Code Version:
- OS Version:
Steps to Reproduce:
1.
2.
1.
2.
+3
View File
@@ -3,3 +3,6 @@ contact_links:
- name: Question
url: https://stackoverflow.com/questions/tagged/visual-studio-code
about: Please ask and answer questions here.
- name: Extension Development
url: https://github.com/microsoft/vscode-discussions/discussions/5
about: Please use this for extension development questions and ideas.
+2 -1
View File
@@ -18,7 +18,7 @@
"callhierarchy": {"assign": ["jrieken"]},
"code-lens": {"assign": ["jrieken"]},
"color-palette": {"assign": []},
"comments": {"assign": ["rebornix"]},
"comments": {"assign": ["alexr00"]},
"config": {"assign": ["sandy081"]},
"context-keys": {"assign": []},
"css-less-scss": {"assign": ["aeschli"]},
@@ -58,6 +58,7 @@
"editor-scrollbar": {"assign": ["alexdima"]},
"editor-symbols": {"assign": ["jrieken"]},
"editor-synced-region": {"assign": ["aeschli"]},
"editor-sticky-scroll": {"assign": ["jrieken"]},
"editor-textbuffer": {"assign": ["alexdima", "rebornix"]},
"editor-theming": {"assign": ["alexdima"]},
"editor-wordnav": {"assign": ["alexdima"]},
-142
View File
@@ -1,142 +0,0 @@
{
"type": "object",
"properties": {
"registrations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"component": {
"oneOf": [
{
"type": "object",
"required": [
"type",
"git"
],
"properties": {
"type": {
"type": "string",
"enum": [
"git"
]
},
"git": {
"type": "object",
"required": [
"name",
"repositoryUrl",
"commitHash"
],
"properties": {
"name": {
"type": "string"
},
"repositoryUrl": {
"type": "string"
},
"commitHash": {
"type": "string"
}
}
}
}
},
{
"type": "object",
"required": [
"type",
"npm"
],
"properties": {
"type": {
"type": "string",
"enum": [
"npm"
]
},
"npm": {
"type": "object",
"required": [
"name",
"version"
],
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
}
}
}
}
},
{
"type": "object",
"required": [
"type",
"other"
],
"properties": {
"type": {
"type": "string",
"enum": [
"other"
]
},
"other": {
"type": "object",
"required": [
"name",
"downloadUrl",
"version"
],
"properties": {
"name": {
"type": "string"
},
"downloadUrl": {
"type": "string"
},
"version": {
"type": "string"
}
}
}
}
}
]
},
"repositoryUrl": {
"type": "string",
"description": "The git url of the component"
},
"version": {
"type": "string",
"description": "The version of the component"
},
"license": {
"type": "string",
"description": "The name of the license"
},
"developmentDependency": {
"type": "boolean",
"description": "This component is inlined in the vscode repo and **is not shipped**."
},
"isOnlyProductionDependency": {
"type": "boolean",
"description": "This component is shipped and **is not inlined in the vscode repo**."
},
"licenseDetail": {
"type": "array",
"items": {
"type": "string"
},
"description": "The license text"
}
}
}
}
}
}
+28 -1
View File
@@ -230,7 +230,7 @@
"runtimeExecutable": "${workspaceFolder}/scripts/code.sh"
},
"port": 9222,
"timeout": 20000,
"timeout": 0,
"env": {
"VSCODE_EXTHOST_WILL_SEND_SOCKET": null,
"VSCODE_SKIP_PRELAUNCH": "1"
@@ -322,6 +322,33 @@
"order": 3
}
},
{
"type": "chrome",
"request": "launch",
"outFiles": [],
"perScriptSourcemaps": "yes",
"name": "VS Code Web (Chrome)",
"url": "http://localhost:8080",
"preLaunchTask": "Run code web",
"presentation": {
"group": "0_vscode",
"order": 3
}
},
{
"type": "msedge",
"request": "launch",
"outFiles": [],
"perScriptSourcemaps": "yes",
"name": "VS Code Web (Edge)",
"url": "http://localhost:8080",
"pauseForSourceMap": false,
"preLaunchTask": "Run code web",
"presentation": {
"group": "0_vscode",
"order": 3
}
},
{
"type": "node",
"request": "launch",
+1 -1
View File
@@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"September 2022\""
"value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"October 2022\""
},
{
"kind": 1,
+7 -7
View File
@@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-unpkg\n\n$MILESTONE=milestone:\"August 2022\""
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n\r\n\r\n$MILESTONE=milestone:\"October 2022\""
},
{
"kind": 1,
@@ -32,7 +32,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS -$MILESTONE is:issue is:closed label:bug label:insiders-released -label:verified -label:*duplicate -label:*as-designed -label:z-author-verified -label:on-testplan"
"value": "$REPOS -$MILESTONE is:issue is:closed reason:completed label:bug label:insiders-released -label:verified -label:*duplicate -label:*as-designed -label:z-author-verified -label:on-testplan"
},
{
"kind": 1,
@@ -42,7 +42,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS -$MILESTONE is:issue is:closed label:feature-request label:insiders-released -label:on-testplan -label:verified -label:*duplicate"
"value": "$REPOS -$MILESTONE is:issue is:closed reason:completed label:feature-request label:insiders-released -label:on-testplan -label:verified -label:*duplicate"
},
{
"kind": 1,
@@ -62,7 +62,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE is:issue is:closed label:feature-request -label:verification-needed -label:on-testplan -label:verified -label:*duplicate"
"value": "$REPOS $MILESTONE is:issue is:closed reason:completed label:feature-request -label:verification-needed -label:on-testplan -label:verified -label:*duplicate"
},
{
"kind": 1,
@@ -97,7 +97,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE is:issue is:closed label:verification-needed -label:verified"
"value": "$REPOS $MILESTONE is:issue is:closed reason:completed label:verification-needed -label:verified"
},
{
"kind": 1,
@@ -112,7 +112,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE is:issue is:closed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -label:z-author-verified -label:unreleased"
"value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -label:z-author-verified -label:unreleased"
},
{
"kind": 1,
@@ -122,7 +122,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE is:issue is:closed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -label:z-author-verified label:unreleased"
"value": "$REPOS $MILESTONE is:issue is:closed reason:completed sort:updated-asc label:bug -label:verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -label:z-author-verified label:unreleased"
},
{
"kind": 1,
+8 -8
View File
@@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal\r\n\r\n$MILESTONE=milestone:\"August 2022\"\r\n\r\n$MINE=assignee:@me"
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n\r\n\r\n$MILESTONE=milestone:\"October 2022\"\r\n\r\n$MINE=assignee:@me"
},
{
"kind": 1,
@@ -42,7 +42,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE $MINE is:issue is:closed label:feature-request -label:verification-needed -label:on-testplan -label:verified -label:*duplicate"
"value": "$REPOS $MILESTONE $MINE is:issue is:closed reason:completed label:feature-request -label:verification-needed -label:on-testplan -label:verified -label:*duplicate"
},
{
"kind": 1,
@@ -62,7 +62,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE $MINE is:issue is:closed label:feature-request label:verification-needed -label:verified"
"value": "$REPOS $MILESTONE $MINE is:issue is:closed reason:completed label:feature-request label:verification-needed -label:verified"
},
{
"kind": 1,
@@ -87,7 +87,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed -assignee:@me -label:verified -label:z-author-verified label:feature-request label:verification-needed"
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed -assignee:@me -label:verified -label:z-author-verified label:feature-request label:verification-needed -label:verification-steps-needed -label:unreleased"
},
{
"kind": 1,
@@ -147,7 +147,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:triage-needed -label:verification-found"
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:triage-needed -label:verification-found"
},
{
"kind": 1,
@@ -157,7 +157,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -author:aeschli -author:alexdima -author:alexr00 -author:AmandaSilver -author:andreamah -author:bamurtaugh -author:bpasero -author:chrisdias -author:chrmarti -author:Chuxel -author:claudiaregio -author:connor4312 -author:dbaeumer -author:deepak1556 -author:devinvalenciano -author:digitarald -author:DonJayamanne -author:egamma -author:fiveisprime -author:gregvanl -author:hediet -author:IanMatthewHuff -author:isidorn -author:joaomoreno -author:joyceerhl -author:jrieken -author:karrtikr -author:kieferrm -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:roblourens -author:rzhao271 -author:sandy081 -author:sbatten -author:stevencl -author:tanhakabir -author:TylerLeonhardt -author:Tyriar -author:weinand -author:amunger"
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found -author:aeschli -author:alexdima -author:alexr00 -author:AmandaSilver -author:andreamah -author:bamurtaugh -author:bpasero -author:chrisdias -author:chrmarti -author:Chuxel -author:claudiaregio -author:connor4312 -author:dbaeumer -author:deepak1556 -author:devinvalenciano -author:digitarald -author:DonJayamanne -author:egamma -author:fiveisprime -author:gregvanl -author:hediet -author:IanMatthewHuff -author:isidorn -author:joaomoreno -author:joyceerhl -author:jrieken -author:karrtikr -author:kieferrm -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:roblourens -author:rzhao271 -author:sandy081 -author:sbatten -author:stevencl -author:tanhakabir -author:TylerLeonhardt -author:Tyriar -author:weinand -author:amunger"
},
{
"kind": 1,
@@ -167,7 +167,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed -author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found"
"value": "$REPOS $MILESTONE -$MINE is:issue is:closed reason:completed -author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:verification-found"
},
{
"kind": 1,
@@ -177,6 +177,6 @@
{
"kind": 2,
"language": "github-issues",
"value": "repo:microsoft/vscode $MILESTONE $MINE is:issue is:closed label:feature-request -label:on-release-notes"
"value": "repo:microsoft/vscode $MILESTONE $MINE is:issue is:closed reason:completed label:feature-request -label:on-release-notes"
}
]
+1 -1
View File
@@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce\n\n// current milestone name\n$milestone=milestone:\"September 2022\""
"value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n\n\n// current milestone name\n$milestone=milestone:\"October 2022\""
},
{
"kind": 1,
+5 -5
View File
@@ -2,7 +2,7 @@
{
"kind": 1,
"language": "markdown",
"value": "### Bug Verification Queries\n\nBefore shipping we want to verify _all_ bugs. That means when a bug is fixed we check that the fix actually works. It's always best to start with bugs that you have filed and the proceed with bugs that have been filed from users outside the development team. "
"value": "### Bug Verification Queries\r\n\r\nBefore shipping we want to verify _all_ bugs. That means when a bug is fixed we check that the fix actually works. It's always best to start with bugs that you have filed and the proceed with bugs that have been filed from users outside the development team. "
},
{
"kind": 1,
@@ -12,7 +12,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-jupyter repo:microsoft/vscode-python\n$milestone=milestone:\"May 2022\""
"value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-l10n\n$milestone=milestone:\"May 2022\""
},
{
"kind": 1,
@@ -22,7 +22,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$repos $milestone is:closed -assignee:@me label:bug -label:verified -label:*duplicate author:@me"
"value": "$repos $milestone is:closed reason:completed -assignee:@me label:bug -label:verified -label:*duplicate author:@me"
},
{
"kind": 1,
@@ -32,7 +32,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$repos $milestone is:closed -assignee:@me label:bug -label:verified -label:*duplicate -author:@me -assignee:@me label:bug -label:verified -author:@me -author:aeschli -author:alexdima -author:alexr00 -author:bpasero -author:chrisdias -author:chrmarti -author:connor4312 -author:dbaeumer -author:deepak1556 -author:eamodio -author:egamma -author:gregvanl -author:isidorn -author:JacksonKearl -author:joaomoreno -author:jrieken -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:RMacfarlane -author:roblourens -author:sana-ajani -author:sandy081 -author:sbatten -author:Tyriar -author:weinand -author:rzhao271 -author:kieferrm -author:TylerLeonhardt -author:bamurtaugh -author:hediet -author:joyceerhl -author:rchiodo -author:IanMatthewHuff"
"value": "$repos $milestone is:closed reason:completed -assignee:@me label:bug -label:verified -label:*duplicate -author:@me -assignee:@me label:bug -label:verified -author:@me -author:aeschli -author:alexdima -author:alexr00 -author:bpasero -author:chrisdias -author:chrmarti -author:connor4312 -author:dbaeumer -author:deepak1556 -author:eamodio -author:egamma -author:gregvanl -author:isidorn -author:JacksonKearl -author:joaomoreno -author:jrieken -author:lramos15 -author:lszomoru -author:meganrogge -author:misolori -author:mjbvz -author:rebornix -author:RMacfarlane -author:roblourens -author:sana-ajani -author:sandy081 -author:sbatten -author:Tyriar -author:weinand -author:rzhao271 -author:kieferrm -author:TylerLeonhardt -author:bamurtaugh -author:hediet -author:joyceerhl -author:rchiodo -author:IanMatthewHuff"
},
{
"kind": 1,
@@ -42,6 +42,6 @@
{
"kind": 2,
"language": "github-issues",
"value": "$repos $milestone is:closed -assignee:@me label:bug -label:verified -label:*duplicate"
"value": "$repos $milestone is:closed reason:completed -assignee:@me label:bug -label:verified -label:*duplicate"
}
]
+3 -7
View File
@@ -53,7 +53,7 @@
"fileMatch": [
"cgmanifest.json"
],
"url": "./.vscode/cgmanifest.schema.json"
"url": "https://json.schemastore.org/component-detection-manifest.json",
},
{
"fileMatch": [
@@ -65,11 +65,12 @@
"git.ignoreLimitWarning": true,
"git.branchProtection": [
"main",
"distro",
"release/*"
],
"git.branchProtectionPrompt": "alwaysCommitToNewBranch",
"git.branchRandomName.enable": true,
"git.fetchBeforeCheckout": true,
"git.pullBeforeCheckout": true,
"git.mergeEditor": true,
"remote.extensionKind": {
"msjsdiag.debugger-for-chrome": "workspace"
@@ -106,11 +107,6 @@
"git",
"sash"
],
"editor.quickSuggestions": {
"other": "inline",
"comments": "inline",
"strings": "inline"
},
"githubPullRequests.assignCreated": "${user}",
"githubPullRequests.defaultMergeMethod": "squash"
}
+22
View File
@@ -203,6 +203,28 @@
"reveal": "never"
}
},
{
"type": "shell",
"command": "./scripts/code-web.sh",
"windows": {
"command": ".\\scripts\\code-web.bat"
},
"args": ["--port", "8080", "--browser", "none"],
"label": "Run code web",
"isBackground": true,
"problemMatcher": {
"pattern": {
"regexp": ""
},
"background": {
"beginsPattern": ".*node .*",
"endsPattern": "Listening on .*"
}
},
"presentation": {
"reveal": "never"
}
},
{
"type": "npm",
"script": "eslint",
+3 -3
View File
@@ -58,10 +58,10 @@ VS Code includes a set of built-in extensions located in the [extensions](extens
## Development Container
This repository includes a Visual Studio Code Remote - Containers / GitHub Codespaces development container.
This repository includes a Visual Studio Code Dev Containers / GitHub Codespaces development container.
- For [Remote - Containers](https://aka.ms/vscode-remote/download/containers), use the **Remote-Containers: Clone Repository in Container Volume...** command which creates a Docker volume for better disk I/O on macOS and Windows.
- If you already have VS Code and Docker installed, you can also click [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. This will cause VS Code to automatically install the Remote - Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
- For [Dev Containers](https://aka.ms/vscode-remote/download/containers), use the **Dev Containers: Clone Repository in Container Volume...** command which creates a Docker volume for better disk I/O on macOS and Windows.
- If you already have VS Code and Docker installed, you can also click [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode) to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
- For Codespaces, install the [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) extension in VS Code, and use the **Codespaces: Create New Codespace** command.
Docker / the Codespace should have at least **4 Cores and 6 GB of RAM (8 GB recommended)** to run full build. See the [development container README](.devcontainer/README.md) for more information.
+430 -362
View File
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,50 @@
parameters:
- name: VSCODE_CLI_TARGET
type: string
- name: VSCODE_CLI_ARTIFACT
type: string
- name: VSCODE_CLI_ENV
type: object
default: {}
steps:
- script: cargo build --release --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code-tunnel
displayName: Compile ${{ parameters.VSCODE_CLI_TARGET }}
workingDirectory: $(Build.SourcesDirectory)/cli
env:
VSCODE_CLI_VERSION: $(VSCODE_CLI_VERSION)
VSCODE_CLI_REMOTE_LICENSE_TEXT: $(VSCODE_CLI_REMOTE_LICENSE_TEXT)
VSCODE_CLI_REMOTE_LICENSE_PROMPT: $(VSCODE_CLI_REMOTE_LICENSE_PROMPT)
VSCODE_CLI_ASSET_NAME: ${{ parameters.VSCODE_CLI_ARTIFACT }}
VSCODE_CLI_AI_KEY: $(VSCODE_CLI_AI_KEY)
VSCODE_CLI_AI_ENDPOINT: $(VSCODE_CLI_AI_ENDPOINT)
${{ each pair in parameters.VSCODE_CLI_ENV }}:
${{ pair.key }}: ${{ pair.value }}
- ${{ if or(contains(parameters.VSCODE_CLI_TARGET, '-windows-'), contains(parameters.VSCODE_CLI_TARGET, '-darwin')) }}:
- task: ArchiveFiles@2
inputs:
${{ if contains(parameters.VSCODE_CLI_TARGET, '-windows-') }}:
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code-tunnel.exe
${{ if contains(parameters.VSCODE_CLI_TARGET, '-darwin') }}:
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code-tunnel
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.VSCODE_CLI_ARTIFACT }}.zip
- publish: $(Build.ArtifactStagingDirectory)/${{ parameters.VSCODE_CLI_ARTIFACT }}.zip
artifact: ${{ parameters.VSCODE_CLI_ARTIFACT }}
displayName: Publish ${{ parameters.VSCODE_CLI_ARTIFACT }} artifact
- ${{ else }}:
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code-tunnel
includeRootFolder: false
archiveType: tar
tarCompression: gz
archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.VSCODE_CLI_ARTIFACT }}.tar.gz
- publish: $(Build.ArtifactStagingDirectory)/${{ parameters.VSCODE_CLI_ARTIFACT }}.tar.gz
artifact: ${{ parameters.VSCODE_CLI_ARTIFACT }}
displayName: Publish ${{ parameters.VSCODE_CLI_ARTIFACT }} artifact
@@ -0,0 +1,40 @@
parameters:
- name: VSCODE_CLI_ARTIFACTS
type: object
default: []
steps:
- task: UseDotNet@2
inputs:
version: 2.x
- task: EsrpClientTool@1
displayName: Download ESRPClient
- ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}:
- task: DownloadPipelineArtifact@2
displayName: Download ${{ target }}
inputs:
artifact: ${{ target }}
path: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}
- script: |
set -e
node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" darwin-sign $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Build.ArtifactStagingDirectory)/pkg "*.zip"
displayName: Codesign
- script: |
set -e
node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" darwin-notarize $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Build.ArtifactStagingDirectory)/pkg "*.zip"
displayName: Notarize
- ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}:
- script: |
set -e
ASSET_ID=$(echo "${{ target }}" | sed "s/unsigned_//")
mv $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/${{ target }}.zip $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/$ASSET_ID.zip
echo "##vso[task.setvariable variable=ASSET_ID]$ASSET_ID"
displayName: Set asset id variable
- publish: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/$(ASSET_ID).zip
artifact: $(ASSET_ID)
@@ -0,0 +1,65 @@
parameters:
- name: VSCODE_CLI_ARTIFACTS
type: object
default: []
steps:
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "ESRP-PKI,esrp-aad-username,esrp-aad-password"
- task: UseDotNet@2
displayName: "Use .NET"
inputs:
version: 3.x
- task: EsrpClientTool@1
displayName: "Use ESRP client"
- ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}:
- task: DownloadPipelineArtifact@2
displayName: Download artifacts
inputs:
artifact: ${{ target }}
path: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}
- task: ExtractFiles@1
inputs:
archiveFilePatterns: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/*.zip
destinationFolder: $(Build.ArtifactStagingDirectory)/sign/${{ target }}
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$EsrpClientTool = (gci -directory -filter EsrpClientTool_* $(Agent.RootDirectory)\_tasks | Select-Object -last 1).FullName
$EsrpCliZip = (gci -recurse -filter esrpcli.*.zip $EsrpClientTool | Select-Object -last 1).FullName
mkdir -p $(Agent.TempDirectory)\esrpcli
Expand-Archive -Path $EsrpCliZip -DestinationPath $(Agent.TempDirectory)\esrpcli
$EsrpCliDllPath = (gci -recurse -filter esrpcli.dll $(Agent.TempDirectory)\esrpcli | Select-Object -last 1).FullName
echo "##vso[task.setvariable variable=EsrpCliDllPath]$EsrpCliDllPath"
displayName: Find ESRP CLI
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { node build\azure-pipelines\common\sign $env:EsrpCliDllPath windows $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Build.ArtifactStagingDirectory)/sign "*.exe" }
displayName: "Code sign"
- ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}:
- powershell: |
$ASSET_ID = "${{ target }}".replace("unsigned_", "");
echo "##vso[task.setvariable variable=ASSET_ID]$ASSET_ID"
displayName: Set asset id variable
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: $(Build.ArtifactStagingDirectory)/sign/${{ target }}/code-tunnel.exe
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(ASSET_ID).zip
- publish: $(Build.ArtifactStagingDirectory)/$(ASSET_ID).zip
artifact: $(ASSET_ID)
@@ -1,52 +0,0 @@
parameters:
- name: VSCODE_CLI_TARGETS
default: []
type: object
- name: VSCODE_CLI_DIR
type: string
default: './'
- name: VSCODE_CLI_BINARY_NAME
type: string
- name: VSCODE_QUALITY
type: string
- name: channel
type: string
default: stable
steps:
# inspired by: https://github.com/emk/rust-musl-builder/blob/main/Dockerfile
- bash: |
sudo apt-get update
sudo apt-get install -yq build-essential cmake curl file git graphviz musl-dev musl-tools linux-libc-dev pkgconf unzip xutils-dev
sudo ln -s "/usr/bin/g++" "/usr/bin/musl-g++" || echo "link exists"
displayName: Install build dependencies
- template: ./install-rust.yml
parameters:
targets: ${{ parameters.VSCODE_CLI_TARGETS }}
channel: ${{ parameters.channel }}
- template: ./cli/prepare.yml
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_IS_POSIX: true
- ${{ each target in parameters.VSCODE_CLI_TARGETS }}:
- script: cargo build --release --target ${{ target.target }} --bin=${{ parameters.VSCODE_CLI_BINARY_NAME }}
displayName: Compile ${{ target.artifact }}
workingDirectory: ${{ parameters.VSCODE_CLI_DIR }}
env:
VSCODE_CLI_VERSION: $(VSCODE_CLI_VERSION)
VSCODE_CLI_REMOTE_LICENSE_TEXT: $(VSCODE_CLI_REMOTE_LICENSE_TEXT)
VSCODE_CLI_REMOTE_LICENSE_PROMPT: $(VSCODE_CLI_REMOTE_LICENSE_PROMPT)
VSCODE_CLI_ASSET_NAME: ${{ target.artifact }}
VSCODE_CLI_AI_KEY: $(VSCODE_CLI_AI_KEY)
VSCODE_CLI_AI_ENDPOINT: $(VSCODE_CLI_AI_ENDPOINT)
VSCODE_CLI_COMMIT: $(VSCODE_CLI_COMMIT)
VSCODE_CLI_QUALITY: $(VSCODE_QUALITY)
CXX_aarch64-unknown-linux-musl: musl-g++
CC_aarch64-unknown-linux-musl: musl-gcc
- publish: ${{ parameters.VSCODE_CLI_DIR }}/target/${{ target.target }}/release/${{ parameters.VSCODE_CLI_BINARY_NAME }}
artifact: ${{ target.artifact }}
displayName: Publish ${{ target.artifact }} artifact
@@ -1,43 +0,0 @@
parameters:
- name: VSCODE_CLI_TARGETS
default: []
type: object
- name: VSCODE_CLI_DIR
type: string
default: './'
- name: VSCODE_CLI_BINARY_NAME
type: string
- name: VSCODE_QUALITY
type: string
- name: channel
type: string
default: stable
steps:
- template: ./install-rust.yml
parameters:
targets: ${{ parameters.VSCODE_CLI_TARGETS }}
channel: ${{ parameters.channel }}
- template: ./cli/prepare.yml
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_IS_POSIX: true
- ${{ each target in parameters.VSCODE_CLI_TARGETS }}:
- script: cargo build --release --target ${{ target.target }} --bin=${{ parameters.VSCODE_CLI_BINARY_NAME }}
displayName: Compile ${{ target.artifact }}
workingDirectory: ${{ parameters.VSCODE_CLI_DIR }}
env:
VSCODE_CLI_VERSION: $(VSCODE_CLI_VERSION)
VSCODE_CLI_REMOTE_LICENSE_TEXT: $(VSCODE_CLI_REMOTE_LICENSE_TEXT)
VSCODE_CLI_REMOTE_LICENSE_PROMPT: $(VSCODE_CLI_REMOTE_LICENSE_PROMPT)
VSCODE_CLI_ASSET_NAME: ${{ target.artifact }}
VSCODE_CLI_AI_KEY: $(VSCODE_CLI_AI_KEY)
VSCODE_CLI_AI_ENDPOINT: $(VSCODE_CLI_AI_ENDPOINT)
VSCODE_CLI_COMMIT: $(VSCODE_CLI_COMMIT)
VSCODE_CLI_QUALITY: $(VSCODE_QUALITY)
- publish: ${{ parameters.VSCODE_CLI_DIR }}/target/${{ target.target }}/release/${{ parameters.VSCODE_CLI_BINARY_NAME }}
artifact: ${{ target.artifact }}
displayName: Publish ${{ target.artifact }} artifact
@@ -1,49 +0,0 @@
parameters:
- name: VSCODE_CLI_TARGETS
default: []
type: object
- name: VSCODE_CLI_DIR
type: string
default: './'
- name: VSCODE_CLI_BINARY_NAME
type: string
- name: VSCODE_QUALITY
type: string
- name: channel
type: string
default: stable
steps:
- template: ./install-rust.yml
parameters:
targets: ${{ parameters.VSCODE_CLI_TARGETS }}
channel: ${{ parameters.channel }}
- template: ./cli/prepare.yml
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_IS_POSIX: false
- ${{ each target in parameters.VSCODE_CLI_TARGETS }}:
- script: cargo build --release --target ${{ target.target }} --bin=${{ parameters.VSCODE_CLI_BINARY_NAME }}
displayName: Compile ${{ target.artifact }}
workingDirectory: ${{ parameters.VSCODE_CLI_DIR }}
env:
VSCODE_CLI_VERSION: $(VSCODE_CLI_VERSION)
VSCODE_CLI_REMOTE_LICENSE_TEXT: $(VSCODE_CLI_REMOTE_LICENSE_TEXT)
VSCODE_CLI_REMOTE_LICENSE_PROMPT: $(VSCODE_CLI_REMOTE_LICENSE_PROMPT)
VSCODE_CLI_ASSET_NAME: ${{ target.artifact }}
VSCODE_CLI_AI_KEY: $(VSCODE_CLI_AI_KEY)
VSCODE_CLI_AI_ENDPOINT: $(VSCODE_CLI_AI_ENDPOINT)
VSCODE_CLI_COMMIT: $(VSCODE_CLI_COMMIT)
VSCODE_CLI_QUALITY: $(VSCODE_QUALITY)
${{ if eq(target, 'x86_64-pc-windows-msvc') }}:
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/deps/x64-windows-static-md/lib
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/deps/x64-windows-static-md/include
${{ if eq(target, 'aarch64-pc-windows-msvc') }}:
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/deps/arm64-windows-static-md/lib
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/deps/arm64-windows-static-md/include
- publish: ${{ parameters.VSCODE_CLI_DIR }}/target/${{ target.target }}/release/${{ parameters.VSCODE_CLI_BINARY_NAME }}.exe
artifact: ${{ target.artifact }}
displayName: Publish ${{ target.artifact }} artifact
@@ -15,20 +15,10 @@ steps:
echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin"
env:
RUSTUP_TOOLCHAIN: ${{ parameters.channel }}
condition: not(eq(variables['Agent.OS'], 'Windows_NT'))
displayName: "Install Rust"
- script: |
curl -sSf -o rustup-init.exe https://win.rustup.rs
rustup-init.exe -y --profile minimal --default-toolchain %RUSTUP_TOOLCHAIN% --default-host x86_64-pc-windows-msvc
set PATH=%PATH%;%USERPROFILE%\.cargo\bin
echo "##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin"
env:
RUSTUP_TOOLCHAIN: ${{ parameters.channel }}
condition: eq(variables['Agent.OS'], 'Windows_NT')
displayName: "Install Rust"
- bash: |
set -e
rustup default $RUSTUP_TOOLCHAIN
rustup update $RUSTUP_TOOLCHAIN
env:
@@ -36,10 +26,11 @@ steps:
displayName: "Set Rust version"
- ${{ each target in parameters.targets }}:
- script: rustup target add ${{ target.target }}
displayName: "🎯 Adding '${{ target.target }}'"
- script: rustup target add ${{ target }}
displayName: "Adding Rust target '${{ target }}'"
- script: |
set -e
rustc --version
cargo --version
rustup --version
@@ -0,0 +1,38 @@
parameters:
- name: channel
type: string
default: stable
- name: targets
default: []
type: object
# Todo: use 1ES pipeline once extension is installed in ADO
steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
exec { curl -sSf -o rustup-init.exe https://win.rustup.rs }
exec { rustup-init.exe -y --profile minimal --default-toolchain %RUSTUP_TOOLCHAIN% --default-host x86_64-pc-windows-msvc }
echo "##vso[task.prependpath]$env:USERPROFILE\.cargo\bin"
env:
RUSTUP_TOOLCHAIN: ${{ parameters.channel }}
displayName: "Install Rust"
- powershell: |
. build/azure-pipelines/win32/exec.ps1
exec { rustup default $RUSTUP_TOOLCHAIN }
exec { rustup update $RUSTUP_TOOLCHAIN }
env:
RUSTUP_TOOLCHAIN: ${{ parameters.channel }}
displayName: "Set Rust version"
- ${{ each target in parameters.targets }}:
- script: rustup target add ${{ target }}
displayName: "Adding Rust target '${{ target }}'"
- powershell: |
. build/azure-pipelines/win32/exec.ps1
exec { rustc --version }
exec { cargo --version }
exec { rustup --version }
displayName: "Check Rust versions"
+3 -47
View File
@@ -6,35 +6,11 @@
Object.defineProperty(exports, "__esModule", { value: true });
const getVersion_1 = require("../../lib/getVersion");
const fs = require("fs");
const cp = require("child_process");
const path = require("path");
const packageJson = require("../../../package.json");
const os_1 = require("os");
const root = path.dirname(path.dirname(path.dirname(__dirname)));
const cliPath = path.join(root, 'cli');
const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'));
const commit = (0, getVersion_1.getVersion)(root);
const getCargoLines = () => {
const fpath = path.join(cliPath, 'Cargo.toml');
const cargo = fs.readFileSync(fpath, 'utf-8').split(/\r?\n/g);
return [fpath, cargo];
};
const addCargoDependency = (line) => {
const [fpath, cargo] = getCargoLines();
const depsLine = cargo.findIndex(line => line.includes('[dependencies]'));
cargo.splice(depsLine + 1, 0, line);
fs.writeFileSync(fpath, cargo.join('\n'));
};
const enableFeature = (feature) => {
const [fpath, cargo] = getCargoLines();
const featuresLine = cargo.findIndex(line => line.includes('[features]'));
const prefix = 'default = ';
const defaultFeaturesLine = cargo.findIndex((line, i) => i > featuresLine && line.startsWith(prefix));
const defaultFeatures = new Set(JSON.parse(cargo[defaultFeaturesLine].slice(prefix.length)));
defaultFeatures.add(feature);
cargo[defaultFeaturesLine] = prefix + JSON.stringify([...defaultFeatures]);
fs.writeFileSync(fpath, cargo.join('\n'));
};
/**
* Sets build environment variables for the CLI for current contextual info.
*/
@@ -51,26 +27,6 @@ const setLauncherEnvironmentVars = () => {
}
}
};
/**
* Enables vscode-encrypt in the CLI if it's available in the current node_modules.
* This is not graceful since Cargo doesn't have a good way to do private or
* true-optional dependencies...
*/
const enableVscodeEncrypt = () => {
const dep = packageJson.dependencies['vscode-encrypt'];
if (!dep) {
return;
}
// If there's a vscode-encrypt in the package.json, install that (alone) in
// a temp dir for the build. This avoids having to do a full install of all
// node modules while building the CLI.
const stagingDir = path.join((0, os_1.tmpdir)(), `vscode-encrypt-staging-${Date.now()}`);
fs.mkdirSync(stagingDir);
fs.writeFileSync(path.join(stagingDir, 'package.json'), JSON.stringify({ dependencies: { 'vscode-encrypt': dep } }));
cp.execSync('yarn', { cwd: stagingDir, stdio: 'inherit' });
const encryptPath = path.join(stagingDir, 'node_modules', 'vscode-encrypt', 'rs-pure');
addCargoDependency(`vscode-encrypt = { "path" = "${encryptPath.replace(/\\/g, '/')}" }`);
enableFeature('vscode-encrypt');
};
setLauncherEnvironmentVars();
enableVscodeEncrypt();
if (require.main === module) {
setLauncherEnvironmentVars();
}
+7 -55
View File
@@ -5,49 +5,24 @@
import { getVersion } from '../../lib/getVersion';
import * as fs from 'fs';
import * as cp from 'child_process';
import * as path from 'path';
import * as packageJson from '../../../package.json';
import { tmpdir } from 'os';
const root = path.dirname(path.dirname(path.dirname(__dirname)));
const cliPath = path.join(root, 'cli');
const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'));
const commit = getVersion(root);
const getCargoLines = () => {
const fpath = path.join(cliPath, 'Cargo.toml');
const cargo = fs.readFileSync(fpath, 'utf-8').split(/\r?\n/g);
return [fpath, cargo] as const;
};
const addCargoDependency = (line: string) => {
const [fpath, cargo] = getCargoLines();
const depsLine = cargo.findIndex(line => line.includes('[dependencies]'));
cargo.splice(depsLine + 1, 0, line);
fs.writeFileSync(fpath, cargo.join('\n'));
};
const enableFeature = (feature: string) => {
const [fpath, cargo] = getCargoLines();
const featuresLine = cargo.findIndex(line => line.includes('[features]'));
const prefix = 'default = ';
const defaultFeaturesLine = cargo.findIndex((line, i) => i > featuresLine && line.startsWith(prefix));
const defaultFeatures = new Set(JSON.parse(cargo[defaultFeaturesLine].slice(prefix.length)));
defaultFeatures.add(feature);
cargo[defaultFeaturesLine] = prefix + JSON.stringify([...defaultFeatures]);
fs.writeFileSync(fpath, cargo.join('\n'));
};
/**
* Sets build environment variables for the CLI for current contextual info.
*/
const setLauncherEnvironmentVars = () => {
const vars = new Map([
['VSCODE_CLI_REMOTE_LICENSE_TEXT', product.serverLicense],
['VSCODE_CLI_REMOTE_LICENSE_TEXT', product.serverLicense?.join('\r\n')],
['VSCODE_CLI_REMOTE_LICENSE_PROMPT', product.serverLicensePrompt],
['VSCODE_CLI_AI_KEY', product.aiConfig?.cliKey],
['VSCODE_CLI_AI_ENDPOINT', product.aiConfig?.cliEndpoint],
['VSCODE_CLI_VERSION', packageJson.version],
['VSCODE_CLI_QUALIY', product.quality],
['VSCODE_CLI_COMMIT', commit],
]);
@@ -58,29 +33,6 @@ const setLauncherEnvironmentVars = () => {
}
};
/**
* Enables vscode-encrypt in the CLI if it's available in the current node_modules.
* This is not graceful since Cargo doesn't have a good way to do private or
* true-optional dependencies...
*/
const enableVscodeEncrypt = () => {
const dep = (packageJson.dependencies as Record<string, string>)['vscode-encrypt'];
if (!dep) {
return;
}
// If there's a vscode-encrypt in the package.json, install that (alone) in
// a temp dir for the build. This avoids having to do a full install of all
// node modules while building the CLI.
const stagingDir = path.join(tmpdir(), `vscode-encrypt-staging-${Date.now()}`);
fs.mkdirSync(stagingDir);
fs.writeFileSync(path.join(stagingDir, 'package.json'), JSON.stringify({ dependencies: { 'vscode-encrypt': dep } }));
cp.execSync('yarn', { cwd: stagingDir, stdio: 'inherit' });
const encryptPath = path.join(stagingDir, 'node_modules', 'vscode-encrypt', 'rs-pure');
addCargoDependency(`vscode-encrypt = { "path" = "${encryptPath.replace(/\\/g, '/')}" }`);
enableFeature('vscode-encrypt');
};
setLauncherEnvironmentVars();
enableVscodeEncrypt();
if (require.main === module) {
setLauncherEnvironmentVars();
}
-35
View File
@@ -1,35 +0,0 @@
parameters:
- name: VSCODE_IS_POSIX
type: boolean
- name: VSCODE_QUALITY
type: string
steps:
- task: NodeTool@0
inputs:
versionSpec: "16.x"
- ${{ if eq(parameters.VSCODE_IS_POSIX, true) }}:
- template: ../mixin-distro-posix.yml
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
- script: |
set -e
node build/azure-pipelines/cli/prepare.js
displayName: Prepare CLI build
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
- ${{ if ne(parameters.VSCODE_IS_POSIX, true) }}:
- template: ../mixin-distro-win32.yml
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { node build/azure-pipelines/cli/prepare.js }
displayName: Prepare CLI build
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
+1 -6
View File
@@ -2,17 +2,12 @@ parameters:
- name: VSCODE_CLI_TARGETS
default: []
type: object
- name: VSCODE_CLI_DIR
type: string
default: './'
- name: VSCODE_CLI_BINARY_NAME
type: string
- name: VSCODE_CLI_RUST_CHANNEL
type: string
default: stable
steps:
- template: ./install-rust.yml
- template: ./install-rust-posix.yml
parameters:
targets: []
channel: ${{ parameters.VSCODE_CLI_RUST_CHANNEL }}
+3 -7
View File
@@ -15,7 +15,6 @@ if (process.argv.length !== 8) {
console.error('Usage: node createAsset.js PRODUCT OS ARCH TYPE NAME FILE');
process.exit(-1);
}
const Ignore = Symbol('Ignore');
// Contains all of the logic for mapping details to our actual product names in CosmosDB
function getPlatform(product, os, arch, type) {
switch (os) {
@@ -45,7 +44,7 @@ function getPlatform(product, os, arch, type) {
}
return arch === 'ia32' ? 'server-win32-web' : `server-win32-${arch}-web`;
case 'cli':
return type === 'cli-unsigned' ? Ignore : `cli-win32-${arch}`;
return `cli-win32-${arch}`;
default:
throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`);
}
@@ -79,7 +78,7 @@ function getPlatform(product, os, arch, type) {
return `linux-deb-${arch}`;
case 'rpm-package':
return `linux-rpm-${arch}`;
case 'cli-unsigned':
case 'cli':
return `cli-linux-${arch}`;
default:
throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`);
@@ -102,7 +101,7 @@ function getPlatform(product, os, arch, type) {
}
return `server-darwin-${arch}-web`;
case 'cli':
return type === 'cli-unsigned' ? Ignore : `cli-darwin-${arch}`;
return `cli-darwin-${arch}`;
default:
throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`);
}
@@ -142,9 +141,6 @@ async function main() {
const [, , product, os, arch, unprocessedType, fileName, filePath] = process.argv;
// getPlatform needs the unprocessedType
const platform = getPlatform(product, os, arch, unprocessedType);
if (platform === Ignore) {
return;
}
const type = getRealType(unprocessedType);
const quality = getEnv('VSCODE_QUALITY');
const commit = process.env['VSCODE_DISTRO_COMMIT'] || getEnv('BUILD_SOURCEVERSION');
+4 -10
View File
@@ -28,10 +28,8 @@ if (process.argv.length !== 8) {
process.exit(-1);
}
const Ignore = Symbol('Ignore');
// Contains all of the logic for mapping details to our actual product names in CosmosDB
function getPlatform(product: string, os: string, arch: string, type: string): string | typeof Ignore {
function getPlatform(product: string, os: string, arch: string, type: string): string {
switch (os) {
case 'win32':
switch (product) {
@@ -59,7 +57,7 @@ function getPlatform(product: string, os: string, arch: string, type: string): s
}
return arch === 'ia32' ? 'server-win32-web' : `server-win32-${arch}-web`;
case 'cli':
return type === 'cli-unsigned' ? Ignore : `cli-win32-${arch}`;
return `cli-win32-${arch}`;
default:
throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`);
}
@@ -93,7 +91,7 @@ function getPlatform(product: string, os: string, arch: string, type: string): s
return `linux-deb-${arch}`;
case 'rpm-package':
return `linux-rpm-${arch}`;
case 'cli-unsigned':
case 'cli':
return `cli-linux-${arch}`;
default:
throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`);
@@ -116,7 +114,7 @@ function getPlatform(product: string, os: string, arch: string, type: string): s
}
return `server-darwin-${arch}-web`;
case 'cli':
return type === 'cli-unsigned' ? Ignore : `cli-darwin-${arch}`;
return `cli-darwin-${arch}`;
default:
throw new Error(`Unrecognized: ${product} ${os} ${arch} ${type}`);
}
@@ -163,10 +161,6 @@ async function main(): Promise<void> {
const [, , product, os, arch, unprocessedType, fileName, filePath] = process.argv;
// getPlatform needs the unprocessedType
const platform = getPlatform(product, os, arch, unprocessedType);
if (platform === Ignore) {
return;
}
const type = getRealType(unprocessedType);
const quality = getEnv('VSCODE_QUALITY');
const commit = process.env['VSCODE_DISTRO_COMMIT'] || getEnv('BUILD_SOURCEVERSION');
+10 -7
View File
@@ -28,22 +28,25 @@ async function getConfig(client, quality) {
}
return res.resources[0];
}
async function main() {
async function main(force) {
const commit = process.env['VSCODE_DISTRO_COMMIT'] || getEnv('BUILD_SOURCEVERSION');
const quality = getEnv('VSCODE_QUALITY');
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) {
console.log(`Skipping release because quality ${quality} is frozen.`);
return;
if (!force) {
const config = await getConfig(client, quality);
console.log('Quality config:', config);
if (config.frozen) {
console.log(`Skipping release because quality ${quality} is frozen.`);
return;
}
}
console.log(`Releasing build ${commit}...`);
const scripts = client.database('builds').container(quality).scripts;
await (0, retry_1.retry)(() => scripts.storedProcedure('releaseBuild').execute('', [commit]));
}
main().then(() => {
const [, , force] = process.argv;
main(force === 'true').then(() => {
console.log('Build successfully released');
process.exit(0);
}, err => {
+12 -7
View File
@@ -41,19 +41,22 @@ async function getConfig(client: CosmosClient, quality: string): Promise<Config>
return res.resources[0] as Config;
}
async function main(): Promise<void> {
async function main(force: boolean): Promise<void> {
const commit = process.env['VSCODE_DISTRO_COMMIT'] || getEnv('BUILD_SOURCEVERSION');
const quality = getEnv('VSCODE_QUALITY');
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);
if (!force) {
const config = await getConfig(client, quality);
if (config.frozen) {
console.log(`Skipping release because quality ${quality} is frozen.`);
return;
console.log('Quality config:', config);
if (config.frozen) {
console.log(`Skipping release because quality ${quality} is frozen.`);
return;
}
}
console.log(`Releasing build ${commit}...`);
@@ -62,7 +65,9 @@ async function main(): Promise<void> {
await retry(() => scripts.storedProcedure('releaseBuild').execute('', [commit]));
}
main().then(() => {
const [, , force] = process.argv;
main(force === 'true').then(() => {
console.log('Build successfully released');
process.exit(0);
}, err => {
@@ -0,0 +1,46 @@
parameters:
- name: VSCODE_QUALITY
type: string
- name: VSCODE_BUILD_MACOS
type: boolean
- name: VSCODE_BUILD_MACOS_ARM64
type: boolean
- name: channel
type: string
default: stable
steps:
- task: NodeTool@0
inputs:
versionSpec: "16.x"
- template: ../mixin-distro-posix.yml
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
- script: |
set -e
node build/azure-pipelines/cli/prepare.js
displayName: Prepare CLI build
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
- template: ../cli/install-rust-posix.yml
parameters:
targets:
- ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}:
- x86_64-apple-darwin
- ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}:
- aarch64-apple-darwin
- ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}:
- template: ../cli/cli-compile-and-publish.yml
parameters:
VSCODE_CLI_TARGET: x86_64-apple-darwin
VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_darwin_x64_cli
- ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}:
- template: ../cli/cli-compile-and-publish.yml
parameters:
VSCODE_CLI_TARGET: aarch64-apple-darwin
VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_darwin_arm64_cli
@@ -1,9 +1,8 @@
parameters:
- name: VSCODE_CLI_BINARY_NAME
type: string
- name: VSCODE_CLI_ARTIFACTS
default: []
type: object
- name: VSCODE_BUILD_MACOS
type: boolean
- name: VSCODE_BUILD_MACOS_ARM64
type: boolean
steps:
- task: NodeTool@0
@@ -19,7 +18,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -37,43 +36,10 @@ steps:
done
displayName: Install build dependencies
- ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}:
- task: DownloadPipelineArtifact@2
displayName: Download ${{ target }}
inputs:
artifact: ${{ target }}
path: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}
- script: |
set -e
mkdir -p $(agent.builddirectory)/signing
zip -j $(agent.builddirectory)/signing/${{ target }}.zip $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/${{ parameters.VSCODE_CLI_BINARY_NAME }}
displayName: Prepare ${{ target }} archive
- task: UseDotNet@2
inputs:
version: 2.x
- task: EsrpClientTool@1
displayName: Download ESRPClient
- script: |
set -e
node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" darwin-sign $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(agent.builddirectory)/signing "*.zip"
displayName: Codesign
- script: |
set -e
node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" darwin-notarize $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(agent.builddirectory)/signing "*.zip"
displayName: Notarize
- ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}:
- script: |
ASSET_ID=$(echo "${{ target }}" | sed "s/-unsigned//")
mkdir -p $(Build.ArtifactStagingDirectory)/final/${{ target }}
unzip $(agent.builddirectory)/signing/${{ target }}.zip -d $(Build.ArtifactStagingDirectory)/final/${{ target }}
echo "##vso[task.setvariable variable=ASSET_ID]$ASSET_ID"
displayName: Set asset id variable
- publish: $(Build.ArtifactStagingDirectory)/final/${{ target }}/${{ parameters.VSCODE_CLI_BINARY_NAME }}
artifact: $(ASSET_ID)
- template: ../cli/cli-darwin-sign.yml
parameters:
VSCODE_CLI_ARTIFACTS:
- ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}:
- unsigned_vscode_cli_darwin_x64_cli
- ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}:
- unsigned_vscode_cli_darwin_arm64_cli
@@ -69,7 +69,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -69,7 +69,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -9,71 +9,67 @@ parameters:
type: boolean
- name: VSCODE_RUN_SMOKE_TESTS
type: boolean
- name: VSCODE_CLI_ARTIFACT
type: string
default: ''
- name: VSCODE_CLI_BINARY_NAME
type: string
default: ''
- name: VSCODE_BUILD_TUNNEL_CLI
type: boolean
steps:
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- checkout: self
fetchDepth: 1
retryCountOnTaskFailure: 3
- checkout: self
fetchDepth: 1
retryCountOnTaskFailure: 3
- task: NodeTool@0
inputs:
versionSpec: "16.x"
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key"
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: DownloadPipelineArtifact@2
inputs:
artifact: Compilation
path: $(Build.ArtifactStagingDirectory)
displayName: Download compilation output
- task: DownloadPipelineArtifact@2
inputs:
artifact: Compilation
path: $(Build.ArtifactStagingDirectory)
displayName: Download compilation output
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz
displayName: Extract compilation output
- script: |
set -e
tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz
displayName: Extract compilation output
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(github-distro-mixin-password)
EOF
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(github-distro-mixin-password)
EOF
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
displayName: Prepare tooling
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
displayName: Prepare tooling
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF
echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)"
git checkout FETCH_HEAD
condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' '))
displayName: Checkout override commit
- script: |
set -e
git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF
echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)"
git checkout FETCH_HEAD
condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' '))
displayName: Checkout override commit
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- 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
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
mkdir -p .build
@@ -102,7 +98,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -144,40 +140,40 @@ steps:
displayName: Create node_modules archive
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
# This script brings in the right resources (images, icons, etc) based on the quality (insiders, stable, exploration)
- script: |
set -e
node build/azure-pipelines/mixin
displayName: Mix in quality
# This script brings in the right resources (images, icons, etc) based on the quality (insiders, stable, exploration)
- script: |
set -e
node build/azure-pipelines/mixin
displayName: Mix in quality
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-darwin-$(VSCODE_ARCH)-min-ci
displayName: Build client
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-darwin-$(VSCODE_ARCH)-min-ci
displayName: Build client
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
node build/azure-pipelines/mixin --server
displayName: Mix in server quality
- script: |
set -e
node build/azure-pipelines/mixin --server
displayName: Mix in server quality
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci
displayName: Build Server
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci
displayName: Build Server
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp "transpile-client-swc" "transpile-extensions"
displayName: Transpile
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp "transpile-client-swc" "transpile-extensions"
displayName: Transpile
- script: |
set -e
@@ -186,122 +182,133 @@ steps:
echo "##vso[task.setvariable variable=APP_PATH]$APP_ROOT/$APP_NAME"
displayName: Find application path
- ${{ if ne(parameters.VSCODE_CLI_ARTIFACT, '') }}:
- task: DownloadPipelineArtifact@2
inputs:
artifact: ${{ parameters.VSCODE_CLI_ARTIFACT }}
patterns: '**'
path: $(APP_PATH)/Contents/Resources/app/bin
displayName: Download VS Code CLI
- ${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
- task: DownloadPipelineArtifact@2
inputs:
artifact: unsigned_vscode_cli_darwin_arm64_cli
patterns: "**"
path: $(Build.ArtifactStagingDirectory)/cli
displayName: Download VS Code CLI
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- script: |
set -e
chmod +x "$(APP_PATH)/Contents/Resources/app/bin/$(VSCODE_CLI_BINARY_NAME)"
if [ "$(VSCODE_QUALITY)" != "stable" ]; then
mv "$(APP_PATH)/Contents/Resources/app/bin/$(VSCODE_CLI_BINARY_NAME)" "$(APP_PATH)/Contents/Resources/app/bin/$(VSCODE_CLI_BINARY_NAME)-$(VSCODE_QUALITY)"
fi
displayName: Make CLI executable
- task: DownloadPipelineArtifact@2
inputs:
artifact: unsigned_vscode_cli_darwin_x64_cli
patterns: "**"
path: $(Build.ArtifactStagingDirectory)/cli
displayName: Download VS Code CLI
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))
- script: |
set -e
ARCHIVE_NAME=$(ls "$(Build.ArtifactStagingDirectory)/cli" | head -n 1)
unzip "$(Build.ArtifactStagingDirectory)/cli/$ARCHIVE_NAME" -d "$(APP_PATH)/Contents/Resources/app/bin"
chmod +x "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel"
if [ "$(VSCODE_QUALITY)" != "stable" ]; then
mv "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel" "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel-$(VSCODE_QUALITY)"
fi
displayName: Make CLI executable
- ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}:
- template: product-build-darwin-test.yml
parameters:
VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }}
VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }}
VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }}
- template: product-build-darwin-test.yml
parameters:
VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }}
VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }}
VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }}
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
# Setting hardened entitlements is a requirement for:
# * Apple notarization
# * Running tests on Big Sur (because Big Sur has additional security precautions)
- script: |
set -e
security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain
security default-keychain -s $(agent.tempdirectory)/buildagent.keychain
security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain
echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12
security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain
VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js
displayName: Set Hardened Entitlements
# Setting hardened entitlements is a requirement for:
# * Apple notarization
# * Running tests on Big Sur (because Big Sur has additional security precautions)
- script: |
set -e
security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain
security default-keychain -s $(agent.tempdirectory)/buildagent.keychain
security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain
echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12
security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain
VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js
displayName: Set Hardened Entitlements
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- script: |
set -e
pushd $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) && zip -r -X -y $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH).zip * && popd
displayName: Archive build
- script: |
set -e
pushd $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) && zip -r -X -y $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH).zip * && popd
displayName: Archive build
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- script: |
set -e
- script: |
set -e
# package Remote Extension Host
pushd .. && mv vscode-reh-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH) && zip -Xry vscode-server-darwin-$(VSCODE_ARCH).zip vscode-server-darwin-$(VSCODE_ARCH) && popd
# package Remote Extension Host
pushd .. && mv vscode-reh-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH) && zip -Xry vscode-server-darwin-$(VSCODE_ARCH).zip vscode-server-darwin-$(VSCODE_ARCH) && popd
# package Remote Extension Host (Web)
pushd .. && mv vscode-reh-web-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH)-web && zip -Xry vscode-server-darwin-$(VSCODE_ARCH)-web.zip vscode-server-darwin-$(VSCODE_ARCH)-web && popd
displayName: Prepare to publish servers
# package Remote Extension Host (Web)
pushd .. && mv vscode-reh-web-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH)-web && zip -Xry vscode-server-darwin-$(VSCODE_ARCH)-web.zip vscode-server-darwin-$(VSCODE_ARCH)-web && popd
displayName: Prepare to publish servers
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: Generate SBOM (client)
inputs:
BuildDropPath: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)
PackageName: Visual Studio Code
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: Generate SBOM (client)
inputs:
BuildDropPath: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)
PackageName: Visual Studio Code
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- publish: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)/_manifest
displayName: Publish SBOM (client)
artifact: vscode_client_darwin_$(VSCODE_ARCH)_sbom
- publish: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)/_manifest
displayName: Publish SBOM (client)
artifact: vscode_client_darwin_$(VSCODE_ARCH)_sbom
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: Generate SBOM (server)
inputs:
BuildDropPath: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)
PackageName: Visual Studio Code Server
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: Generate SBOM (server)
inputs:
BuildDropPath: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)
PackageName: Visual Studio Code Server
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- publish: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)/_manifest
displayName: Publish SBOM (server)
artifact: vscode_server_darwin_$(VSCODE_ARCH)_sbom
- publish: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)/_manifest
displayName: Publish SBOM (server)
artifact: vscode_server_darwin_$(VSCODE_ARCH)_sbom
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- publish: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH).zip
artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive
displayName: Publish client archive
- publish: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH).zip
artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive
displayName: Publish client archive
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH).zip
artifact: vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish server archive
- publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH).zip
artifact: vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish server archive
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web.zip
artifact: vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish web server archive
- publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web.zip
artifact: vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish web server archive
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, 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"
- 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"
- ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}:
- script: |
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)" \
node build/azure-pipelines/upload-configuration
displayName: Upload configuration (for Bing settings search)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))
continueOnError: true
- script: |
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)" \
node build/azure-pipelines/upload-configuration
displayName: Upload configuration (for Bing settings search)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))
continueOnError: true
@@ -0,0 +1,84 @@
parameters:
- name: VSCODE_BUILD_LINUX_ALPINE
type: boolean
default: false
- name: VSCODE_BUILD_LINUX
type: boolean
default: false
- name: VSCODE_BUILD_LINUX_ALPINE_ARM64
type: boolean
default: false
- name: VSCODE_BUILD_LINUX_ARM64
type: boolean
default: false
- name: VSCODE_QUALITY
type: string
- name: channel
type: string
default: stable
steps:
# inspired by: https://github.com/emk/rust-musl-builder/blob/main/Dockerfile
- bash: |
set -e
sudo apt-get update
sudo apt-get install -yq build-essential cmake curl file git graphviz musl-dev musl-tools linux-libc-dev pkgconf unzip xutils-dev
sudo ln -s "/usr/bin/g++" "/usr/bin/musl-g++" || echo "link exists"
displayName: Install build dependencies
- task: NodeTool@0
inputs:
versionSpec: "16.x"
- template: ../mixin-distro-posix.yml
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
- script: |
set -e
node build/azure-pipelines/cli/prepare.js
displayName: Prepare CLI build
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
- template: ../cli/install-rust-posix.yml
parameters:
targets:
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true) }}:
- aarch64-unknown-linux-musl
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true) }}:
- x86_64-unknown-linux-musl
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}:
- aarch64-unknown-linux-gnu
- ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}:
- x86_64-unknown-linux-gnu
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true) }}:
- template: ../cli/cli-compile-and-publish.yml
parameters:
VSCODE_CLI_TARGET: aarch64-unknown-linux-musl
VSCODE_CLI_ARTIFACT: vscode_cli_alpine_arm64_cli
VSCODE_CLI_ENV:
CXX_aarch64-unknown-linux-musl: musl-g++
CC_aarch64-unknown-linux-musl: musl-gcc
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true) }}:
- template: ../cli/cli-compile-and-publish.yml
parameters:
VSCODE_CLI_TARGET: x86_64-unknown-linux-musl
VSCODE_CLI_ARTIFACT: vscode_cli_alpine_x64_cli
VSCODE_CLI_ENV:
CXX_aarch64-unknown-linux-musl: musl-g++
CC_aarch64-unknown-linux-musl: musl-gcc
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}:
- template: ../cli/cli-compile-and-publish.yml
parameters:
VSCODE_CLI_TARGET: aarch64-unknown-linux-gnu
VSCODE_CLI_ARTIFACT: vscode_cli_linux_arm64_cli
- ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}:
- template: ../cli/cli-compile-and-publish.yml
parameters:
VSCODE_CLI_TARGET: x86_64-unknown-linux-gnu
VSCODE_CLI_ARTIFACT: vscode_cli_linux_x64_cli
@@ -82,7 +82,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -9,90 +9,86 @@ parameters:
type: boolean
- name: VSCODE_RUN_SMOKE_TESTS
type: boolean
- name: VSCODE_CLI_ARTIFACT
type: string
default: ''
- name: VSCODE_CLI_BINARY_NAME
type: string
default: ''
- name: VSCODE_BUILD_TUNNEL_CLI
type: boolean
steps:
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- checkout: self
fetchDepth: 1
retryCountOnTaskFailure: 3
- checkout: self
fetchDepth: 1
retryCountOnTaskFailure: 3
- task: NodeTool@0
inputs:
versionSpec: "16.x"
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password"
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: DownloadPipelineArtifact@2
inputs:
artifact: Compilation
path: $(Build.ArtifactStagingDirectory)
displayName: Download compilation output
- task: DownloadPipelineArtifact@2
inputs:
artifact: Compilation
path: $(Build.ArtifactStagingDirectory)
displayName: Download compilation output
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: DownloadPipelineArtifact@2
inputs:
artifact: reh_node_modules-$(VSCODE_ARCH)
path: $(Build.ArtifactStagingDirectory)
displayName: Download server build dependencies
condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'armhf'))
- task: DownloadPipelineArtifact@2
inputs:
artifact: reh_node_modules-$(VSCODE_ARCH)
path: $(Build.ArtifactStagingDirectory)
displayName: Download server build dependencies
condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'armhf'))
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
# Start X server
/etc/init.d/xvfb start
# Start dbus session
DBUS_LAUNCH_RESULT=$(sudo dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address)
echo "##vso[task.setvariable variable=DBUS_SESSION_BUS_ADDRESS]$DBUS_LAUNCH_RESULT"
displayName: Setup system services
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))
- script: |
set -e
# Start X server
/etc/init.d/xvfb start
# Start dbus session
DBUS_LAUNCH_RESULT=$(sudo dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address)
echo "##vso[task.setvariable variable=DBUS_SESSION_BUS_ADDRESS]$DBUS_LAUNCH_RESULT"
displayName: Setup system services
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz
displayName: Extract compilation output
- script: |
set -e
tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz
displayName: Extract compilation output
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(github-distro-mixin-password)
EOF
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(github-distro-mixin-password)
EOF
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
displayName: Prepare tooling
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
displayName: Prepare tooling
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF
echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)"
git checkout FETCH_HEAD
condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' '))
displayName: Checkout override commit
- script: |
set -e
git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF
echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)"
git checkout FETCH_HEAD
condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' '))
displayName: Checkout override commit
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- 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
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
mkdir -p .build
@@ -101,20 +97,20 @@ steps:
displayName: Prepare yarn cache flags
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- task: Cache@2
inputs:
key: "genericNodeModules | $(Agent.OS) | .build/yarnlockhash"
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache
- task: Cache@2
inputs:
key: "genericNodeModules | $(Agent.OS) | .build/yarnlockhash"
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore node_modules cache
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- 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
- task: Cache@2
inputs:
@@ -130,7 +126,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -208,12 +204,12 @@ steps:
displayName: Download missing built-in extensions
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
rm -rf remote/node_modules
tar -xzf $(Build.ArtifactStagingDirectory)/reh_node_modules-$(VSCODE_ARCH).tar.gz --directory $(Build.SourcesDirectory)/remote
displayName: Extract server node_modules output
condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'armhf'))
- script: |
set -e
rm -rf remote/node_modules
tar -xzf $(Build.ArtifactStagingDirectory)/reh_node_modules-$(VSCODE_ARCH).tar.gz --directory $(Build.SourcesDirectory)/remote
displayName: Extract server node_modules output
condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'armhf'))
- script: |
set -e
@@ -224,151 +220,160 @@ steps:
displayName: Create node_modules archive
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
node build/azure-pipelines/mixin
displayName: Mix in quality
- script: |
set -e
node build/azure-pipelines/mixin
displayName: Mix in quality
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-linux-$(VSCODE_ARCH)-min-ci
displayName: Build
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-linux-$(VSCODE_ARCH)-min-ci
displayName: Build
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
node build/azure-pipelines/mixin --server
displayName: Mix in server quality
- script: |
set -e
node build/azure-pipelines/mixin --server
displayName: Mix in server quality
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci
displayName: Build Server
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci
displayName: Build Server
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp "transpile-client-swc" "transpile-extensions"
displayName: Transpile
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn gulp "transpile-client-swc" "transpile-extensions"
displayName: Transpile
- ${{ if ne(parameters.VSCODE_CLI_ARTIFACT, '') }}:
- task: DownloadPipelineArtifact@2
inputs:
artifact: ${{ parameters.VSCODE_CLI_ARTIFACT }}
patterns: '**'
path: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin
displayName: Download VS Code CLI
- ${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
- task: DownloadPipelineArtifact@2
inputs:
artifact: vscode_cli_linux_arm64_cli
patterns: "**"
path: $(Build.ArtifactStagingDirectory)/cli
displayName: Download VS Code CLI
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- script: |
set -e
chmod +x "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/$(VSCODE_CLI_BINARY_NAME)"
if [ "$(VSCODE_QUALITY)" != "stable" ]; then
mv "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/$(VSCODE_CLI_BINARY_NAME)" "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/$(VSCODE_CLI_BINARY_NAME)-$(VSCODE_QUALITY)"
fi
displayName: Make CLI executable
- task: DownloadPipelineArtifact@2
inputs:
artifact: vscode_cli_linux_x64_cli
patterns: "**"
path: $(Build.ArtifactStagingDirectory)/cli
displayName: Download VS Code CLI
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))
- script: |
set -e
tar -xzvf $(Build.ArtifactStagingDirectory)/cli/*.tar.gz -C $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin
if [ "$(VSCODE_QUALITY)" != "stable" ]; then
mv "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/code-tunnel" "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/code-tunnel-$(VSCODE_QUALITY)"
fi
displayName: Make CLI executable
- ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}:
- template: product-build-linux-client-test.yml
parameters:
VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }}
VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }}
VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }}
- template: product-build-linux-client-test.yml
parameters:
VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }}
VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }}
VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }}
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- script: |
set -e
yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-deb"
yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-rpm"
displayName: Build deb, rpm packages
- script: |
set -e
yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-deb"
yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-rpm"
displayName: Build deb, rpm packages
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- script: |
set -e
yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-snap"
displayName: Prepare snap package
- script: |
set -e
yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-snap"
displayName: Prepare snap package
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- task: UseDotNet@2
inputs:
version: 2.x
- task: UseDotNet@2
inputs:
version: 2.x
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- task: EsrpClientTool@1
displayName: Download ESRPClient
- task: EsrpClientTool@1
displayName: Download ESRPClient
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- script: |
set -e
node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" rpm $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm'
displayName: Codesign rpm
- script: |
set -e
node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" rpm $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm'
displayName: Codesign rpm
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- script: |
set -e
VSCODE_ARCH="$(VSCODE_ARCH)" \
./build/azure-pipelines/linux/prepare-publish.sh
displayName: Prepare for Publish
- script: |
set -e
VSCODE_ARCH="$(VSCODE_ARCH)" \
./build/azure-pipelines/linux/prepare-publish.sh
displayName: Prepare for Publish
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: Generate SBOM (client)
inputs:
BuildDropPath: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)
PackageName: Visual Studio Code
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: Generate SBOM (client)
inputs:
BuildDropPath: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)
PackageName: Visual Studio Code
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- publish: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/_manifest
displayName: Publish SBOM (client)
artifact: vscode_client_linux_$(VSCODE_ARCH)_sbom
- publish: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/_manifest
displayName: Publish SBOM (client)
artifact: vscode_client_linux_$(VSCODE_ARCH)_sbom
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: Generate SBOM (server)
inputs:
BuildDropPath: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)
PackageName: Visual Studio Code Server
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
displayName: Generate SBOM (server)
inputs:
BuildDropPath: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)
PackageName: Visual Studio Code Server
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- publish: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)/_manifest
displayName: Publish SBOM (server)
artifact: vscode_server_linux_$(VSCODE_ARCH)_sbom
- publish: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)/_manifest
displayName: Publish SBOM (server)
artifact: vscode_server_linux_$(VSCODE_ARCH)_sbom
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- publish: $(DEB_PATH)
artifact: vscode_client_linux_$(VSCODE_ARCH)_deb-package
displayName: Publish deb package
- publish: $(DEB_PATH)
artifact: vscode_client_linux_$(VSCODE_ARCH)_deb-package
displayName: Publish deb package
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- publish: $(RPM_PATH)
artifact: vscode_client_linux_$(VSCODE_ARCH)_rpm-package
displayName: Publish rpm package
- publish: $(RPM_PATH)
artifact: vscode_client_linux_$(VSCODE_ARCH)_rpm-package
displayName: Publish rpm package
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- publish: $(TARBALL_PATH)
artifact: vscode_client_linux_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish client archive
- publish: $(TARBALL_PATH)
artifact: vscode_client_linux_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish client archive
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH).tar.gz
artifact: vscode_server_linux_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish server archive
- publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH).tar.gz
artifact: vscode_server_linux_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish server archive
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH)-web.tar.gz
artifact: vscode_web_linux_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish web server archive
- publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH)-web.tar.gz
artifact: vscode_web_linux_$(VSCODE_ARCH)_archive-unsigned
displayName: Publish web server archive
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- task: PublishPipelineArtifact@0
displayName: "Publish Pipeline Artifact"
inputs:
artifactName: "snap-$(VSCODE_ARCH)"
targetPath: .build/linux/snap-tarball
- task: PublishPipelineArtifact@0
displayName: "Publish Pipeline Artifact"
inputs:
artifactName: "snap-$(VSCODE_ARCH)"
targetPath: .build/linux/snap-tarball
@@ -8,55 +8,55 @@ steps:
versionSpec: "16.x"
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password"
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: Docker@1
displayName: "Pull Docker image"
inputs:
azureSubscriptionEndpoint: "vscode-builds-subscription"
azureContainerRegistry: vscodehub.azurecr.io
command: "Run an image"
imageName: "vscode-linux-build-agent:centos7-devtoolset8-arm64"
containerCommand: uname
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- task: Docker@1
displayName: "Pull Docker image"
inputs:
azureSubscriptionEndpoint: "vscode-builds-subscription"
azureContainerRegistry: vscodehub.azurecr.io
command: "Run an image"
imageName: "vscode-linux-build-agent:centos7-devtoolset8-arm64"
containerCommand: uname
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(github-distro-mixin-password)
EOF
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(github-distro-mixin-password)
EOF
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
displayName: Prepare tooling
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
displayName: Prepare tooling
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF
echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)"
git checkout FETCH_HEAD
condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' '))
displayName: Checkout override commit
- script: |
set -e
git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF
echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)"
git checkout FETCH_HEAD
condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' '))
displayName: Checkout override commit
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- 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
git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -71,18 +71,18 @@ steps:
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
displayName: Register Docker QEMU
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- script: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
displayName: Register Docker QEMU
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
docker run -e VSCODE_QUALITY -e GITHUB_TOKEN -v $(pwd):/root/vscode -v ~/.netrc:/root/.netrc vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-arm64 /root/vscode/build/azure-pipelines/linux/scripts/install-remote-dependencies.sh
displayName: Install dependencies via qemu
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- script: |
set -e
docker run -e VSCODE_QUALITY -e GITHUB_TOKEN -v $(pwd):/root/vscode -v ~/.netrc:/root/.netrc vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-arm64 /root/vscode/build/azure-pipelines/linux/scripts/install-remote-dependencies.sh
displayName: Install dependencies via qemu
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- script: |
set -e
@@ -1,4 +1,3 @@
parameters:
- name: VSCODE_QUALITY
type: string
@@ -34,7 +34,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
+9 -24
View File
@@ -26,10 +26,7 @@ jobs:
- ${{ if ne(variables['VSCODE_CIBUILD'], true) }}:
- job: Compile
displayName: Compile & Hygiene
pool:
name: vscode-1es-vscode-linux-20.04
demands:
- ImageVersionOverride -equals 40.0.0
pool: vscode-1es-vscode-linux-20.04
timeoutInMinutes: 30
variables:
VSCODE_ARCH: x64
@@ -40,10 +37,7 @@ jobs:
- job: Linuxx64UnitTest
displayName: Linux (Unit Tests)
pool:
name: vscode-1es-vscode-linux-20.04
demands:
- ImageVersionOverride -equals 40.0.0
pool: vscode-1es-vscode-linux-20.04
timeoutInMinutes: 30
variables:
VSCODE_ARCH: x64
@@ -54,16 +48,14 @@ jobs:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: true
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
- job: Linuxx64IntegrationTest
displayName: Linux (Integration Tests)
pool:
name: vscode-1es-vscode-linux-20.04
demands:
- ImageVersionOverride -equals 40.0.0
pool: vscode-1es-vscode-linux-20.04
timeoutInMinutes: 30
variables:
VSCODE_ARCH: x64
@@ -74,16 +66,14 @@ jobs:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: true
VSCODE_RUN_SMOKE_TESTS: false
- job: Linuxx64SmokeTest
displayName: Linux (Smoke Tests)
pool:
name: vscode-1es-vscode-linux-20.04
demands:
- ImageVersionOverride -equals 40.0.0
pool: vscode-1es-vscode-linux-20.04
timeoutInMinutes: 30
variables:
VSCODE_ARCH: x64
@@ -94,6 +84,7 @@ jobs:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: true
@@ -101,10 +92,7 @@ jobs:
- ${{ if eq(variables['VSCODE_CIBUILD'], true) }}:
- job: Linuxx64MaintainNodeModulesCache
displayName: Linux (Maintain node_modules cache)
pool:
name: vscode-1es-vscode-linux-20.04
demands:
- ImageVersionOverride -equals 40.0.0
pool: vscode-1es-vscode-linux-20.04
timeoutInMinutes: 30
variables:
VSCODE_ARCH: x64
@@ -114,10 +102,7 @@ jobs:
- ${{ if eq(variables['VSCODE_CIBUILD'], true) }}:
- job: LinuxCLI
displayName: Linux (CLI)
pool:
name: vscode-1es-vscode-linux-20.04
demands:
- ImageVersionOverride -equals 40.0.0
pool: vscode-1es-vscode-linux-20.04
timeoutInMinutes: 30
steps:
- template: cli/test.yml
+61 -80
View File
@@ -28,7 +28,7 @@ parameters:
- name: ENABLE_TERRAPIN
displayName: "Enable Terrapin"
type: boolean
default: false
default: true
- name: VSCODE_BUILD_WIN32
displayName: "🎯 Windows x64"
type: boolean
@@ -111,10 +111,6 @@ variables:
value: ${{ parameters.VSCODE_QUALITY }}
- name: VSCODE_BUILD_STAGE_WINDOWS
value: ${{ or(eq(parameters.VSCODE_BUILD_WIN32, true), eq(parameters.VSCODE_BUILD_WIN32_32BIT, true), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}
- name: VSCODE_BUILD_STAGE_ARM_LINUX
value: ${{ or(eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true)) }}
- name: VSCODE_BUILD_STAGE_X86_LINUX
value: ${{ or(eq(parameters.VSCODE_BUILD_LINUX, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true)) }}
- name: VSCODE_BUILD_STAGE_LINUX
value: ${{ or(eq(parameters.VSCODE_BUILD_LINUX, true), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true)) }}
- name: VSCODE_BUILD_STAGE_MACOS
@@ -145,8 +141,6 @@ variables:
value: true
- name: Codeql.SkipTaskAutoInjection
value: true
- name: VSCODE_CLI_BINARY_NAME
value: code-tunnel
resources:
containers:
@@ -185,24 +179,23 @@ stages:
- stage: CompileCLI
dependsOn: []
jobs:
- ${{ if eq(variables.VSCODE_BUILD_STAGE_X86_LINUX, true) }}:
- ${{ if or(eq(parameters.VSCODE_BUILD_LINUX, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true)) }}:
- job: LinuxX86
pool: vscode-1es-linux
variables:
VSCODE_ARCH: x64
steps:
- template: ./cli/compile-linux.yml
- template: ./linux/cli-build-linux.yml
parameters:
VSCODE_CLI_DIR: $(Build.SourcesDirectory)/cli
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_CLI_TARGETS:
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true) }}:
- { target: x86_64-unknown-linux-musl, artifact: vscode_cli_alpine_x64_cli-unsigned }
- ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}:
- { target: x86_64-unknown-linux-gnu, artifact: vscode_cli_linux_x64_cli-unsigned }
VSCODE_BUILD_LINUX_ALPINE: ${{ parameters.VSCODE_BUILD_LINUX_ALPINE }}
VSCODE_BUILD_LINUX: ${{ parameters.VSCODE_BUILD_LINUX }}
- ${{ if eq(variables.VSCODE_BUILD_STAGE_ARM_LINUX, true) }}:
- ${{ if or(eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true)) }}:
- job: LinuxArm64
pool: vscode-1es-linux-20.04-arm64
variables:
VSCODE_ARCH: arm64
steps:
- task: NodeTool@0
displayName: Install Node.js
@@ -214,56 +207,32 @@ stages:
sudo apt update -y
sudo apt install -y build-essential pkg-config
displayName: Install build dependencies
- template: ./cli/compile-linux.yml
- template: ./linux/cli-build-linux.yml
parameters:
VSCODE_CLI_DIR: $(Build.SourcesDirectory)/cli
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_CLI_TARGETS:
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true) }}:
- { target: aarch64-unknown-linux-musl, artifact: vscode_cli_alpine_arm64_cli-unsigned }
- ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}:
- { target: aarch64-unknown-linux-gnu, artifact: vscode_cli_linux_arm64_cli-unsigned }
VSCODE_BUILD_LINUX_ALPINE_ARM64: ${{ parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64 }}
VSCODE_BUILD_LINUX_ARM64: ${{ parameters.VSCODE_BUILD_LINUX_ARM64 }}
- ${{ if eq(variables.VSCODE_BUILD_STAGE_MACOS, true) }}:
- job: MacOS
pool:
vmImage: macOS-latest
steps:
- template: ./cli/compile-macos.yml
- template: ./darwin/cli-build-darwin.yml
parameters:
VSCODE_CLI_DIR: $(Build.SourcesDirectory)/cli
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_CLI_TARGETS:
- ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}:
- { target: x86_64-apple-darwin, artifact: vscode_cli_darwin_x64_cli-unsigned }
- ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}:
- { target: aarch64-apple-darwin, artifact: vscode_cli_darwin_arm64_cli-unsigned }
VSCODE_BUILD_MACOS: ${{ parameters.VSCODE_BUILD_MACOS }}
VSCODE_BUILD_MACOS_ARM64: ${{ parameters.VSCODE_BUILD_MACOS_ARM64 }}
- ${{ if eq(variables.VSCODE_BUILD_STAGE_WINDOWS, true) }}:
- job: Windows
pool: vscode-1es-windows
steps:
- template: ./cli/vcpkg-deps.yml
- template: ./win32/cli-build-win32.yml
parameters:
targets:
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- x64-windows-static-md
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
- arm64-windows-static-md
vcpkgDir: $(Build.SourcesDirectory)/build/azure-pipelines/cli/vcpkg
targetDirectory: $(Build.ArtifactStagingDirectory)/deps
- template: ./cli/compile-windows.yml
parameters:
VSCODE_CLI_DIR: $(Build.SourcesDirectory)/cli
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_CLI_TARGETS:
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- { target: x86_64-pc-windows-msvc, artifact: vscode_cli_win32_x64_cli-unsigned }
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
- { target: aarch64-pc-windows-msvc, artifact: vscode_cli_win32_arm64_cli-unsigned }
VSCODE_BUILD_WIN32: ${{ parameters.VSCODE_BUILD_WIN32 }}
VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }}
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_WINDOWS'], true)) }}:
- stage: Windows
@@ -284,6 +253,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: true
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
@@ -297,6 +267,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: true
VSCODE_RUN_SMOKE_TESTS: false
@@ -310,6 +281,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: true
@@ -324,12 +296,10 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: ${{ parameters.VSCODE_BUILD_TUNNEL_CLI }}
VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
VSCODE_CLI_ARTIFACT: vscode_cli_win32_x64_cli-unsigned
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_32BIT, true)) }}:
- job: Windows32
@@ -341,6 +311,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false # todo until 32 bit CLI is available
VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
@@ -355,12 +326,10 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: ${{ parameters.VSCODE_BUILD_TUNNEL_CLI }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
VSCODE_CLI_ARTIFACT: vscode_cli_win32_arm64_cli-unsigned
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
- ${{ if and(eq(variables['VSCODE_PUBLISH'], true), eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true)) }}:
- job: windowsCLISign
@@ -368,12 +337,8 @@ stages:
steps:
- template: win32/product-build-win32-cli-sign.yml
parameters:
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
VSCODE_CLI_ARTIFACTS:
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- vscode_cli_win32_x64_cli-unsigned
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
- vscode_cli_win32_arm64_cli-unsigned
VSCODE_BUILD_WIN32: ${{ parameters.VSCODE_BUILD_WIN32 }}
VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }}
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_LINUX'], true)) }}:
- stage: LinuxServerDependencies
@@ -422,6 +387,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: true
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
@@ -437,6 +403,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: true
VSCODE_RUN_SMOKE_TESTS: false
@@ -452,6 +419,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: true
@@ -468,12 +436,10 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: ${{ parameters.VSCODE_BUILD_TUNNEL_CLI }}
VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
VSCODE_CLI_ARTIFACT: vscode_cli_linux_x64_cli-unsigned
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX, true), ne(variables['VSCODE_PUBLISH'], 'false')) }}:
- job: LinuxSnap
@@ -496,6 +462,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false # todo: not built yet
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
@@ -522,12 +489,10 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: ${{ parameters.VSCODE_BUILD_TUNNEL_CLI }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
VSCODE_CLI_ARTIFACT: vscode_cli_linux_arm64_cli-unsigned
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
# 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)) }}:
@@ -577,6 +542,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: true
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
@@ -590,6 +556,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: true
VSCODE_RUN_SMOKE_TESTS: false
@@ -603,6 +570,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: true
@@ -617,12 +585,10 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: ${{ parameters.VSCODE_BUILD_TUNNEL_CLI }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
VSCODE_CLI_ARTIFACT: vscode_cli_darwin_x64_cli-unsigned
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
- ${{ if eq(parameters.VSCODE_STEP_ON_IT, false) }}:
- job: macOSTest
@@ -634,6 +600,7 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: false
VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }}
@@ -654,12 +621,8 @@ stages:
steps:
- template: darwin/product-build-darwin-cli-sign.yml
parameters:
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
VSCODE_CLI_ARTIFACTS:
- ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}:
- vscode_cli_darwin_x64_cli-unsigned
- ${{ if eq(parameters.VSCODE_BUILD_MACOS_ARM64, true) }}:
- vscode_cli_darwin_arm64_cli-unsigned
VSCODE_BUILD_MACOS: ${{ parameters.VSCODE_BUILD_MACOS }}
VSCODE_BUILD_MACOS_ARM64: ${{ parameters.VSCODE_BUILD_MACOS_ARM64 }}
- ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true)) }}:
- job: macOSARM64
@@ -671,12 +634,10 @@ stages:
parameters:
VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }}
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
VSCODE_BUILD_TUNNEL_CLI: ${{ parameters.VSCODE_BUILD_TUNNEL_CLI }}
VSCODE_RUN_UNIT_TESTS: false
VSCODE_RUN_INTEGRATION_TESTS: false
VSCODE_RUN_SMOKE_TESTS: false
${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
VSCODE_CLI_ARTIFACT: vscode_cli_darwin_arm64_cli-unsigned
VSCODE_CLI_BINARY_NAME: ${{ variables.VSCODE_CLI_BINARY_NAME }}
- ${{ if eq(variables['VSCODE_PUBLISH'], true) }}:
- job: macOSARM64Sign
@@ -737,13 +698,33 @@ stages:
steps:
- template: product-publish.yml
- ${{ if and(parameters.VSCODE_RELEASE, eq(parameters.VSCODE_DISTRO_REF, ' ')) }}:
- stage: ApproveRelease
dependsOn: [] # run in parallel to compile stage
pool: vscode-1es-linux
jobs:
- deployment: ApproveRelease
displayName: "Approve Release"
environment: "vscode"
variables:
skipComponentGovernanceDetection: true
strategy:
runOnce:
deploy:
steps:
- checkout: none
- ${{ if or(and(parameters.VSCODE_RELEASE, eq(parameters.VSCODE_DISTRO_REF, ' ')), and(in(parameters.VSCODE_QUALITY, 'insider', 'exploration'), eq(variables['VSCODE_SCHEDULEDBUILD'], true))) }}:
- stage: Release
dependsOn:
- Publish
- ${{ if and(parameters.VSCODE_RELEASE, eq(parameters.VSCODE_DISTRO_REF, ' ')) }}:
- ApproveRelease
pool: vscode-1es-linux
jobs:
- job: ReleaseBuild
displayName: Release Build
steps:
- template: product-release.yml
parameters:
VSCODE_RELEASE: ${{ parameters.VSCODE_RELEASE }}
+58 -58
View File
@@ -40,7 +40,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -86,11 +86,11 @@ steps:
displayName: Create node_modules archive
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
# Mixin must run before optimize, because the CSS loader will inline small SVGs
- script: |
set -e
node build/azure-pipelines/mixin
displayName: Mix in quality
# Mixin must run before optimize, because the CSS loader will inline small SVGs
- script: |
set -e
node build/azure-pipelines/mixin
displayName: Mix in quality
- script: |
set -e
@@ -100,71 +100,71 @@ steps:
displayName: Compile & Hygiene
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
yarn --cwd build compile
./.github/workflows/check-clean-git-state.sh
displayName: Check /build/ folder
- script: |
set -e
yarn --cwd build compile
./.github/workflows/check-clean-git-state.sh
displayName: Check /build/ folder
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
yarn --cwd test/smoke compile
yarn --cwd test/integration/browser compile
displayName: Compile test suites
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
set -e
yarn --cwd test/smoke compile
yarn --cwd test/integration/browser compile
displayName: Compile test suites
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- 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-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"
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
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
- script: |
set -e
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
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -
./build/azure-pipelines/common/extract-telemetry.sh
displayName: Extract Telemetry
- script: |
set -
./build/azure-pipelines/common/extract-telemetry.sh
displayName: Extract Telemetry
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
tar -cz --ignore-failed-read -f $(Build.ArtifactStagingDirectory)/compilation.tar.gz .build out-* test/integration/browser/out test/smoke/out test/automation/out
displayName: Compress compilation artifact
- script: |
set -e
tar -cz --ignore-failed-read -f $(Build.ArtifactStagingDirectory)/compilation.tar.gz .build out-* test/integration/browser/out test/smoke/out test/automation/out
displayName: Compress compilation artifact
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: PublishPipelineArtifact@1
inputs:
targetPath: $(Build.ArtifactStagingDirectory)/compilation.tar.gz
artifactName: Compilation
displayName: Publish compilation artifact
- task: PublishPipelineArtifact@1
inputs:
targetPath: $(Build.ArtifactStagingDirectory)/compilation.tar.gz
artifactName: Compilation
displayName: Publish compilation artifact
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn download-builtin-extensions-cg
displayName: Built-in extensions component details
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \
yarn download-builtin-extensions-cg
displayName: Built-in extensions component details
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: "Component Detection"
inputs:
sourceScanPath: $(Build.SourcesDirectory)
continueOnError: true
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: "Component Detection"
inputs:
sourceScanPath: $(Build.SourcesDirectory)
continueOnError: true
+13 -3
View File
@@ -62,12 +62,15 @@ do {
if($set.Add($artifactName)) {
Write-Host "Processing artifact: '$artifactName. Downloading from: $($_.resource.downloadUrl)"
$extractPath = "$env:AGENT_TEMPDIRECTORY/$artifactName.zip"
try {
Invoke-RestMethod $_.resource.downloadUrl -OutFile "$env:AGENT_TEMPDIRECTORY/$artifactName.zip" -Headers @{
Invoke-RestMethod $_.resource.downloadUrl -OutFile $extractPath -Headers @{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
} -MaximumRetryCount 5 -RetryIntervalSec 1 | Out-Null
} -MaximumRetryCount 5 -RetryIntervalSec 1 -TimeoutSec 300 | Out-Null
Expand-Archive -Path "$env:AGENT_TEMPDIRECTORY/$artifactName.zip" -DestinationPath $env:AGENT_TEMPDIRECTORY | Out-Null
Write-Host "Extracting artifact: '$extractPath'"
Expand-Archive -Path $extractPath -DestinationPath $env:AGENT_TEMPDIRECTORY | Out-Null
} catch {
Write-Warning $_
$set.Remove($artifactName) | Out-Null
@@ -76,6 +79,13 @@ do {
$null,$product,$os,$arch,$type = $artifactName -split '_'
$asset = Get-ChildItem -rec "$env:AGENT_TEMPDIRECTORY/$artifactName"
if ($asset.Size -ne $_.resource.properties.artifactsize) {
Write-Warning "Artifact size mismatch for '$artifactName'. Expected: $($_.resource.properties.artifactsize). Actual: $($asset.Size)"
$set.Remove($artifactName) | Out-Null
continue
}
Write-Host "Processing artifact with the following values:"
# turning in into an object just to log nicely
@{
+5 -1
View File
@@ -1,3 +1,7 @@
parameters:
- name: VSCODE_RELEASE
type: boolean
steps:
- task: NodeTool@0
inputs:
@@ -20,4 +24,4 @@ steps:
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
node build/azure-pipelines/common/releaseBuild.js ${{ parameters.VSCODE_RELEASE }}
+3 -2
View File
@@ -83,7 +83,8 @@ stages:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npx https://aka.ms/enablesecurefeed standAlone }
exec { npm install https://aka.ms/enablesecurefeed --global }
exec { npm exec terrapinadotask -- standAlone }
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -184,7 +185,7 @@ stages:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -8,11 +8,14 @@ parameters:
type: string
steps:
- script: git clone https://github.com/microsoft/vcpkg.git $(Build.ArtifactStagingDirectory)/vcpkg
displayName: Checkout vcpkg
- script: $(Build.ArtifactStagingDirectory)/vcpkg/bootstrap-vcpkg.bat
- powershell: |
. build/azure-pipelines/win32/exec.ps1
exec { git clone https://github.com/microsoft/vcpkg.git $(Build.ArtifactStagingDirectory)/vcpkg }
exec { cd $(Build.ArtifactStagingDirectory)/vcpkg; git checkout 779ce74ef67d3e12d904da1b15f9ed5626d5f677 }
exec { $(Build.ArtifactStagingDirectory)/vcpkg/bootstrap-vcpkg.bat }
Write-Output "##vso[task.setvariable variable=VSCODE_DID_BOOTSTRAP_VCPKG]true"
displayName: Bootstrap vcpkg
condition: not(eq(variables.VSCODE_DID_BOOTSTRAP_VCPKG, true))
- ${{ each target in parameters.targets }}:
- task: Cache@2
@@ -73,7 +73,7 @@ steps:
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
npm install https://aka.ms/enablesecurefeed --global && npm exec terrapinadotask -- standAlone
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -0,0 +1,63 @@
parameters:
- name: VSCODE_BUILD_WIN32
type: boolean
- name: VSCODE_BUILD_WIN32_ARM64
type: boolean
- name: VSCODE_QUALITY
type: string
- name: channel
type: string
default: stable
steps:
- task: NodeTool@0
inputs:
versionSpec: "16.x"
- template: ../mixin-distro-win32.yml
parameters:
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { node build/azure-pipelines/cli/prepare.js }
displayName: Prepare CLI build
env:
GITHUB_TOKEN: "$(github-distro-mixin-password)"
- template: ../cli/install-rust-win32.yml
parameters:
targets:
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- x86_64-pc-windows-msvc
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
- aarch64-pc-windows-msvc
- template: ../vcpkg-install.yml
parameters:
targets:
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- x64-windows-static-md
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
- arm64-windows-static-md
vcpkgDir: $(Build.SourcesDirectory)/build/azure-pipelines/cli/vcpkg
targetDirectory: $(Build.ArtifactStagingDirectory)/deps
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- template: ../cli/cli-compile-and-publish.yml
parameters:
VSCODE_CLI_TARGET: x86_64-pc-windows-msvc
VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_win32_x64_cli
VSCODE_CLI_ENV:
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/deps/x64-windows-static-md/lib
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/deps/x64-windows-static-md/include
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
- template: ../cli/cli-compile-and-publish.yml
parameters:
VSCODE_CLI_TARGET: aarch64-pc-windows-msvc
VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_win32_arm64_cli
VSCODE_CLI_ENV:
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/deps/arm64-windows-static-md/lib
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/deps/arm64-windows-static-md/include
@@ -1,10 +1,16 @@
parameters:
- name: VSCODE_CLI_BINARY_NAME
type: string
- name: VSCODE_CLI_ARTIFACTS
default: []
type: object
- name: VSCODE_BUILD_WIN32
type: boolean
- name: VSCODE_BUILD_WIN32_ARM64
type: boolean
variables:
- name: VSCODE_CLI_ARTIFACTS
value:
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- unsigned_vscode_cli_win32_x64_cli
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
- unsigned_vscode_cli_win32_arm64_cli
steps:
- task: NodeTool@0
displayName: "Use Node.js"
@@ -17,50 +23,10 @@ steps:
exec { yarn }
displayName: Install build dependencies
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "ESRP-PKI,esrp-aad-username,esrp-aad-password"
- ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}:
- task: DownloadPipelineArtifact@2
displayName: Download artifacts
inputs:
artifact: ${{ target }}
path: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}
- task: UseDotNet@2
displayName: "Use .NET"
inputs:
version: 3.x
- task: EsrpClientTool@1
displayName: "Use ESRP client"
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$EsrpClientTool = (gci -directory -filter EsrpClientTool_* $(Agent.RootDirectory)\_tasks | Select-Object -last 1).FullName
$EsrpCliZip = (gci -recurse -filter esrpcli.*.zip $EsrpClientTool | Select-Object -last 1).FullName
mkdir -p $(Agent.TempDirectory)\esrpcli
Expand-Archive -Path $EsrpCliZip -DestinationPath $(Agent.TempDirectory)\esrpcli
$EsrpCliDllPath = (gci -recurse -filter esrpcli.dll $(Agent.TempDirectory)\esrpcli | Select-Object -last 1).FullName
echo "##vso[task.setvariable variable=EsrpCliDllPath]$EsrpCliDllPath"
displayName: Find ESRP CLI
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { node build\azure-pipelines\common\sign $env:EsrpCliDllPath windows $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(Build.ArtifactStagingDirectory)/pkg "*.exe" }
displayName: "Code sign"
- ${{ each target in parameters.VSCODE_CLI_ARTIFACTS }}:
- powershell: |
$ASSET_ID = "${{ target }}".replace("-unsigned", "");
echo "##vso[task.setvariable variable=ASSET_ID]$ASSET_ID"
displayName: Set asset id variable
- publish: $(Build.ArtifactStagingDirectory)/pkg/${{ target }}/${{ parameters.VSCODE_CLI_BINARY_NAME }}.exe
artifact: $(ASSET_ID)
- template: ../cli/cli-win32-sign.yml
parameters:
VSCODE_CLI_ARTIFACTS:
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
- unsigned_vscode_cli_win32_x64_cli
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
- unsigned_vscode_cli_win32_arm64_cli
@@ -9,12 +9,8 @@ parameters:
type: boolean
- name: VSCODE_RUN_SMOKE_TESTS
type: boolean
- name: VSCODE_CLI_ARTIFACT
type: string
default: ''
- name: VSCODE_CLI_BINARY_NAME
type: string
default: ''
- name: VSCODE_BUILD_TUNNEL_CLI
type: boolean
steps:
- ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}:
@@ -112,7 +108,8 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npx https://aka.ms/enablesecurefeed standAlone }
exec { npm install https://aka.ms/enablesecurefeed --global }
exec { npm exec terrapinadotask -- standAlone }
timeoutInMinutes: 5
retryCountOnTaskFailure: 3
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
@@ -181,19 +178,35 @@ steps:
echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)"
displayName: Build
- ${{ if ne(parameters.VSCODE_CLI_ARTIFACT, '') }}:
- ${{ if eq(parameters.VSCODE_BUILD_TUNNEL_CLI, true) }}:
- task: DownloadPipelineArtifact@2
inputs:
artifact: ${{ parameters.VSCODE_CLI_ARTIFACT }}
artifact: unsigned_vscode_cli_win32_arm64_cli
patterns: '**'
path: $(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin
path: $(Build.ArtifactStagingDirectory)/cli
displayName: Download VS Code CLI
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64'))
- ${{ if ne(parameters.VSCODE_QUALITY, 'stable') }}:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
Move-Item -Path "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/$(VSCODE_CLI_BINARY_NAME).exe" -Destination "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/$(VSCODE_CLI_BINARY_NAME)-$(VSCODE_QUALITY).exe"
displayName: Move VS Code CLI
- task: DownloadPipelineArtifact@2
inputs:
artifact: unsigned_vscode_cli_win32_x64_cli
patterns: '**'
path: $(Build.ArtifactStagingDirectory)/cli
displayName: Download VS Code CLI
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$ArtifactName = (gci -Path "$(Build.ArtifactStagingDirectory)/cli" | Select-Object -last 1).FullName
Expand-Archive -Path $ArtifactName -DestinationPath "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin"
if ("$(VSCODE_QUALITY)" -ne "stable")
{
Move-Item -Path "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/code-tunnel.exe" -Destination "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/code-tunnel-$(VSCODE_QUALITY).exe"
}
displayName: Move VS Code CLI
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:
- powershell: |
+2 -1
View File
@@ -6,6 +6,7 @@
const gulp = require('gulp');
const path = require('path');
const util = require('./lib/util');
const { getVersion } = require('./lib/getVersion');
const task = require('./lib/task');
const optimize = require('./lib/optimize');
const es = require('event-stream');
@@ -18,7 +19,7 @@ const monacoapi = require('./lib/monaco-api');
const fs = require('fs');
const root = path.dirname(__dirname);
const sha1 = util.getVersion(root);
const sha1 = getVersion(root);
const semver = require('./monaco/package.json').version;
const headerVersion = semver + '(' + sha1 + ')';
+3 -2
View File
@@ -12,12 +12,13 @@ const nodeUtil = require('util');
const es = require('event-stream');
const filter = require('gulp-filter');
const util = require('./lib/util');
const { getVersion } = require('./lib/getVersion');
const task = require('./lib/task');
const watcher = require('./lib/watch');
const createReporter = require('./lib/reporter').createReporter;
const glob = require('glob');
const root = path.dirname(__dirname);
const commit = util.getVersion(root);
const commit = getVersion(root);
const plumber = require('gulp-plumber');
const ext = require('./lib/extensions');
@@ -46,7 +47,6 @@ const compilations = [
'gulp/tsconfig.json',
'html-language-features/client/tsconfig.json',
'html-language-features/server/tsconfig.json',
'image-preview/tsconfig.json',
'ipynb/tsconfig.json',
'jake/tsconfig.json',
'json-language-features/client/tsconfig.json',
@@ -55,6 +55,7 @@ const compilations = [
'markdown-language-features/server/tsconfig.json',
'markdown-language-features/tsconfig.json',
'markdown-math/tsconfig.json',
'media-preview/tsconfig.json',
'merge-conflict/tsconfig.json',
'microsoft-authentication/tsconfig.json',
'npm/tsconfig.json',
+2 -1
View File
@@ -9,6 +9,7 @@ const gulp = require('gulp');
const path = require('path');
const es = require('event-stream');
const util = require('./lib/util');
const { getVersion } = require('./lib/getVersion');
const task = require('./lib/task');
const optimize = require('./lib/optimize');
const product = require('../product.json');
@@ -30,7 +31,7 @@ const { vscodeWebEntryPoints, vscodeWebResourceIncludes, createVSCodeWebFileCont
const cp = require('child_process');
const REPO_ROOT = path.dirname(__dirname);
const commit = util.getVersion(REPO_ROOT);
const commit = getVersion(REPO_ROOT);
const BUILD_ROOT = path.dirname(REPO_ROOT);
const REMOTE_FOLDER = path.join(REPO_ROOT, 'remote');
+2 -1
View File
@@ -18,11 +18,12 @@ const replace = require('gulp-replace');
const filter = require('gulp-filter');
const _ = require('underscore');
const util = require('./lib/util');
const { getVersion } = require('./lib/getVersion');
const task = require('./lib/task');
const buildfile = require('../src/buildfile');
const optimize = require('./lib/optimize');
const root = path.dirname(__dirname);
const commit = util.getVersion(root);
const commit = getVersion(root);
const packageJson = require('../package.json');
const product = require('../product.json');
const crypto = require('crypto');
+2 -1
View File
@@ -12,6 +12,7 @@ const shell = require('gulp-shell');
const es = require('event-stream');
const vfs = require('vinyl-fs');
const util = require('./lib/util');
const { getVersion } = require('./lib/getVersion');
const task = require('./lib/task');
const packageJson = require('../package.json');
const product = require('../product.json');
@@ -20,7 +21,7 @@ const sysrootInstaller = require('./linux/debian/install-sysroot');
const debianRecommendedDependencies = require('./linux/debian/dep-lists').recommendedDeps;
const path = require('path');
const root = path.dirname(__dirname);
const commit = util.getVersion(root);
const commit = getVersion(root);
const linuxPackageRevision = Math.floor(new Date().getTime() / 1000);
+2 -1
View File
@@ -9,6 +9,7 @@ const gulp = require('gulp');
const path = require('path');
const es = require('event-stream');
const util = require('./lib/util');
const { getVersion } = require('./lib/getVersion');
const task = require('./lib/task');
const optimize = require('./lib/optimize');
const product = require('../product.json');
@@ -26,7 +27,7 @@ const REPO_ROOT = path.dirname(__dirname);
const BUILD_ROOT = path.dirname(REPO_ROOT);
const WEB_FOLDER = path.join(REPO_ROOT, 'remote', 'web');
const commit = util.getVersion(REPO_ROOT);
const commit = getVersion(REPO_ROOT);
const quality = product.quality;
const version = (quality && quality !== 'stable') ? `${packageJson.version}-${quality}` : packageJson.version;
+2 -1
View File
@@ -11,12 +11,13 @@ const vfs = require("vinyl-fs");
const filter = require("gulp-filter");
const _ = require("underscore");
const util = require("./util");
const getVersion_1 = require("./getVersion");
function isDocumentSuffix(str) {
return str === 'document' || str === 'script' || str === 'file' || str === 'source code';
}
const root = path.dirname(path.dirname(__dirname));
const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'));
const commit = util.getVersion(root);
const commit = (0, getVersion_1.getVersion)(root);
const darwinCreditsTemplate = product.darwinCredits && _.template(fs.readFileSync(path.join(root, product.darwinCredits), 'utf8'));
/**
* Generate a `DarwinDocumentType` given a list of file extensions, an icon name, and an optional suffix or file type name.
+2 -1
View File
@@ -9,6 +9,7 @@ import * as vfs from 'vinyl-fs';
import * as filter from 'gulp-filter';
import * as _ from 'underscore';
import * as util from './util';
import { getVersion } from './getVersion';
type DarwinDocumentSuffix = 'document' | 'script' | 'file' | 'source code';
type DarwinDocumentType = {
@@ -26,7 +27,7 @@ function isDocumentSuffix(str?: string): str is DarwinDocumentSuffix {
const root = path.dirname(path.dirname(__dirname));
const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'));
const commit = util.getVersion(root);
const commit = getVersion(root);
const darwinCreditsTemplate = product.darwinCredits && _.template(fs.readFileSync(path.join(root, product.darwinCredits), 'utf8'));
+2 -2
View File
@@ -26,9 +26,9 @@ const jsoncParser = require("jsonc-parser");
const dependencies_1 = require("./dependencies");
const _ = require("underscore");
const builtInExtensions_1 = require("./builtInExtensions");
const util = require('./util');
const getVersion_1 = require("./getVersion");
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const commit = (0, getVersion_1.getVersion)(root);
const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`;
function minifyExtensionResources(input) {
const jsonFilter = filter(['**/*.json', '**/*.code-snippets'], { restore: true });
+3 -2
View File
@@ -26,9 +26,10 @@ import webpack = require('webpack');
import { getProductionDependencies } from './dependencies';
import _ = require('underscore');
import { getExtensionStream } from './builtInExtensions';
const util = require('./util');
import { getVersion } from './getVersion';
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const commit = getVersion(root);
const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`;
function minifyExtensionResources(input: Stream): Stream {
+75 -414
View File
@@ -4,19 +4,18 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareIslFiles = exports.prepareI18nPackFiles = exports.prepareI18nFiles = exports.pullSetupXlfFiles = exports.findObsoleteResources = exports.pushXlfFiles = exports.createXlfFilesForIsl = exports.createXlfFilesForExtensions = exports.createXlfFilesForCoreBundle = exports.getResource = exports.processNlsFiles = exports.Limiter = exports.XLF = exports.Line = exports.externalExtensionsWithTranslations = exports.extraLanguages = exports.defaultLanguages = void 0;
exports.prepareIslFiles = exports.prepareI18nPackFiles = exports.createXlfFilesForIsl = exports.createXlfFilesForExtensions = exports.createXlfFilesForCoreBundle = exports.getResource = exports.processNlsFiles = exports.XLF = exports.Line = exports.extraLanguages = exports.defaultLanguages = void 0;
const path = require("path");
const fs = require("fs");
const event_stream_1 = require("event-stream");
const File = require("vinyl");
const Is = require("is");
const xml2js = require("xml2js");
const https = require("https");
const gulp = require("gulp");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const iconv = require("@vscode/iconv-lite-umd");
const NUMBER_OF_CONCURRENT_DOWNLOADS = 4;
const l10n_dev_1 = require("@vscode/l10n-dev");
function log(message, ...rest) {
fancyLog(ansiColors.green('[i18n]'), message, ...rest);
}
@@ -38,7 +37,7 @@ exports.extraLanguages = [
{ id: 'tr', folderName: 'trk' }
];
// non built-in extensions also that are transifex and need to be part of the language packs
exports.externalExtensionsWithTranslations = {
const externalExtensionsWithTranslations = {
'vscode-chrome-debug': 'msjsdiag.debugger-for-chrome',
'vscode-node-debug': 'ms-vscode.node-debug',
'vscode-node-debug2': 'ms-vscode.node-debug2'
@@ -63,19 +62,6 @@ var BundledFormat;
}
BundledFormat.is = is;
})(BundledFormat || (BundledFormat = {}));
var PackageJsonFormat;
(function (PackageJsonFormat) {
function is(value) {
if (Is.undef(value) || !Is.object(value)) {
return false;
}
return Object.keys(value).every(key => {
const element = value[key];
return Is.string(element) || (Is.object(element) && Is.defined(element.message) && Is.defined(element.comment));
});
}
PackageJsonFormat.is = is;
})(PackageJsonFormat || (PackageJsonFormat = {}));
class Line {
constructor(indent = 0) {
this.buffer = [];
@@ -184,31 +170,6 @@ class XLF {
}
}
exports.XLF = XLF;
XLF.parsePseudo = function (xlfString) {
return new Promise((resolve) => {
const parser = new xml2js.Parser();
const files = [];
parser.parseString(xlfString, function (_err, result) {
const fileNodes = result['xliff']['file'];
fileNodes.forEach(file => {
const originalFilePath = file.$.original;
const messages = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit) => {
const key = unit.$.id;
const val = pseudify(unit.source[0]['_'].toString());
if (key && val) {
messages[key] = decodeEntities(val);
}
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: 'ps' });
}
});
resolve(files);
});
});
};
XLF.parse = function (xlfString) {
return new Promise((resolve, reject) => {
const parser = new xml2js.Parser();
@@ -222,8 +183,8 @@ XLF.parse = function (xlfString) {
reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`));
}
fileNodes.forEach((file) => {
const originalFilePath = file.$.original;
if (!originalFilePath) {
const name = file.$.original;
if (!name) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`));
}
const language = file.$['target-language'];
@@ -244,45 +205,18 @@ XLF.parse = function (xlfString) {
val = val._ ? val._ : '';
}
if (!key) {
reject(new Error(`XLF parsing error: trans-unit ${JSON.stringify(unit, undefined, 0)} defined in file ${originalFilePath} is missing the ID attribute.`));
reject(new Error(`XLF parsing error: trans-unit ${JSON.stringify(unit, undefined, 0)} defined in file ${name} is missing the ID attribute.`));
return;
}
messages[key] = decodeEntities(val);
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: language.toLowerCase() });
files.push({ messages, name, language: language.toLowerCase() });
}
});
resolve(files);
});
});
};
class Limiter {
constructor(maxDegreeOfParalellism) {
this.maxDegreeOfParalellism = maxDegreeOfParalellism;
this.outstandingPromises = [];
this.runningPromises = 0;
}
queue(factory) {
return new Promise((c, e) => {
this.outstandingPromises.push({ factory, c, e });
this.consume();
});
}
consume() {
while (this.outstandingPromises.length && this.runningPromises < this.maxDegreeOfParalellism) {
const iLimitedTask = this.outstandingPromises.shift();
this.runningPromises++;
const promise = iLimitedTask.factory();
promise.then(iLimitedTask.c).catch(iLimitedTask.e);
promise.then(() => this.consumed()).catch(() => this.consumed());
}
}
consumed() {
this.runningPromises--;
this.consume();
}
}
exports.Limiter = Limiter;
function sortLanguages(languages) {
return languages.sort((a, b) => {
return a.id < b.id ? -1 : (a.id > b.id ? 1 : 0);
@@ -574,6 +508,28 @@ function createXlfFilesForCoreBundle() {
});
}
exports.createXlfFilesForCoreBundle = createXlfFilesForCoreBundle;
function createL10nBundleForExtension(extensionName) {
const result = (0, event_stream_1.through)();
gulp.src([
`extensions/${extensionName}/src/**/*.ts`,
]).pipe((0, event_stream_1.writeArray)((err, files) => {
if (err) {
result.emit('error', err);
return;
}
const json = (0, l10n_dev_1.getL10nJson)(files.map(file => {
return file.contents.toString('utf8');
}));
if (Object.keys(json).length > 0) {
result.emit('data', new File({
path: `${extensionName}/bundle.l10n.json`,
contents: Buffer.from(JSON.stringify(json), 'utf8')
}));
}
result.emit('end');
}));
return result;
}
function createXlfFilesForExtensions() {
let counter = 0;
let folderStreamEnded = false;
@@ -589,59 +545,51 @@ function createXlfFilesForExtensions() {
return;
}
counter++;
let _xlf;
function getXlf() {
if (!_xlf) {
_xlf = new XLF(extensionsProject);
let _l10nMap;
function getL10nMap() {
if (!_l10nMap) {
_l10nMap = new Map();
}
return _xlf;
return _l10nMap;
}
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe((0, event_stream_1.through)(function (file) {
(0, event_stream_1.merge)(gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }), createL10nBundleForExtension(extensionName)).pipe((0, event_stream_1.through)(function (file) {
if (file.isBuffer()) {
const buffer = file.contents;
const basename = path.basename(file.path);
if (basename === 'package.nls.json') {
const json = JSON.parse(buffer.toString('utf8'));
const keys = [];
const messages = [];
Object.keys(json).forEach((key) => {
const value = json[key];
if (Is.string(value)) {
keys.push(key);
messages.push(value);
}
else if (value) {
keys.push({
key,
comment: value.comment
});
messages.push(value.message);
}
else {
keys.push(key);
messages.push(`Unknown message for key: ${key}`);
}
});
getXlf().addFile(`extensions/${extensionName}/package`, keys, messages);
getL10nMap().set(`extensions/${extensionName}/package`, json);
}
else if (basename === 'nls.metadata.json') {
const json = JSON.parse(buffer.toString('utf8'));
const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path));
for (const file in json) {
const fileContent = json[file];
getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages);
const info = Object.create(null);
for (let i = 0; i < fileContent.messages.length; i++) {
const message = fileContent.messages[i];
const { key, comment } = LocalizeInfo.is(fileContent.keys[i])
? fileContent.keys[i]
: { key: fileContent.keys[i], comment: undefined };
info[key] = comment ? { message, comment } : message;
}
getL10nMap().set(`extensions/${extensionName}/${relPath}/${file}`, info);
}
}
else if (basename === 'bundle.l10n.json') {
const json = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/bundle`, json);
}
else {
this.emit('error', new Error(`${file.path} is not a valid extension nls file`));
return;
}
}
}, function () {
if (_xlf) {
if (_l10nMap?.size > 0) {
const xlfFile = new File({
path: path.join(extensionsProject, extensionName + '.xlf'),
contents: Buffer.from(_xlf.toString(), 'utf8')
contents: Buffer.from((0, l10n_dev_1.getL10nXlf)(_l10nMap), 'utf8')
});
folderStream.queue(xlfFile);
}
@@ -712,299 +660,7 @@ function createXlfFilesForIsl() {
});
}
exports.createXlfFilesForIsl = createXlfFilesForIsl;
function pushXlfFiles(apiHostname, username, password) {
const tryGetPromises = [];
const updateCreatePromises = [];
return (0, event_stream_1.through)(function (file) {
const project = path.dirname(file.relative);
const fileName = path.basename(file.path);
const slug = fileName.substr(0, fileName.length - '.xlf'.length);
const credentials = `${username}:${password}`;
// Check if resource already exists, if not, then create it.
let promise = tryGetResource(project, slug, apiHostname, credentials);
tryGetPromises.push(promise);
promise.then(exists => {
if (exists) {
promise = updateResource(project, slug, file, apiHostname, credentials);
}
else {
promise = createResource(project, slug, file, apiHostname, credentials);
}
updateCreatePromises.push(promise);
});
}, function () {
// End the pipe only after all the communication with Transifex API happened
Promise.all(tryGetPromises).then(() => {
Promise.all(updateCreatePromises).then(() => {
this.queue(null);
}).catch((reason) => { throw new Error(reason); });
}).catch((reason) => { throw new Error(reason); });
});
}
exports.pushXlfFiles = pushXlfFiles;
function getAllResources(project, apiHostname, username, password) {
return new Promise((resolve, reject) => {
const credentials = `${username}:${password}`;
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resources`,
auth: credentials,
method: 'GET'
};
const request = https.request(options, (res) => {
const buffer = [];
res.on('data', (chunk) => buffer.push(chunk));
res.on('end', () => {
if (res.statusCode === 200) {
const json = JSON.parse(Buffer.concat(buffer).toString());
if (Array.isArray(json)) {
resolve(json.map(o => o.slug));
return;
}
reject(`Unexpected data format. Response code: ${res.statusCode}.`);
}
else {
reject(`No resources in ${project} returned no data. Response code: ${res.statusCode}.`);
}
});
});
request.on('error', (err) => {
reject(`Failed to query resources in ${project} with the following error: ${err}. ${options.path}`);
});
request.end();
});
}
function findObsoleteResources(apiHostname, username, password) {
const resourcesByProject = Object.create(null);
resourcesByProject[extensionsProject] = [].concat(exports.externalExtensionsWithTranslations); // clone
return (0, event_stream_1.through)(function (file) {
const project = path.dirname(file.relative);
const fileName = path.basename(file.path);
const slug = fileName.substr(0, fileName.length - '.xlf'.length);
let slugs = resourcesByProject[project];
if (!slugs) {
resourcesByProject[project] = slugs = [];
}
slugs.push(slug);
this.push(file);
}, function () {
const json = JSON.parse(fs.readFileSync('./build/lib/i18n.resources.json', 'utf8'));
const i18Resources = [...json.editor, ...json.workbench].map((r) => r.project + '/' + r.name.replace(/\//g, '_'));
const extractedResources = [];
for (const project of [workbenchProject, editorProject]) {
for (const resource of resourcesByProject[project]) {
if (resource !== 'setup_messages') {
extractedResources.push(project + '/' + resource);
}
}
}
if (i18Resources.length !== extractedResources.length) {
console.log(`[i18n] Obsolete resources in file 'build/lib/i18n.resources.json': JSON.stringify(${i18Resources.filter(p => extractedResources.indexOf(p) === -1)})`);
console.log(`[i18n] Missing resources in file 'build/lib/i18n.resources.json': JSON.stringify(${extractedResources.filter(p => i18Resources.indexOf(p) === -1)})`);
}
const promises = [];
for (const project in resourcesByProject) {
promises.push(getAllResources(project, apiHostname, username, password).then(resources => {
const expectedResources = resourcesByProject[project];
const unusedResources = resources.filter(resource => resource && expectedResources.indexOf(resource) === -1);
if (unusedResources.length) {
console.log(`[transifex] Obsolete resources in project '${project}': ${unusedResources.join(', ')}`);
}
}));
}
return Promise.all(promises).then(_ => {
this.push(null);
}).catch((reason) => { throw new Error(reason); });
});
}
exports.findObsoleteResources = findObsoleteResources;
function tryGetResource(project, slug, apiHostname, credentials) {
return new Promise((resolve, reject) => {
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resource/${slug}/?details`,
auth: credentials,
method: 'GET'
};
const request = https.request(options, (response) => {
if (response.statusCode === 404) {
resolve(false);
}
else if (response.statusCode === 200) {
resolve(true);
}
else {
reject(`Failed to query resource ${project}/${slug}. Response: ${response.statusCode} ${response.statusMessage}`);
}
});
request.on('error', (err) => {
reject(`Failed to get ${project}/${slug} on Transifex: ${err}`);
});
request.end();
});
}
function createResource(project, slug, xlfFile, apiHostname, credentials) {
return new Promise((_resolve, reject) => {
const data = JSON.stringify({
'content': xlfFile.contents.toString(),
'name': slug,
'slug': slug,
'i18n_type': 'XLIFF'
});
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resources`,
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(data)
},
auth: credentials,
method: 'POST'
};
const request = https.request(options, (res) => {
if (res.statusCode === 201) {
log(`Resource ${project}/${slug} successfully created on Transifex.`);
}
else {
reject(`Something went wrong in the request creating ${slug} in ${project}. ${res.statusCode}`);
}
});
request.on('error', (err) => {
reject(`Failed to create ${project}/${slug} on Transifex: ${err}`);
});
request.write(data);
request.end();
});
}
/**
* The following link provides information about how Transifex handles updates of a resource file:
* https://dev.befoolish.co/tx-docs/public/projects/updating-content#what-happens-when-you-update-files
*/
function updateResource(project, slug, xlfFile, apiHostname, credentials) {
return new Promise((resolve, reject) => {
const data = JSON.stringify({ content: xlfFile.contents.toString() });
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resource/${slug}/content`,
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(data)
},
auth: credentials,
method: 'PUT'
};
const request = https.request(options, (res) => {
if (res.statusCode === 200) {
res.setEncoding('utf8');
let responseBuffer = '';
res.on('data', function (chunk) {
responseBuffer += chunk;
});
res.on('end', () => {
const response = JSON.parse(responseBuffer);
log(`Resource ${project}/${slug} successfully updated on Transifex. Strings added: ${response.strings_added}, updated: ${response.strings_added}, deleted: ${response.strings_added}`);
resolve();
});
}
else {
reject(`Something went wrong in the request updating ${slug} in ${project}. ${res.statusCode}`);
}
});
request.on('error', (err) => {
reject(`Failed to update ${project}/${slug} on Transifex: ${err}`);
});
request.write(data);
request.end();
});
}
function pullSetupXlfFiles(apiHostname, username, password, language, includeDefault) {
const setupResources = [{ name: 'setup_messages', project: workbenchProject }];
if (includeDefault) {
setupResources.push({ name: 'setup_default', project: setupProject });
}
return pullXlfFiles(apiHostname, username, password, language, setupResources);
}
exports.pullSetupXlfFiles = pullSetupXlfFiles;
function pullXlfFiles(apiHostname, username, password, language, resources) {
const credentials = `${username}:${password}`;
const expectedTranslationsCount = resources.length;
let translationsRetrieved = 0, called = false;
return (0, event_stream_1.readable)(function (_count, callback) {
// Mark end of stream when all resources were retrieved
if (translationsRetrieved === expectedTranslationsCount) {
return this.emit('end');
}
if (!called) {
called = true;
const stream = this;
resources.map(function (resource) {
retrieveResource(language, resource, apiHostname, credentials).then((file) => {
if (file) {
stream.emit('data', file);
}
translationsRetrieved++;
}).catch(error => { throw new Error(error); });
});
}
callback();
});
}
const limiter = new Limiter(NUMBER_OF_CONCURRENT_DOWNLOADS);
function retrieveResource(language, resource, apiHostname, credentials) {
return limiter.queue(() => new Promise((resolve, reject) => {
const slug = resource.name.replace(/\//g, '_');
const project = resource.project;
const transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id;
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resource/${slug}/translation/${transifexLanguageId}?file&mode=onlyreviewed`,
auth: credentials,
port: 443,
method: 'GET'
};
console.log('[transifex] Fetching ' + options.path);
const request = https.request(options, (res) => {
const xlfBuffer = [];
res.on('data', (chunk) => xlfBuffer.push(chunk));
res.on('end', () => {
if (res.statusCode === 200) {
resolve(new File({ contents: Buffer.concat(xlfBuffer), path: `${project}/${slug}.xlf` }));
}
else if (res.statusCode === 404) {
console.log(`[transifex] ${slug} in ${project} returned no data.`);
resolve(null);
}
else {
reject(`${slug} in ${project} returned no data. Response code: ${res.statusCode}.`);
}
});
});
request.on('error', (err) => {
reject(`Failed to query resource ${slug} with the following error: ${err}. ${options.path}`);
});
request.end();
}));
}
function prepareI18nFiles() {
const parsePromises = [];
return (0, event_stream_1.through)(function (xlf) {
const stream = this;
const parsePromise = XLF.parse(xlf.contents.toString());
parsePromises.push(parsePromise);
parsePromise.then(resolvedFiles => {
resolvedFiles.forEach(file => {
const translatedFile = createI18nFile(file.originalFilePath, file.messages);
stream.queue(translatedFile);
});
});
}, function () {
Promise.all(parsePromises)
.then(() => { this.queue(null); })
.catch(reason => { throw new Error(reason); });
});
}
exports.prepareI18nFiles = prepareI18nFiles;
function createI18nFile(originalFilePath, messages) {
function createI18nFile(name, messages) {
const result = Object.create(null);
result[''] = [
'--------------------------------------------------------------------------------------------',
@@ -1021,12 +677,20 @@ function createI18nFile(originalFilePath, messages) {
content = content.replace(/\n/g, '\r\n');
}
return new File({
path: path.join(originalFilePath + '.i18n.json'),
path: path.join(name + '.i18n.json'),
contents: Buffer.from(content, 'utf8')
});
}
const i18nPackVersion = '1.0.0';
function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pseudo = false) {
function getRecordFromL10nJsonFormat(l10nJsonFormat) {
const record = {};
for (const key of Object.keys(l10nJsonFormat)) {
const value = l10nJsonFormat[key];
record[key] = typeof value === 'string' ? value : value.message;
}
return record;
}
function prepareI18nPackFiles(resultingTranslationPaths) {
const parsePromises = [];
const mainPack = { version: i18nPackVersion, contents: {} };
const extensionsPacks = {};
@@ -1036,28 +700,28 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pse
const resource = path.basename(xlf.relative, '.xlf');
const contents = xlf.contents.toString();
log(`Found ${project}: ${resource}`);
const parsePromise = pseudo ? XLF.parsePseudo(contents) : XLF.parse(contents);
const parsePromise = (0, l10n_dev_1.getL10nFilesFromXlf)(contents);
parsePromises.push(parsePromise);
parsePromise.then(resolvedFiles => {
resolvedFiles.forEach(file => {
const path = file.originalFilePath;
const path = file.name;
const firstSlash = path.indexOf('/');
if (project === extensionsProject) {
let extPack = extensionsPacks[resource];
if (!extPack) {
extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} };
}
const externalId = externalExtensions[resource];
const externalId = externalExtensionsWithTranslations[resource];
if (!externalId) { // internal extension: remove 'extensions/extensionId/' segnent
const secondSlash = path.indexOf('/', firstSlash + 1);
extPack.contents[path.substr(secondSlash + 1)] = file.messages;
extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
}
else {
extPack.contents[path] = file.messages;
extPack.contents[path] = getRecordFromL10nJsonFormat(file.messages);
}
}
else {
mainPack.contents[path.substr(firstSlash + 1)] = file.messages;
mainPack.contents[path.substring(firstSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
}
});
}).catch(reason => {
@@ -1075,7 +739,7 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pse
for (const extension in extensionsPacks) {
const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]);
this.queue(translatedExtFile);
const externalExtensionId = externalExtensions[extension];
const externalExtensionId = externalExtensionsWithTranslations[extension];
if (externalExtensionId) {
resultingTranslationPaths.push({ id: externalExtensionId, resourceName: `extensions/${extension}.i18n.json` });
}
@@ -1099,7 +763,7 @@ function prepareIslFiles(language, innoSetupConfig) {
parsePromises.push(parsePromise);
parsePromise.then(resolvedFiles => {
resolvedFiles.forEach(file => {
const translatedFile = createIslFile(file.originalFilePath, file.messages, language, innoSetupConfig);
const translatedFile = createIslFile(file.name, file.messages, language, innoSetupConfig);
stream.queue(translatedFile);
});
}).catch(reason => {
@@ -1114,14 +778,14 @@ function prepareIslFiles(language, innoSetupConfig) {
});
}
exports.prepareIslFiles = prepareIslFiles;
function createIslFile(originalFilePath, messages, language, innoSetup) {
function createIslFile(name, messages, language, innoSetup) {
const content = [];
let originalContent;
if (path.basename(originalFilePath) === 'Default') {
originalContent = new TextModel(fs.readFileSync(originalFilePath + '.isl', 'utf8'));
if (path.basename(name) === 'Default') {
originalContent = new TextModel(fs.readFileSync(name + '.isl', 'utf8'));
}
else {
originalContent = new TextModel(fs.readFileSync(originalFilePath + '.en.isl', 'utf8'));
originalContent = new TextModel(fs.readFileSync(name + '.en.isl', 'utf8'));
}
originalContent.lines.forEach(line => {
if (line.length > 0) {
@@ -1143,7 +807,7 @@ function createIslFile(originalFilePath, messages, language, innoSetup) {
}
}
});
const basename = path.basename(originalFilePath);
const basename = path.basename(name);
const filePath = `${basename}.${language.id}.isl`;
const encoded = iconv.encode(Buffer.from(content.join('\r\n'), 'utf8').toString(), innoSetup.codePage);
return new File({
@@ -1174,6 +838,3 @@ function encodeEntities(value) {
function decodeEntities(value) {
return value.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
}
function pseudify(message) {
return '\uFF3B' + message.replace(/[aouei]/g, '$&$&') + '\uFF3D';
}
+4
View File
@@ -306,6 +306,10 @@
"name": "vs/workbench/contrib/offline",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/remoteTunnel",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/services/actions",
"project": "vscode-workbench"
+100 -489
View File
@@ -6,17 +6,15 @@
import * as path from 'path';
import * as fs from 'fs';
import { through, readable, ThroughStream } from 'event-stream';
import { merge, through, ThroughStream, writeArray } from 'event-stream';
import * as File from 'vinyl';
import * as Is from 'is';
import * as xml2js from 'xml2js';
import * as https from 'https';
import * as gulp from 'gulp';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
import * as iconv from '@vscode/iconv-lite-umd';
const NUMBER_OF_CONCURRENT_DOWNLOADS = 4;
import { l10nJsonFormat, getL10nXlf, l10nJsonDetails, getL10nFilesFromXlf, getL10nJson } from '@vscode/l10n-dev';
function log(message: any, ...rest: any[]): void {
fancyLog(ansiColors.green('[i18n]'), message, ...rest);
@@ -52,17 +50,12 @@ export const extraLanguages: Language[] = [
];
// non built-in extensions also that are transifex and need to be part of the language packs
export const externalExtensionsWithTranslations = {
const externalExtensionsWithTranslations: Record<string, string> = {
'vscode-chrome-debug': 'msjsdiag.debugger-for-chrome',
'vscode-node-debug': 'ms-vscode.node-debug',
'vscode-node-debug2': 'ms-vscode.node-debug2'
};
interface Map<V> {
[key: string]: V;
}
interface Item {
id: string;
message: string;
@@ -74,12 +67,6 @@ export interface Resource {
project: string;
}
interface ParsedXLF {
messages: Map<string>;
originalFilePath: string;
language: string;
}
interface LocalizeInfo {
key: string;
comment: string[];
@@ -93,9 +80,9 @@ module LocalizeInfo {
}
interface BundledFormat {
keys: Map<(string | LocalizeInfo)[]>;
messages: Map<string[]>;
bundles: Map<string[]>;
keys: Record<string, (string | LocalizeInfo)[]>;
messages: Record<string, string[]>;
bundles: Record<string, string[]>;
}
module BundledFormat {
@@ -111,27 +98,6 @@ module BundledFormat {
}
}
interface ValueFormat {
message: string;
comment: string[];
}
interface PackageJsonFormat {
[key: string]: string | ValueFormat;
}
module PackageJsonFormat {
export function is(value: any): value is PackageJsonFormat {
if (Is.undef(value) || !Is.object(value)) {
return false;
}
return Object.keys(value).every(key => {
const element = value[key];
return Is.string(element) || (Is.object(element) && Is.defined(element.message) && Is.defined(element.comment));
});
}
}
interface BundledExtensionFormat {
[key: string]: {
messages: string[];
@@ -181,7 +147,7 @@ class TextModel {
export class XLF {
private buffer: string[];
private files: Map<Item[]>;
private files: Record<string, Item[]>;
public numberOfMessages: number;
constructor(public project: string) {
@@ -274,37 +240,11 @@ export class XLF {
this.buffer.push(line.toString());
}
static parsePseudo = function (xlfString: string): Promise<ParsedXLF[]> {
return new Promise((resolve) => {
const parser = new xml2js.Parser();
const files: { messages: Map<string>; originalFilePath: string; language: string }[] = [];
parser.parseString(xlfString, function (_err: any, result: any) {
const fileNodes: any[] = result['xliff']['file'];
fileNodes.forEach(file => {
const originalFilePath = file.$.original;
const messages: Map<string> = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit: any) => {
const key = unit.$.id;
const val = pseudify(unit.source[0]['_'].toString());
if (key && val) {
messages[key] = decodeEntities(val);
}
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: 'ps' });
}
});
resolve(files);
});
});
};
static parse = function (xlfString: string): Promise<ParsedXLF[]> {
static parse = function (xlfString: string): Promise<l10nJsonDetails[]> {
return new Promise((resolve, reject) => {
const parser = new xml2js.Parser();
const files: { messages: Map<string>; originalFilePath: string; language: string }[] = [];
const files: { messages: Record<string, string>; name: string; language: string }[] = [];
parser.parseString(xlfString, function (err: any, result: any) {
if (err) {
@@ -317,15 +257,15 @@ export class XLF {
}
fileNodes.forEach((file) => {
const originalFilePath = file.$.original;
if (!originalFilePath) {
const name = file.$.original;
if (!name) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`));
}
const language = file.$['target-language'];
if (!language) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`));
}
const messages: Map<string> = {};
const messages: Record<string, string> = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
@@ -341,12 +281,12 @@ export class XLF {
val = val._ ? val._ : '';
}
if (!key) {
reject(new Error(`XLF parsing error: trans-unit ${JSON.stringify(unit, undefined, 0)} defined in file ${originalFilePath} is missing the ID attribute.`));
reject(new Error(`XLF parsing error: trans-unit ${JSON.stringify(unit, undefined, 0)} defined in file ${name} is missing the ID attribute.`));
return;
}
messages[key] = decodeEntities(val);
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: language.toLowerCase() });
files.push({ messages, name, language: language.toLowerCase() });
}
});
@@ -356,49 +296,6 @@ export class XLF {
};
}
export interface ITask<T> {
(): T;
}
interface ILimitedTaskFactory<T> {
factory: ITask<Promise<T>>;
c: (value?: T | Promise<T>) => void;
e: (error?: any) => void;
}
export class Limiter<T> {
private runningPromises: number;
private outstandingPromises: ILimitedTaskFactory<any>[];
constructor(private maxDegreeOfParalellism: number) {
this.outstandingPromises = [];
this.runningPromises = 0;
}
queue(factory: ITask<Promise<T>>): Promise<T> {
return new Promise<T>((c, e) => {
this.outstandingPromises.push({ factory, c, e });
this.consume();
});
}
private consume(): void {
while (this.outstandingPromises.length && this.runningPromises < this.maxDegreeOfParalellism) {
const iLimitedTask = this.outstandingPromises.shift()!;
this.runningPromises++;
const promise = iLimitedTask.factory();
promise.then(iLimitedTask.c).catch(iLimitedTask.e);
promise.then(() => this.consumed()).catch(() => this.consumed());
}
}
private consumed(): void {
this.runningPromises--;
this.consume();
}
}
function sortLanguages(languages: Language[]): Language[] {
return languages.sort((a: Language, b: Language): number => {
return a.id < b.id ? -1 : (a.id > b.id ? 1 : 0);
@@ -480,9 +377,9 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
const messageSection = json.messages;
const bundleSection = json.bundles;
const statistics: Map<number> = Object.create(null);
const statistics: Record<string, number> = Object.create(null);
const defaultMessages: Map<Map<string>> = Object.create(null);
const defaultMessages: Record<string, Record<string, string>> = Object.create(null);
const modules = Object.keys(keysSection);
modules.forEach((module) => {
const keys = keysSection[module];
@@ -491,7 +388,7 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
emitter.emit('error', `Message for module ${module} corrupted. Mismatch in number of keys and messages.`);
return;
}
const messageMap: Map<string> = Object.create(null);
const messageMap: Record<string, string> = Object.create(null);
defaultMessages[module] = messageMap;
keys.map((key, i) => {
if (typeof key === 'string') {
@@ -514,7 +411,7 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
}
statistics[language.id] = 0;
const localizedModules: Map<string[]> = Object.create(null);
const localizedModules: Record<string, string[]> = Object.create(null);
const languageFolderName = language.translationId || language.id;
const i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json');
let allMessages: I18nFormat | undefined;
@@ -648,7 +545,7 @@ export function createXlfFilesForCoreBundle(): ThroughStream {
const basename = path.basename(file.path);
if (basename === 'nls.metadata.json') {
if (file.isBuffer()) {
const xlfs: Map<XLF> = Object.create(null);
const xlfs: Record<string, XLF> = Object.create(null);
const json: BundledFormat = JSON.parse((file.contents as Buffer).toString('utf8'));
for (const coreModule in json.keys) {
const projectResource = getResource(coreModule);
@@ -689,6 +586,32 @@ export function createXlfFilesForCoreBundle(): ThroughStream {
});
}
function createL10nBundleForExtension(extensionName: string): ThroughStream {
const result = through();
gulp.src([
`extensions/${extensionName}/src/**/*.ts`,
]).pipe(writeArray((err, files: File[]) => {
if (err) {
result.emit('error', err);
return;
}
const json = getL10nJson(files.map(file => {
return file.contents.toString('utf8');
}));
if (Object.keys(json).length > 0) {
result.emit('data', new File({
path: `${extensionName}/bundle.l10n.json`,
contents: Buffer.from(JSON.stringify(json), 'utf8')
}));
}
result.emit('end');
}));
return result;
}
export function createXlfFilesForExtensions(): ThroughStream {
let counter: number = 0;
let folderStreamEnded: boolean = false;
@@ -704,55 +627,52 @@ export function createXlfFilesForExtensions(): ThroughStream {
return;
}
counter++;
let _xlf: XLF;
function getXlf() {
if (!_xlf) {
_xlf = new XLF(extensionsProject);
let _l10nMap: Map<string, l10nJsonFormat>;
function getL10nMap() {
if (!_l10nMap) {
_l10nMap = new Map();
}
return _xlf;
return _l10nMap;
}
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(through(function (file: File) {
merge(
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }),
createL10nBundleForExtension(extensionName)
).pipe(through(function (file: File) {
if (file.isBuffer()) {
const buffer: Buffer = file.contents as Buffer;
const basename = path.basename(file.path);
if (basename === 'package.nls.json') {
const json: PackageJsonFormat = JSON.parse(buffer.toString('utf8'));
const keys: Array<string | LocalizeInfo> = [];
const messages: string[] = [];
Object.keys(json).forEach((key) => {
const value = json[key];
if (Is.string(value)) {
keys.push(key);
messages.push(value);
} else if (value) {
keys.push({
key,
comment: value.comment
});
messages.push(value.message);
} else {
keys.push(key);
messages.push(`Unknown message for key: ${key}`);
}
});
getXlf().addFile(`extensions/${extensionName}/package`, keys, messages);
const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/package`, json);
} else if (basename === 'nls.metadata.json') {
const json: BundledExtensionFormat = JSON.parse(buffer.toString('utf8'));
const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path));
for (const file in json) {
const fileContent = json[file];
getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages);
const info: l10nJsonFormat = Object.create(null);
for (let i = 0; i < fileContent.messages.length; i++) {
const message = fileContent.messages[i];
const { key, comment } = LocalizeInfo.is(fileContent.keys[i])
? fileContent.keys[i] as LocalizeInfo
: { key: fileContent.keys[i] as string, comment: undefined };
info[key] = comment ? { message, comment } : message;
}
getL10nMap().set(`extensions/${extensionName}/${relPath}/${file}`, info);
}
} else if (basename === 'bundle.l10n.json') {
const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/bundle`, json);
} else {
this.emit('error', new Error(`${file.path} is not a valid extension nls file`));
return;
}
}
}, function () {
if (_xlf) {
if (_l10nMap?.size > 0) {
const xlfFile = new File({
path: path.join(extensionsProject, extensionName + '.xlf'),
contents: Buffer.from(_xlf.toString(), 'utf8')
contents: Buffer.from(getL10nXlf(_l10nMap), 'utf8')
});
folderStream.queue(xlfFile);
}
@@ -828,321 +748,7 @@ export function createXlfFilesForIsl(): ThroughStream {
});
}
export function pushXlfFiles(apiHostname: string, username: string, password: string): ThroughStream {
const tryGetPromises: Array<Promise<boolean>> = [];
const updateCreatePromises: Array<Promise<boolean>> = [];
return through(function (this: ThroughStream, file: File) {
const project = path.dirname(file.relative);
const fileName = path.basename(file.path);
const slug = fileName.substr(0, fileName.length - '.xlf'.length);
const credentials = `${username}:${password}`;
// Check if resource already exists, if not, then create it.
let promise = tryGetResource(project, slug, apiHostname, credentials);
tryGetPromises.push(promise);
promise.then(exists => {
if (exists) {
promise = updateResource(project, slug, file, apiHostname, credentials);
} else {
promise = createResource(project, slug, file, apiHostname, credentials);
}
updateCreatePromises.push(promise);
});
}, function () {
// End the pipe only after all the communication with Transifex API happened
Promise.all(tryGetPromises).then(() => {
Promise.all(updateCreatePromises).then(() => {
this.queue(null);
}).catch((reason) => { throw new Error(reason); });
}).catch((reason) => { throw new Error(reason); });
});
}
function getAllResources(project: string, apiHostname: string, username: string, password: string): Promise<string[]> {
return new Promise((resolve, reject) => {
const credentials = `${username}:${password}`;
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resources`,
auth: credentials,
method: 'GET'
};
const request = https.request(options, (res) => {
const buffer: Buffer[] = [];
res.on('data', (chunk: Buffer) => buffer.push(chunk));
res.on('end', () => {
if (res.statusCode === 200) {
const json = JSON.parse(Buffer.concat(buffer).toString());
if (Array.isArray(json)) {
resolve(json.map(o => o.slug));
return;
}
reject(`Unexpected data format. Response code: ${res.statusCode}.`);
} else {
reject(`No resources in ${project} returned no data. Response code: ${res.statusCode}.`);
}
});
});
request.on('error', (err) => {
reject(`Failed to query resources in ${project} with the following error: ${err}. ${options.path}`);
});
request.end();
});
}
export function findObsoleteResources(apiHostname: string, username: string, password: string): ThroughStream {
const resourcesByProject: Map<string[]> = Object.create(null);
resourcesByProject[extensionsProject] = ([] as any[]).concat(externalExtensionsWithTranslations); // clone
return through(function (this: ThroughStream, file: File) {
const project = path.dirname(file.relative);
const fileName = path.basename(file.path);
const slug = fileName.substr(0, fileName.length - '.xlf'.length);
let slugs = resourcesByProject[project];
if (!slugs) {
resourcesByProject[project] = slugs = [];
}
slugs.push(slug);
this.push(file);
}, function () {
const json = JSON.parse(fs.readFileSync('./build/lib/i18n.resources.json', 'utf8'));
const i18Resources = [...json.editor, ...json.workbench].map((r: Resource) => r.project + '/' + r.name.replace(/\//g, '_'));
const extractedResources: string[] = [];
for (const project of [workbenchProject, editorProject]) {
for (const resource of resourcesByProject[project]) {
if (resource !== 'setup_messages') {
extractedResources.push(project + '/' + resource);
}
}
}
if (i18Resources.length !== extractedResources.length) {
console.log(`[i18n] Obsolete resources in file 'build/lib/i18n.resources.json': JSON.stringify(${i18Resources.filter(p => extractedResources.indexOf(p) === -1)})`);
console.log(`[i18n] Missing resources in file 'build/lib/i18n.resources.json': JSON.stringify(${extractedResources.filter(p => i18Resources.indexOf(p) === -1)})`);
}
const promises: Array<Promise<void>> = [];
for (const project in resourcesByProject) {
promises.push(
getAllResources(project, apiHostname, username, password).then(resources => {
const expectedResources = resourcesByProject[project];
const unusedResources = resources.filter(resource => resource && expectedResources.indexOf(resource) === -1);
if (unusedResources.length) {
console.log(`[transifex] Obsolete resources in project '${project}': ${unusedResources.join(', ')}`);
}
})
);
}
return Promise.all(promises).then(_ => {
this.push(null);
}).catch((reason) => { throw new Error(reason); });
});
}
function tryGetResource(project: string, slug: string, apiHostname: string, credentials: string): Promise<boolean> {
return new Promise((resolve, reject) => {
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resource/${slug}/?details`,
auth: credentials,
method: 'GET'
};
const request = https.request(options, (response) => {
if (response.statusCode === 404) {
resolve(false);
} else if (response.statusCode === 200) {
resolve(true);
} else {
reject(`Failed to query resource ${project}/${slug}. Response: ${response.statusCode} ${response.statusMessage}`);
}
});
request.on('error', (err) => {
reject(`Failed to get ${project}/${slug} on Transifex: ${err}`);
});
request.end();
});
}
function createResource(project: string, slug: string, xlfFile: File, apiHostname: string, credentials: any): Promise<any> {
return new Promise((_resolve, reject) => {
const data = JSON.stringify({
'content': xlfFile.contents.toString(),
'name': slug,
'slug': slug,
'i18n_type': 'XLIFF'
});
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resources`,
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(data)
},
auth: credentials,
method: 'POST'
};
const request = https.request(options, (res) => {
if (res.statusCode === 201) {
log(`Resource ${project}/${slug} successfully created on Transifex.`);
} else {
reject(`Something went wrong in the request creating ${slug} in ${project}. ${res.statusCode}`);
}
});
request.on('error', (err) => {
reject(`Failed to create ${project}/${slug} on Transifex: ${err}`);
});
request.write(data);
request.end();
});
}
/**
* The following link provides information about how Transifex handles updates of a resource file:
* https://dev.befoolish.co/tx-docs/public/projects/updating-content#what-happens-when-you-update-files
*/
function updateResource(project: string, slug: string, xlfFile: File, apiHostname: string, credentials: string): Promise<any> {
return new Promise<void>((resolve, reject) => {
const data = JSON.stringify({ content: xlfFile.contents.toString() });
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resource/${slug}/content`,
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(data)
},
auth: credentials,
method: 'PUT'
};
const request = https.request(options, (res) => {
if (res.statusCode === 200) {
res.setEncoding('utf8');
let responseBuffer: string = '';
res.on('data', function (chunk) {
responseBuffer += chunk;
});
res.on('end', () => {
const response = JSON.parse(responseBuffer);
log(`Resource ${project}/${slug} successfully updated on Transifex. Strings added: ${response.strings_added}, updated: ${response.strings_added}, deleted: ${response.strings_added}`);
resolve();
});
} else {
reject(`Something went wrong in the request updating ${slug} in ${project}. ${res.statusCode}`);
}
});
request.on('error', (err) => {
reject(`Failed to update ${project}/${slug} on Transifex: ${err}`);
});
request.write(data);
request.end();
});
}
export function pullSetupXlfFiles(apiHostname: string, username: string, password: string, language: Language, includeDefault: boolean): NodeJS.ReadableStream {
const setupResources = [{ name: 'setup_messages', project: workbenchProject }];
if (includeDefault) {
setupResources.push({ name: 'setup_default', project: setupProject });
}
return pullXlfFiles(apiHostname, username, password, language, setupResources);
}
function pullXlfFiles(apiHostname: string, username: string, password: string, language: Language, resources: Resource[]): NodeJS.ReadableStream {
const credentials = `${username}:${password}`;
const expectedTranslationsCount = resources.length;
let translationsRetrieved = 0, called = false;
return readable(function (_count: any, callback: any) {
// Mark end of stream when all resources were retrieved
if (translationsRetrieved === expectedTranslationsCount) {
return this.emit('end');
}
if (!called) {
called = true;
const stream = this;
resources.map(function (resource) {
retrieveResource(language, resource, apiHostname, credentials).then((file: File | null) => {
if (file) {
stream.emit('data', file);
}
translationsRetrieved++;
}).catch(error => { throw new Error(error); });
});
}
callback();
});
}
const limiter = new Limiter<File | null>(NUMBER_OF_CONCURRENT_DOWNLOADS);
function retrieveResource(language: Language, resource: Resource, apiHostname: string, credentials: string): Promise<File | null> {
return limiter.queue(() => new Promise<File | null>((resolve, reject) => {
const slug = resource.name.replace(/\//g, '_');
const project = resource.project;
const transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id;
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resource/${slug}/translation/${transifexLanguageId}?file&mode=onlyreviewed`,
auth: credentials,
port: 443,
method: 'GET'
};
console.log('[transifex] Fetching ' + options.path);
const request = https.request(options, (res) => {
const xlfBuffer: Buffer[] = [];
res.on('data', (chunk: Buffer) => xlfBuffer.push(chunk));
res.on('end', () => {
if (res.statusCode === 200) {
resolve(new File({ contents: Buffer.concat(xlfBuffer), path: `${project}/${slug}.xlf` }));
} else if (res.statusCode === 404) {
console.log(`[transifex] ${slug} in ${project} returned no data.`);
resolve(null);
} else {
reject(`${slug} in ${project} returned no data. Response code: ${res.statusCode}.`);
}
});
});
request.on('error', (err) => {
reject(`Failed to query resource ${slug} with the following error: ${err}. ${options.path}`);
});
request.end();
}));
}
export function prepareI18nFiles(): ThroughStream {
const parsePromises: Promise<ParsedXLF[]>[] = [];
return through(function (this: ThroughStream, xlf: File) {
const stream = this;
const parsePromise = XLF.parse(xlf.contents.toString());
parsePromises.push(parsePromise);
parsePromise.then(
resolvedFiles => {
resolvedFiles.forEach(file => {
const translatedFile = createI18nFile(file.originalFilePath, file.messages);
stream.queue(translatedFile);
});
}
);
}, function () {
Promise.all(parsePromises)
.then(() => { this.queue(null); })
.catch(reason => { throw new Error(reason); });
});
}
function createI18nFile(originalFilePath: string, messages: any): File {
function createI18nFile(name: string, messages: any): File {
const result = Object.create(null);
result[''] = [
'--------------------------------------------------------------------------------------------',
@@ -1160,7 +766,7 @@ function createI18nFile(originalFilePath: string, messages: any): File {
content = content.replace(/\n/g, '\r\n');
}
return new File({
path: path.join(originalFilePath + '.i18n.json'),
path: path.join(name + '.i18n.json'),
contents: Buffer.from(content, 'utf8')
});
}
@@ -1168,7 +774,7 @@ function createI18nFile(originalFilePath: string, messages: any): File {
interface I18nPack {
version: string;
contents: {
[path: string]: Map<string>;
[path: string]: Record<string, string>;
};
}
@@ -1179,22 +785,31 @@ export interface TranslationPath {
resourceName: string;
}
export function prepareI18nPackFiles(externalExtensions: Map<string>, resultingTranslationPaths: TranslationPath[], pseudo = false): NodeJS.ReadWriteStream {
const parsePromises: Promise<ParsedXLF[]>[] = [];
function getRecordFromL10nJsonFormat(l10nJsonFormat: l10nJsonFormat): Record<string, string> {
const record: Record<string, string> = {};
for (const key of Object.keys(l10nJsonFormat)) {
const value = l10nJsonFormat[key];
record[key] = typeof value === 'string' ? value : value.message;
}
return record;
}
export function prepareI18nPackFiles(resultingTranslationPaths: TranslationPath[]): NodeJS.ReadWriteStream {
const parsePromises: Promise<l10nJsonDetails[]>[] = [];
const mainPack: I18nPack = { version: i18nPackVersion, contents: {} };
const extensionsPacks: Map<I18nPack> = {};
const extensionsPacks: Record<string, I18nPack> = {};
const errors: any[] = [];
return through(function (this: ThroughStream, xlf: File) {
const project = path.basename(path.dirname(path.dirname(xlf.relative)));
const resource = path.basename(xlf.relative, '.xlf');
const contents = xlf.contents.toString();
log(`Found ${project}: ${resource}`);
const parsePromise = pseudo ? XLF.parsePseudo(contents) : XLF.parse(contents);
const parsePromise = getL10nFilesFromXlf(contents);
parsePromises.push(parsePromise);
parsePromise.then(
resolvedFiles => {
resolvedFiles.forEach(file => {
const path = file.originalFilePath;
const path = file.name;
const firstSlash = path.indexOf('/');
if (project === extensionsProject) {
@@ -1202,15 +817,15 @@ export function prepareI18nPackFiles(externalExtensions: Map<string>, resultingT
if (!extPack) {
extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} };
}
const externalId = externalExtensions[resource];
const externalId = externalExtensionsWithTranslations[resource];
if (!externalId) { // internal extension: remove 'extensions/extensionId/' segnent
const secondSlash = path.indexOf('/', firstSlash + 1);
extPack.contents[path.substr(secondSlash + 1)] = file.messages;
extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
} else {
extPack.contents[path] = file.messages;
extPack.contents[path] = getRecordFromL10nJsonFormat(file.messages);
}
} else {
mainPack.contents[path.substr(firstSlash + 1)] = file.messages;
mainPack.contents[path.substring(firstSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
}
});
}
@@ -1231,7 +846,7 @@ export function prepareI18nPackFiles(externalExtensions: Map<string>, resultingT
const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]);
this.queue(translatedExtFile);
const externalExtensionId = externalExtensions[extension];
const externalExtensionId = externalExtensionsWithTranslations[extension];
if (externalExtensionId) {
resultingTranslationPaths.push({ id: externalExtensionId, resourceName: `extensions/${extension}.i18n.json` });
} else {
@@ -1248,7 +863,7 @@ export function prepareI18nPackFiles(externalExtensions: Map<string>, resultingT
}
export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup): ThroughStream {
const parsePromises: Promise<ParsedXLF[]>[] = [];
const parsePromises: Promise<l10nJsonDetails[]>[] = [];
return through(function (this: ThroughStream, xlf: File) {
const stream = this;
@@ -1257,7 +872,7 @@ export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup):
parsePromise.then(
resolvedFiles => {
resolvedFiles.forEach(file => {
const translatedFile = createIslFile(file.originalFilePath, file.messages, language, innoSetupConfig);
const translatedFile = createIslFile(file.name, file.messages, language, innoSetupConfig);
stream.queue(translatedFile);
});
}
@@ -1273,13 +888,13 @@ export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup):
});
}
function createIslFile(originalFilePath: string, messages: Map<string>, language: Language, innoSetup: InnoSetup): File {
function createIslFile(name: string, messages: l10nJsonFormat, language: Language, innoSetup: InnoSetup): File {
const content: string[] = [];
let originalContent: TextModel;
if (path.basename(originalFilePath) === 'Default') {
originalContent = new TextModel(fs.readFileSync(originalFilePath + '.isl', 'utf8'));
if (path.basename(name) === 'Default') {
originalContent = new TextModel(fs.readFileSync(name + '.isl', 'utf8'));
} else {
originalContent = new TextModel(fs.readFileSync(originalFilePath + '.en.isl', 'utf8'));
originalContent = new TextModel(fs.readFileSync(name + '.en.isl', 'utf8'));
}
originalContent.lines.forEach(line => {
if (line.length > 0) {
@@ -1302,7 +917,7 @@ function createIslFile(originalFilePath: string, messages: Map<string>, language
}
});
const basename = path.basename(originalFilePath);
const basename = path.basename(name);
const filePath = `${basename}.${language.id}.isl`;
const encoded = iconv.encode(Buffer.from(content.join('\r\n'), 'utf8').toString(), innoSetup.codePage);
@@ -1336,7 +951,3 @@ function encodeEntities(value: string): string {
function decodeEntities(value: string): string {
return value.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
}
function pseudify(message: string) {
return '\uFF3B' + message.replace(/[aouei]/g, '$&$&') + '\uFF3D';
}
+2 -1
View File
@@ -56,7 +56,8 @@ const CORE_TYPES = [
'MessageChannel',
'MessagePort',
'URL',
'URLSearchParams'
'URLSearchParams',
'ReadonlyArray',
];
// Types that are defined in a common layer but are known to be only
// available in native environments should not be allowed in browser
+2 -1
View File
@@ -57,7 +57,8 @@ const CORE_TYPES = [
'MessageChannel',
'MessagePort',
'URL',
'URLSearchParams'
'URLSearchParams',
'ReadonlyArray',
];
// Types that are defined in a common layer but are known to be only
+1 -1
View File
@@ -180,7 +180,7 @@ function createESMSourcesAndResources2(options) {
+ relativePath
+ fileContents.substring(end + 1));
}
fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) {
fileContents = fileContents.replace(/import ([a-zA-Z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) {
return `import * as ${m1} from ${m2};`;
});
write(getDestAbsoluteFilePath(file), fileContents);
+1 -1
View File
@@ -212,7 +212,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void {
);
}
fileContents = fileContents.replace(/import ([a-zA-z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) {
fileContents = fileContents.replace(/import ([a-zA-Z0-9]+) = require\(('[^']+')\);/g, function (_, m1, m2) {
return `import * as ${m1} from ${m2};`;
});
+3 -3
View File
@@ -9,20 +9,20 @@ const i18n = require("../i18n");
suite('XLF Parser Tests', () => {
const sampleXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source></trans-unit></body></file></xliff>';
const sampleTranslatedXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" target-language="ru" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source><target>Кнопка #1</target></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source><target>Кнопка #2 &amp;</target></trans-unit></body></file></xliff>';
const originalFilePath = 'vs/base/common/keybinding';
const name = 'vs/base/common/keybinding';
const keys = ['key1', 'key2'];
const messages = ['Key #1', 'Key #2 &'];
const translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
test('Keys & messages to XLF conversion', () => {
const xlf = new i18n.XLF('vscode-workbench');
xlf.addFile(originalFilePath, keys, messages);
xlf.addFile(name, keys, messages);
const xlfString = xlf.toString();
assert.strictEqual(xlfString.replace(/\s{2,}/g, ''), sampleXlf);
});
test('XLF to keys & messages conversion', () => {
i18n.XLF.parse(sampleTranslatedXlf).then(function (resolvedFiles) {
assert.deepStrictEqual(resolvedFiles[0].messages, translatedMessages);
assert.strictEqual(resolvedFiles[0].originalFilePath, originalFilePath);
assert.strictEqual(resolvedFiles[0].name, name);
});
});
test('JSON file source path to Transifex resource match', () => {
+3 -3
View File
@@ -9,14 +9,14 @@ import i18n = require('../i18n');
suite('XLF Parser Tests', () => {
const sampleXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source></trans-unit></body></file></xliff>';
const sampleTranslatedXlf = '<?xml version="1.0" encoding="utf-8"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"><file original="vs/base/common/keybinding" source-language="en" target-language="ru" datatype="plaintext"><body><trans-unit id="key1"><source xml:lang="en">Key #1</source><target>Кнопка #1</target></trans-unit><trans-unit id="key2"><source xml:lang="en">Key #2 &amp;</source><target>Кнопка #2 &amp;</target></trans-unit></body></file></xliff>';
const originalFilePath = 'vs/base/common/keybinding';
const name = 'vs/base/common/keybinding';
const keys = ['key1', 'key2'];
const messages = ['Key #1', 'Key #2 &'];
const translatedMessages = { key1: 'Кнопка #1', key2: 'Кнопка #2 &' };
test('Keys & messages to XLF conversion', () => {
const xlf = new i18n.XLF('vscode-workbench');
xlf.addFile(originalFilePath, keys, messages);
xlf.addFile(name, keys, messages);
const xlfString = xlf.toString();
assert.strictEqual(xlfString.replace(/\s{2,}/g, ''), sampleXlf);
@@ -25,7 +25,7 @@ suite('XLF Parser Tests', () => {
test('XLF to keys & messages conversion', () => {
i18n.XLF.parse(sampleTranslatedXlf).then(function (resolvedFiles) {
assert.deepStrictEqual(resolvedFiles[0].messages, translatedMessages);
assert.strictEqual(resolvedFiles[0].originalFilePath, originalFilePath);
assert.strictEqual(resolvedFiles[0].name, name);
});
});
+66 -50
View File
@@ -490,54 +490,56 @@ function markNodes(ts, languageService, options) {
}
const nodeSourceFile = node.getSourceFile();
const loop = (node) => {
const [symbol, symbolImportNode] = getRealNodeSymbol(ts, checker, node);
if (symbolImportNode) {
setColor(symbolImportNode, 2 /* NodeColor.Black */);
const importDeclarationNode = findParentImportDeclaration(symbolImportNode);
if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) {
enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text);
const symbols = getRealNodeSymbol(ts, checker, node);
for (const { symbol, symbolImportNode } of symbols) {
if (symbolImportNode) {
setColor(symbolImportNode, 2 /* NodeColor.Black */);
const importDeclarationNode = findParentImportDeclaration(symbolImportNode);
if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) {
enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text);
}
}
}
if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const declaration = symbol.declarations[i];
if (ts.isSourceFile(declaration)) {
// Do not enqueue full source files
// (they can be the declaration of a module import)
continue;
}
if (options.shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) {
enqueue_black(declaration.name);
for (let j = 0; j < declaration.members.length; j++) {
const member = declaration.members[j];
const memberName = member.name ? member.name.getText() : null;
if (ts.isConstructorDeclaration(member)
|| ts.isConstructSignatureDeclaration(member)
|| ts.isIndexSignatureDeclaration(member)
|| ts.isCallSignatureDeclaration(member)
|| memberName === '[Symbol.iterator]'
|| memberName === '[Symbol.toStringTag]'
|| memberName === 'toJSON'
|| memberName === 'toString'
|| memberName === 'dispose' // TODO: keeping all `dispose` methods
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
) {
enqueue_black(member);
if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const declaration = symbol.declarations[i];
if (ts.isSourceFile(declaration)) {
// Do not enqueue full source files
// (they can be the declaration of a module import)
continue;
}
if (options.shakeLevel === 2 /* ShakeLevel.ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) {
enqueue_black(declaration.name);
for (let j = 0; j < declaration.members.length; j++) {
const member = declaration.members[j];
const memberName = member.name ? member.name.getText() : null;
if (ts.isConstructorDeclaration(member)
|| ts.isConstructSignatureDeclaration(member)
|| ts.isIndexSignatureDeclaration(member)
|| ts.isCallSignatureDeclaration(member)
|| memberName === '[Symbol.iterator]'
|| memberName === '[Symbol.toStringTag]'
|| memberName === 'toJSON'
|| memberName === 'toString'
|| memberName === 'dispose' // TODO: keeping all `dispose` methods
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
) {
enqueue_black(member);
}
if (isStaticMemberWithSideEffects(ts, member)) {
enqueue_black(member);
}
}
if (isStaticMemberWithSideEffects(ts, member)) {
enqueue_black(member);
// queue the heritage clauses
if (declaration.heritageClauses) {
for (const heritageClause of declaration.heritageClauses) {
enqueue_black(heritageClause);
}
}
}
// queue the heritage clauses
if (declaration.heritageClauses) {
for (const heritageClause of declaration.heritageClauses) {
enqueue_black(heritageClause);
}
else {
enqueue_black(declaration);
}
}
else {
enqueue_black(declaration);
}
}
}
node.forEachChild(loop);
@@ -736,13 +738,20 @@ function findSymbolFromHeritageType(ts, checker, type) {
return findSymbolFromHeritageType(ts, checker, type.expression);
}
if (ts.isIdentifier(type)) {
return getRealNodeSymbol(ts, checker, type)[0];
const tmp = getRealNodeSymbol(ts, checker, type);
return (tmp.length > 0 ? tmp[0].symbol : null);
}
if (ts.isPropertyAccessExpression(type)) {
return findSymbolFromHeritageType(ts, checker, type.name);
}
return null;
}
class SymbolImportTuple {
constructor(symbol, symbolImportNode) {
this.symbol = symbol;
this.symbolImportNode = symbolImportNode;
}
}
/**
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
*/
@@ -774,7 +783,7 @@ function getRealNodeSymbol(ts, checker, node) {
}
if (!ts.isShorthandPropertyAssignment(node)) {
if (node.getChildCount() !== 0) {
return [null, null];
return [];
}
}
const { parent } = node;
@@ -820,10 +829,7 @@ function getRealNodeSymbol(ts, checker, node) {
const type = checker.getTypeAtLocation(parent.parent);
if (name && type) {
if (type.isUnion()) {
const prop = type.types[0].getProperty(name);
if (prop) {
symbol = prop;
}
return generateMultipleSymbols(type, name, importNode);
}
else {
const prop = type.getProperty(name);
@@ -854,9 +860,19 @@ function getRealNodeSymbol(ts, checker, node) {
}
}
if (symbol && symbol.declarations) {
return [symbol, importNode];
return [new SymbolImportTuple(symbol, importNode)];
}
return [];
function generateMultipleSymbols(type, name, importNode) {
const result = [];
for (const t of type.types) {
const prop = t.getProperty(name);
if (prop && prop.declarations) {
result.push(new SymbolImportTuple(prop, importNode));
}
}
return result;
}
return [null, null];
}
/** Get the token whose text contains the position */
function getTokenAtPosition(ts, sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) {
+73 -55
View File
@@ -609,58 +609,60 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language
const nodeSourceFile = node.getSourceFile();
const loop = (node: ts.Node) => {
const [symbol, symbolImportNode] = getRealNodeSymbol(ts, checker, node);
if (symbolImportNode) {
setColor(symbolImportNode, NodeColor.Black);
const importDeclarationNode = findParentImportDeclaration(symbolImportNode);
if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) {
enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text);
}
}
if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const declaration = symbol.declarations[i];
if (ts.isSourceFile(declaration)) {
// Do not enqueue full source files
// (they can be the declaration of a module import)
continue;
const symbols = getRealNodeSymbol(ts, checker, node);
for (const { symbol, symbolImportNode } of symbols) {
if (symbolImportNode) {
setColor(symbolImportNode, NodeColor.Black);
const importDeclarationNode = findParentImportDeclaration(symbolImportNode);
if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) {
enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text);
}
}
if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) {
enqueue_black(declaration.name!);
for (let j = 0; j < declaration.members.length; j++) {
const member = declaration.members[j];
const memberName = member.name ? member.name.getText() : null;
if (
ts.isConstructorDeclaration(member)
|| ts.isConstructSignatureDeclaration(member)
|| ts.isIndexSignatureDeclaration(member)
|| ts.isCallSignatureDeclaration(member)
|| memberName === '[Symbol.iterator]'
|| memberName === '[Symbol.toStringTag]'
|| memberName === 'toJSON'
|| memberName === 'toString'
|| memberName === 'dispose'// TODO: keeping all `dispose` methods
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
) {
enqueue_black(member);
}
if (isStaticMemberWithSideEffects(ts, member)) {
enqueue_black(member);
}
if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) {
for (let i = 0, len = symbol.declarations.length; i < len; i++) {
const declaration = symbol.declarations[i];
if (ts.isSourceFile(declaration)) {
// Do not enqueue full source files
// (they can be the declaration of a module import)
continue;
}
// queue the heritage clauses
if (declaration.heritageClauses) {
for (const heritageClause of declaration.heritageClauses) {
enqueue_black(heritageClause);
if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) {
enqueue_black(declaration.name!);
for (let j = 0; j < declaration.members.length; j++) {
const member = declaration.members[j];
const memberName = member.name ? member.name.getText() : null;
if (
ts.isConstructorDeclaration(member)
|| ts.isConstructSignatureDeclaration(member)
|| ts.isIndexSignatureDeclaration(member)
|| ts.isCallSignatureDeclaration(member)
|| memberName === '[Symbol.iterator]'
|| memberName === '[Symbol.toStringTag]'
|| memberName === 'toJSON'
|| memberName === 'toString'
|| memberName === 'dispose'// TODO: keeping all `dispose` methods
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
) {
enqueue_black(member);
}
if (isStaticMemberWithSideEffects(ts, member)) {
enqueue_black(member);
}
}
// queue the heritage clauses
if (declaration.heritageClauses) {
for (const heritageClause of declaration.heritageClauses) {
enqueue_black(heritageClause);
}
}
} else {
enqueue_black(declaration);
}
} else {
enqueue_black(declaration);
}
}
}
@@ -879,7 +881,8 @@ function findSymbolFromHeritageType(ts: typeof import('typescript'), checker: ts
return findSymbolFromHeritageType(ts, checker, type.expression);
}
if (ts.isIdentifier(type)) {
return getRealNodeSymbol(ts, checker, type)[0];
const tmp = getRealNodeSymbol(ts, checker, type);
return (tmp.length > 0 ? tmp[0].symbol : null);
}
if (ts.isPropertyAccessExpression(type)) {
return findSymbolFromHeritageType(ts, checker, type.name);
@@ -887,10 +890,17 @@ function findSymbolFromHeritageType(ts: typeof import('typescript'), checker: ts
return null;
}
class SymbolImportTuple {
constructor(
public readonly symbol: ts.Symbol | null,
public readonly symbolImportNode: ts.Declaration | null
) { }
}
/**
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
*/
function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChecker, node: ts.Node): [ts.Symbol | null, ts.Declaration | null] {
function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChecker, node: ts.Node): SymbolImportTuple[] {
// Use some TypeScript internals to avoid code duplication
type ObjectLiteralElementWithName = ts.ObjectLiteralElement & { name: ts.PropertyName; parent: ts.ObjectLiteralExpression | ts.JsxAttributes };
@@ -923,7 +933,7 @@ function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChec
if (!ts.isShorthandPropertyAssignment(node)) {
if (node.getChildCount() !== 0) {
return [null, null];
return [];
}
}
@@ -976,10 +986,7 @@ function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChec
const type = checker.getTypeAtLocation(parent.parent);
if (name && type) {
if (type.isUnion()) {
const prop = type.types[0].getProperty(name);
if (prop) {
symbol = prop;
}
return generateMultipleSymbols(type, name, importNode);
} else {
const prop = type.getProperty(name);
if (prop) {
@@ -1011,10 +1018,21 @@ function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChec
}
if (symbol && symbol.declarations) {
return [symbol, importNode];
return [new SymbolImportTuple(symbol, importNode)];
}
return [null, null];
return [];
function generateMultipleSymbols(type: ts.UnionType, name: string, importNode: ts.Declaration | null): SymbolImportTuple[] {
const result: SymbolImportTuple[] = [];
for (const t of type.types) {
const prop = t.getProperty(name);
if (prop && prop.declarations) {
result.push(new SymbolImportTuple(prop, importNode));
}
}
return result;
}
}
/** Get the token whose text contains the position */
+1 -3
View File
@@ -4,7 +4,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildWebNodePaths = exports.createExternalLoaderConfig = exports.acquireWebNodePaths = exports.getElectronVersion = exports.streamToPromise = exports.versionStringToNumber = exports.filter = exports.rebase = exports.ensureDir = exports.rreddir = exports.rimraf = exports.rewriteSourceMappingURL = exports.stripSourceMappingURL = exports.loadSourcemaps = exports.cleanNodeModules = exports.skipDirectories = exports.toFileUri = exports.setExecutableBit = exports.fixWin32DirectoryPermissions = exports.debounce = exports.incremental = exports.getVersion = void 0;
exports.buildWebNodePaths = exports.createExternalLoaderConfig = exports.acquireWebNodePaths = exports.getElectronVersion = exports.streamToPromise = exports.versionStringToNumber = exports.filter = exports.rebase = exports.ensureDir = exports.rreddir = exports.rimraf = exports.rewriteSourceMappingURL = exports.stripSourceMappingURL = exports.loadSourcemaps = exports.cleanNodeModules = exports.skipDirectories = exports.toFileUri = exports.setExecutableBit = exports.fixWin32DirectoryPermissions = exports.debounce = exports.incremental = void 0;
const es = require("event-stream");
const _debounce = require("debounce");
const _filter = require("gulp-filter");
@@ -13,8 +13,6 @@ const path = require("path");
const fs = require("fs");
const _rimraf = require("rimraf");
const VinylFile = require("vinyl");
var getVersion_1 = require("./getVersion");
Object.defineProperty(exports, "getVersion", { enumerable: true, get: function () { return getVersion_1.getVersion; } });
const root = path.dirname(path.dirname(__dirname));
const NoCancellationToken = { isCancellationRequested: () => false };
function incremental(streamProvider, initial, supportsCancellation) {
-2
View File
@@ -15,8 +15,6 @@ import * as VinylFile from 'vinyl';
import { ThroughStream } from 'through';
import * as sm from 'source-map';
export { getVersion } from './getVersion';
const root = path.dirname(path.dirname(__dirname));
export interface ICancellationToken {
+1 -1
View File
@@ -23,7 +23,6 @@ exports.dirs = [
'extensions/gulp',
'extensions/html-language-features',
'extensions/html-language-features/server',
'extensions/image-preview',
'extensions/ipynb',
'extensions/jake',
'extensions/json-language-features',
@@ -31,6 +30,7 @@ exports.dirs = [
'extensions/markdown-language-features/server',
'extensions/markdown-language-features',
'extensions/markdown-math',
'extensions/media-preview',
'extensions/merge-conflict',
'extensions/microsoft-authentication',
'extensions/notebook-renderers',
+10 -3
View File
@@ -21,12 +21,19 @@ const path = require('path');
const fs = require('fs');
const cp = require('child_process');
const yarnVersion = cp.execSync('yarn -v', { encoding: 'utf8' }).trim();
const parsedYarnVersion = /^(\d+)\.(\d+)\./.exec(yarnVersion);
const parsedYarnVersion = /^(\d+)\.(\d+)\.(\d+)/.exec(yarnVersion);
const majorYarnVersion = parseInt(parsedYarnVersion[1]);
const minorYarnVersion = parseInt(parsedYarnVersion[2]);
const patchYarnVersion = parseInt(parsedYarnVersion[3]);
if (majorYarnVersion < 1 || minorYarnVersion < 10) {
console.error('\033[1;31m*** Please use yarn >=1.10.1.\033[0;0m');
if (
majorYarnVersion < 1 ||
majorYarnVersion === 1 && (
minorYarnVersion < 10 || (minorYarnVersion === 10 && patchYarnVersion < 1)
) ||
majorYarnVersion >= 2
) {
console.error('\033[1;31m*** Please use yarn >=1.10.1 and <2.\033[0;0m');
err = true;
}
+1 -1
View File
@@ -68,7 +68,7 @@ function update(options) {
console.log(`Importing translations for ${languageId} form '${location}' to '${translationDataFolder}' ...`);
let translationPaths = [];
gulp.src(path.join(location, '**', languageId, '*.xlf'), { silent: false })
.pipe(i18n.prepareI18nPackFiles(i18n.externalExtensionsWithTranslations, translationPaths, languageId === 'ps'))
.pipe(i18n.prepareI18nPackFiles(translationPaths))
.on('error', (error) => {
console.log(`Error occurred while importing translations:`);
translationPaths = undefined;
+222 -149
View File
@@ -1,258 +1,331 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "build_const"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
version = 3
[[package]]
name = "byteorder"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chrono"
version = "0.4.0"
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "crc"
version = "1.7.0"
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "build_const"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
dependencies = [
"build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"build_const",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "getrandom"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "inno_updater"
version = "0.8.2"
version = "0.9.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"slog-async 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slog-term 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder",
"crc",
"slog",
"slog-async",
"slog-term",
"winapi",
]
[[package]]
name = "isatty"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.0.0"
name = "itoa"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "libc"
version = "0.2.36"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "num"
version = "0.1.41"
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
"num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"libc",
]
[[package]]
name = "num-integer"
version = "0.1.35"
name = "once_cell"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
[[package]]
name = "proc-macro2"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-ident",
]
[[package]]
name = "num-iter"
version = "0.1.34"
name = "quote"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2",
]
[[package]]
name = "num-traits"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_syscall"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_termios"
version = "0.1.1"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags",
]
[[package]]
name = "slog"
version = "2.1.1"
name = "redox_users"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom",
"redox_syscall",
"thiserror",
]
[[package]]
name = "rustversion"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf"
[[package]]
name = "slog"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06"
[[package]]
name = "slog-async"
version = "2.2.0"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "766c59b252e62a34651412870ff55d8c4e6d04df19b43eecb2703e417b097ffe"
dependencies = [
"slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"take_mut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel",
"slog",
"take_mut",
"thread_local",
]
[[package]]
name = "slog-term"
version = "2.3.0"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87d29185c55b7b258b4f120eab00f48557d4d9bc814f41713f449d35b0f8977c"
dependencies = [
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"atty",
"slog",
"term",
"thread_local",
"time",
]
[[package]]
name = "syn"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "take_mut"
version = "0.2.0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
[[package]]
name = "term"
version = "0.4.6"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "termion"
version = "1.5.1"
name = "thiserror"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "0.3.5"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"once_cell",
]
[[package]]
name = "time"
version = "0.1.39"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa",
"libc",
"num_threads",
"time-macros",
]
[[package]]
name = "unreachable"
version = "1.0.0"
name = "time-macros"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
[[package]]
name = "void"
version = "1.0.2"
name = "unicode-ident"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.4"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9"
"checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7"
"checksum isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f2a233726c7bb76995cec749d59582e5664823b7245d4970354408f1d79a7a2"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca"
"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
"checksum num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9936036cc70fe4a8b2d338ab665900323290efb03983c86cbe235ae800ad8017"
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6b13b17f4225771f7f15cece704a4e68d3a5f31278ed26367f497133398a18"
"checksum slog-async 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e319a30c08b004618d5f7ca2f2b1dad7b4623ba7fcb1a12846fc3b01e9eaa10"
"checksum slog-term 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bb5d9360b2b279b326824b3b4ca2402ead8a8138f0e5ec1900605c861bb6671"
"checksum take_mut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50b910a1174df4aeb5738e8a0e7253883cf7801de40d094175a5a557e487f4c5"
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+19
View File
@@ -0,0 +1,19 @@
[package]
name = "inno_updater"
version = "0.9.0"
authors = ["Microsoft <monacotools@microsoft.com>"]
build = "build.rs"
[dependencies]
byteorder = "1"
crc = "^1.0.0"
slog = "2.1.1"
slog-async = "2.2.0"
slog-term = "2.3.0"
[target.'cfg(windows)'.dependencies]
winapi = { version = "^0.3.9", features = ["winuser", "libloaderapi", "commctrl", "processthreadsapi", "tlhelp32", "handleapi", "psapi", "errhandlingapi", "winbase", "shellapi"] }
[profile.release]
lto = true
panic = 'abort'
Binary file not shown.
+3 -3
View File
@@ -502,9 +502,9 @@
integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==
"@types/node@16.x":
version "16.11.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
version "16.11.64"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.64.tgz#9171f327298b619e2c52238b120c19056415d820"
integrity sha512-z5hPTlVFzNwtJ2LNozTpJcD1Cu44c4LNuzaq1mwxmiHWQh2ULdR6Vjwo1UGldzRpzL0yUEdZddnfqGW2G70z6Q==
"@types/p-limit@^2.2.0":
version "2.2.0"
+99 -61
View File
@@ -32,20 +32,6 @@
"Copyright (c) tunnel-agent authors"
]
},
{
// Reason: Waiting for https://github.com/segmentio/noop-logger/issues/2
"name": "noop-logger",
"fullLicenseText": [
"This project is licensed under the MIT license.",
"Copyrights are respective of each contributor listed at the beginning of each definition file.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// Reason: The license at https://github.com/rbuckton/reflect-metadata/blob/master/LICENSE
// does not include a clear Copyright statement (it's in https://github.com/rbuckton/reflect-metadata/blob/master/CopyrightNotice.txt).
@@ -102,36 +88,6 @@
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// Reason: Repository lacks license text.
// https://github.com/othiym23/emitter-listener/blob/master/package.json declares BSD-2-Clause.
// https://github.com/othiym23/emitter-listener/issues/3
"name": "emitter-listener",
"fullLicenseText": [
"BSD 2-Clause \"Simplified\" License",
"Copyright (c) 2018, Forrest L Norvell <ogd@aoaioxxysz.net>",
"",
"Redistribution and use in source and binary forms, with or without",
"modification, are permitted provided that the following conditions are met:",
"",
"1. Redistributions of source code must retain the above copyright notice, this",
" list of conditions and the following disclaimer.",
"2. Redistributions in binary form must reproduce the above copyright notice,",
" this list of conditions and the following disclaimer in the documentation",
" and/or other materials provided with the distribution.",
"",
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND",
"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED",
"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE",
"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR",
"ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
"(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;",
"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND",
"ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT",
"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS",
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
]
},
{
// Reason: Repository lacks license text.
// https://github.com/tjwebb/fnv-plus/blob/master/package.json declares MIT.
@@ -174,23 +130,6 @@
"SOFTWARE"
]
},
{
// Reason: This product includes AVC coding technology. MPEG LA LLC requires this notice.
"name": "H.264/AVC Video Standard",
"fullLicenseText": [
"This product is licensed under the AVC patent portfolio license for the personal",
"and non-commercial use of a consumer to (i) encode video in compliance with the AVC standard (\"AVC VIDEO\")",
"and/or (ii) decode AVC video that was encoded by a consumer",
"engaged in a personal and non-commercial activity and/or was obtained from a video provider",
"licensed to provide AVC video. No license is granted or shall be implied for any other use.",
"Additional information may be obtained from MPEG LA LLC. See http://www.MPEGLA.COM.",
"",
"For clarification purposes, this notice does not limit or inhibit the use of the product",
"for normal business uses that are personal to that business which do not include",
"(i) redistribution of the product to third parties, or",
"(ii) creation of content with AVC Standard compliant technologies for distribution to third parties."
]
},
{
// Reason: Missing license file
"name": "@tokenizer/token",
@@ -220,5 +159,104 @@
"",
"THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// Reason: The substack org has been deleted on GH
"name": "concat-map",
"fullLicenseText": [
"This software is released under the MIT license:",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of",
"this software and associated documentation files (the \"Software\"), to deal in",
"the Software without restriction, including without limitation the rights to",
"use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of",
"the Software, and to permit persons to whom the Software is furnished to do so,",
"subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS",
"FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR",
"COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER",
"IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN",
"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// Reason: The substack org has been deleted on GH
"name": "github-from-package",
"fullLicenseText": [
"This software is released under the MIT license:",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of",
"this software and associated documentation files (the \"Software\"), to deal in",
"the Software without restriction, including without limitation the rights to",
"use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of",
"the Software, and to permit persons to whom the Software is furnished to do so,",
"subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS",
"FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR",
"COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER",
"IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN",
"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// Reason: The substack org has been deleted on GH
"name": "minimist",
"fullLicenseText": [
"This software is released under the MIT license:",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of",
"this software and associated documentation files (the \"Software\"), to deal in",
"the Software without restriction, including without limitation the rights to",
"use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of",
"the Software, and to permit persons to whom the Software is furnished to do so,",
"subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS",
"FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR",
"COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER",
"IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN",
"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// Reason: The substack org has been deleted on GH
"name": "mkdirp",
"fullLicenseText": [
"Copyright 2010 James Halliday (mail@substack.net)",
"",
"This project is free software released under the MIT/X11 license:",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and associated documentation files (the \"Software\"), to deal",
"in the Software without restriction, including without limitation the rights",
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
"copies of the Software, and to permit persons to whom the Software is",
"furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in",
"all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN",
"THE SOFTWARE."
]
}
]
+26
View File
@@ -484,6 +484,32 @@
"That's all there is to it!"
]
},
{
"component": {
"type": "other",
"other": {
"name": "H.264/AVC Video Standard",
"downloadUrl": "https://chromium.googlesource.com/chromium/third_party/ffmpeg",
"version": "4.4.git"
}
},
"licenseDetail": [
"This product is licensed under the AVC patent portfolio license for the personal",
"and non-commercial use of a consumer to (i) encode video in compliance with the AVC standard (\"AVC VIDEO\")",
"and/or (ii) decode AVC video that was encoded by a consumer",
"engaged in a personal and non-commercial activity and/or was obtained from a video provider",
"licensed to provide AVC video. No license is granted or shall be implied for any other use.",
"Additional information may be obtained from MPEG LA LLC. See http://www.MPEGLA.COM.",
"",
"For clarification purposes, this notice does not limit or inhibit the use of the product",
"for normal business uses that are personal to that business which do not include",
"(i) redistribution of the product to third parties, or",
"(ii) creation of content with AVC Standard compliant technologies for distribution to third parties."
],
"version": "H.264 (08/21)",
"isOnlyProductionDependency": true,
"license": "OTHER"
},
{
"component": {
"type": "git",
+1 -1
View File
@@ -1,7 +1,7 @@
# Setup
0. Clone, and then run `git submodule update --init --recursive`
1. Get the extensions: [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer) and [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)
1. Get the extensions: [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) and [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)
2. Ensure your workspace is set to the `launcher` folder being the root.
## Building the CLI on Windows
+592 -723
View File
File diff suppressed because it is too large Load Diff
+7 -1
View File
@@ -39,7 +39,7 @@ serde_bytes = "0.11.5"
chrono = { version = "0.4", features = ["serde"] }
gethostname = "0.2.3"
libc = "0.2"
tunnels = { git = "https://github.com/connor4312/dev-tunnels", branch = "host-relay", features = ["connections", "vendored-openssl"] }
tunnels = { git = "https://github.com/microsoft/dev-tunnels", rev = "3870e9133dfb9557774521bb447827f19b26e55d", default-features = false, features = ["connections", "vendored-openssl"] }
keyring = "1.1"
dialoguer = "0.10"
hyper = "0.14"
@@ -56,6 +56,12 @@ windows-service = "0.5"
[target.'cfg(target_os = "linux")'.dependencies]
tar = { version = "0.4" }
[patch.crates-io]
russh = { git = "https://github.com/microsoft/vscode-russh", branch = "main" }
russh-cryptovec = { git = "https://github.com/microsoft/vscode-russh", branch = "main" }
russh-keys = { git = "https://github.com/microsoft/vscode-russh", branch = "main" }
secret-service = { git = "https://github.com/microsoft/vscode-secret-service-rs", rev = "ccef335714cdf3744ff85f812b8fba5b6194dcfa" }
[profile.release]
strip = true
lto = true
+1 -1
View File
@@ -419,7 +419,7 @@ mod tests {
.to_string_lossy()
.to_string();
assert_eq!(
RequestedVersion::try_from((&exe).as_str()).unwrap(),
RequestedVersion::try_from(exe.as_str()).unwrap(),
RequestedVersion::Path(exe),
);
}
+4 -4
View File
@@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use tokio::sync::{mpsc, watch};
use tunnels::connections::{ForwardedPortConnection, HostRelay};
use tunnels::connections::{ForwardedPortConnection, RelayTunnelHost};
use tunnels::contracts::{
Tunnel, TunnelPort, TunnelRelayTunnelEndpoint, PORT_TOKEN, TUNNEL_PROTOCOL_AUTO,
};
@@ -607,7 +607,7 @@ impl DevTunnels {
struct ActiveTunnelManager {
close_tx: Option<mpsc::Sender<()>>,
endpoint_rx: watch::Receiver<Option<Result<TunnelRelayTunnelEndpoint, WrappedError>>>,
relay: Arc<tokio::sync::Mutex<HostRelay>>,
relay: Arc<tokio::sync::Mutex<RelayTunnelHost>>,
}
impl ActiveTunnelManager {
@@ -620,7 +620,7 @@ impl ActiveTunnelManager {
let (endpoint_tx, endpoint_rx) = watch::channel(None);
let (close_tx, close_rx) = mpsc::channel(1);
let relay = Arc::new(tokio::sync::Mutex::new(HostRelay::new(locator, mgmt)));
let relay = Arc::new(tokio::sync::Mutex::new(RelayTunnelHost::new(locator, mgmt)));
let relay_spawned = relay.clone();
tokio::spawn(async move {
@@ -719,7 +719,7 @@ impl ActiveTunnelManager {
async fn spawn_tunnel(
log: log::Logger,
relay: Arc<tokio::sync::Mutex<HostRelay>>,
relay: Arc<tokio::sync::Mutex<RelayTunnelHost>>,
mut close_rx: mpsc::Receiver<()>,
endpoint_tx: watch::Sender<Option<Result<TunnelRelayTunnelEndpoint, WrappedError>>>,
access_token_provider: impl AccessTokenProvider + 'static,
+1 -1
View File
@@ -26,7 +26,7 @@ where
e,
format!(
"failed to execute command '{}'",
(&command_str).as_ref().to_string_lossy()
command_str.as_ref().to_string_lossy()
),
)
})
+1 -3
View File
@@ -19,9 +19,7 @@ where
/// Waits for the barrier to be closed, returning a value if one was sent.
pub async fn wait(&mut self) -> Result<T, RecvError> {
loop {
if let Err(e) = self.0.changed().await {
return Err(e);
}
self.0.changed().await?;
if let Some(v) = *(self.0.borrow()) {
return Ok(v);
@@ -21,7 +21,7 @@
},
"dependencies": {
"jsonc-parser": "^2.2.1",
"vscode-nls": "^5.1.0"
"vscode-nls": "^5.2.0"
},
"capabilities": {
"virtualWorkspaces": true,
@@ -71,6 +71,10 @@
"fileMatch": "%APP_SETTINGS_HOME%/keybindings.json",
"url": "vscode://schemas/keybindings"
},
{
"fileMatch": "%APP_SETTINGS_HOME%/profiles/*/keybindings.json",
"url": "vscode://schemas/keybindings"
},
{
"fileMatch": "vscode://defaultsettings/*.json",
"url": "vscode://schemas/settings/default"
@@ -119,6 +123,10 @@
"fileMatch": "%APP_SETTINGS_HOME%/snippets/*.json",
"url": "vscode://schemas/snippets"
},
{
"fileMatch": "%APP_SETTINGS_HOME%/profiles/*/snippets/.json",
"url": "vscode://schemas/snippets"
},
{
"fileMatch": "%APP_SETTINGS_HOME%/sync/snippets/preview/*.json",
"url": "vscode://schemas/snippets"
@@ -173,6 +173,13 @@
]
}
}
},
"openFiles": {
"type": "array",
"description": "The paths to the files to open when the codespace is created. Paths are relative to the workspace.",
"items": {
"type": "string"
}
}
}
}
@@ -62,24 +62,6 @@
]
}
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"type": "string"
}
},
"runArgs": {
"type": "array",
"description": "The arguments required when starting in the container.",
@@ -278,6 +260,83 @@
"type": "boolean",
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default when opening from a local folder."
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"bind",
"volume"
],
"description": "Mount type."
},
"source": {
"type": "string",
"description": "Mount source."
},
"target": {
"type": "string",
"description": "Mount target."
}
},
"required": [
"type",
"source",
"target"
],
"additionalProperties": false
},
{
"type": "string"
}
]
}
},
"init": {
"type": "boolean",
"description": "Passes the --init flag when creating the dev container."
},
"privileged": {
"type": "boolean",
"description": "Passes the --privileged flag when creating the dev container."
},
"capAdd": {
"type": "array",
"description": "Passes docker capabilities to include when creating the dev container.",
"examples": [
"SYS_PTRACE"
],
"items": {
"type": "string"
}
},
"securityOpt": {
"type": "array",
"description": "Passes docker security options to include when creating the dev container.",
"examples": [
"seccomp=unconfined"
],
"items": {
"type": "string"
}
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@@ -600,6 +659,13 @@
}
},
"additionalProperties": false
},
"openFiles": {
"type": "array",
"description": "The paths to the files to open when the codespace is created. Paths are relative to the workspace.",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
@@ -672,24 +738,6 @@
]
}
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"type": "string"
}
},
"runArgs": {
"type": "array",
"description": "The arguments required when starting in the container.",
@@ -888,6 +936,83 @@
"type": "boolean",
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default when opening from a local folder."
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"bind",
"volume"
],
"description": "Mount type."
},
"source": {
"type": "string",
"description": "Mount source."
},
"target": {
"type": "string",
"description": "Mount target."
}
},
"required": [
"type",
"source",
"target"
],
"additionalProperties": false
},
{
"type": "string"
}
]
}
},
"init": {
"type": "boolean",
"description": "Passes the --init flag when creating the dev container."
},
"privileged": {
"type": "boolean",
"description": "Passes the --privileged flag when creating the dev container."
},
"capAdd": {
"type": "array",
"description": "Passes docker capabilities to include when creating the dev container.",
"examples": [
"SYS_PTRACE"
],
"items": {
"type": "string"
}
},
"securityOpt": {
"type": "array",
"description": "Passes docker security options to include when creating the dev container.",
"examples": [
"seccomp=unconfined"
],
"items": {
"type": "string"
}
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@@ -1210,6 +1335,13 @@
}
},
"additionalProperties": false
},
"openFiles": {
"type": "array",
"description": "The paths to the files to open when the codespace is created. Paths are relative to the workspace.",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
@@ -1248,24 +1380,6 @@
]
}
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"type": "string"
}
},
"runArgs": {
"type": "array",
"description": "The arguments required when starting in the container.",
@@ -1464,6 +1578,83 @@
"type": "boolean",
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default when opening from a local folder."
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"bind",
"volume"
],
"description": "Mount type."
},
"source": {
"type": "string",
"description": "Mount source."
},
"target": {
"type": "string",
"description": "Mount target."
}
},
"required": [
"type",
"source",
"target"
],
"additionalProperties": false
},
{
"type": "string"
}
]
}
},
"init": {
"type": "boolean",
"description": "Passes the --init flag when creating the dev container."
},
"privileged": {
"type": "boolean",
"description": "Passes the --privileged flag when creating the dev container."
},
"capAdd": {
"type": "array",
"description": "Passes docker capabilities to include when creating the dev container.",
"examples": [
"SYS_PTRACE"
],
"items": {
"type": "string"
}
},
"securityOpt": {
"type": "array",
"description": "Passes docker security options to include when creating the dev container.",
"examples": [
"seccomp=unconfined"
],
"items": {
"type": "string"
}
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@@ -1786,6 +1977,13 @@
}
},
"additionalProperties": false
},
"openFiles": {
"type": "array",
"description": "The paths to the files to open when the codespace is created. Paths are relative to the workspace.",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
@@ -2014,6 +2212,83 @@
"type": "boolean",
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default when opening from a local folder."
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"bind",
"volume"
],
"description": "Mount type."
},
"source": {
"type": "string",
"description": "Mount source."
},
"target": {
"type": "string",
"description": "Mount target."
}
},
"required": [
"type",
"source",
"target"
],
"additionalProperties": false
},
{
"type": "string"
}
]
}
},
"init": {
"type": "boolean",
"description": "Passes the --init flag when creating the dev container."
},
"privileged": {
"type": "boolean",
"description": "Passes the --privileged flag when creating the dev container."
},
"capAdd": {
"type": "array",
"description": "Passes docker capabilities to include when creating the dev container.",
"examples": [
"SYS_PTRACE"
],
"items": {
"type": "string"
}
},
"securityOpt": {
"type": "array",
"description": "Passes docker security options to include when creating the dev container.",
"examples": [
"seccomp=unconfined"
],
"items": {
"type": "string"
}
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@@ -2336,6 +2611,13 @@
}
},
"additionalProperties": false
},
"openFiles": {
"type": "array",
"description": "The paths to the files to open when the codespace is created. Paths are relative to the workspace.",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
@@ -2529,6 +2811,83 @@
"type": "boolean",
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default when opening from a local folder."
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"bind",
"volume"
],
"description": "Mount type."
},
"source": {
"type": "string",
"description": "Mount source."
},
"target": {
"type": "string",
"description": "Mount target."
}
},
"required": [
"type",
"source",
"target"
],
"additionalProperties": false
},
{
"type": "string"
}
]
}
},
"init": {
"type": "boolean",
"description": "Passes the --init flag when creating the dev container."
},
"privileged": {
"type": "boolean",
"description": "Passes the --privileged flag when creating the dev container."
},
"capAdd": {
"type": "array",
"description": "Passes docker capabilities to include when creating the dev container.",
"examples": [
"SYS_PTRACE"
],
"items": {
"type": "string"
}
},
"securityOpt": {
"type": "array",
"description": "Passes docker security options to include when creating the dev container.",
"examples": [
"seccomp=unconfined"
],
"items": {
"type": "string"
}
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@@ -2851,6 +3210,13 @@
}
},
"additionalProperties": false
},
"openFiles": {
"type": "array",
"description": "The paths to the files to open when the codespace is created. Paths are relative to the workspace.",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
@@ -177,6 +177,55 @@
"type": "boolean",
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default when opening from a local folder."
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"anyOf": [
{
"$ref": "#/definitions/Mount"
},
{
"type": "string"
}
]
}
},
"init": {
"type": "boolean",
"description": "Passes the --init flag when creating the dev container."
},
"privileged": {
"type": "boolean",
"description": "Passes the --privileged flag when creating the dev container."
},
"capAdd": {
"type": "array",
"description": "Passes docker capabilities to include when creating the dev container.",
"examples": [ "SYS_PTRACE" ],
"items": {
"type": "string"
}
},
"securityOpt": {
"type": "array",
"description": "Passes docker security options to include when creating the dev container.",
"examples": [ "seccomp=unconfined" ],
"items": {
"type": "string"
}
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
@@ -501,6 +550,13 @@
]
}
}
},
"openFiles": {
"type": "array",
"description": "The paths to the files to open when the codespace is created. Paths are relative to the workspace.",
"items": {
"type": "string"
}
}
}
}
@@ -529,24 +585,6 @@
]
}
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"type": "string"
}
},
"runArgs": {
"type": "array",
"description": "The arguments required when starting in the container.",
@@ -728,6 +766,33 @@
"service",
"workspaceFolder"
]
},
"Mount": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"bind",
"volume"
],
"description": "Mount type."
},
"source": {
"type": "string",
"description": "Mount source."
},
"target": {
"type": "string",
"description": "Mount target."
}
},
"required": [
"type",
"source",
"target"
],
"additionalProperties": false
}
},
"oneOf": [
+4 -4
View File
@@ -12,7 +12,7 @@ jsonc-parser@^2.2.1:
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc"
integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==
vscode-nls@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.1.0.tgz#443b301a7465d88c81c0f4e1914f9857f0dce1e4"
integrity sha512-37Ha44QrLFwR2IfSSYdOArzUvOyoWbOYTwQC+wS0NfqKjhW7s0WQ1lMy5oJXgSZy9sAiZS5ifELhbpXodeMR8w==
vscode-nls@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==
+2 -2
View File
@@ -6,11 +6,11 @@
"git": {
"name": "jeff-hykin/better-cpp-syntax",
"repositoryUrl": "https://github.com/jeff-hykin/better-cpp-syntax",
"commitHash": "924295fc44bde1a00fab60da3a2caca4509adb25"
"commitHash": "32be139c7d3cdf07195af4b3a5c639ebf4e3b356"
}
},
"license": "MIT",
"version": "1.15.18",
"version": "1.15.23",
"description": "The original JSON grammars were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle."
},
{
+2 -1
View File
@@ -13,7 +13,8 @@
{ "open": "{", "close": "}" },
{ "open": "(", "close": ")" },
{ "open": "'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "\"", "close": "\"", "notIn": ["string"] }
{ "open": "\"", "close": "\"", "notIn": ["string"] },
{ "open": "/*", "close": "*/", "notIn": ["string", "comment"] }
],
"surroundingPairs": [
["{", "}"],

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