From ca4f40a458c4e07d587cacb99a867454d27af46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 18 Jun 2026 18:10:01 +0200 Subject: [PATCH 01/29] build: derive GitHub token from Monaco GitHub App instead of PAT Replace the github-distro-mixin-password PAT (subject to 7-day rotation) with a GitHub App installation token extracted from the persisted checkout credentials. The token is republished under the same variable name to avoid churning the many GITHUB_TOKEN consumers, and the distro netrc auth now uses the x-access-token login. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../product-build-alpine-node-modules.yml | 7 ---- .../alpine/product-build-alpine.yml | 7 ---- build/azure-pipelines/common/checkout.yml | 3 ++ build/azure-pipelines/copilot/setup-steps.yml | 13 +++---- .../product-build-darwin-node-modules.yml | 2 +- .../darwin/product-build-darwin-universal.yml | 2 +- .../steps/product-build-darwin-compile.yml | 2 +- build/azure-pipelines/dependencies-check.yml | 7 ++++ build/azure-pipelines/distro-build.yml | 2 ++ .../distro/download-distro.yml | 13 +++---- .../distro/setup-github-auth.yml | 34 +++++++++++++++++++ .../product-build-linux-node-modules.yml | 7 ---- .../steps/product-build-linux-compile.yml | 7 ---- .../product-copilot-recovery.yml | 1 + build/azure-pipelines/product-copilot.yml | 1 + build/azure-pipelines/product-publish.yml | 7 ---- .../product-quality-checks.yml | 7 ---- .../web/product-build-web-node-modules.yml | 7 ---- .../azure-pipelines/web/product-build-web.yml | 7 ---- .../product-build-win32-node-modules.yml | 7 ---- .../azure-pipelines/win32/sdl-scan-win32.yml | 7 ---- .../steps/product-build-win32-compile.yml | 7 ---- 22 files changed, 61 insertions(+), 96 deletions(-) create mode 100644 build/azure-pipelines/distro/setup-github-auth.yml diff --git a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml index 07f1545ca24835..5f9c7a24ecb562 100644 --- a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml +++ b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml @@ -22,13 +22,6 @@ jobs: - template: ../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index 3359224d3ed8d9..6c52f2b13a44e3 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -64,13 +64,6 @@ jobs: - template: ../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/common/checkout.yml b/build/azure-pipelines/common/checkout.yml index 427f190480a534..031a3e2835d3f9 100644 --- a/build/azure-pipelines/common/checkout.yml +++ b/build/azure-pipelines/common/checkout.yml @@ -2,5 +2,8 @@ steps: - checkout: self fetchDepth: 1 fetchTags: false + persistCredentials: true retryCountOnTaskFailure: 3 displayName: Checkout microsoft/vscode + + - template: ../distro/setup-github-auth.yml@self diff --git a/build/azure-pipelines/copilot/setup-steps.yml b/build/azure-pipelines/copilot/setup-steps.yml index 83699f8152d632..b3ab4cee5f00bc 100644 --- a/build/azure-pipelines/copilot/setup-steps.yml +++ b/build/azure-pipelines/copilot/setup-steps.yml @@ -3,15 +3,12 @@ steps: inputs: versionSpec: "22.21.x" - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + # The github-distro-mixin-password variable is derived from the Monaco GitHub App + # token. Requires the enclosing checkout to use persistCredentials: true. + - template: ../distro/setup-github-auth.yml@self - pwsh: | - "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII + "machine github.com`nlogin x-access-token`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) displayName: Setup distro auth (Windows) @@ -19,7 +16,7 @@ steps: mkdir -p .build cat << EOF | tee ~/.netrc .build/.netrc > /dev/null machine github.com - login vscode + login x-access-token password $(github-distro-mixin-password) EOF condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) diff --git a/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml b/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml index d70adbee0af010..925de682696e5e 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml @@ -28,7 +28,7 @@ jobs: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/darwin/product-build-darwin-universal.yml b/build/azure-pipelines/darwin/product-build-darwin-universal.yml index f0b468db15f9ea..5600a6c7e6e472 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-universal.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-universal.yml @@ -36,7 +36,7 @@ jobs: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" - script: node build/setup-npm-registry.ts $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml index dd8b3e88930d08..82d7051d210b7b 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml @@ -28,7 +28,7 @@ steps: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/dependencies-check.yml b/build/azure-pipelines/dependencies-check.yml index d7d0d9f12b6dd8..663835024c0dfc 100644 --- a/build/azure-pipelines/dependencies-check.yml +++ b/build/azure-pipelines/dependencies-check.yml @@ -22,6 +22,13 @@ jobs: variables: VSCODE_ARCH: x64 steps: + - checkout: self + persistCredentials: true + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode + + - template: ./distro/setup-github-auth.yml@self + - task: NodeTool@0 inputs: versionSource: fromFile diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index 1d0a50b129778f..40e924a724b6f3 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -8,6 +8,8 @@ trigger: pr: none steps: + - template: ./common/checkout.yml@self + - task: NodeTool@0 inputs: versionSource: fromFile diff --git a/build/azure-pipelines/distro/download-distro.yml b/build/azure-pipelines/distro/download-distro.yml index b7c52dd36b41c0..09a9ab4c87620b 100644 --- a/build/azure-pipelines/distro/download-distro.yml +++ b/build/azure-pipelines/distro/download-distro.yml @@ -1,14 +1,11 @@ steps: - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + # The github-distro-mixin-password variable is derived from the Monaco GitHub App + # token by common/checkout.yml (via distro/setup-github-auth.yml). The Monaco app + # installation must have read access to the private microsoft/vscode-distro repo. # TODO@joaomoreno: Keep pwsh once we move out of running entire jobs in containers - pwsh: | - "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII + "machine github.com`nlogin x-access-token`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) displayName: Setup distro auth (Windows) @@ -32,7 +29,7 @@ steps: mkdir -p .build cat << EOF | tee ~/.netrc .build/.netrc > /dev/null machine github.com - login vscode + login x-access-token password $(github-distro-mixin-password) EOF condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) diff --git a/build/azure-pipelines/distro/setup-github-auth.yml b/build/azure-pipelines/distro/setup-github-auth.yml new file mode 100644 index 00000000000000..f7d2f711e74600 --- /dev/null +++ b/build/azure-pipelines/distro/setup-github-auth.yml @@ -0,0 +1,34 @@ +steps: + # Derive a GitHub token from the Monaco GitHub App credentials that Azure + # Pipelines persisted into .git/config during checkout (persistCredentials: true). + # This replaces the github-distro-mixin-password PAT. The installation token is + # short-lived (~1h) and scoped to the repos the Monaco app can access in the org + # (which must include microsoft/vscode-distro for the distro download to work). + # The resulting secret variable keeps the historical name to avoid churn across + # the many GITHUB_TOKEN consumers. + - pwsh: | + $ErrorActionPreference = "Stop" + $header = (git config --get-all "http.https://github.com/.extraheader" | Select-Object -First 1) + if (-not $header) { + Write-Error "Could not find persisted GitHub credentials. Ensure checkout uses persistCredentials: true." + exit 1 + } + $b64 = ($header -replace '.*basic ', '').Trim() + $decoded = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($b64)) + $token = $decoded.Substring($decoded.IndexOf(':') + 1) + Write-Host "##vso[task.setvariable variable=github-distro-mixin-password;issecret=true]$token" + condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) + displayName: Setup GitHub auth (Windows) + + - script: | + set -e + header="$(git config --get-all "http.https://github.com/.extraheader" | head -n1)" + if [ -z "$header" ]; then + echo "Could not find persisted GitHub credentials. Ensure checkout uses persistCredentials: true." >&2 + exit 1 + fi + b64="${header##*basic }" + token="$(printf '%s' "$b64" | base64 -d | cut -d: -f2-)" + echo "##vso[task.setvariable variable=github-distro-mixin-password;issecret=true]$token" + condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) + displayName: Setup GitHub auth (non-Windows) diff --git a/build/azure-pipelines/linux/product-build-linux-node-modules.yml b/build/azure-pipelines/linux/product-build-linux-node-modules.yml index ad0e149816014d..6ac98f151b84ba 100644 --- a/build/azure-pipelines/linux/product-build-linux-node-modules.yml +++ b/build/azure-pipelines/linux/product-build-linux-node-modules.yml @@ -24,13 +24,6 @@ jobs: - template: ../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - script: | set -e # Start X server diff --git a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml index ca58ca10d511e7..e10016f29418f1 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml @@ -31,13 +31,6 @@ steps: - template: ../../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - script: | set -e # Start X server diff --git a/build/azure-pipelines/product-copilot-recovery.yml b/build/azure-pipelines/product-copilot-recovery.yml index a0c52e68302470..32e43adb38f8ab 100644 --- a/build/azure-pipelines/product-copilot-recovery.yml +++ b/build/azure-pipelines/product-copilot-recovery.yml @@ -68,6 +68,7 @@ extends: testSteps: - checkout: self lfs: true + persistCredentials: true retryCountOnTaskFailure: 3 - template: copilot/setup-steps.yml - template: copilot/test-steps.yml diff --git a/build/azure-pipelines/product-copilot.yml b/build/azure-pipelines/product-copilot.yml index cebe647882facf..5d15cdf0cd49a7 100644 --- a/build/azure-pipelines/product-copilot.yml +++ b/build/azure-pipelines/product-copilot.yml @@ -20,6 +20,7 @@ jobs: lfs: true fetchDepth: 1 fetchTags: false + persistCredentials: true retryCountOnTaskFailure: 3 displayName: Checkout microsoft/vscode diff --git a/build/azure-pipelines/product-publish.yml b/build/azure-pipelines/product-publish.yml index 0a0ada4ec3d41d..f5b8a176bb0b16 100644 --- a/build/azure-pipelines/product-publish.yml +++ b/build/azure-pipelines/product-publish.yml @@ -36,13 +36,6 @@ jobs: - script: node build/azure-pipelines/distro/mixin-quality.ts displayName: Mixin distro quality - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get ESRP Secrets" inputs: diff --git a/build/azure-pipelines/product-quality-checks.yml b/build/azure-pipelines/product-quality-checks.yml index a885e45f49afba..32b0977ae5d266 100644 --- a/build/azure-pipelines/product-quality-checks.yml +++ b/build/azure-pipelines/product-quality-checks.yml @@ -17,13 +17,6 @@ jobs: - template: ./distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/web/product-build-web-node-modules.yml b/build/azure-pipelines/web/product-build-web-node-modules.yml index 75a0cc6cd6e750..797a12026e3553 100644 --- a/build/azure-pipelines/web/product-build-web-node-modules.yml +++ b/build/azure-pipelines/web/product-build-web-node-modules.yml @@ -15,13 +15,6 @@ jobs: - template: ../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 86d6215f31cf0c..23e160bda2af85 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -27,13 +27,6 @@ jobs: - template: ../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/product-build-win32-node-modules.yml b/build/azure-pipelines/win32/product-build-win32-node-modules.yml index 6780073f57af7d..e18cffa1d933ff 100644 --- a/build/azure-pipelines/win32/product-build-win32-node-modules.yml +++ b/build/azure-pipelines/win32/product-build-win32-node-modules.yml @@ -26,13 +26,6 @@ jobs: - template: ../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/sdl-scan-win32.yml b/build/azure-pipelines/win32/sdl-scan-win32.yml index 1d41892bf8d314..49d7065f420d89 100644 --- a/build/azure-pipelines/win32/sdl-scan-win32.yml +++ b/build/azure-pipelines/win32/sdl-scan-win32.yml @@ -19,13 +19,6 @@ steps: - template: ../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml index e64b0f0e03255d..56c65766ccf5b5 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml @@ -30,13 +30,6 @@ steps: - template: ../../distro/download-distro.yml@self - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry From fe46521db81fcc9e154c21d2b607001614898983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 19 Jun 2026 08:32:57 +0200 Subject: [PATCH 02/29] build: probe vscode-distro checkout via Monaco GitHub App endpoint Reverts the failed token-extraction approach (1ES persists only a credential placeholder, so the GitHub App token cannot be read from disk). Instead validate Option A: add microsoft/vscode-distro as a pipeline repository resource authenticated via the Monaco GitHub App endpoint, then check out the exact pinned SHA locally. This probe job confirms the agent can authenticate the distro checkout and that a local `git checkout ` resolves the pinned commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../product-build-alpine-node-modules.yml | 7 +++ .../alpine/product-build-alpine.yml | 7 +++ build/azure-pipelines/common/checkout.yml | 3 -- build/azure-pipelines/copilot/setup-steps.yml | 13 +++--- .../product-build-darwin-node-modules.yml | 2 +- .../darwin/product-build-darwin-universal.yml | 2 +- .../steps/product-build-darwin-compile.yml | 2 +- build/azure-pipelines/dependencies-check.yml | 7 --- build/azure-pipelines/distro-build.yml | 2 - .../distro/download-distro.yml | 13 +++--- .../distro/setup-github-auth.yml | 34 -------------- .../product-build-linux-node-modules.yml | 7 +++ .../steps/product-build-linux-compile.yml | 7 +++ build/azure-pipelines/product-build.yml | 45 +++++++++++++++++++ .../product-copilot-recovery.yml | 1 - build/azure-pipelines/product-copilot.yml | 1 - build/azure-pipelines/product-publish.yml | 7 +++ .../product-quality-checks.yml | 7 +++ .../web/product-build-web-node-modules.yml | 7 +++ .../azure-pipelines/web/product-build-web.yml | 7 +++ .../product-build-win32-node-modules.yml | 7 +++ .../azure-pipelines/win32/sdl-scan-win32.yml | 7 +++ .../steps/product-build-win32-compile.yml | 7 +++ 23 files changed, 141 insertions(+), 61 deletions(-) delete mode 100644 build/azure-pipelines/distro/setup-github-auth.yml diff --git a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml index 5f9c7a24ecb562..07f1545ca24835 100644 --- a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml +++ b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml @@ -22,6 +22,13 @@ jobs: - template: ../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index 6c52f2b13a44e3..3359224d3ed8d9 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -64,6 +64,13 @@ jobs: - template: ../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/common/checkout.yml b/build/azure-pipelines/common/checkout.yml index 031a3e2835d3f9..427f190480a534 100644 --- a/build/azure-pipelines/common/checkout.yml +++ b/build/azure-pipelines/common/checkout.yml @@ -2,8 +2,5 @@ steps: - checkout: self fetchDepth: 1 fetchTags: false - persistCredentials: true retryCountOnTaskFailure: 3 displayName: Checkout microsoft/vscode - - - template: ../distro/setup-github-auth.yml@self diff --git a/build/azure-pipelines/copilot/setup-steps.yml b/build/azure-pipelines/copilot/setup-steps.yml index b3ab4cee5f00bc..83699f8152d632 100644 --- a/build/azure-pipelines/copilot/setup-steps.yml +++ b/build/azure-pipelines/copilot/setup-steps.yml @@ -3,12 +3,15 @@ steps: inputs: versionSpec: "22.21.x" - # The github-distro-mixin-password variable is derived from the Monaco GitHub App - # token. Requires the enclosing checkout to use persistCredentials: true. - - template: ../distro/setup-github-auth.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" - pwsh: | - "machine github.com`nlogin x-access-token`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII + "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) displayName: Setup distro auth (Windows) @@ -16,7 +19,7 @@ steps: mkdir -p .build cat << EOF | tee ~/.netrc .build/.netrc > /dev/null machine github.com - login x-access-token + login vscode password $(github-distro-mixin-password) EOF condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) diff --git a/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml b/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml index 925de682696e5e..d70adbee0af010 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml @@ -28,7 +28,7 @@ jobs: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/darwin/product-build-darwin-universal.yml b/build/azure-pipelines/darwin/product-build-darwin-universal.yml index 5600a6c7e6e472..f0b468db15f9ea 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-universal.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-universal.yml @@ -36,7 +36,7 @@ jobs: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" - script: node build/setup-npm-registry.ts $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml index 82d7051d210b7b..dd8b3e88930d08 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml @@ -28,7 +28,7 @@ steps: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) diff --git a/build/azure-pipelines/dependencies-check.yml b/build/azure-pipelines/dependencies-check.yml index 663835024c0dfc..d7d0d9f12b6dd8 100644 --- a/build/azure-pipelines/dependencies-check.yml +++ b/build/azure-pipelines/dependencies-check.yml @@ -22,13 +22,6 @@ jobs: variables: VSCODE_ARCH: x64 steps: - - checkout: self - persistCredentials: true - retryCountOnTaskFailure: 3 - displayName: Checkout microsoft/vscode - - - template: ./distro/setup-github-auth.yml@self - - task: NodeTool@0 inputs: versionSource: fromFile diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index 40e924a724b6f3..1d0a50b129778f 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -8,8 +8,6 @@ trigger: pr: none steps: - - template: ./common/checkout.yml@self - - task: NodeTool@0 inputs: versionSource: fromFile diff --git a/build/azure-pipelines/distro/download-distro.yml b/build/azure-pipelines/distro/download-distro.yml index 09a9ab4c87620b..b7c52dd36b41c0 100644 --- a/build/azure-pipelines/distro/download-distro.yml +++ b/build/azure-pipelines/distro/download-distro.yml @@ -1,11 +1,14 @@ steps: - # The github-distro-mixin-password variable is derived from the Monaco GitHub App - # token by common/checkout.yml (via distro/setup-github-auth.yml). The Monaco app - # installation must have read access to the private microsoft/vscode-distro repo. + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" # TODO@joaomoreno: Keep pwsh once we move out of running entire jobs in containers - pwsh: | - "machine github.com`nlogin x-access-token`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII + "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) displayName: Setup distro auth (Windows) @@ -29,7 +32,7 @@ steps: mkdir -p .build cat << EOF | tee ~/.netrc .build/.netrc > /dev/null machine github.com - login x-access-token + login vscode password $(github-distro-mixin-password) EOF condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) diff --git a/build/azure-pipelines/distro/setup-github-auth.yml b/build/azure-pipelines/distro/setup-github-auth.yml deleted file mode 100644 index f7d2f711e74600..00000000000000 --- a/build/azure-pipelines/distro/setup-github-auth.yml +++ /dev/null @@ -1,34 +0,0 @@ -steps: - # Derive a GitHub token from the Monaco GitHub App credentials that Azure - # Pipelines persisted into .git/config during checkout (persistCredentials: true). - # This replaces the github-distro-mixin-password PAT. The installation token is - # short-lived (~1h) and scoped to the repos the Monaco app can access in the org - # (which must include microsoft/vscode-distro for the distro download to work). - # The resulting secret variable keeps the historical name to avoid churn across - # the many GITHUB_TOKEN consumers. - - pwsh: | - $ErrorActionPreference = "Stop" - $header = (git config --get-all "http.https://github.com/.extraheader" | Select-Object -First 1) - if (-not $header) { - Write-Error "Could not find persisted GitHub credentials. Ensure checkout uses persistCredentials: true." - exit 1 - } - $b64 = ($header -replace '.*basic ', '').Trim() - $decoded = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($b64)) - $token = $decoded.Substring($decoded.IndexOf(':') + 1) - Write-Host "##vso[task.setvariable variable=github-distro-mixin-password;issecret=true]$token" - condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) - displayName: Setup GitHub auth (Windows) - - - script: | - set -e - header="$(git config --get-all "http.https://github.com/.extraheader" | head -n1)" - if [ -z "$header" ]; then - echo "Could not find persisted GitHub credentials. Ensure checkout uses persistCredentials: true." >&2 - exit 1 - fi - b64="${header##*basic }" - token="$(printf '%s' "$b64" | base64 -d | cut -d: -f2-)" - echo "##vso[task.setvariable variable=github-distro-mixin-password;issecret=true]$token" - condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) - displayName: Setup GitHub auth (non-Windows) diff --git a/build/azure-pipelines/linux/product-build-linux-node-modules.yml b/build/azure-pipelines/linux/product-build-linux-node-modules.yml index 6ac98f151b84ba..ad0e149816014d 100644 --- a/build/azure-pipelines/linux/product-build-linux-node-modules.yml +++ b/build/azure-pipelines/linux/product-build-linux-node-modules.yml @@ -24,6 +24,13 @@ jobs: - template: ../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - script: | set -e # Start X server diff --git a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml index e10016f29418f1..ca58ca10d511e7 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml @@ -31,6 +31,13 @@ steps: - template: ../../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - script: | set -e # Start X server diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 443ae00f5d1556..6c1400d5ab82c5 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -180,11 +180,19 @@ resources: type: git name: 1ESPipelineTemplates/1ESPipelineTemplates ref: refs/tags/release + - repository: distro + type: github + name: microsoft/vscode-distro + endpoint: Monaco + ref: main extends: template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines parameters: sdl: + sourceRepositoriesToScan: + exclude: + - repository: distro tsa: enabled: true configFile: $(Build.SourcesDirectory)/build/azure-pipelines/config/tsaoptions.json @@ -216,6 +224,43 @@ extends: jobs: - template: build/azure-pipelines/product-quality-checks.yml@self + - stage: DistroProbe + dependsOn: [] + pool: + name: 1es-ubuntu-22.04-x64 + os: linux + jobs: + - job: DistroProbe + displayName: Distro Probe + steps: + - checkout: self + path: s/vscode + fetchDepth: 1 + fetchTags: false + displayName: Checkout microsoft/vscode + - checkout: distro + path: s/vscode-distro + fetchDepth: 0 + displayName: Checkout microsoft/vscode-distro + - task: NodeTool@0 + inputs: + versionSource: fromFile + versionFilePath: $(Agent.BuildDirectory)/s/vscode/.nvmrc + - script: | + set -e + SELF="$(Agent.BuildDirectory)/s/vscode" + DISTRO="$(Agent.BuildDirectory)/s/vscode-distro" + SHA=$(node -p "require('$SELF/package.json').distro") + echo "package.json distro SHA: $SHA" + echo "distro HEAD before checkout:" + git -C "$DISTRO" log -1 --oneline + git -C "$DISTRO" checkout "$SHA" + echo "checked out distro SHA OK:" + git -C "$DISTRO" log -1 --oneline + echo "distro top-level contents:" + ls -la "$DISTRO" | head -30 + displayName: Probe distro checkout + - stage: Copilot dependsOn: [] pool: diff --git a/build/azure-pipelines/product-copilot-recovery.yml b/build/azure-pipelines/product-copilot-recovery.yml index 32e43adb38f8ab..a0c52e68302470 100644 --- a/build/azure-pipelines/product-copilot-recovery.yml +++ b/build/azure-pipelines/product-copilot-recovery.yml @@ -68,7 +68,6 @@ extends: testSteps: - checkout: self lfs: true - persistCredentials: true retryCountOnTaskFailure: 3 - template: copilot/setup-steps.yml - template: copilot/test-steps.yml diff --git a/build/azure-pipelines/product-copilot.yml b/build/azure-pipelines/product-copilot.yml index 5d15cdf0cd49a7..cebe647882facf 100644 --- a/build/azure-pipelines/product-copilot.yml +++ b/build/azure-pipelines/product-copilot.yml @@ -20,7 +20,6 @@ jobs: lfs: true fetchDepth: 1 fetchTags: false - persistCredentials: true retryCountOnTaskFailure: 3 displayName: Checkout microsoft/vscode diff --git a/build/azure-pipelines/product-publish.yml b/build/azure-pipelines/product-publish.yml index f5b8a176bb0b16..0a0ada4ec3d41d 100644 --- a/build/azure-pipelines/product-publish.yml +++ b/build/azure-pipelines/product-publish.yml @@ -36,6 +36,13 @@ jobs: - script: node build/azure-pipelines/distro/mixin-quality.ts displayName: Mixin distro quality + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get ESRP Secrets" inputs: diff --git a/build/azure-pipelines/product-quality-checks.yml b/build/azure-pipelines/product-quality-checks.yml index 32b0977ae5d266..a885e45f49afba 100644 --- a/build/azure-pipelines/product-quality-checks.yml +++ b/build/azure-pipelines/product-quality-checks.yml @@ -17,6 +17,13 @@ jobs: - template: ./distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/web/product-build-web-node-modules.yml b/build/azure-pipelines/web/product-build-web-node-modules.yml index 797a12026e3553..75a0cc6cd6e750 100644 --- a/build/azure-pipelines/web/product-build-web-node-modules.yml +++ b/build/azure-pipelines/web/product-build-web-node-modules.yml @@ -15,6 +15,13 @@ jobs: - template: ../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 23e160bda2af85..86d6215f31cf0c 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -27,6 +27,13 @@ jobs: - template: ../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/product-build-win32-node-modules.yml b/build/azure-pipelines/win32/product-build-win32-node-modules.yml index e18cffa1d933ff..6780073f57af7d 100644 --- a/build/azure-pipelines/win32/product-build-win32-node-modules.yml +++ b/build/azure-pipelines/win32/product-build-win32-node-modules.yml @@ -26,6 +26,13 @@ jobs: - template: ../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/sdl-scan-win32.yml b/build/azure-pipelines/win32/sdl-scan-win32.yml index 49d7065f420d89..1d41892bf8d314 100644 --- a/build/azure-pipelines/win32/sdl-scan-win32.yml +++ b/build/azure-pipelines/win32/sdl-scan-win32.yml @@ -19,6 +19,13 @@ steps: - template: ../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry diff --git a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml index 56c65766ccf5b5..e64b0f0e03255d 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml @@ -30,6 +30,13 @@ steps: - template: ../../distro/download-distro.yml@self + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: vscode + KeyVaultName: vscode-build-secrets + SecretsFilter: "github-distro-mixin-password" + - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Registry From 8f0960f2119adb6cd48799c7a3494a90a5d1ed50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 19 Jun 2026 08:58:36 +0200 Subject: [PATCH 03/29] build: check out vscode-distro via Monaco GitHub App instead of PAT Replace the PAT-based zipball download of the private microsoft/vscode-distro repository with an agent-authenticated checkout of the distro repository resource (Monaco GitHub App). The distro is checked out into .build/distro and the pinned commit from package.json is checked out locally, preserving the existing contract for mixin-npm.ts / mixin-quality.ts. Self is pinned to the default sources directory so the added distro checkout does not relocate it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- build/azure-pipelines/common/checkout.yml | 5 ++ .../distro/download-distro.yml | 65 ++++--------------- build/azure-pipelines/product-build.yml | 37 ----------- 3 files changed, 19 insertions(+), 88 deletions(-) diff --git a/build/azure-pipelines/common/checkout.yml b/build/azure-pipelines/common/checkout.yml index 427f190480a534..d1313b5e2ed6d2 100644 --- a/build/azure-pipelines/common/checkout.yml +++ b/build/azure-pipelines/common/checkout.yml @@ -1,5 +1,10 @@ steps: + # Pin self to the default sources directory (`s`) so that adding a second + # checkout (e.g. the distro repository in download-distro.yml) does not relocate + # self into a repo-named subfolder, which would break every script that assumes + # self lives at $(Build.SourcesDirectory). - checkout: self + path: s fetchDepth: 1 fetchTags: false retryCountOnTaskFailure: 3 diff --git a/build/azure-pipelines/distro/download-distro.yml b/build/azure-pipelines/distro/download-distro.yml index b7c52dd36b41c0..d6ed23609b6e09 100644 --- a/build/azure-pipelines/distro/download-distro.yml +++ b/build/azure-pipelines/distro/download-distro.yml @@ -1,58 +1,21 @@ steps: - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - # TODO@joaomoreno: Keep pwsh once we move out of running entire jobs in containers - - pwsh: | - "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII - condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) - displayName: Setup distro auth (Windows) + # Check out the private microsoft/vscode-distro repository using the agent's + # GitHub App (Monaco) credentials. This avoids the need for a long-lived PAT. + # The repository resource is declared in the top-level pipeline (resources.repositories) + # and is checked out into .build/distro so that mixin-npm.ts / mixin-quality.ts can + # consume it from there (`.build/distro/npm`, `.build/distro/mixin/`). + - checkout: distro + path: s/.build/distro + fetchDepth: 0 + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode-distro - pwsh: | $ErrorActionPreference = "Stop" - $ArchivePath = "$(Agent.TempDirectory)/distro.zip" - $PackageJson = Get-Content -Path package.json -Raw | ConvertFrom-Json - $DistroVersion = $PackageJson.distro - - Invoke-WebRequest -Uri "https://api.github.com/repos/microsoft/vscode-distro/zipball/$DistroVersion" ` - -OutFile $ArchivePath ` - -Headers @{ "Accept" = "application/vnd.github+json"; "Authorization" = "Bearer $(github-distro-mixin-password)"; "X-GitHub-Api-Version" = "2022-11-28" } - - New-Item -ItemType Directory -Path .build -Force - Expand-Archive -Path $ArchivePath -DestinationPath .build - Rename-Item -Path ".build/microsoft-vscode-distro-$DistroVersion" -NewName distro - condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) - displayName: Download distro (Windows) - - - script: | - mkdir -p .build - cat << EOF | tee ~/.netrc .build/.netrc > /dev/null - machine github.com - login vscode - password $(github-distro-mixin-password) - EOF - condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) - displayName: Setup distro auth (non-Windows) - - - script: | - set -e - ArchivePath="$(Agent.TempDirectory)/distro.zip" - DistroVersion=$(node -p "require('./package.json').distro") - - curl -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer $(github-distro-mixin-password)" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -o $ArchivePath \ - -L "https://api.github.com/repos/microsoft/vscode-distro/zipball/$DistroVersion" - - unzip $ArchivePath -d .build - mv .build/microsoft-vscode-distro-$DistroVersion .build/distro - condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) - displayName: Download distro (non-Windows) + $DistroVersion = (Get-Content -Path package.json -Raw | ConvertFrom-Json).distro + Write-Host "Checking out distro commit $DistroVersion" + git -C .build/distro checkout $DistroVersion + displayName: Checkout distro commit - script: git lfs install --local displayName: Initialize Git LFS diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 6c1400d5ab82c5..5d2c4adaf2f9d6 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -224,43 +224,6 @@ extends: jobs: - template: build/azure-pipelines/product-quality-checks.yml@self - - stage: DistroProbe - dependsOn: [] - pool: - name: 1es-ubuntu-22.04-x64 - os: linux - jobs: - - job: DistroProbe - displayName: Distro Probe - steps: - - checkout: self - path: s/vscode - fetchDepth: 1 - fetchTags: false - displayName: Checkout microsoft/vscode - - checkout: distro - path: s/vscode-distro - fetchDepth: 0 - displayName: Checkout microsoft/vscode-distro - - task: NodeTool@0 - inputs: - versionSource: fromFile - versionFilePath: $(Agent.BuildDirectory)/s/vscode/.nvmrc - - script: | - set -e - SELF="$(Agent.BuildDirectory)/s/vscode" - DISTRO="$(Agent.BuildDirectory)/s/vscode-distro" - SHA=$(node -p "require('$SELF/package.json').distro") - echo "package.json distro SHA: $SHA" - echo "distro HEAD before checkout:" - git -C "$DISTRO" log -1 --oneline - git -C "$DISTRO" checkout "$SHA" - echo "checked out distro SHA OK:" - git -C "$DISTRO" log -1 --oneline - echo "distro top-level contents:" - ls -la "$DISTRO" | head -30 - displayName: Probe distro checkout - - stage: Copilot dependsOn: [] pool: From a08d03f38d1127161280e754a5234fec11c3422b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 19 Jun 2026 09:12:30 +0200 Subject: [PATCH 04/29] build: route vscode-capi and vscode-encrypt through Monaco GitHub App The github-distro-mixin-password PAT was also (via netrc) authenticating two other private repositories that are no longer reachable once the netrc is gone: - vscode-capi: cloned by common/mixin-vscode-capi.yml. Now checked out as a Monaco GitHub App repository resource and consumed from .build/vscode-capi. - vscode-encrypt: a cargo git dependency injected by the distro cli-patches. Checked out via the Monaco GitHub App and redirected with git insteadOf to the local checkout so cargo (CARGO_NET_GIT_FETCH_WITH_CLI) resolves it without a PAT. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../azure-pipelines/cli/cli-apply-patches.yml | 14 ++++++++ .../common/mixin-vscode-capi.yml | 32 +++++++++---------- build/azure-pipelines/product-build.yml | 12 +++++++ 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/build/azure-pipelines/cli/cli-apply-patches.yml b/build/azure-pipelines/cli/cli-apply-patches.yml index e04951f3f5607e..74dd78cbd7b94d 100644 --- a/build/azure-pipelines/cli/cli-apply-patches.yml +++ b/build/azure-pipelines/cli/cli-apply-patches.yml @@ -1,6 +1,20 @@ steps: - template: ../distro/download-distro.yml@self + # Check out the private microsoft/vscode-encrypt repository using the agent's + # GitHub App (Monaco) credentials. The distro cli-patches add vscode-encrypt as + # a cargo git dependency; since cargo fetches git dependencies with the git CLI + # (CARGO_NET_GIT_FETCH_WITH_CLI), we redirect the public GitHub URL to this local + # checkout via git's insteadOf so no PAT is required to resolve it. + - checkout: encrypt + path: s/.build/vscode-encrypt + fetchDepth: 0 + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode-encrypt + + - script: git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt" + displayName: Redirect vscode-encrypt to local checkout + - script: node build/azure-pipelines/distro/mixin-quality.ts displayName: Mixin distro quality diff --git a/build/azure-pipelines/common/mixin-vscode-capi.yml b/build/azure-pipelines/common/mixin-vscode-capi.yml index 6acbd604ddd3a4..4d2a42f619dc6f 100644 --- a/build/azure-pipelines/common/mixin-vscode-capi.yml +++ b/build/azure-pipelines/common/mixin-vscode-capi.yml @@ -1,4 +1,13 @@ steps: + # Check out the private microsoft/vscode-capi repository using the agent's + # GitHub App (Monaco) credentials instead of cloning it with a PAT. The + # repository resource is declared in the top-level pipeline (resources.repositories). + - checkout: capi + path: s/.build/vscode-capi + fetchDepth: 1 + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode-capi + - pwsh: | $ErrorActionPreference = 'Stop' @@ -10,25 +19,14 @@ steps: } } - $CapiPath = Join-Path '$(Agent.BuildDirectory)' 'vscode-capi' - if (Test-Path $CapiPath) { - Remove-Item -Recurse -Force $CapiPath - } + $CapiPath = Join-Path '$(Build.SourcesDirectory)' '.build/vscode-capi' + Push-Location $CapiPath try { - Invoke-CheckedCommand { git clone https://github.com/microsoft/vscode-capi.git --depth 1 $CapiPath } - Push-Location $CapiPath - - try { - Invoke-CheckedCommand { npm ci } - $env:BUILD_SOURCESDIRECTORY = '$(Build.SourcesDirectory)' - Invoke-CheckedCommand { npm run mixin_vscode } - } finally { - Pop-Location - } + Invoke-CheckedCommand { npm ci } + $env:BUILD_SOURCESDIRECTORY = '$(Build.SourcesDirectory)' + Invoke-CheckedCommand { npm run mixin_vscode } } finally { - if (Test-Path $CapiPath) { - Remove-Item -Recurse -Force $CapiPath - } + Pop-Location } displayName: Mixin vscode-capi diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 5d2c4adaf2f9d6..c4e2cce4a3e690 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -185,6 +185,16 @@ resources: name: microsoft/vscode-distro endpoint: Monaco ref: main + - repository: capi + type: github + name: microsoft/vscode-capi + endpoint: Monaco + ref: main + - repository: encrypt + type: github + name: microsoft/vscode-encrypt + endpoint: Monaco + ref: main extends: template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines @@ -193,6 +203,8 @@ extends: sourceRepositoriesToScan: exclude: - repository: distro + - repository: capi + - repository: encrypt tsa: enabled: true configFile: $(Build.SourcesDirectory)/build/azure-pipelines/config/tsaoptions.json From f0628212fdca75d06602b396784c36c7c66047e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 19 Jun 2026 09:19:06 +0200 Subject: [PATCH 05/29] build: also route vsda cargo dependency through Monaco GitHub App The distro cli-patches inject both vscode-encrypt and vsda as private cargo git dependencies. Add vsda as a Monaco GitHub App repository resource and redirect it to a local checkout via git insteadOf, mirroring the vscode-encrypt handling. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../azure-pipelines/cli/cli-apply-patches.yml | 22 +++++++++++++------ build/azure-pipelines/product-build.yml | 6 +++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/build/azure-pipelines/cli/cli-apply-patches.yml b/build/azure-pipelines/cli/cli-apply-patches.yml index 74dd78cbd7b94d..5c215e25c17713 100644 --- a/build/azure-pipelines/cli/cli-apply-patches.yml +++ b/build/azure-pipelines/cli/cli-apply-patches.yml @@ -1,19 +1,27 @@ steps: - template: ../distro/download-distro.yml@self - # Check out the private microsoft/vscode-encrypt repository using the agent's - # GitHub App (Monaco) credentials. The distro cli-patches add vscode-encrypt as - # a cargo git dependency; since cargo fetches git dependencies with the git CLI - # (CARGO_NET_GIT_FETCH_WITH_CLI), we redirect the public GitHub URL to this local - # checkout via git's insteadOf so no PAT is required to resolve it. + # Check out the private microsoft/vscode-encrypt and microsoft/vsda repositories + # using the agent's GitHub App (Monaco) credentials. The distro cli-patches add + # both as cargo git dependencies; since cargo fetches git dependencies with the + # git CLI (CARGO_NET_GIT_FETCH_WITH_CLI), we redirect the public GitHub URLs to + # these local checkouts via git's insteadOf so no PAT is required to resolve them. - checkout: encrypt path: s/.build/vscode-encrypt fetchDepth: 0 retryCountOnTaskFailure: 3 displayName: Checkout microsoft/vscode-encrypt - - script: git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt" - displayName: Redirect vscode-encrypt to local checkout + - checkout: vsda + path: s/.build/vsda + fetchDepth: 0 + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vsda + + - script: | + git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt" + git config --global url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda" + displayName: Redirect private cargo git dependencies to local checkouts - script: node build/azure-pipelines/distro/mixin-quality.ts displayName: Mixin distro quality diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index c4e2cce4a3e690..85d859ac62f932 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -195,6 +195,11 @@ resources: name: microsoft/vscode-encrypt endpoint: Monaco ref: main + - repository: vsda + type: github + name: microsoft/vsda + endpoint: Monaco + ref: main extends: template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines @@ -205,6 +210,7 @@ extends: - repository: distro - repository: capi - repository: encrypt + - repository: vsda tsa: enabled: true configFile: $(Build.SourcesDirectory)/build/azure-pipelines/config/tsaoptions.json From 3dde02073314f4279f052d0eb61f3c2bd7fbd32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 19 Jun 2026 09:44:08 +0200 Subject: [PATCH 06/29] build: drop github-distro-mixin-password PAT Replace the broad github-distro-mixin-password PAT with: - Monaco GitHub App repo-resource checkouts for private repos (vscode-distro, vscode-capi, vscode-encrypt, vsda) - the public github-token-code-oss secret (vscode-oss-build-secrets keyvault) for generic GITHUB_TOKEN rate-limit usages Copilot now checks out vscode-capi via the Monaco App instead of a netrc clone; checkDistroCommit derives the distro branch head from the local checkout instead of the private GitHub API. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../alpine/product-build-alpine-cli.yml | 9 +++- .../product-build-alpine-node-modules.yml | 10 ++--- .../alpine/product-build-alpine.yml | 16 +++---- build/azure-pipelines/cli/cli-compile.yml | 2 +- .../common/checkDistroCommit.ts | 42 +++++-------------- .../common/install-builtin-extensions.yml | 2 +- build/azure-pipelines/copilot/build-steps.yml | 16 +++++-- build/azure-pipelines/copilot/setup-steps.yml | 22 ---------- .../darwin/product-build-darwin-cli.yml | 7 ++++ .../product-build-darwin-node-modules.yml | 11 ++++- .../darwin/product-build-darwin-universal.yml | 11 ++++- .../steps/product-build-darwin-compile.yml | 19 ++++++--- .../steps/product-build-darwin-test.yml | 2 +- build/azure-pipelines/dependencies-check.yml | 9 +++- build/azure-pipelines/distro-build.yml | 13 ++++++ .../linux/product-build-linux-cli.yml | 9 +++- .../product-build-linux-node-modules.yml | 12 +++--- .../steps/product-build-linux-compile.yml | 24 +++++------ .../linux/steps/product-build-linux-test.yml | 2 +- .../product-copilot-recovery.yml | 5 +++ build/azure-pipelines/product-copilot.yml | 1 + build/azure-pipelines/product-publish.yml | 8 ++-- .../product-quality-checks.yml | 17 ++++---- .../web/product-build-web-node-modules.yml | 8 ++-- .../azure-pipelines/web/product-build-web.yml | 12 +++--- .../win32/product-build-win32-cli.yml | 7 ++++ .../product-build-win32-node-modules.yml | 8 ++-- .../azure-pipelines/win32/sdl-scan-win32.yml | 12 +++--- .../steps/product-build-win32-compile.yml | 16 +++---- .../win32/steps/product-build-win32-test.yml | 2 +- 30 files changed, 187 insertions(+), 147 deletions(-) diff --git a/build/azure-pipelines/alpine/product-build-alpine-cli.yml b/build/azure-pipelines/alpine/product-build-alpine-cli.yml index 4a8bc36e0ecf9f..3081390b6a8c2d 100644 --- a/build/azure-pipelines/alpine/product-build-alpine-cli.yml +++ b/build/azure-pipelines/alpine/product-build-alpine-cli.yml @@ -34,6 +34,13 @@ jobs: versionSource: fromFile versionFilePath: .nvmrc + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get GitHub token" + inputs: + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" + - template: ../cli/cli-apply-patches.yml@self - script: | @@ -41,7 +48,7 @@ jobs: npm ci workingDirectory: build env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install build dependencies - task: Npm@1 diff --git a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml index 07f1545ca24835..05e3bbd6f5a0c4 100644 --- a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml +++ b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml @@ -25,9 +25,9 @@ jobs: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -92,7 +92,7 @@ jobs: tar -xzf ".build/nodejs-musl/node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" -C ".build/nodejs-musl" --strip-components=1 rm ".build/nodejs-musl/node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download NodeJS MUSL condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -111,7 +111,7 @@ jobs: npm_config_arch: $(NPM_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:alpine-$(VSCODE_ARCH) VSCODE_HOST_MOUNT: "/mnt/vss/_work/1/s" VSCODE_NPMRC_PATH: $(NPMRC_PATH) diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index 3359224d3ed8d9..c7f156e4e6534e 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -67,9 +67,9 @@ jobs: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -138,7 +138,7 @@ jobs: tar -xzf ".build/nodejs-musl/node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" -C ".build/nodejs-musl" --strip-components=1 rm ".build/nodejs-musl/node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download NodeJS MUSL condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -157,7 +157,7 @@ jobs: npm_config_arch: $(NPM_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:alpine-$(VSCODE_ARCH) VSCODE_HOST_MOUNT: "/mnt/vss/_work/1/s" VSCODE_NPMRC_PATH: $(NPMRC_PATH) @@ -194,7 +194,7 @@ jobs: - script: npm run gulp core-ci env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Compile - script: npx deemon --attach -- node build/azure-pipelines/common/downloadCopilotVsix.ts @@ -214,7 +214,7 @@ jobs: echo "##vso[task.setvariable variable=SERVER_DIR_PATH]$DIR_PATH" echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build server - script: | @@ -229,5 +229,5 @@ jobs: echo "##vso[task.setvariable variable=WEB_DIR_PATH]$DIR_PATH" echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build server (web) diff --git a/build/azure-pipelines/cli/cli-compile.yml b/build/azure-pipelines/cli/cli-compile.yml index c3565a9bf4b236..9b92bfcd08389a 100644 --- a/build/azure-pipelines/cli/cli-compile.yml +++ b/build/azure-pipelines/cli/cli-compile.yml @@ -135,7 +135,7 @@ steps: env: CARGO_NET_GIT_FETCH_WITH_CLI: true VSCODE_CLI_COMMIT: $(Build.SourceVersion) - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" RUSTC_WRAPPER: sccache SCCACHE_DIR: $(Pipeline.Workspace)/sccache ${{ each pair in parameters.VSCODE_CLI_ENV }}: diff --git a/build/azure-pipelines/common/checkDistroCommit.ts b/build/azure-pipelines/common/checkDistroCommit.ts index 4003a10df317c0..887d073e9edee3 100644 --- a/build/azure-pipelines/common/checkDistroCommit.ts +++ b/build/azure-pipelines/common/checkDistroCommit.ts @@ -5,7 +5,7 @@ import path from 'path'; import fs from 'fs'; -import { retry } from './retry.ts'; +import { execSync } from 'child_process'; const root = path.dirname(path.dirname(path.dirname(import.meta.dirname))); @@ -19,30 +19,13 @@ function getEnv(name: string): string { return result; } -interface GitHubBranchResponse { - commit: { - sha: string; - }; -} - -async function getDistroBranchHead(branch: string, token: string): Promise { - const url = `https://api.github.com/repos/microsoft/vscode-distro/branches/${encodeURIComponent(branch)}`; - - const response = await fetch(url, { - headers: { - 'Accept': 'application/vnd.github+json', - 'Authorization': `Bearer ${token}`, - 'X-GitHub-Api-Version': '2022-11-28', - 'User-Agent': 'VSCode Build' - } - }); - - if (!response.ok) { - throw new Error(`Failed to fetch branch ${branch} from vscode-distro: ${response.status} ${response.statusText}`); - } - - const data = await response.json() as GitHubBranchResponse; - return data.commit.sha; +function getDistroBranchHead(branch: string): string { + // The microsoft/vscode-distro repository is checked out locally by + // download-distro.yml (into .build/distro) using the agent's GitHub App + // (Monaco) credentials. Resolve the branch head from that checkout so we + // don't need a token with private repository access. + const distroPath = path.join(root, '.build', 'distro'); + return execSync(`git -C "${distroPath}" rev-parse "refs/remotes/origin/${branch}"`, { encoding: 'utf8' }).trim(); } async function checkDistroCommit(): Promise { @@ -71,16 +54,13 @@ async function checkDistroCommit(): Promise { const branch = branchMatch[1]; console.log(`Current branch: ${branch}`); - // Get the GitHub token - const token = getEnv('GITHUB_TOKEN'); - - // Fetch the HEAD of the matching branch in vscode-distro + // Resolve the HEAD of the matching branch from the local distro checkout let distroBranchHead: string; try { - distroBranchHead = await retry(() => getDistroBranchHead(branch, token)); + distroBranchHead = getDistroBranchHead(branch); } catch (error) { // If the branch doesn't exist in distro, that's expected for feature branches - console.log(`Could not fetch branch '${branch}' from vscode-distro: ${error}`); + console.log(`Could not resolve branch '${branch}' from local vscode-distro checkout: ${error}`); console.log('This is expected for feature branches that have not been merged to distro'); return; } diff --git a/build/azure-pipelines/common/install-builtin-extensions.yml b/build/azure-pipelines/common/install-builtin-extensions.yml index f9cbfd4b0854a6..d431bff7fc10e4 100644 --- a/build/azure-pipelines/common/install-builtin-extensions.yml +++ b/build/azure-pipelines/common/install-builtin-extensions.yml @@ -19,6 +19,6 @@ steps: - script: node build/lib/builtInExtensions.ts env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" condition: and(succeeded(), ne(variables.BUILTIN_EXTENSIONS_RESTORED, 'true')) displayName: Download built-in extensions diff --git a/build/azure-pipelines/copilot/build-steps.yml b/build/azure-pipelines/copilot/build-steps.yml index 6a0ae05d86d11c..4e4d8afd87ded5 100644 --- a/build/azure-pipelines/copilot/build-steps.yml +++ b/build/azure-pipelines/copilot/build-steps.yml @@ -1,10 +1,18 @@ steps: + # Check out the private microsoft/vscode-capi repository using the agent's + # GitHub App (Monaco) credentials instead of cloning it with a PAT. The + # repository resource is declared in the top-level pipeline (resources.repositories). + - checkout: capi + path: s/.build/vscode-capi + fetchDepth: 1 + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode-capi + - script: | set -e - git clone https://github.com/microsoft/vscode-capi.git --depth 1 $(Agent.BuildDirectory)/vscode-capi - cd $(Agent.BuildDirectory)/vscode-capi - npm ci && BUILD_SOURCESDIRECTORY=$(Build.SourcesDirectory)/extensions/copilot npm run mixin - rm -rf $(Agent.BuildDirectory)/vscode-capi + cd $(Build.SourcesDirectory)/.build/vscode-capi + npm ci + BUILD_SOURCESDIRECTORY=$(Build.SourcesDirectory)/extensions/copilot npm run mixin displayName: Mixin vscode-capi - script: npm run build diff --git a/build/azure-pipelines/copilot/setup-steps.yml b/build/azure-pipelines/copilot/setup-steps.yml index 83699f8152d632..e550d6ac696058 100644 --- a/build/azure-pipelines/copilot/setup-steps.yml +++ b/build/azure-pipelines/copilot/setup-steps.yml @@ -3,28 +3,6 @@ steps: inputs: versionSpec: "22.21.x" - - task: AzureKeyVault@2 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" - - - pwsh: | - "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$Home/_netrc" -Encoding ASCII - condition: and(succeeded(), contains(variables['Agent.OS'], 'windows')) - displayName: Setup distro auth (Windows) - - - script: | - mkdir -p .build - cat << EOF | tee ~/.netrc .build/.netrc > /dev/null - machine github.com - login vscode - password $(github-distro-mixin-password) - EOF - condition: and(succeeded(), not(contains(variables['Agent.OS'], 'windows'))) - displayName: Setup distro auth (non-Windows) - - pwsh: node build/setup-npm-registry.ts $env:NPM_REGISTRY workingDirectory: $(Build.SourcesDirectory) condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'), contains(variables['Agent.OS'], 'windows')) diff --git a/build/azure-pipelines/darwin/product-build-darwin-cli.yml b/build/azure-pipelines/darwin/product-build-darwin-cli.yml index 1b6ea51bd146fb..c6f33af73a12e4 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-cli.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-cli.yml @@ -38,6 +38,13 @@ jobs: versionSource: fromFile versionFilePath: .nvmrc + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get GitHub token" + inputs: + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" + - template: ../cli/cli-apply-patches.yml@self - task: Npm@1 diff --git a/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml b/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml index d70adbee0af010..e811c7397a72cd 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-node-modules.yml @@ -28,7 +28,14 @@ jobs: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" + + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get GitHub token" + inputs: + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -78,7 +85,7 @@ jobs: npm_config_arch: $(VSCODE_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" # Avoid using dlopen to load Kerberos on macOS which can cause missing libraries # https://github.com/mongodb-js/kerberos/commit/04044d2814ad1d01e77f1ce87f26b03d86692cf2 # flipped the default to support legacy linux distros which shouldn't happen diff --git a/build/azure-pipelines/darwin/product-build-darwin-universal.yml b/build/azure-pipelines/darwin/product-build-darwin-universal.yml index f0b468db15f9ea..bc54ab1c4f8d96 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-universal.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-universal.yml @@ -36,7 +36,14 @@ jobs: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" + + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get GitHub token" + inputs: + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: node build/setup-npm-registry.ts $NPM_REGISTRY build condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -71,7 +78,7 @@ jobs: done workingDirectory: build env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install build dependencies - pwsh: node -- build/azure-pipelines/common/waitForArtifacts.ts unsigned_vscode_client_darwin_x64_archive unsigned_vscode_client_darwin_arm64_archive diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml index dd8b3e88930d08..5c74f715a576e6 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml @@ -28,7 +28,14 @@ steps: inputs: azureSubscription: vscode KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" + SecretsFilter: "macos-developer-certificate,macos-developer-certificate-key" + + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get GitHub token" + inputs: + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -82,7 +89,7 @@ steps: npm_config_arch: $(VSCODE_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" # Avoid using dlopen to load Kerberos on macOS which can cause missing libraries # https://github.com/mongodb-js/kerberos/commit/04044d2814ad1d01e77f1ce87f26b03d86692cf2 # flipped the default to support legacy linux distros which shouldn't happen @@ -127,7 +134,7 @@ steps: - script: npm run gulp core-ci env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Compile - script: node build/azure-pipelines/common/extract-telemetry.ts @@ -156,7 +163,7 @@ steps: npm run gulp vscode-darwin-$(VSCODE_ARCH)-min-ci echo "##vso[task.setvariable variable=BUILT_CLIENT]true" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build client - script: | @@ -164,7 +171,7 @@ steps: npm run gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci mv ../vscode-reh-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH) # TODO@joaomoreno env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build server - script: | @@ -172,7 +179,7 @@ steps: npm run gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci mv ../vscode-reh-web-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH)-web # TODO@joaomoreno env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build server (web) - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-test.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-test.yml index 2cb75de8dddd69..a7572e918beca5 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-test.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-test.yml @@ -9,7 +9,7 @@ parameters: steps: - script: npm exec -- npm-run-all2 -lp "electron $(VSCODE_ARCH)" "playwright-install" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 diff --git a/build/azure-pipelines/dependencies-check.yml b/build/azure-pipelines/dependencies-check.yml index d7d0d9f12b6dd8..78b74bc3425238 100644 --- a/build/azure-pipelines/dependencies-check.yml +++ b/build/azure-pipelines/dependencies-check.yml @@ -27,6 +27,13 @@ jobs: versionSource: fromFile versionFilePath: .nvmrc + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get GitHub token" + inputs: + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" + - script: | set -e echo "Checking if package.json or package-lock.json files were modified..." @@ -102,7 +109,7 @@ jobs: npm_command: 'install --ignore-scripts' ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install dependencies with retries timeoutInMinutes: 1300 condition: and(succeeded(), eq(variables['SHOULD_VALIDATE'], 'true')) diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index 1d0a50b129778f..f0e2b4460ae91a 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -7,7 +7,20 @@ trigger: include: ["main", "release/*"] pr: none +resources: + repositories: + - repository: distro + type: github + name: microsoft/vscode-distro + ref: main + endpoint: Monaco + steps: + - checkout: self + path: s + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode + - task: NodeTool@0 inputs: versionSource: fromFile diff --git a/build/azure-pipelines/linux/product-build-linux-cli.yml b/build/azure-pipelines/linux/product-build-linux-cli.yml index a9107129b73b56..c84a1fd08e2733 100644 --- a/build/azure-pipelines/linux/product-build-linux-cli.yml +++ b/build/azure-pipelines/linux/product-build-linux-cli.yml @@ -34,6 +34,13 @@ jobs: versionSource: fromFile versionFilePath: .nvmrc + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get GitHub token" + inputs: + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" + - template: ../cli/cli-apply-patches.yml@self - task: Npm@1 @@ -84,7 +91,7 @@ jobs: done workingDirectory: build env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install build dependencies - script: | diff --git a/build/azure-pipelines/linux/product-build-linux-node-modules.yml b/build/azure-pipelines/linux/product-build-linux-node-modules.yml index ad0e149816014d..9be0c3f1daf40d 100644 --- a/build/azure-pipelines/linux/product-build-linux-node-modules.yml +++ b/build/azure-pipelines/linux/product-build-linux-node-modules.yml @@ -27,9 +27,9 @@ jobs: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: | set -e @@ -93,7 +93,7 @@ jobs: done workingDirectory: build env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install build dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -109,7 +109,7 @@ jobs: SYSROOT_ARCH="$SYSROOT_ARCH" VSCODE_SYSROOT_PREFIX="-glibc-2.28-gcc-8.5.0" node -e 'import { getVSCodeSysroot } from "./build/linux/debian/install-sysroot.ts"; (async () => { await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()' env: VSCODE_ARCH: $(VSCODE_ARCH) - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download vscode sysroots condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -135,7 +135,7 @@ jobs: VSCODE_ARCH: $(VSCODE_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) diff --git a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml index ca58ca10d511e7..86a90ada9d820e 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml @@ -34,9 +34,9 @@ steps: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: | set -e @@ -104,7 +104,7 @@ steps: done workingDirectory: build env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install build dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -120,7 +120,7 @@ steps: SYSROOT_ARCH="$SYSROOT_ARCH" VSCODE_SYSROOT_PREFIX="-glibc-2.28-gcc-8.5.0" node -e 'import { getVSCodeSysroot } from "./build/linux/debian/install-sysroot.ts"; (async () => { await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()' env: VSCODE_ARCH: $(VSCODE_ARCH) - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download vscode sysroots - script: | @@ -145,7 +145,7 @@ steps: VSCODE_ARCH: $(VSCODE_ARCH) ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -186,7 +186,7 @@ steps: - script: npm run gulp core-ci env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Compile - ${{ if eq(parameters.VSCODE_ARCH, 'x64') }}: @@ -219,7 +219,7 @@ steps: echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH" echo "##vso[task.setvariable variable=CLIENT_ARCHIVE_NAME]$(basename $ARCHIVE_PATH)" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build client - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: @@ -247,7 +247,7 @@ steps: set -e tar -czf $CLIENT_PATH -C .. VSCode-linux-$(VSCODE_ARCH) env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Archive client - ${{ if ne(parameters.VSCODE_ARCH, 'armhf') }}: @@ -262,7 +262,7 @@ steps: echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" echo "##vso[task.setvariable variable=SERVER_UNARCHIVE_PATH]$UNARCHIVE_PATH" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build server - script: | @@ -274,7 +274,7 @@ steps: tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-server-linux-$(VSCODE_ARCH)-web echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build server (web) - ${{ if or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64')) }}: @@ -296,7 +296,7 @@ steps: set -e npm run gulp "vscode-linux-$(VSCODE_ARCH)-prepare-deb" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Prepare deb package - script: | diff --git a/build/azure-pipelines/linux/steps/product-build-linux-test.yml b/build/azure-pipelines/linux/steps/product-build-linux-test.yml index 5c6223cf371d81..7ce9791be40eef 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-test.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-test.yml @@ -9,7 +9,7 @@ parameters: steps: - script: npm exec -- npm-run-all2 -lp "electron $(VSCODE_ARCH)" "playwright-install" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 diff --git a/build/azure-pipelines/product-copilot-recovery.yml b/build/azure-pipelines/product-copilot-recovery.yml index a0c52e68302470..59ee945baa0395 100644 --- a/build/azure-pipelines/product-copilot-recovery.yml +++ b/build/azure-pipelines/product-copilot-recovery.yml @@ -10,6 +10,11 @@ resources: name: microsoft/vscode-engineering ref: main endpoint: Monaco + - repository: capi + type: github + name: microsoft/vscode-capi + ref: main + endpoint: Monaco parameters: - name: customNPMRegistry diff --git a/build/azure-pipelines/product-copilot.yml b/build/azure-pipelines/product-copilot.yml index cebe647882facf..cb3210e41cc618 100644 --- a/build/azure-pipelines/product-copilot.yml +++ b/build/azure-pipelines/product-copilot.yml @@ -17,6 +17,7 @@ jobs: value: true steps: - checkout: self + path: s lfs: true fetchDepth: 1 fetchTags: false diff --git a/build/azure-pipelines/product-publish.yml b/build/azure-pipelines/product-publish.yml index 0a0ada4ec3d41d..6403a6303a1592 100644 --- a/build/azure-pipelines/product-publish.yml +++ b/build/azure-pipelines/product-publish.yml @@ -39,9 +39,9 @@ jobs: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get ESRP Secrets" @@ -58,7 +58,7 @@ jobs: npm ci workingDirectory: build env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install build dependencies - download: current diff --git a/build/azure-pipelines/product-quality-checks.yml b/build/azure-pipelines/product-quality-checks.yml index a885e45f49afba..b6c127d532d87c 100644 --- a/build/azure-pipelines/product-quality-checks.yml +++ b/build/azure-pipelines/product-quality-checks.yml @@ -20,9 +20,9 @@ jobs: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -68,7 +68,7 @@ jobs: done workingDirectory: build env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install build dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -78,7 +78,7 @@ jobs: SYSROOT_ARCH="amd64" VSCODE_SYSROOT_PREFIX="-glibc-2.28-gcc-8.5.0" node -e 'import { getVSCodeSysroot } from "./build/linux/debian/install-sysroot.ts"; (async () => { await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()' env: VSCODE_ARCH: x64 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download vscode sysroots - script: | @@ -100,7 +100,7 @@ jobs: VSCODE_ARCH: x64 ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -122,7 +122,6 @@ jobs: - script: node build/azure-pipelines/common/checkDistroCommit.ts displayName: Check distro commit env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" BUILD_SOURCEBRANCH: "$(Build.SourceBranch)" continueOnError: true condition: and(succeeded(), eq(lower(variables['VSCODE_PUBLISH']), 'true')) @@ -131,12 +130,12 @@ jobs: - script: npm exec -- npm-run-all2 -lp core-ci hygiene eslint valid-layers-check define-class-fields-check vscode-dts-compile-check tsec-compile-check test-build-scripts env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Compile & Hygiene - script: npm run download-builtin-extensions-cg env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download component details of built-in extensions condition: and(succeeded(), eq(lower(variables['VSCODE_PUBLISH']), 'true')) diff --git a/build/azure-pipelines/web/product-build-web-node-modules.yml b/build/azure-pipelines/web/product-build-web-node-modules.yml index 75a0cc6cd6e750..fdd15d54f1a102 100644 --- a/build/azure-pipelines/web/product-build-web-node-modules.yml +++ b/build/azure-pipelines/web/product-build-web-node-modules.yml @@ -18,9 +18,9 @@ jobs: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -73,7 +73,7 @@ jobs: env: ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 86d6215f31cf0c..7666105b4d1474 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -30,9 +30,9 @@ jobs: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - script: node build/setup-npm-registry.ts $NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -89,7 +89,7 @@ jobs: env: ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -119,7 +119,7 @@ jobs: - script: npm run gulp core-ci env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Compile - script: npx deemon --attach -- node build/azure-pipelines/common/downloadCopilotVsix.ts @@ -135,7 +135,7 @@ jobs: tar --owner=0 --group=0 -czf $ARCHIVE_PATH -C .. vscode-web echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build - task: AzureCLI@2 diff --git a/build/azure-pipelines/win32/product-build-win32-cli.yml b/build/azure-pipelines/win32/product-build-win32-cli.yml index 20e49d34866bf5..8bbb1cdc8568f3 100644 --- a/build/azure-pipelines/win32/product-build-win32-cli.yml +++ b/build/azure-pipelines/win32/product-build-win32-cli.yml @@ -35,6 +35,13 @@ jobs: versionSource: fromFile versionFilePath: .nvmrc + - task: AzureKeyVault@2 + displayName: "Azure Key Vault: Get GitHub token" + inputs: + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" + - template: ../cli/cli-apply-patches.yml@self - task: Npm@1 diff --git a/build/azure-pipelines/win32/product-build-win32-node-modules.yml b/build/azure-pipelines/win32/product-build-win32-node-modules.yml index 6780073f57af7d..9167e5b6a004b8 100644 --- a/build/azure-pipelines/win32/product-build-win32-node-modules.yml +++ b/build/azure-pipelines/win32/product-build-win32-node-modules.yml @@ -29,9 +29,9 @@ jobs: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -76,7 +76,7 @@ jobs: npm_config_foreground_scripts: "true" ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" retryCountOnTaskFailure: 5 displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) diff --git a/build/azure-pipelines/win32/sdl-scan-win32.yml b/build/azure-pipelines/win32/sdl-scan-win32.yml index 1d41892bf8d314..945c1b795a49e9 100644 --- a/build/azure-pipelines/win32/sdl-scan-win32.yml +++ b/build/azure-pipelines/win32/sdl-scan-win32.yml @@ -22,9 +22,9 @@ steps: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -88,7 +88,7 @@ steps: npm_config_foreground_scripts: "true" ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" retryCountOnTaskFailure: 5 displayName: Install dependencies @@ -106,12 +106,12 @@ steps: - powershell: npm run gulp core-ci env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Compile - powershell: npm run gulp "vscode-symbols-win32-${{ parameters.VSCODE_ARCH }}" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download Symbols - powershell: | diff --git a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml index e64b0f0e03255d..f6005308baea8a 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml @@ -33,9 +33,9 @@ steps: - task: AzureKeyVault@2 displayName: "Azure Key Vault: Get Secrets" inputs: - azureSubscription: vscode - KeyVaultName: vscode-build-secrets - SecretsFilter: "github-distro-mixin-password" + azureSubscription: vscode-oss-build-secrets + KeyVaultName: vscode-oss-build-secrets + SecretsFilter: "github-token-code-oss" - powershell: node build/setup-npm-registry.ts $env:NPM_REGISTRY condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) @@ -84,7 +84,7 @@ steps: npm_config_foreground_scripts: "true" ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" retryCountOnTaskFailure: 5 displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) @@ -126,7 +126,7 @@ steps: - powershell: npm run gulp core-ci env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Compile - script: node build/azure-pipelines/common/extract-telemetry.ts @@ -168,7 +168,7 @@ steps: echo "##vso[task.setvariable variable=BUILT_CLIENT]true" echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH)" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build client # Note: the appx prepare step has to follow Build client step since build step replaces the template @@ -199,7 +199,7 @@ steps: echo "##vso[task.setvariable variable=BUILT_SERVER]true" echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build server - powershell: | @@ -213,7 +213,7 @@ steps: echo "##vso[task.setvariable variable=BUILT_WEB]true" echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)-web" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Build server (web) - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: diff --git a/build/azure-pipelines/win32/steps/product-build-win32-test.yml b/build/azure-pipelines/win32/steps/product-build-win32-test.yml index 187856b227229f..5b5e3e1d6df6dc 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-test.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-test.yml @@ -11,7 +11,7 @@ parameters: steps: - powershell: npm exec -- npm-run-all2 -lp "electron $(VSCODE_ARCH)" "playwright-install" env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + GITHUB_TOKEN: "$(github-token-code-oss)" displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 From 9294ed525316da042e30c215e5ade25a33db14ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 19 Jun 2026 09:50:20 +0200 Subject: [PATCH 07/29] build: check out vscode-extensions-loc via Monaco App The copilot l10n import cloned the private microsoft/vscode-extensions-loc repository with the distro PAT. Replace it with a Monaco GitHub App repo-resource checkout (sparse) so no PAT is needed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- build/azure-pipelines/copilot/l10n-steps.yml | 23 ++++++++++---------- build/azure-pipelines/product-build.yml | 6 +++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/build/azure-pipelines/copilot/l10n-steps.yml b/build/azure-pipelines/copilot/l10n-steps.yml index 99d5b249d6fc85..a7857a69c8afee 100644 --- a/build/azure-pipelines/copilot/l10n-steps.yml +++ b/build/azure-pipelines/copilot/l10n-steps.yml @@ -1,21 +1,23 @@ steps: + # Check out the private microsoft/vscode-extensions-loc repository using the + # agent's GitHub App (Monaco) credentials instead of cloning it with a PAT. + # The repository resource is declared in the top-level pipeline (resources.repositories). + - checkout: vscode_loc + path: s/.build/vscode-extensions-loc + fetchDepth: 1 + sparseCheckoutDirectories: out/GitHub.copilot-chat + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode-extensions-loc + - script: | set -e EXTENSION_ID="GitHub.copilot-chat" - L10N_REPO="https://github.com/microsoft/vscode-extensions-loc.git" - L10N_DIR="$(Agent.TempDirectory)/vscode-extensions-loc" - - echo "Cloning vscode-extensions-loc (sparse checkout)..." - git clone --depth 1 --filter=blob:none --sparse "$L10N_REPO" "$L10N_DIR" - cd "$L10N_DIR" - git sparse-checkout set "out/$EXTENSION_ID" - + L10N_DIR="$(Build.SourcesDirectory)/.build/vscode-extensions-loc" TRANSLATED_DIR="$L10N_DIR/out/$EXTENSION_ID" if [ ! -d "$TRANSLATED_DIR" ] || [ -z "$(ls -A "$TRANSLATED_DIR" 2>/dev/null)" ]; then echo "No translated strings found for $EXTENSION_ID, skipping l10n import." - rm -rf "$L10N_DIR" exit 0 fi @@ -36,7 +38,4 @@ steps: echo "Localized files:" ls -la package.nls.*.json 2>/dev/null || echo " (no package.nls.*.json)" ls -la "$L10N_ROOT"/bundle.l10n.*.json 2>/dev/null || echo " (no bundle.l10n.*.json)" - - # Cleanup - rm -rf "$L10N_DIR" displayName: Import localized strings diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 85d859ac62f932..080cd9fba0450c 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -200,6 +200,11 @@ resources: name: microsoft/vsda endpoint: Monaco ref: main + - repository: vscode_loc + type: github + name: microsoft/vscode-extensions-loc + endpoint: Monaco + ref: main extends: template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines @@ -211,6 +216,7 @@ extends: - repository: capi - repository: encrypt - repository: vsda + - repository: vscode_loc tsa: enabled: true configFile: $(Build.SourcesDirectory)/build/azure-pipelines/config/tsaoptions.json From 8aec21b19caa1458945e6cb5c11f1c7ccf28ff34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Fri, 19 Jun 2026 21:57:48 +0200 Subject: [PATCH 08/29] build: download prebuilt Electron from Azure Artifacts feed Replaces the private GitHub release download (which required the github-distro-mixin-password PAT) with an on-demand fetch from the vscode-electron-prebuilt Azure Artifacts feed, via the new asset-resolver support in @vscode/gulp-electron 1.42.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../steps/product-build-darwin-compile.yml | 2 + .../steps/product-build-linux-compile.yml | 2 + .../azure-pipelines/win32/sdl-scan-win32.yml | 2 + .../steps/product-build-win32-compile.yml | 2 + build/lib/electron.ts | 78 ++- package-lock.json | 655 ++++++++---------- package.json | 2 +- 7 files changed, 360 insertions(+), 383 deletions(-) diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml index 5c74f715a576e6..85c3301bdb759f 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml @@ -164,6 +164,8 @@ steps: echo "##vso[task.setvariable variable=BUILT_CLIENT]true" env: GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt displayName: Build client - script: | diff --git a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml index 86a90ada9d820e..70bc7d88f1e94d 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml @@ -220,6 +220,8 @@ steps: echo "##vso[task.setvariable variable=CLIENT_ARCHIVE_NAME]$(basename $ARCHIVE_PATH)" env: GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt displayName: Build client - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: diff --git a/build/azure-pipelines/win32/sdl-scan-win32.yml b/build/azure-pipelines/win32/sdl-scan-win32.yml index 945c1b795a49e9..093699cc193679 100644 --- a/build/azure-pipelines/win32/sdl-scan-win32.yml +++ b/build/azure-pipelines/win32/sdl-scan-win32.yml @@ -112,6 +112,8 @@ steps: - powershell: npm run gulp "vscode-symbols-win32-${{ parameters.VSCODE_ARCH }}" env: GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt displayName: Download Symbols - powershell: | diff --git a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml index f6005308baea8a..bc57b21031346b 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml @@ -169,6 +169,8 @@ steps: echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(Agent.BuildDirectory)/VSCode-win32-$(VSCODE_ARCH)" env: GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt displayName: Build client # Note: the appx prepare step has to follow Build client step since build step replaces the template diff --git a/build/lib/electron.ts b/build/lib/electron.ts index 016c25f7553db0..167fd88716676f 100644 --- a/build/lib/electron.ts +++ b/build/lib/electron.ts @@ -3,8 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import cp from 'child_process'; import fs from 'fs'; import path from 'path'; +import { Readable } from 'stream'; import vfs from 'vinyl-fs'; import { filter, jsonEditor } from './gulp/facade.ts'; import * as util from './util.ts'; @@ -101,7 +103,79 @@ function darwinBundleDocumentTypes(types: { [name: string]: string | string[] }, } const { msBuildId } = util.getElectronVersion(); -const electronVersion = '42.2.0'; +export const electronVersion = '42.2.0'; + +// In product builds, `@vscode/gulp-electron` is given an asset resolver (via the +// `repo` option) that fetches the prebuilt Electron archives on demand from our +// Azure Artifacts feed using the `az` CLI, instead of downloading them from a +// private GitHub release (which would require a long-lived Personal Access +// Token). Each universal package contains exactly one file, which is streamed +// back as a `Response` and validated against the feed's `SHASUMS256.txt`. +const ELECTRON_FEED_ORGANIZATION = 'https://dev.azure.com/monacotools'; +const ELECTRON_FEED_PROJECT = 'Monaco'; +const electronFeed = process.env['VSCODE_ELECTRON_PREBUILT_FEED']; + +function azExecFile(args: string[]): Promise { + return new Promise((resolve, reject) => { + const child = cp.spawn('az', args, { stdio: 'inherit', shell: process.platform === 'win32' }); + child.on('error', reject); + child.on('close', code => code === 0 ? resolve() : reject(new Error(`az ${args[0]} ${args[1] ?? ''} exited with code ${code}`))); + }); +} + +let azureDevOpsExtension: Promise | undefined; +function ensureAzureDevOpsExtension(): Promise { + if (!azureDevOpsExtension) { + azureDevOpsExtension = (async () => { + const result = cp.spawnSync('az', ['extension', 'show', '--name', 'azure-devops'], { stdio: 'ignore', shell: process.platform === 'win32' }); + if (result.status !== 0) { + await azExecFile(['extension', 'add', '--name', 'azure-devops', '--only-show-errors']); + } + })(); + } + return azureDevOpsExtension; +} + +// Maps the artifact file name `@vscode/gulp-electron` requests to the matching +// universal package name in the feed, or `undefined` when it is not mirrored. +function feedPackageName(fileName: string): string | undefined { + if (fileName === 'SHASUMS256.txt') { + return 'shasums256'; + } + if (fileName.endsWith('-symbols.zip')) { + return undefined; + } + return fileName.replace(/\.zip$/, ''); +} + +const electronAssetResolver = electronFeed + ? async ({ fileName }: { url: string; fileName: string }): Promise => { + const name = feedPackageName(fileName); + if (!name) { + return new Response(null, { status: 404 }); + } + const version = `${electronVersion}-${msBuildId}`; + const dir = path.join(root, '.build', 'electron-feed', `${name}-${version}`); + if (!fs.existsSync(dir)) { + await ensureAzureDevOpsExtension(); + await azExecFile([ + 'artifacts', 'universal', 'download', + '--organization', ELECTRON_FEED_ORGANIZATION, + '--project', ELECTRON_FEED_PROJECT, + '--scope', 'project', + '--feed', electronFeed, + '--name', name, + '--version', version, + '--path', dir, + ]); + } + const [only] = await fs.promises.readdir(dir); + const filePath = path.join(dir, only); + const size = (await fs.promises.stat(filePath)).size; + const body = Readable.toWeb(fs.createReadStream(filePath)) as ReadableStream; + return new Response(body, { status: 200, headers: { 'Content-Length': String(size) } }); + } + : undefined; export const config = { version: electronVersion, @@ -203,7 +277,7 @@ export const config = { linuxExecutableName: product.applicationName, winIcon: 'resources/win32/code.ico', token: process.env['GITHUB_TOKEN'], - repo: product.electronRepository || undefined, + repo: electronAssetResolver ?? (product.electronRepository || undefined), validateChecksum: true, checksumFile: path.join(root, 'build', 'checksums', 'electron.txt'), createVersionedResources: useVersionedUpdate, diff --git a/package-lock.json b/package-lock.json index c1ebbfa6c7eb0e..39aaa97fac506e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -107,7 +107,7 @@ "@typescript/native-preview": "^7.0.0-dev.20260609", "@vscode/component-explorer": "^0.2.1-27", "@vscode/component-explorer-cli": "^0.2.1-27", - "@vscode/gulp-electron": "1.41.3", + "@vscode/gulp-electron": "^1.42.0", "@vscode/l10n-dev": "0.0.35", "@vscode/telemetry-extractor": "^1.20.2", "@vscode/test-cli": "^0.0.6", @@ -2814,6 +2814,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/is": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-8.1.0.tgz", + "integrity": "sha512-2SX/1jW6CIMAiebvVv5ZInoCEuWQmMyBoJXXGC6Vjakjp/fpxP5eHs7/V6WKuPEIbuK06+VpjH+vjLQhr98rDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -3011,9 +3024,9 @@ } }, "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", "dev": true, "license": "MIT" }, @@ -3737,15 +3750,16 @@ "license": "MIT" }, "node_modules/@vscode/gulp-electron": { - "version": "1.41.3", - "resolved": "https://registry.npmjs.org/@vscode/gulp-electron/-/gulp-electron-1.41.3.tgz", - "integrity": "sha512-M+f3LqnZKyIf3k5fxAeKHtz5/0V9PALJqneVh7vDZ32wdbokhFmfVqzP8Z+alBjZViuL80cLe65znjELnsxUBw==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@vscode/gulp-electron/-/gulp-electron-1.42.0.tgz", + "integrity": "sha512-DQLhu7p3GnGAc1tvYtArqp3duHD+b7ddpWitqYckdioFJGAszUSf7o6KZ5szo6sjFBz+E8rvpu9EMYOjdAAMzg==", "dev": true, "license": "MIT", "dependencies": { - "@electron/get": "^4.0.1", + "@electron/get": "^5.0.0", "@octokit/rest": "^22.0.0", "event-stream": "3.3.4", + "got": "^15.0.5", "gulp-filter": "^5.1.0", "gulp-rename": "1.2.2", "gulp-symdest": "^1.2.0", @@ -3765,203 +3779,6 @@ "node": ">=22" } }, - "node_modules/@vscode/gulp-electron/node_modules/@electron/get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-4.0.1.tgz", - "integrity": "sha512-fTMFb/ZiK6xQace5YZlhT+vNR08ogat9SqpvwpaC9vD6hgx7ouz9cdcrSrFuNji4823Jmmy90/CDhJq0I4vRFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "env-paths": "^3.0.0", - "got": "^14.4.5", - "graceful-fs": "^4.2.11", - "progress": "^2.0.3", - "semver": "^7.6.3", - "sumchecker": "^3.0.1" - }, - "engines": { - "node": ">=22.12.0" - }, - "optionalDependencies": { - "global-agent": "^3.0.0" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/@electron/get/node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/@sindresorhus/is": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", - "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/cacheable-request": { - "version": "13.0.18", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.18.tgz", - "integrity": "sha512-rFWadDRKJs3s2eYdXlGggnBZKG7MTblkFBB0YllFds+UYnfogDp2wcR6JN97FhRkHTvq59n2vhNoHNZn29dh/Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "^4.0.4", - "get-stream": "^9.0.1", - "http-cache-semantics": "^4.2.0", - "keyv": "^5.5.5", - "mimic-response": "^4.0.0", - "normalize-url": "^8.1.1", - "responselike": "^4.0.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/decompress-response": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-10.0.0.tgz", - "integrity": "sha512-oj7KWToJuuxlPr7VV0vabvxEIiqNMo+q0NueIiL3XhtwC6FVOX7Hr1c0C4eD0bmf7Zr+S/dSf2xvkH3Ad6sU3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^4.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/got": { - "version": "14.6.6", - "resolved": "https://registry.npmjs.org/got/-/got-14.6.6.tgz", - "integrity": "sha512-QLV1qeYSo5l13mQzWgP/y0LbMr5Plr5fJilgAIwgnwseproEbtNym8xpLsDzeZ6MWXgNE6kdWGBjdh3zT/Qerg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^7.0.1", - "byte-counter": "^0.1.0", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^13.0.12", - "decompress-response": "^10.0.0", - "form-data-encoder": "^4.0.2", - "http2-wrapper": "^2.2.1", - "keyv": "^5.5.3", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^4.0.1", - "responselike": "^4.0.2", - "type-fest": "^4.26.1" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/keyv": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", - "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@keyv/serialize": "^1.1.1" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@vscode/gulp-electron/node_modules/mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -3974,29 +3791,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/@vscode/gulp-electron/node_modules/normalize-url": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", - "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vscode/gulp-electron/node_modules/p-cancelable": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-4.0.1.tgz", - "integrity": "sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - } - }, "node_modules/@vscode/gulp-electron/node_modules/rcedit": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-4.0.1.tgz", @@ -4010,22 +3804,6 @@ "node": ">= 14.0.0" } }, - "node_modules/@vscode/gulp-electron/node_modules/responselike": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-4.0.2.tgz", - "integrity": "sha512-cGk8IbWEAnaCpdAt1BHzJ3Ahz5ewDJa0KseTsE3qIRMJ3C698W8psM7byCeWVpd/Ha7FUYzuRVzXoKoM6nRUbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@vscode/iconv-lite-umd": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.1.tgz", @@ -5582,13 +5360,6 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24= sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true }, - "node_modules/boolean": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.2.tgz", - "integrity": "sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==", - "dev": true, - "optional": true - }, "node_modules/brace-expansion": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", @@ -5808,6 +5579,75 @@ "node": ">=0.10.0" } }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "13.0.19", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.19.tgz", + "integrity": "sha512-SVXGH037+Mo1aIMO5B2UcleR43FGjFdN+M8JObSyEoQ2Mn4CODRWx28gN5jiTF0n5ItsgtIZfyargMNs8GX4kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.2.0", + "get-stream": "^9.0.1", + "http-cache-semantics": "^4.2.0", + "keyv": "^5.6.0", + "mimic-response": "^4.0.0", + "normalize-url": "^8.1.1", + "responselike": "^4.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, "node_modules/call-bind": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", @@ -6016,6 +5856,19 @@ "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", "dev": true }, + "node_modules/chunk-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chunk-data/-/chunk-data-0.1.0.tgz", + "integrity": "sha512-zFyPtyC0SZ6Zu79b9sOYtXZcgrsXe0RpePrzRyj52hYVFG1+Rk6rBqjjOEk+GNQwc3PIX+86teQMok970pod1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", @@ -7062,13 +6915,6 @@ "node": ">=0.10.0" } }, - "node_modules/detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true, - "optional": true - }, "node_modules/devtools-protocol": { "version": "0.0.1173815", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1173815.tgz", @@ -7555,13 +7401,6 @@ "node": ">=0.10" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, "node_modules/es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", @@ -9050,16 +8889,6 @@ "node": ">= 6" } }, - "node_modules/form-data-encoder": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.1.0.tgz", - "integrity": "sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 18" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -9756,24 +9585,6 @@ "node": ">=0.10.0" } }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -9870,6 +9681,59 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/got/-/got-15.0.5.tgz", + "integrity": "sha512-PMIMaZuYUCK43+Z9JWEXea4kkX2b3301m81D5TS6QpfG4PmNyirzEdO/Oa2OHAN4GsjnPfvWCWsshKN2rq4/gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^8.0.0", + "byte-counter": "^0.1.0", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^13.0.18", + "chunk-data": "^0.1.0", + "decompress-response": "^10.0.0", + "http2-wrapper": "^2.2.1", + "keyv": "^5.6.0", + "lowercase-keys": "^4.0.1", + "responselike": "^4.0.2", + "type-fest": "^5.6.0", + "uint8array-extras": "^1.5.0" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/decompress-response": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-10.0.0.tgz", + "integrity": "sha512-oj7KWToJuuxlPr7VV0vabvxEIiqNMo+q0NueIiL3XhtwC6FVOX7Hr1c0C4eD0bmf7Zr+S/dSf2xvkH3Ad6sU3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^4.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -11446,6 +11310,20 @@ "node": ">= 14" } }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -12728,14 +12606,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC", - "optional": true - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -13261,6 +13131,19 @@ "loose-envify": "cli.js" } }, + "node_modules/lowercase-keys": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-4.0.1.tgz", + "integrity": "sha512-wI9Nui/L8VfADa/cr/7NQruaASk1k23/Uh1khQ02BCVYiiy8F4AhOGnQzJy3Fl/c44GnYSbZHv8g7EcG3kJ1Qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -13554,19 +13437,6 @@ "node": ">=0.10.0" } }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -13737,6 +13607,19 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -14376,6 +14259,19 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/now-and-later": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", @@ -15795,6 +15691,7 @@ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -16305,7 +16202,8 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/resolve-dir": { "version": "1.0.1", @@ -16407,6 +16305,35 @@ "deprecated": "https://github.com/lydell/resolve-url#deprecated", "dev": true }, + "node_modules/responselike": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-4.0.2.tgz", + "integrity": "sha512-cGk8IbWEAnaCpdAt1BHzJ3Ahz5ewDJa0KseTsE3qIRMJ3C698W8psM7byCeWVpd/Ha7FUYzuRVzXoKoM6nRUbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/responselike/node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/restore-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", @@ -16482,24 +16409,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -16677,13 +16586,6 @@ "node": ">=10" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w= sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "optional": true - }, "node_modules/semver-greatest-satisfied-range": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", @@ -16760,35 +16662,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/serialize-javascript": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", @@ -17502,13 +17375,6 @@ "node": ">=0.10.0" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "optional": true - }, "node_modules/ssh2": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz", @@ -18162,6 +18028,19 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tapable": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", @@ -18710,13 +18589,16 @@ } }, "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.7.0.tgz", + "integrity": "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==", "dev": true, "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, "engines": { - "node": ">=16" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -18912,6 +18794,19 @@ "dev": true, "license": "MIT" }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", diff --git a/package.json b/package.json index 504e0672ffc113..5a60ec7208b834 100644 --- a/package.json +++ b/package.json @@ -190,7 +190,7 @@ "@typescript/native-preview": "^7.0.0-dev.20260609", "@vscode/component-explorer": "^0.2.1-27", "@vscode/component-explorer-cli": "^0.2.1-27", - "@vscode/gulp-electron": "1.41.3", + "@vscode/gulp-electron": "^1.42.0", "@vscode/l10n-dev": "0.0.35", "@vscode/telemetry-extractor": "^1.20.2", "@vscode/test-cli": "^0.0.6", From 2c11783d3f7aa9872175f7f4b6c7b97337f09700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sat, 20 Jun 2026 08:42:28 +0200 Subject: [PATCH 09/29] build: resolve private vsda/vscode-encrypt git deps via local checkouts The distro's npm postinstall and the CLI cargo patches both depend on the private microsoft/vsda and microsoft/vscode-encrypt repositories. Now that the distro PAT/.netrc is gone, redirect their public GitHub URLs (https and ssh) to local GitHub App checkouts via git insteadOf in download-distro.yml so every job that consumes the distro can resolve them without a PAT. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../azure-pipelines/cli/cli-apply-patches.yml | 22 --------------- build/azure-pipelines/distro-build.yml | 10 +++++++ .../distro/download-distro.yml | 28 +++++++++++++++++++ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/build/azure-pipelines/cli/cli-apply-patches.yml b/build/azure-pipelines/cli/cli-apply-patches.yml index 5c215e25c17713..e04951f3f5607e 100644 --- a/build/azure-pipelines/cli/cli-apply-patches.yml +++ b/build/azure-pipelines/cli/cli-apply-patches.yml @@ -1,28 +1,6 @@ steps: - template: ../distro/download-distro.yml@self - # Check out the private microsoft/vscode-encrypt and microsoft/vsda repositories - # using the agent's GitHub App (Monaco) credentials. The distro cli-patches add - # both as cargo git dependencies; since cargo fetches git dependencies with the - # git CLI (CARGO_NET_GIT_FETCH_WITH_CLI), we redirect the public GitHub URLs to - # these local checkouts via git's insteadOf so no PAT is required to resolve them. - - checkout: encrypt - path: s/.build/vscode-encrypt - fetchDepth: 0 - retryCountOnTaskFailure: 3 - displayName: Checkout microsoft/vscode-encrypt - - - checkout: vsda - path: s/.build/vsda - fetchDepth: 0 - retryCountOnTaskFailure: 3 - displayName: Checkout microsoft/vsda - - - script: | - git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt" - git config --global url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda" - displayName: Redirect private cargo git dependencies to local checkouts - - script: node build/azure-pipelines/distro/mixin-quality.ts displayName: Mixin distro quality diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index f0e2b4460ae91a..26a56280ef77a2 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -14,6 +14,16 @@ resources: name: microsoft/vscode-distro ref: main endpoint: Monaco + - repository: encrypt + type: github + name: microsoft/vscode-encrypt + ref: main + endpoint: Monaco + - repository: vsda + type: github + name: microsoft/vsda + ref: main + endpoint: Monaco steps: - checkout: self diff --git a/build/azure-pipelines/distro/download-distro.yml b/build/azure-pipelines/distro/download-distro.yml index d6ed23609b6e09..31c23baf144799 100644 --- a/build/azure-pipelines/distro/download-distro.yml +++ b/build/azure-pipelines/distro/download-distro.yml @@ -22,3 +22,31 @@ steps: - script: git lfs pull displayName: Pull Git LFS objects + + # Check out the private microsoft/vscode-encrypt and microsoft/vsda repositories + # using the agent's GitHub App (Monaco) credentials. The distro's npm dependencies + # reference both as git dependencies; npm resolves these over ssh while cargo (CLI + # build) resolves them over https. We redirect both public GitHub URLs to these + # local checkouts via git's insteadOf so no PAT is required to resolve them. + - checkout: encrypt + path: s/.build/vscode-encrypt + fetchDepth: 0 + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode-encrypt + + - checkout: vsda + path: s/.build/vsda + fetchDepth: 0 + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vsda + + - script: | + git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt.git" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "ssh://git@github.com/microsoft/vscode-encrypt" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "ssh://git@github.com/microsoft/vscode-encrypt.git" + git config --global url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda.git" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "ssh://git@github.com/microsoft/vsda" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "ssh://git@github.com/microsoft/vsda.git" + displayName: Redirect private git dependencies to local checkouts From 3b6dc0aae0322334d4ce4db472d92ec7b0298d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sat, 20 Jun 2026 19:14:09 +0200 Subject: [PATCH 10/29] build: download Alpine musl Node.js from Azure Artifacts feed The Alpine build downloaded the musl Node.js tarball from the private microsoft/vscode-node GitHub releases, which the public github-token-code-oss cannot access. Consume the new vscode-node Azure Artifacts feed via az artifacts universal download instead (authenticated with System.AccessToken), mirroring the Electron prebuilt download. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../alpine/product-build-alpine-node-modules.yml | 13 +++++++++++-- .../azure-pipelines/alpine/product-build-alpine.yml | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml index 05e3bbd6f5a0c4..7b560b328677b9 100644 --- a/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml +++ b/build/azure-pipelines/alpine/product-build-alpine-node-modules.yml @@ -88,11 +88,20 @@ jobs: mkdir -p .build/nodejs-musl NODE_VERSION=$(grep '^target=' remote/.npmrc | cut -d '"' -f 2) BUILD_ID=$(grep '^ms_build_id=' remote/.npmrc | cut -d '"' -f 2) - gh release download "v${NODE_VERSION}-${BUILD_ID}" -R microsoft/vscode-node -p "node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" --dir .build/nodejs-musl --clobber + az extension add --name azure-devops --upgrade --only-show-errors + az artifacts universal download \ + --organization "https://dev.azure.com/monacotools" \ + --project "Monaco" \ + --scope project \ + --feed "vscode-node" \ + --name "node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar" \ + --version "${NODE_VERSION}-${BUILD_ID}" \ + --path .build/nodejs-musl \ + --only-show-errors tar -xzf ".build/nodejs-musl/node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" -C ".build/nodejs-musl" --strip-components=1 rm ".build/nodejs-musl/node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" env: - GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: "$(System.AccessToken)" displayName: Download NodeJS MUSL condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index c7f156e4e6534e..0c65e6e6c2698b 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -134,11 +134,20 @@ jobs: mkdir -p .build/nodejs-musl NODE_VERSION=$(grep '^target=' remote/.npmrc | cut -d '"' -f 2) BUILD_ID=$(grep '^ms_build_id=' remote/.npmrc | cut -d '"' -f 2) - gh release download "v${NODE_VERSION}-${BUILD_ID}" -R microsoft/vscode-node -p "node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" --dir .build/nodejs-musl --clobber + az extension add --name azure-devops --upgrade --only-show-errors + az artifacts universal download \ + --organization "https://dev.azure.com/monacotools" \ + --project "Monaco" \ + --scope project \ + --feed "vscode-node" \ + --name "node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar" \ + --version "${NODE_VERSION}-${BUILD_ID}" \ + --path .build/nodejs-musl \ + --only-show-errors tar -xzf ".build/nodejs-musl/node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" -C ".build/nodejs-musl" --strip-components=1 rm ".build/nodejs-musl/node-v${NODE_VERSION}-linux-${VSCODE_ARCH}-musl.tar.gz" env: - GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: "$(System.AccessToken)" displayName: Download NodeJS MUSL condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) From 89d7f3136acc53b968aeb0d07dc8ef77a872ae8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sat, 20 Jun 2026 19:16:47 +0200 Subject: [PATCH 11/29] build: resolve private vscode-regexp-languagedetection git dep via local checkout The distro's npm dependencies reference microsoft/vscode-regexp-languagedetection in addition to microsoft/vsda. Check it out via the Monaco GitHub App and redirect its public GitHub URL (https and ssh) to the local checkout so the distro npm postinstall resolves it without a PAT. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- build/azure-pipelines/distro-build.yml | 5 +++++ .../distro/download-distro.yml | 22 ++++++++++++++----- build/azure-pipelines/product-build.yml | 6 +++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index 26a56280ef77a2..05ac00cec7db8f 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -24,6 +24,11 @@ resources: name: microsoft/vsda ref: main endpoint: Monaco + - repository: regexp + type: github + name: microsoft/vscode-regexp-languagedetection + ref: main + endpoint: Monaco steps: - checkout: self diff --git a/build/azure-pipelines/distro/download-distro.yml b/build/azure-pipelines/distro/download-distro.yml index 31c23baf144799..843aee48d98f84 100644 --- a/build/azure-pipelines/distro/download-distro.yml +++ b/build/azure-pipelines/distro/download-distro.yml @@ -23,11 +23,13 @@ steps: - script: git lfs pull displayName: Pull Git LFS objects - # Check out the private microsoft/vscode-encrypt and microsoft/vsda repositories - # using the agent's GitHub App (Monaco) credentials. The distro's npm dependencies - # reference both as git dependencies; npm resolves these over ssh while cargo (CLI - # build) resolves them over https. We redirect both public GitHub URLs to these - # local checkouts via git's insteadOf so no PAT is required to resolve them. + # Check out the private microsoft/vscode-encrypt, microsoft/vsda and + # microsoft/vscode-regexp-languagedetection repositories using the agent's GitHub + # App (Monaco) credentials. The distro's npm dependencies reference vsda and + # vscode-regexp-languagedetection as git dependencies, and the CLI cargo patches + # reference vsda and vscode-encrypt; npm resolves these over ssh while cargo + # resolves them over https. We redirect both public GitHub URLs to these local + # checkouts via git's insteadOf so no PAT is required to resolve them. - checkout: encrypt path: s/.build/vscode-encrypt fetchDepth: 0 @@ -40,6 +42,12 @@ steps: retryCountOnTaskFailure: 3 displayName: Checkout microsoft/vsda + - checkout: regexp + path: s/.build/vscode-regexp-languagedetection + fetchDepth: 0 + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode-regexp-languagedetection + - script: | git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt" git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt.git" @@ -49,4 +57,8 @@ steps: git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda.git" git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "ssh://git@github.com/microsoft/vsda" git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "ssh://git@github.com/microsoft/vsda.git" + git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "https://github.com/microsoft/vscode-regexp-languagedetection" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "https://github.com/microsoft/vscode-regexp-languagedetection.git" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "ssh://git@github.com/microsoft/vscode-regexp-languagedetection" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "ssh://git@github.com/microsoft/vscode-regexp-languagedetection.git" displayName: Redirect private git dependencies to local checkouts diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 080cd9fba0450c..5c46f22ede6fcc 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -200,6 +200,11 @@ resources: name: microsoft/vsda endpoint: Monaco ref: main + - repository: regexp + type: github + name: microsoft/vscode-regexp-languagedetection + endpoint: Monaco + ref: main - repository: vscode_loc type: github name: microsoft/vscode-extensions-loc @@ -216,6 +221,7 @@ extends: - repository: capi - repository: encrypt - repository: vsda + - repository: regexp - repository: vscode_loc tsa: enabled: true From 752ca8a71bd920dc816d416a3ff2bd03850a5446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sat, 20 Jun 2026 21:49:03 +0200 Subject: [PATCH 12/29] build: download server Node.js from Azure Artifacts feed Fetch the prebuilt server (reh) Node.js binaries on demand from the vscode-node Azure Artifacts feed (gated on VSCODE_NODEJS_INTERNAL_FEED) instead of from a private GitHub release, so the build no longer needs a long-lived PAT. Extracts the shared az universal-package download helper into build/lib/azureFeed.ts, reused by the Electron resolver. Bumps the server node ms_build_id to 449655 to match the feed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../alpine/product-build-alpine.yml | 4 ++ .../steps/product-build-darwin-compile.yml | 4 ++ .../steps/product-build-linux-compile.yml | 4 ++ .../steps/product-build-win32-compile.yml | 4 ++ build/gulpfile.reh.ts | 56 ++++++++++++++- build/lib/azureFeed.ts | 70 +++++++++++++++++++ build/lib/electron.ts | 42 +---------- remote/.npmrc | 2 +- 8 files changed, 142 insertions(+), 44 deletions(-) create mode 100644 build/lib/azureFeed.ts diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index 0c65e6e6c2698b..671937411f1dcd 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -224,6 +224,8 @@ jobs: echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-token-code-oss)" + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server - script: | @@ -239,4 +241,6 @@ jobs: echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-token-code-oss)" + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server (web) diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml index 85c3301bdb759f..e0d849587fb977 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml @@ -174,6 +174,8 @@ steps: mv ../vscode-reh-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH) # TODO@joaomoreno env: GITHUB_TOKEN: "$(github-token-code-oss)" + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server - script: | @@ -182,6 +184,8 @@ steps: mv ../vscode-reh-web-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH)-web # TODO@joaomoreno env: GITHUB_TOKEN: "$(github-token-code-oss)" + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server (web) - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: diff --git a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml index 70bc7d88f1e94d..2176a35793c5a0 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml @@ -265,6 +265,8 @@ steps: echo "##vso[task.setvariable variable=SERVER_UNARCHIVE_PATH]$UNARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-token-code-oss)" + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server - script: | @@ -277,6 +279,8 @@ steps: echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-token-code-oss)" + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server (web) - ${{ if or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64')) }}: diff --git a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml index bc57b21031346b..f6f6ae86132aa4 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml @@ -202,6 +202,8 @@ steps: echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)" env: GITHUB_TOKEN: "$(github-token-code-oss)" + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server - powershell: | @@ -216,6 +218,8 @@ steps: echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)-web" env: GITHUB_TOKEN: "$(github-token-code-oss)" + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server (web) - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: diff --git a/build/gulpfile.reh.ts b/build/gulpfile.reh.ts index 62c30da5216af7..5efa7404752216 100644 --- a/build/gulpfile.reh.ts +++ b/build/gulpfile.reh.ts @@ -26,9 +26,11 @@ import { compileBuildWithManglingTask } from './gulpfile.compile.ts'; import { cleanExtensionsBuildTask, compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileExtensionMediaBuildTask, compileCopilotExtensionBuildTask } from './gulpfile.extensions.ts'; import { vscodeWebResourceIncludes, createVSCodeWebFileContentMapper } from './gulpfile.vscode.web.ts'; import * as cp from 'child_process'; +import crypto from 'crypto'; import log from 'fancy-log'; import buildfile from './buildfile.ts'; import { fetchUrls, fetchGithub } from './lib/fetch.ts'; +import { downloadFeedPackage } from './lib/azureFeed.ts'; import { getCopilotExcludeFilter, getCopilotRuntimePrebuildFiles, getCopilotTgrepExcludeFilter, getRipgrepExcludeFilter, prepareBuiltInCopilotRipgrepShim } from './lib/copilot.ts'; import { readAgentSdkResults } from './agent-sdk/common.ts'; @@ -208,6 +210,45 @@ function patchElfLoadAlign(): NodeJS.ReadWriteStream { const { nodeVersion, internalNodeVersion } = getNodeVersion(); +// In product builds, the server (reh) Node.js binaries are fetched on demand +// from our Azure Artifacts `vscode-node` feed using the `az` CLI (gated on +// `VSCODE_NODEJS_INTERNAL_FEED`), instead of from a private GitHub release +// (which would require a long-lived Personal Access Token). Each universal +// package contains exactly one file, named after the asset minus its last +// extension, lowercased and sanitized (e.g. `node-v24.15.0-linux-x64.tar`, +// `win-x64-node`). +const nodejsInternalFeed = process.env['VSCODE_NODEJS_INTERNAL_FEED']; + +function internalNodeFeedPackageName(assetName: string): string { + return assetName + .replace(/\.[^.]+$/, '') + .toLowerCase() + .replace(/[^a-z0-9._-]+/g, '-') + .replace(/^[._-]+/, '') + .replace(/[._-]+$/, ''); +} + +function fetchNodejsFromInternalFeed(feed: string, assetName: string, version: string, checksumSha256: string | undefined): NodeJS.ReadWriteStream { + const result = es.through(); + (async () => { + try { + const filePath = await downloadFeedPackage(REPO_ROOT, 'nodejs-feed', { feed, name: internalNodeFeedPackageName(assetName), version }); + const contents = await fs.promises.readFile(filePath); + if (checksumSha256) { + const actual = crypto.createHash('sha256').update(contents).digest('hex'); + if (actual !== checksumSha256) { + throw new Error(`Checksum mismatch for ${assetName} (expected ${checksumSha256}, actual ${actual})`); + } + } + result.emit('data', new File({ path: path.basename(filePath), contents })); + result.emit('end'); + } catch (err) { + result.emit('error', err); + } + })(); + return result; +} + BUILD_TARGETS.forEach(({ platform, arch }) => { task.task(task.define(`node-${platform}-${arch}`, () => { const nodePath = path.join('.build', 'node', `v${nodeVersion}`, `${platform}-${arch}`); @@ -268,13 +309,13 @@ function nodejs(platform: string, arch: string): NodeJS.ReadWriteStream | undefi switch (platform) { case 'win32': return (product.nodejsRepository !== 'https://nodejs.org' ? - fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName!, checksumSha256 }) : + fetchNodejs(expectedName!, checksumSha256) : fetchUrls(`/dist/v${nodeVersion}/win-${arch}/node.exe`, { base: 'https://nodejs.org', checksumSha256 })) .pipe(rename('node.exe')); case 'darwin': case 'linux': { const downloaded = (product.nodejsRepository !== 'https://nodejs.org' ? - fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName!, checksumSha256 }) : + fetchNodejs(expectedName!, checksumSha256) : fetchUrls(`/dist/v${nodeVersion}/node-v${nodeVersion}-${platform}-${arch}.tar.gz`, { base: 'https://nodejs.org', checksumSha256 }) ).pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar()))) .pipe(filter('**/node')) @@ -284,7 +325,7 @@ function nodejs(platform: string, arch: string): NodeJS.ReadWriteStream | undefi } case 'alpine': return product.nodejsRepository !== 'https://nodejs.org' ? - fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName!, checksumSha256 }) + fetchNodejs(expectedName!, checksumSha256) .pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar()))) .pipe(filter('**/node')) .pipe(util.setExecutableBit('**')) @@ -293,6 +334,15 @@ function nodejs(platform: string, arch: string): NodeJS.ReadWriteStream | undefi } } +// Fetches a server (reh) Node.js asset either from the internal Azure Artifacts +// feed (product builds) or directly from the private GitHub release. +function fetchNodejs(assetName: string, checksumSha256: string | undefined): NodeJS.ReadWriteStream { + const version = `${nodeVersion}-${internalNodeVersion}`; + return nodejsInternalFeed ? + fetchNodejsFromInternalFeed(nodejsInternalFeed, assetName, version, checksumSha256) : + fetchGithub(product.nodejsRepository, { version, name: assetName, checksumSha256 }) as NodeJS.ReadWriteStream; +} + function packageTask(type: string, platform: string, arch: string, sourceFolderName: string, destinationFolderName: string) { const destination = path.join(BUILD_ROOT, destinationFolderName); diff --git a/build/lib/azureFeed.ts b/build/lib/azureFeed.ts new file mode 100644 index 00000000000000..5913ac99364fb3 --- /dev/null +++ b/build/lib/azureFeed.ts @@ -0,0 +1,70 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import cp from 'child_process'; +import fs from 'fs'; +import path from 'path'; + +// Shared helpers for downloading prebuilt binaries (Electron, Node.js) on demand +// from our Azure Artifacts universal package feeds using the `az` CLI, instead +// of fetching them from private GitHub releases (which would require a +// long-lived Personal Access Token). +const ORGANIZATION = 'https://dev.azure.com/monacotools'; +const PROJECT = 'Monaco'; + +function azExecFile(args: string[]): Promise { + return new Promise((resolve, reject) => { + const child = cp.spawn('az', args, { stdio: 'inherit', shell: process.platform === 'win32' }); + child.on('error', reject); + child.on('close', code => code === 0 ? resolve() : reject(new Error(`az ${args[0]} ${args[1] ?? ''} exited with code ${code}`))); + }); +} + +let azureDevOpsExtension: Promise | undefined; +function ensureAzureDevOpsExtension(): Promise { + if (!azureDevOpsExtension) { + azureDevOpsExtension = (async () => { + const result = cp.spawnSync('az', ['extension', 'show', '--name', 'azure-devops'], { stdio: 'ignore', shell: process.platform === 'win32' }); + if (result.status !== 0) { + await azExecFile(['extension', 'add', '--name', 'azure-devops', '--only-show-errors']); + } + })(); + } + return azureDevOpsExtension; +} + +export interface IFeedPackage { + readonly feed: string; + readonly name: string; + readonly version: string; +} + +/** + * Downloads a universal package from an Azure Artifacts feed into a cache + * directory under `/.build/` and returns the absolute path to + * the single file it contains. Subsequent requests for the same package are + * served from the cache. + * @param root the repository root + * @param cacheDir the `.build` sub directory used to cache downloaded packages + * @param pkg the feed, package name and version to download + */ +export async function downloadFeedPackage(root: string, cacheDir: string, pkg: IFeedPackage): Promise { + const dir = path.join(root, '.build', cacheDir, `${pkg.name}-${pkg.version}`); + if (!fs.existsSync(dir)) { + await ensureAzureDevOpsExtension(); + await azExecFile([ + 'artifacts', 'universal', 'download', + '--organization', ORGANIZATION, + '--project', PROJECT, + '--scope', 'project', + '--feed', pkg.feed, + '--name', pkg.name, + '--version', pkg.version, + '--path', dir, + ]); + } + const [only] = await fs.promises.readdir(dir); + return path.join(dir, only); +} diff --git a/build/lib/electron.ts b/build/lib/electron.ts index 167fd88716676f..9a2db04deb8fac 100644 --- a/build/lib/electron.ts +++ b/build/lib/electron.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import cp from 'child_process'; import fs from 'fs'; import path from 'path'; import { Readable } from 'stream'; @@ -11,6 +10,7 @@ import vfs from 'vinyl-fs'; import { filter, jsonEditor } from './gulp/facade.ts'; import * as util from './util.ts'; import { getVersion } from './getVersion.ts'; +import { downloadFeedPackage } from './azureFeed.ts'; import electron from '@vscode/gulp-electron'; type DarwinDocumentSuffix = 'document' | 'script' | 'file' | 'source code'; @@ -111,31 +111,8 @@ export const electronVersion = '42.2.0'; // private GitHub release (which would require a long-lived Personal Access // Token). Each universal package contains exactly one file, which is streamed // back as a `Response` and validated against the feed's `SHASUMS256.txt`. -const ELECTRON_FEED_ORGANIZATION = 'https://dev.azure.com/monacotools'; -const ELECTRON_FEED_PROJECT = 'Monaco'; const electronFeed = process.env['VSCODE_ELECTRON_PREBUILT_FEED']; -function azExecFile(args: string[]): Promise { - return new Promise((resolve, reject) => { - const child = cp.spawn('az', args, { stdio: 'inherit', shell: process.platform === 'win32' }); - child.on('error', reject); - child.on('close', code => code === 0 ? resolve() : reject(new Error(`az ${args[0]} ${args[1] ?? ''} exited with code ${code}`))); - }); -} - -let azureDevOpsExtension: Promise | undefined; -function ensureAzureDevOpsExtension(): Promise { - if (!azureDevOpsExtension) { - azureDevOpsExtension = (async () => { - const result = cp.spawnSync('az', ['extension', 'show', '--name', 'azure-devops'], { stdio: 'ignore', shell: process.platform === 'win32' }); - if (result.status !== 0) { - await azExecFile(['extension', 'add', '--name', 'azure-devops', '--only-show-errors']); - } - })(); - } - return azureDevOpsExtension; -} - // Maps the artifact file name `@vscode/gulp-electron` requests to the matching // universal package name in the feed, or `undefined` when it is not mirrored. function feedPackageName(fileName: string): string | undefined { @@ -155,22 +132,7 @@ const electronAssetResolver = electronFeed return new Response(null, { status: 404 }); } const version = `${electronVersion}-${msBuildId}`; - const dir = path.join(root, '.build', 'electron-feed', `${name}-${version}`); - if (!fs.existsSync(dir)) { - await ensureAzureDevOpsExtension(); - await azExecFile([ - 'artifacts', 'universal', 'download', - '--organization', ELECTRON_FEED_ORGANIZATION, - '--project', ELECTRON_FEED_PROJECT, - '--scope', 'project', - '--feed', electronFeed, - '--name', name, - '--version', version, - '--path', dir, - ]); - } - const [only] = await fs.promises.readdir(dir); - const filePath = path.join(dir, only); + const filePath = await downloadFeedPackage(root, 'electron-feed', { feed: electronFeed, name, version }); const size = (await fs.promises.stat(filePath)).size; const body = Readable.toWeb(fs.createReadStream(filePath)) as ReadableStream; return new Response(body, { status: 200, headers: { 'Content-Length': String(size) } }); diff --git a/remote/.npmrc b/remote/.npmrc index 6f2d4e8df7b2cf..0fd6a00ec089ea 100644 --- a/remote/.npmrc +++ b/remote/.npmrc @@ -1,6 +1,6 @@ disturl="https://nodejs.org/dist" target="24.15.0" -ms_build_id="438265" +ms_build_id="449655" runtime="node" build_from_source="true" legacy-peer-deps="true" From 4b26f5e86196ca17e19629013edf9428b3baf35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sat, 20 Jun 2026 22:40:14 +0200 Subject: [PATCH 13/29] build: resolve distro private git deps inside the Alpine container The Alpine server build installs the distro's npm dependencies (which reference the private vsda and vscode-regexp-languagedetection git repos) inside a docker container. The host git insteadOf redirects are not visible there and use host paths, so emit a container-pathed gitconfig (.build/.gitconfig-distro) from download-distro.yml and bind-mount it as /root/.gitconfig, replacing the now-unused .netrc mount. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../distro/download-distro.yml | 33 ++++++++++++------- build/npm/postinstall.ts | 2 +- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/build/azure-pipelines/distro/download-distro.yml b/build/azure-pipelines/distro/download-distro.yml index 843aee48d98f84..4be08bd49ca6db 100644 --- a/build/azure-pipelines/distro/download-distro.yml +++ b/build/azure-pipelines/distro/download-distro.yml @@ -49,16 +49,25 @@ steps: displayName: Checkout microsoft/vscode-regexp-languagedetection - script: | - git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt.git" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "ssh://git@github.com/microsoft/vscode-encrypt" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "ssh://git@github.com/microsoft/vscode-encrypt.git" - git config --global url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda.git" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "ssh://git@github.com/microsoft/vsda" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "ssh://git@github.com/microsoft/vsda.git" - git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "https://github.com/microsoft/vscode-regexp-languagedetection" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "https://github.com/microsoft/vscode-regexp-languagedetection.git" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "ssh://git@github.com/microsoft/vscode-regexp-languagedetection" - git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "ssh://git@github.com/microsoft/vscode-regexp-languagedetection.git" + set -e + # Redirect the private git dependencies referenced by the distro's npm and + # cargo manifests to the local checkouts above, so no PAT is required to + # resolve them. npm resolves these over ssh while cargo resolves them over + # https, with and without a trailing `.git`, so we register every form. + # We write two sets of redirects: the global config is used by builds that + # run on the agent directly (host paths), while .build/.gitconfig-distro + # uses the paths seen inside the Alpine dependency container (which mounts + # the sources at /root/vscode) and is bind-mounted as /root/.gitconfig. + CONTAINER_GITCONFIG="$(Build.SourcesDirectory)/.build/.gitconfig-distro" + rm -f "$CONTAINER_GITCONFIG" + for repo in vscode-encrypt vsda vscode-regexp-languagedetection; do + for url in \ + "https://github.com/microsoft/$repo" \ + "https://github.com/microsoft/$repo.git" \ + "ssh://git@github.com/microsoft/$repo" \ + "ssh://git@github.com/microsoft/$repo.git"; do + git config --global --add url."file://$(Build.SourcesDirectory)/.build/$repo".insteadOf "$url" + git config --file "$CONTAINER_GITCONFIG" --add url."file:///root/vscode/.build/$repo".insteadOf "$url" + done + done displayName: Redirect private git dependencies to local checkouts diff --git a/build/npm/postinstall.ts b/build/npm/postinstall.ts index 0d00ac3926141f..5df04a796373f5 100644 --- a/build/npm/postinstall.ts +++ b/build/npm/postinstall.ts @@ -79,7 +79,7 @@ async function npmInstallAsync(dir: string, opts?: child_process.SpawnOptions): 'docker', 'run', '-e', 'GITHUB_TOKEN', '-v', `${process.env['VSCODE_HOST_MOUNT']}:/root/vscode`, - '-v', `${process.env['VSCODE_HOST_MOUNT']}/.build/.netrc:/root/.netrc`, + '-v', `${process.env['VSCODE_HOST_MOUNT']}/.build/.gitconfig-distro:/root/.gitconfig`, '-v', `${process.env['VSCODE_NPMRC_PATH']}:/root/.npmrc`, '-w', path.resolve('/root/vscode', dir), process.env['VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME'], From b85f5d0ba4faccb332c66bc6a6a33eded05a76e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sun, 21 Jun 2026 07:28:26 +0200 Subject: [PATCH 14/29] build: use Electron/Node feeds job-wide and fix cmd.exe git redirect Promote VSCODE_ELECTRON_PREBUILT_FEED, VSCODE_NODEJS_INTERNAL_FEED and AZURE_DEVOPS_EXT_PAT to job-level variables so every step (including the integration/smoke test steps that download Electron) resolves binaries from our Azure Artifacts feeds instead of private GitHub releases. Also keep the cross-platform private git redirect step to plain 'git config' invocations so it works in cmd.exe on Windows agents, and move the bash-only container gitconfig generation into a Linux-only step. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../alpine/product-build-alpine.yml | 4 ++ .../darwin/product-build-darwin.yml | 6 +++ .../distro/download-distro.yml | 37 ++++++++++++++----- .../linux/product-build-linux.yml | 6 +++ .../win32/product-build-win32.yml | 6 +++ 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index 671937411f1dcd..f2d48a0d79130a 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -13,6 +13,10 @@ jobs: NPM_ARCH: ${{ parameters.VSCODE_ARCH }} VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ + # Resolve server Node.js (incl. musl) from our Azure Artifacts feed + # (instead of private GitHub releases) for every step in the job. + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out outputs: diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 9e8b77ccc470c3..bd1b01418c1d36 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -20,6 +20,12 @@ jobs: variables: VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ + # Resolve prebuilt Electron and server Node.js from our Azure Artifacts + # feeds (instead of private GitHub releases) for every step in the job, + # including the integration/smoke test steps that download Electron. + VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out outputs: diff --git a/build/azure-pipelines/distro/download-distro.yml b/build/azure-pipelines/distro/download-distro.yml index 4be08bd49ca6db..7d6319ee0be73c 100644 --- a/build/azure-pipelines/distro/download-distro.yml +++ b/build/azure-pipelines/distro/download-distro.yml @@ -48,16 +48,33 @@ steps: retryCountOnTaskFailure: 3 displayName: Checkout microsoft/vscode-regexp-languagedetection + # Redirect the private git dependencies to the local checkouts above, so no PAT + # is required to resolve them. npm resolves these over ssh while cargo resolves + # them over https, with and without a trailing `.git`, so we register every + # form. This step runs on the agent directly and must work in both bash and + # cmd.exe (Windows), so it uses plain `git config` invocations. + - script: | + git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "https://github.com/microsoft/vscode-encrypt.git" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "ssh://git@github.com/microsoft/vscode-encrypt" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-encrypt".insteadOf "ssh://git@github.com/microsoft/vscode-encrypt.git" + git config --global url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "https://github.com/microsoft/vsda.git" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "ssh://git@github.com/microsoft/vsda" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vsda".insteadOf "ssh://git@github.com/microsoft/vsda.git" + git config --global url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "https://github.com/microsoft/vscode-regexp-languagedetection" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "https://github.com/microsoft/vscode-regexp-languagedetection.git" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "ssh://git@github.com/microsoft/vscode-regexp-languagedetection" + git config --global --add url."file://$(Build.SourcesDirectory)/.build/vscode-regexp-languagedetection".insteadOf "ssh://git@github.com/microsoft/vscode-regexp-languagedetection.git" + displayName: Redirect private git dependencies to local checkouts + + # The Alpine server build installs the distro's npm dependencies inside a docker + # container that mounts the sources at /root/vscode, so the host redirects above + # (which use agent paths) do not apply there. Emit a container-pathed gitconfig + # that postinstall.ts bind-mounts as /root/.gitconfig. Only needed (and only + # bash-compatible) on Linux agents. - script: | set -e - # Redirect the private git dependencies referenced by the distro's npm and - # cargo manifests to the local checkouts above, so no PAT is required to - # resolve them. npm resolves these over ssh while cargo resolves them over - # https, with and without a trailing `.git`, so we register every form. - # We write two sets of redirects: the global config is used by builds that - # run on the agent directly (host paths), while .build/.gitconfig-distro - # uses the paths seen inside the Alpine dependency container (which mounts - # the sources at /root/vscode) and is bind-mounted as /root/.gitconfig. CONTAINER_GITCONFIG="$(Build.SourcesDirectory)/.build/.gitconfig-distro" rm -f "$CONTAINER_GITCONFIG" for repo in vscode-encrypt vsda vscode-regexp-languagedetection; do @@ -66,8 +83,8 @@ steps: "https://github.com/microsoft/$repo.git" \ "ssh://git@github.com/microsoft/$repo" \ "ssh://git@github.com/microsoft/$repo.git"; do - git config --global --add url."file://$(Build.SourcesDirectory)/.build/$repo".insteadOf "$url" git config --file "$CONTAINER_GITCONFIG" --add url."file:///root/vscode/.build/$repo".insteadOf "$url" done done - displayName: Redirect private git dependencies to local checkouts + condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) + displayName: Write container git redirects for Alpine diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index bf3d4196f0f574..fb2f37512ac2b0 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -32,6 +32,12 @@ jobs: BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ NPM_ARCH: ${{ parameters.NPM_ARCH }} VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} + # Resolve prebuilt Electron and server Node.js from our Azure Artifacts + # feeds (instead of private GitHub releases) for every step in the job, + # including the integration/smoke test steps that download Electron. + VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: sdl: binskim: diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index d5dc4e2eb2e587..fa18929efdeab9 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -22,6 +22,12 @@ jobs: variables: VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ + # Resolve prebuilt Electron and server Node.js from our Azure Artifacts + # feeds (instead of private GitHub releases) for every step in the job, + # including the integration/smoke test steps that download Electron. + VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt + VSCODE_NODEJS_INTERNAL_FEED: vscode-node + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out outputs: From 5305c3651a30fe0bdab697d51fcf395082f9cfa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sun, 21 Jun 2026 07:36:57 +0200 Subject: [PATCH 15/29] build: pin server Node.js to build 438265 to match distro checksums The distro overlays build/checksums/nodejs.txt with checksums for the original 24.15.0-438265 Node.js build (including the Alpine musl binary, whose contents differ from later rebuilds). Republish the original 438265 artifacts to the vscode-node Azure Artifacts feed and pin ms_build_id back to 438265 so feed downloads match the pinned checksums. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- remote/.npmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/remote/.npmrc b/remote/.npmrc index 0fd6a00ec089ea..6f2d4e8df7b2cf 100644 --- a/remote/.npmrc +++ b/remote/.npmrc @@ -1,6 +1,6 @@ disturl="https://nodejs.org/dist" target="24.15.0" -ms_build_id="449655" +ms_build_id="438265" runtime="node" build_from_source="true" legacy-peer-deps="true" From bcaec622ef50a8b53e18a1d9c64470080d6a8ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Sun, 21 Jun 2026 22:38:14 +0200 Subject: [PATCH 16/29] build: require ADO org/project from pipeline env vars Resolve the Azure Artifacts organization and project from the SYSTEM_COLLECTIONURI / SYSTEM_TEAMPROJECT pipeline variables (the predefined System.CollectionUri / System.TeamProject), failing fast if either is missing instead of falling back to hardcoded values. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- build/lib/azureFeed.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/build/lib/azureFeed.ts b/build/lib/azureFeed.ts index 5913ac99364fb3..0be6e7100eac53 100644 --- a/build/lib/azureFeed.ts +++ b/build/lib/azureFeed.ts @@ -11,8 +11,15 @@ import path from 'path'; // from our Azure Artifacts universal package feeds using the `az` CLI, instead // of fetching them from private GitHub releases (which would require a // long-lived Personal Access Token). -const ORGANIZATION = 'https://dev.azure.com/monacotools'; -const PROJECT = 'Monaco'; + +// Reads a required environment variable, throwing if it is not set. +function getEnv(name: string): string { + const value = process.env[name]; + if (!value) { + throw new Error(`Missing required environment variable: ${name}`); + } + return value; +} function azExecFile(args: string[]): Promise { return new Promise((resolve, reject) => { @@ -56,8 +63,8 @@ export async function downloadFeedPackage(root: string, cacheDir: string, pkg: I await ensureAzureDevOpsExtension(); await azExecFile([ 'artifacts', 'universal', 'download', - '--organization', ORGANIZATION, - '--project', PROJECT, + '--organization', getEnv('SYSTEM_COLLECTIONURI').replace(/\/+$/, ''), + '--project', getEnv('SYSTEM_TEAMPROJECT'), '--scope', 'project', '--feed', pkg.feed, '--name', pkg.name, From 73e93d4ed54e96f1baedfea419c16bb19d997a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 09:37:02 +0200 Subject: [PATCH 17/29] refactor: remove internal feed variables for Node.js and Electron from build configurations --- .../alpine/product-build-alpine.yml | 5 --- .../darwin/product-build-darwin.yml | 5 --- .../steps/product-build-darwin-compile.yml | 3 -- .../linux/product-build-linux.yml | 5 --- .../steps/product-build-linux-compile.yml | 3 -- .../win32/product-build-win32.yml | 5 --- .../azure-pipelines/win32/sdl-scan-win32.yml | 1 - .../steps/product-build-win32-compile.yml | 3 -- build/gulpfile.reh.ts | 33 +++++++++---------- build/lib/electron.ts | 16 ++++----- product.json | 3 +- 11 files changed, 25 insertions(+), 57 deletions(-) diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index f2d48a0d79130a..c753f1c0b0c153 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -13,9 +13,6 @@ jobs: NPM_ARCH: ${{ parameters.VSCODE_ARCH }} VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ - # Resolve server Node.js (incl. musl) from our Azure Artifacts feed - # (instead of private GitHub releases) for every step in the job. - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out @@ -228,7 +225,6 @@ jobs: echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-token-code-oss)" - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server @@ -245,6 +241,5 @@ jobs: echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-token-code-oss)" - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server (web) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index bd1b01418c1d36..ac16cccfc6679e 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -20,11 +20,6 @@ jobs: variables: VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ - # Resolve prebuilt Electron and server Node.js from our Azure Artifacts - # feeds (instead of private GitHub releases) for every step in the job, - # including the integration/smoke test steps that download Electron. - VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml index e0d849587fb977..685c7f37b02819 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-compile.yml @@ -165,7 +165,6 @@ steps: env: GITHUB_TOKEN: "$(github-token-code-oss)" AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt displayName: Build client - script: | @@ -174,7 +173,6 @@ steps: mv ../vscode-reh-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH) # TODO@joaomoreno env: GITHUB_TOKEN: "$(github-token-code-oss)" - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server @@ -184,7 +182,6 @@ steps: mv ../vscode-reh-web-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH)-web # TODO@joaomoreno env: GITHUB_TOKEN: "$(github-token-code-oss)" - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server (web) diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index fb2f37512ac2b0..bfa9ceebe9e806 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -32,11 +32,6 @@ jobs: BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ NPM_ARCH: ${{ parameters.NPM_ARCH }} VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} - # Resolve prebuilt Electron and server Node.js from our Azure Artifacts - # feeds (instead of private GitHub releases) for every step in the job, - # including the integration/smoke test steps that download Electron. - VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: sdl: diff --git a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml index 2176a35793c5a0..ba70fa0eba95f7 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-compile.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-compile.yml @@ -221,7 +221,6 @@ steps: env: GITHUB_TOKEN: "$(github-token-code-oss)" AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt displayName: Build client - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: @@ -265,7 +264,6 @@ steps: echo "##vso[task.setvariable variable=SERVER_UNARCHIVE_PATH]$UNARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-token-code-oss)" - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server @@ -279,7 +277,6 @@ steps: echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH" env: GITHUB_TOKEN: "$(github-token-code-oss)" - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server (web) diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index fa18929efdeab9..1a44dd3ecda9ec 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -22,11 +22,6 @@ jobs: variables: VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ - # Resolve prebuilt Electron and server Node.js from our Azure Artifacts - # feeds (instead of private GitHub releases) for every step in the job, - # including the integration/smoke test steps that download Electron. - VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out diff --git a/build/azure-pipelines/win32/sdl-scan-win32.yml b/build/azure-pipelines/win32/sdl-scan-win32.yml index 093699cc193679..65c3423d648005 100644 --- a/build/azure-pipelines/win32/sdl-scan-win32.yml +++ b/build/azure-pipelines/win32/sdl-scan-win32.yml @@ -113,7 +113,6 @@ steps: env: GITHUB_TOKEN: "$(github-token-code-oss)" AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt displayName: Download Symbols - powershell: | diff --git a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml index f6f6ae86132aa4..4b02c04c8c4d1b 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-compile.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-compile.yml @@ -170,7 +170,6 @@ steps: env: GITHUB_TOKEN: "$(github-token-code-oss)" AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) - VSCODE_ELECTRON_PREBUILT_FEED: vscode-electron-prebuilt displayName: Build client # Note: the appx prepare step has to follow Build client step since build step replaces the template @@ -202,7 +201,6 @@ steps: echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)" env: GITHUB_TOKEN: "$(github-token-code-oss)" - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server @@ -218,7 +216,6 @@ steps: echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(Agent.BuildDirectory)/vscode-server-win32-$(VSCODE_ARCH)-web" env: GITHUB_TOKEN: "$(github-token-code-oss)" - VSCODE_NODEJS_INTERNAL_FEED: vscode-node AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Build server (web) diff --git a/build/gulpfile.reh.ts b/build/gulpfile.reh.ts index 5efa7404752216..b00894781aee62 100644 --- a/build/gulpfile.reh.ts +++ b/build/gulpfile.reh.ts @@ -29,7 +29,7 @@ import * as cp from 'child_process'; import crypto from 'crypto'; import log from 'fancy-log'; import buildfile from './buildfile.ts'; -import { fetchUrls, fetchGithub } from './lib/fetch.ts'; +import { fetchUrls } from './lib/fetch.ts'; import { downloadFeedPackage } from './lib/azureFeed.ts'; import { getCopilotExcludeFilter, getCopilotRuntimePrebuildFiles, getCopilotTgrepExcludeFilter, getRipgrepExcludeFilter, prepareBuiltInCopilotRipgrepShim } from './lib/copilot.ts'; import { readAgentSdkResults } from './agent-sdk/common.ts'; @@ -211,13 +211,12 @@ function patchElfLoadAlign(): NodeJS.ReadWriteStream { const { nodeVersion, internalNodeVersion } = getNodeVersion(); // In product builds, the server (reh) Node.js binaries are fetched on demand -// from our Azure Artifacts `vscode-node` feed using the `az` CLI (gated on -// `VSCODE_NODEJS_INTERNAL_FEED`), instead of from a private GitHub release -// (which would require a long-lived Personal Access Token). Each universal -// package contains exactly one file, named after the asset minus its last -// extension, lowercased and sanitized (e.g. `node-v24.15.0-linux-x64.tar`, -// `win-x64-node`). -const nodejsInternalFeed = process.env['VSCODE_NODEJS_INTERNAL_FEED']; +// from our Azure Artifacts feed named by `product.nodejsArtifactFeed` using the +// `az` CLI, instead of from nodejs.org (which is used by OSS builds when no feed +// is configured). Each universal package contains exactly one file, named after +// the asset minus its last extension, lowercased and sanitized (e.g. +// `node-v24.15.0-linux-x64.tar`, `win-x64-node`). +const nodejsArtifactFeed = product.nodejsArtifactFeed; function internalNodeFeedPackageName(assetName: string): string { return assetName @@ -278,13 +277,13 @@ function nodejs(platform: string, arch: string): NodeJS.ReadWriteStream | undefi arch = 'x64'; } - log(`Downloading node.js ${nodeVersion} ${platform} ${arch} from ${product.nodejsRepository}...`); + log(`Downloading node.js ${nodeVersion} ${platform} ${arch} from ${nodejsArtifactFeed || 'https://nodejs.org'}...`); const glibcPrefix = process.env['VSCODE_NODE_GLIBC'] ?? ''; let expectedName: string | undefined; switch (platform) { case 'win32': - expectedName = product.nodejsRepository !== 'https://nodejs.org' ? + expectedName = nodejsArtifactFeed ? `win-${arch}-node.exe` : `win-${arch}/node.exe`; break; @@ -308,13 +307,13 @@ function nodejs(platform: string, arch: string): NodeJS.ReadWriteStream | undefi switch (platform) { case 'win32': - return (product.nodejsRepository !== 'https://nodejs.org' ? + return (nodejsArtifactFeed ? fetchNodejs(expectedName!, checksumSha256) : fetchUrls(`/dist/v${nodeVersion}/win-${arch}/node.exe`, { base: 'https://nodejs.org', checksumSha256 })) .pipe(rename('node.exe')); case 'darwin': case 'linux': { - const downloaded = (product.nodejsRepository !== 'https://nodejs.org' ? + const downloaded = (nodejsArtifactFeed ? fetchNodejs(expectedName!, checksumSha256) : fetchUrls(`/dist/v${nodeVersion}/node-v${nodeVersion}-${platform}-${arch}.tar.gz`, { base: 'https://nodejs.org', checksumSha256 }) ).pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar()))) @@ -324,7 +323,7 @@ function nodejs(platform: string, arch: string): NodeJS.ReadWriteStream | undefi return platform === 'linux' && arch === 'x64' ? downloaded.pipe(patchElfLoadAlign()) : downloaded; } case 'alpine': - return product.nodejsRepository !== 'https://nodejs.org' ? + return nodejsArtifactFeed ? fetchNodejs(expectedName!, checksumSha256) .pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar()))) .pipe(filter('**/node')) @@ -334,13 +333,11 @@ function nodejs(platform: string, arch: string): NodeJS.ReadWriteStream | undefi } } -// Fetches a server (reh) Node.js asset either from the internal Azure Artifacts -// feed (product builds) or directly from the private GitHub release. +// Fetches a server (reh) Node.js asset from the Azure Artifacts feed named by +// `product.nodejsArtifactFeed`. Only called when that feed is configured. function fetchNodejs(assetName: string, checksumSha256: string | undefined): NodeJS.ReadWriteStream { const version = `${nodeVersion}-${internalNodeVersion}`; - return nodejsInternalFeed ? - fetchNodejsFromInternalFeed(nodejsInternalFeed, assetName, version, checksumSha256) : - fetchGithub(product.nodejsRepository, { version, name: assetName, checksumSha256 }) as NodeJS.ReadWriteStream; + return fetchNodejsFromInternalFeed(nodejsArtifactFeed, assetName, version, checksumSha256); } function packageTask(type: string, platform: string, arch: string, sourceFolderName: string, destinationFolderName: string) { diff --git a/build/lib/electron.ts b/build/lib/electron.ts index 9a2db04deb8fac..e229b875f552c7 100644 --- a/build/lib/electron.ts +++ b/build/lib/electron.ts @@ -106,12 +106,13 @@ const { msBuildId } = util.getElectronVersion(); export const electronVersion = '42.2.0'; // In product builds, `@vscode/gulp-electron` is given an asset resolver (via the -// `repo` option) that fetches the prebuilt Electron archives on demand from our -// Azure Artifacts feed using the `az` CLI, instead of downloading them from a -// private GitHub release (which would require a long-lived Personal Access -// Token). Each universal package contains exactly one file, which is streamed -// back as a `Response` and validated against the feed's `SHASUMS256.txt`. -const electronFeed = process.env['VSCODE_ELECTRON_PREBUILT_FEED']; +// `repo` option) that fetches the prebuilt Electron archives on demand from the +// Azure Artifacts feed named by `product.electronArtifactFeed` using the `az` +// CLI, instead of downloading them from electron's official GitHub releases +// (which OSS builds use when no feed is configured). Each universal package +// contains exactly one file, which is streamed back as a `Response` and +// validated against the feed's `SHASUMS256.txt`. +const electronFeed: string | undefined = product.electronArtifactFeed; // Maps the artifact file name `@vscode/gulp-electron` requests to the matching // universal package name in the feed, or `undefined` when it is not mirrored. @@ -141,7 +142,6 @@ const electronAssetResolver = electronFeed export const config = { version: electronVersion, - tag: product.electronRepository ? `v${electronVersion}-${msBuildId}` : undefined, productAppName: product.nameLong, companyName: 'Microsoft Corporation', copyright: 'Copyright (C) 2026 Microsoft. All rights reserved', @@ -239,7 +239,7 @@ export const config = { linuxExecutableName: product.applicationName, winIcon: 'resources/win32/code.ico', token: process.env['GITHUB_TOKEN'], - repo: electronAssetResolver ?? (product.electronRepository || undefined), + repo: electronAssetResolver, validateChecksum: true, checksumFile: path.join(root, 'build', 'checksums', 'electron.txt'), createVersionedResources: useVersionedUpdate, diff --git a/product.json b/product.json index 06ab8fcda8e8bc..9b7a7947ee3036 100644 --- a/product.json +++ b/product.json @@ -31,7 +31,8 @@ "linuxIconName": "code-oss", "licenseFileName": "LICENSE.txt", "reportIssueUrl": "https://github.com/microsoft/vscode/issues/new", - "nodejsRepository": "https://nodejs.org", + "nodejsArtifactFeed": "", + "electronArtifactFeed": "", "urlProtocol": "code-oss", "agentsTelemetryAppName": "agents", "webviewContentExternalBaseUrlTemplate": "https://{{uuid}}.vscode-cdn.net/insider/ef65ac1ba57f57f2a3961bfe94aa20481caca4c6/out/vs/workbench/contrib/webview/browser/pre/", From 6d771566ff9676f7613c886476e579d2eb94b360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 09:40:02 +0200 Subject: [PATCH 18/29] build: scope AZURE_DEVOPS_EXT_PAT to individual steps Move the System.AccessToken propagation out of the job-level variables in the alpine/darwin/linux/win32 product-build jobs and onto only the steps that actually download Electron or Node.js from the Azure Artifacts feeds. Adds it to the test 'Download Electron and Playwright' step (the sole feed download outside the compile templates); every other download step already declared it at step scope. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- build/azure-pipelines/alpine/product-build-alpine.yml | 1 - build/azure-pipelines/darwin/product-build-darwin.yml | 1 - build/azure-pipelines/darwin/steps/product-build-darwin-test.yml | 1 + build/azure-pipelines/linux/product-build-linux.yml | 1 - build/azure-pipelines/linux/steps/product-build-linux-test.yml | 1 + build/azure-pipelines/win32/product-build-win32.yml | 1 - build/azure-pipelines/win32/steps/product-build-win32-test.yml | 1 + 7 files changed, 3 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/alpine/product-build-alpine.yml b/build/azure-pipelines/alpine/product-build-alpine.yml index c753f1c0b0c153..8151a3397af5a8 100644 --- a/build/azure-pipelines/alpine/product-build-alpine.yml +++ b/build/azure-pipelines/alpine/product-build-alpine.yml @@ -13,7 +13,6 @@ jobs: NPM_ARCH: ${{ parameters.VSCODE_ARCH }} VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out outputs: diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index ac16cccfc6679e..9e8b77ccc470c3 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -20,7 +20,6 @@ jobs: variables: VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out outputs: diff --git a/build/azure-pipelines/darwin/steps/product-build-darwin-test.yml b/build/azure-pipelines/darwin/steps/product-build-darwin-test.yml index a7572e918beca5..e790f126a77294 100644 --- a/build/azure-pipelines/darwin/steps/product-build-darwin-test.yml +++ b/build/azure-pipelines/darwin/steps/product-build-darwin-test.yml @@ -10,6 +10,7 @@ steps: - script: npm exec -- npm-run-all2 -lp "electron $(VSCODE_ARCH)" "playwright-install" env: GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index bfa9ceebe9e806..bf3d4196f0f574 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -32,7 +32,6 @@ jobs: BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ NPM_ARCH: ${{ parameters.NPM_ARCH }} VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: sdl: binskim: diff --git a/build/azure-pipelines/linux/steps/product-build-linux-test.yml b/build/azure-pipelines/linux/steps/product-build-linux-test.yml index 7ce9791be40eef..2dfd2a85d5adb8 100644 --- a/build/azure-pipelines/linux/steps/product-build-linux-test.yml +++ b/build/azure-pipelines/linux/steps/product-build-linux-test.yml @@ -10,6 +10,7 @@ steps: - script: npm exec -- npm-run-all2 -lp "electron $(VSCODE_ARCH)" "playwright-install" env: GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 1a44dd3ecda9ec..d5dc4e2eb2e587 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -22,7 +22,6 @@ jobs: variables: VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} BUILDS_API_URL: $(System.CollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/ - AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) templateContext: outputParentDirectory: $(Build.ArtifactStagingDirectory)/out outputs: diff --git a/build/azure-pipelines/win32/steps/product-build-win32-test.yml b/build/azure-pipelines/win32/steps/product-build-win32-test.yml index 5b5e3e1d6df6dc..128ff569ca03ee 100644 --- a/build/azure-pipelines/win32/steps/product-build-win32-test.yml +++ b/build/azure-pipelines/win32/steps/product-build-win32-test.yml @@ -12,6 +12,7 @@ steps: - powershell: npm exec -- npm-run-all2 -lp "electron $(VSCODE_ARCH)" "playwright-install" env: GITHUB_TOKEN: "$(github-token-code-oss)" + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) displayName: Download Electron and Playwright retryCountOnTaskFailure: 3 From 6750a264dfef2e5f6c15b37599c023ccac5591d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 10:07:21 +0200 Subject: [PATCH 19/29] :lipsitck: --- build/lib/azureFeed.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/build/lib/azureFeed.ts b/build/lib/azureFeed.ts index 0be6e7100eac53..f32fb21885daa0 100644 --- a/build/lib/azureFeed.ts +++ b/build/lib/azureFeed.ts @@ -7,12 +7,6 @@ import cp from 'child_process'; import fs from 'fs'; import path from 'path'; -// Shared helpers for downloading prebuilt binaries (Electron, Node.js) on demand -// from our Azure Artifacts universal package feeds using the `az` CLI, instead -// of fetching them from private GitHub releases (which would require a -// long-lived Personal Access Token). - -// Reads a required environment variable, throwing if it is not set. function getEnv(name: string): string { const value = process.env[name]; if (!value) { From e4f282eb1d67a99b6d7a62ab92de7e784308cf05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 10:10:55 +0200 Subject: [PATCH 20/29] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 424eaa117dfc75..6afe1ed62bc91a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.126.0", - "distro": "e6b302180cc8fecde16d482d0f2add78b067b6bf", + "distro": "570b3a1548ab2d28d0399d3a3c5bf4726ec8c5e7", "author": { "name": "Microsoft Corporation" }, @@ -285,4 +285,4 @@ "optionalDependencies": { "windows-foreground-love": "0.6.1" } -} +} \ No newline at end of file From 6304b447af86b23131649fabebc3ccf15f9909d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 13:19:03 +0200 Subject: [PATCH 21/29] build: declare vscode-capi for SDL scan in copilot recovery pipeline The Copilot build steps now check out microsoft/vscode-capi via the Monaco GitHub App (instead of a PAT). The product-copilot-recovery pipeline extends the 1ES extension template, which requires every checked-out repository to be declared under sdl.sourceRepositoriesToScan. Re-declare the template's default excludes plus capi to fix 'repository "capi" ... has not been specified'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- build/azure-pipelines/product-copilot-recovery.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/build/azure-pipelines/product-copilot-recovery.yml b/build/azure-pipelines/product-copilot-recovery.yml index 59ee945baa0395..a2cb7d9d512d83 100644 --- a/build/azure-pipelines/product-copilot-recovery.yml +++ b/build/azure-pipelines/product-copilot-recovery.yml @@ -83,6 +83,17 @@ extends: serviceTreeID: '1788a767-5861-45fb-973b-c686b67c5541' enabled: true + # The Copilot build steps check out microsoft/vscode-capi (via the Monaco + # GitHub App instead of a PAT). Every checked-out repository must be declared + # for the 1ES SDL source analysis, so re-declare the template defaults plus + # capi here. + sourceRepositoriesToScan: + exclude: + - repository: translations + - repository: vscode-copilot-cache + - repository: templates + - repository: capi + ${{ if eq(parameters.customNPMRegistry, false) }}: customNPMRegistry: '' From 7c114f7a9d372a734a095443e5651ee930026fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 13:28:30 +0200 Subject: [PATCH 22/29] refactor: add assertDistroCheckout function to validate vscode-distro checkout --- .../common/checkDistroCommit.ts | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/build/azure-pipelines/common/checkDistroCommit.ts b/build/azure-pipelines/common/checkDistroCommit.ts index 887d073e9edee3..f6bf4657b14721 100644 --- a/build/azure-pipelines/common/checkDistroCommit.ts +++ b/build/azure-pipelines/common/checkDistroCommit.ts @@ -9,6 +9,12 @@ import { execSync } from 'child_process'; const root = path.dirname(path.dirname(path.dirname(import.meta.dirname))); +// The microsoft/vscode-distro repository is checked out locally by +// download-distro.yml (into .build/distro) using the agent's GitHub App +// (Monaco) credentials, so we can resolve branch heads without a token that +// has private repository access. +const distroPath = path.join(root, '.build', 'distro'); + function getEnv(name: string): string { const result = process.env[name]; @@ -19,12 +25,13 @@ function getEnv(name: string): string { return result; } +function assertDistroCheckout(): void { + if (!fs.existsSync(path.join(distroPath, '.git'))) { + throw new Error(`Expected a vscode-distro checkout at ${distroPath} but found none. Ensure download-distro.yml ran before this check.`); + } +} + function getDistroBranchHead(branch: string): string { - // The microsoft/vscode-distro repository is checked out locally by - // download-distro.yml (into .build/distro) using the agent's GitHub App - // (Monaco) credentials. Resolve the branch head from that checkout so we - // don't need a token with private repository access. - const distroPath = path.join(root, '.build', 'distro'); return execSync(`git -C "${distroPath}" rev-parse "refs/remotes/origin/${branch}"`, { encoding: 'utf8' }).trim(); } @@ -54,6 +61,11 @@ async function checkDistroCommit(): Promise { const branch = branchMatch[1]; console.log(`Current branch: ${branch}`); + // Make sure the distro repository is actually checked out before we try to + // resolve a branch head from it; otherwise a missing checkout would be + // indistinguishable from a branch that simply doesn't exist in distro. + assertDistroCheckout(); + // Resolve the HEAD of the matching branch from the local distro checkout let distroBranchHead: string; try { From bcc9e340891466d97f9f45ea1ed12db5eebf267c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 13:32:03 +0200 Subject: [PATCH 23/29] build: fix NPM registry corruption in copilot recovery pipeline setup-npm-registry.ts silently substituted the literal string "undefined" into package-lock.json resolved URLs when invoked without a registry URL, producing build/undefined/... paths that npm ci could not resolve. - Fail fast in setup-npm-registry.ts when no registry URL is provided. - Set NPM_REGISTRY=none in product-copilot-recovery.yml so the shared copilot/setup-steps.yml skips its registry rewrite; the 1ES extension template already configures the registry via customNPMRegistry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- build/azure-pipelines/product-copilot-recovery.yml | 6 ++++++ build/setup-npm-registry.ts | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/build/azure-pipelines/product-copilot-recovery.yml b/build/azure-pipelines/product-copilot-recovery.yml index a2cb7d9d512d83..1e8b5c9cad8db3 100644 --- a/build/azure-pipelines/product-copilot-recovery.yml +++ b/build/azure-pipelines/product-copilot-recovery.yml @@ -29,6 +29,12 @@ parameters: variables: - name: VSCODE_QUALITY value: stable + # The 1ES extension template configures the NPM registry itself (via the + # customNPMRegistry / Terrapin parameter below). Set NPM_REGISTRY to 'none' + # so the shared copilot/setup-steps.yml skips its own registry rewrite, which + # would otherwise corrupt package-lock.json resolved URLs when unset. + - name: NPM_REGISTRY + value: none extends: template: azure-pipelines/extension/stable.yml@templates diff --git a/build/setup-npm-registry.ts b/build/setup-npm-registry.ts index 670c3e339db0f8..4560f2c0007286 100644 --- a/build/setup-npm-registry.ts +++ b/build/setup-npm-registry.ts @@ -37,6 +37,10 @@ async function setup(url: string, file: string): Promise { * Main function to set up custom NPM registry */ async function main(url: string, dir?: string): Promise { + if (!url) { + throw new Error('Usage: node setup-npm-registry.ts [dir]. A registry URL is required.'); + } + const root = dir ?? process.cwd(); for await (const file of getPackageLockFiles(root)) { @@ -45,4 +49,7 @@ async function main(url: string, dir?: string): Promise { } } -main(process.argv[2], process.argv[3]); +main(process.argv[2], process.argv[3]).catch(err => { + console.error(err.message); + process.exit(1); +}); From 5a9053d675431c056ebbd66dc14127c79364ff35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 13:55:05 +0200 Subject: [PATCH 24/29] build: fix self checkout and l10n in copilot recovery pipeline The 1ES extension template's package job runs import-localized-files before buildSteps, relying on an implicit self checkout. That implicit checkout is disabled because copilot/build-steps.yml checks out microsoft/vscode-capi, so the source tree was missing and the l10n-detection step failed with 'Not found workingDirectory: .../extensions/copilot'. Mirror product-copilot.yml: check out self at the start of buildSteps, import translations via copilot/l10n-steps.yml (with the vscode_loc resource), and disable the template's own l10n jobs/import (l10nShouldProcess: false). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../product-copilot-recovery.yml | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/product-copilot-recovery.yml b/build/azure-pipelines/product-copilot-recovery.yml index 1e8b5c9cad8db3..deafda2d3814f9 100644 --- a/build/azure-pipelines/product-copilot-recovery.yml +++ b/build/azure-pipelines/product-copilot-recovery.yml @@ -15,6 +15,11 @@ resources: name: microsoft/vscode-capi ref: main endpoint: Monaco + - repository: vscode_loc + type: github + name: microsoft/vscode-extensions-loc + ref: main + endpoint: Monaco parameters: - name: customNPMRegistry @@ -42,6 +47,13 @@ extends: workingDirectory: ./extensions/copilot l10nSourcePaths: ./extensions/copilot/src nodeVersion: 22.21.x + # Copilot handles localization itself via copilot/l10n-steps.yml (importing + # translated strings from the microsoft/vscode-extensions-loc checkout), + # mirroring product-copilot.yml. Disable the template's own l10n jobs and + # the import-localized-files step: the latter runs before buildSteps and + # expects an implicit self checkout, which is unavailable here because + # build-steps.yml checks out microsoft/vscode-capi. + l10nShouldProcess: false cgIgnoreDirectories: $(Build.SourcesDirectory)/extensions/copilot/script @@ -57,8 +69,17 @@ extends: exit 1 displayName: Validate release branch + - checkout: self + path: s + lfs: true + fetchDepth: 1 + fetchTags: false + retryCountOnTaskFailure: 3 + displayName: Checkout microsoft/vscode + - template: copilot/setup-steps.yml - template: copilot/build-steps.yml + - template: copilot/l10n-steps.yml - script: | set -e @@ -89,16 +110,17 @@ extends: serviceTreeID: '1788a767-5861-45fb-973b-c686b67c5541' enabled: true - # The Copilot build steps check out microsoft/vscode-capi (via the Monaco - # GitHub App instead of a PAT). Every checked-out repository must be declared - # for the 1ES SDL source analysis, so re-declare the template defaults plus - # capi here. + # The Copilot build steps check out microsoft/vscode-capi and + # microsoft/vscode-extensions-loc (via the Monaco GitHub App instead of a + # PAT). Every checked-out repository must be declared for the 1ES SDL source + # analysis, so re-declare the template defaults plus capi and vscode_loc here. sourceRepositoriesToScan: exclude: - repository: translations - repository: vscode-copilot-cache - repository: templates - repository: capi + - repository: vscode_loc ${{ if eq(parameters.customNPMRegistry, false) }}: customNPMRegistry: '' From 77e2076f5a3fd46e672c6f62443a8603bb5742e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 14:05:29 +0200 Subject: [PATCH 25/29] build: exclude vscode build-tooling natives from copilot recovery GLIBC check The 1ES extension template's GLIBC/GLIBCXX check scans every .node under the sources root, but only extensions/copilot is packaged into the VSIX. Native modules outside it (e.g. build/node_modules/tree-sitter) belong to the vscode build tooling and are never shipped, yet their newer GLIBC/GLIBCXX deps fail the check. Remove them before the check so it only validates the copilot extension's own shipped natives, alongside the existing pvrecorder removal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../product-copilot-recovery.yml | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/build/azure-pipelines/product-copilot-recovery.yml b/build/azure-pipelines/product-copilot-recovery.yml index deafda2d3814f9..1f4d55bafc025f 100644 --- a/build/azure-pipelines/product-copilot-recovery.yml +++ b/build/azure-pipelines/product-copilot-recovery.yml @@ -84,15 +84,25 @@ extends: set -e # The GLIBC check (from the shared extension template) scans every .node - # under $PWD. @github/copilot vendors @picovoice/pvrecorder-node, whose - # linux/x86_64 prebuild depends on GLIBC > 2.28. The native is not - # shipped in the VSIX, so just remove the pvrecorder prebuilds before - # the check runs. + # under the sources root, but only extensions/copilot is packaged into + # the VSIX. Native modules outside it belong to the vscode build tooling + # (e.g. build/node_modules/tree-sitter) and are never shipped, yet their + # newer GLIBC/GLIBCXX dependencies fail the check. Remove them so the + # check only validates the copilot extension's own shipped natives. + find "$(Build.SourcesDirectory)" \ + -type f -name '*.node' \ + -not -path "$(Build.SourcesDirectory)/extensions/copilot/*" \ + -print -delete + + # @github/copilot (inside extensions/copilot) vendors + # @picovoice/pvrecorder-node, whose linux/x86_64 prebuild depends on + # GLIBC > 2.28. The native is not shipped in the VSIX, so remove the + # pvrecorder prebuilds before the check runs. find "$(Build.SourcesDirectory)" \ -type d -name pvrecorder-node \ -path "*@picovoice/pvrecorder-node" \ -print -exec rm -rf {} + - displayName: Remove pvrecorder native binaries before GLIBC check + displayName: Remove build-only native binaries before GLIBC check uploadSourceMaps: enabled: true From 8cd1703ddb7beaaf6d5400fb53033145195c3027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 14:17:25 +0200 Subject: [PATCH 26/29] build: disable sysroot GLIBC check in copilot recovery pipeline The copilot extension is bundled with esbuild and vendors prebuilt native modules (@os-theme, @picovoice/pvrecorder-node) that depend on a newer GLIBC than the 1ES template's sysroot check allows. The main product build ships these natives without a sysroot or GLIBC check, so set useSysroot: false on the recovery pipeline's Linux platform for parity, which skips the toolchain setup and the GLIBC/GLIBCXX verification. Drop the now-unnecessary native-removal workaround. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../product-copilot-recovery.yml | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/build/azure-pipelines/product-copilot-recovery.yml b/build/azure-pipelines/product-copilot-recovery.yml index 1f4d55bafc025f..6f7888e934c212 100644 --- a/build/azure-pipelines/product-copilot-recovery.yml +++ b/build/azure-pipelines/product-copilot-recovery.yml @@ -47,6 +47,17 @@ extends: workingDirectory: ./extensions/copilot l10nSourcePaths: ./extensions/copilot/src nodeVersion: 22.21.x + # The copilot extension is bundled with esbuild and vendors prebuilt native + # modules (e.g. @os-theme, @picovoice/pvrecorder-node) that depend on a + # newer GLIBC than the template's sysroot check allows. The main product + # build (product-copilot.yml) ships these natives without a sysroot or GLIBC + # check, so disable the sysroot here for parity; this also skips the GLIBC/ + # GLIBCXX verification that would otherwise fail on those vendored natives. + buildPlatforms: + - name: Linux + vsceTarget: "" + useSysroot: false + codesignPaths: [] # Copilot handles localization itself via copilot/l10n-steps.yml (importing # translated strings from the microsoft/vscode-extensions-loc checkout), # mirroring product-copilot.yml. Disable the template's own l10n jobs and @@ -80,29 +91,6 @@ extends: - template: copilot/setup-steps.yml - template: copilot/build-steps.yml - template: copilot/l10n-steps.yml - - script: | - set -e - - # The GLIBC check (from the shared extension template) scans every .node - # under the sources root, but only extensions/copilot is packaged into - # the VSIX. Native modules outside it belong to the vscode build tooling - # (e.g. build/node_modules/tree-sitter) and are never shipped, yet their - # newer GLIBC/GLIBCXX dependencies fail the check. Remove them so the - # check only validates the copilot extension's own shipped natives. - find "$(Build.SourcesDirectory)" \ - -type f -name '*.node' \ - -not -path "$(Build.SourcesDirectory)/extensions/copilot/*" \ - -print -delete - - # @github/copilot (inside extensions/copilot) vendors - # @picovoice/pvrecorder-node, whose linux/x86_64 prebuild depends on - # GLIBC > 2.28. The native is not shipped in the VSIX, so remove the - # pvrecorder prebuilds before the check runs. - find "$(Build.SourcesDirectory)" \ - -type d -name pvrecorder-node \ - -path "*@picovoice/pvrecorder-node" \ - -print -exec rm -rf {} + - displayName: Remove build-only native binaries before GLIBC check uploadSourceMaps: enabled: true From 09192b9ce745d1671eb1fb9e8cfe99a3e1025e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 16:01:55 +0200 Subject: [PATCH 27/29] fix: update distro version in package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 391695d89c2538..02b29ebb079153 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.127.0", - "distro": "570b3a1548ab2d28d0399d3a3c5bf4726ec8c5e7", + "distro": "0d726028b9bf2f38975a035474182955e771bccd", "author": { "name": "Microsoft Corporation" }, @@ -285,4 +285,4 @@ "optionalDependencies": { "windows-foreground-love": "0.6.1" } -} +} \ No newline at end of file From 7c767dc723a9a8ddb9de47d7e5794011f3816ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 17:10:17 +0200 Subject: [PATCH 28/29] bump cache salt --- build/.cachesalt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/.cachesalt b/build/.cachesalt index df1d8c82aab641..d382d477ac6c74 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2026-06-19T12:30:00.000Z +2026-06-22T15:10:10.546Z From b929b04649cf75f49e06145ef82379f4bf0aa9d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 22 Jun 2026 20:05:36 +0200 Subject: [PATCH 29/29] missing libc field from optional dependencies --- package-lock.json | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 724df4b5bd83bd..450186b2b58199 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1146,9 +1146,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -1165,9 +1162,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -1184,9 +1178,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -1203,9 +1194,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [