Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
bf63569
Pin Corepack explicitly for the VS Code extension build
adamint May 28, 2026
aae3dd5
Address code review for Corepack pin
adamint May 28, 2026
bfe70a5
Drop unnecessary --registry override on corepack install
adamint May 28, 2026
7b49877
Fix Corepack registry handling
adamint May 28, 2026
ff7454b
Avoid Corepack registry override for Azure Artifacts
adamint May 28, 2026
f544e0b
Force Corepack shim install in CI
adamint May 28, 2026
0959adb
Prepend npm Corepack shim path in CI
adamint May 28, 2026
f8ea0a5
Seed Corepack Yarn cache via npm pack
adamint May 29, 2026
98078ee
Invoke npm CLI directly for Corepack Yarn seed
adamint May 29, 2026
1a26f40
Handle duplicate equivalent ATS capabilities
adamint May 29, 2026
d1c3252
Merge remote-tracking branch 'microsoft/main' into dev/adamint/extens…
adamint May 29, 2026
328aa22
Align duplicate ATS compatibility fix
adamint May 29, 2026
bc819bc
Remove duplicate ATS compatibility fix
adamint May 29, 2026
21d7304
Merge remote-tracking branch 'microsoft/main' into dev/adamint/extens…
adamint May 29, 2026
c15ab5a
Export NPM_REGISTRY in build.sh and document Corepack cache-path coup…
adamint May 29, 2026
994f7b2
Address PR review feedback for Corepack bootstrap
adamint May 29, 2026
fdcb5f5
Set COREPACK_HOME via $GITHUB_ENV instead of job env
adamint May 29, 2026
1c9eeee
Merge remote-tracking branch 'microsoft/main' into dev/adamint/extens…
adamint May 30, 2026
93ac6f2
Address PR #17630 round-3 review feedback
adamint May 30, 2026
0e2136e
Address PR #17630 Mitch review feedback
adamint May 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions eng/pipelines/azure-pipelines-codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,20 @@ jobs:
version: '20.x'

- task: PowerShell@2
displayName: Install yarn
displayName: Install Corepack
inputs:
targetType: 'inline'
script: |
npm install -g yarn@1.22.22
yarn --version
workingDirectory: '$(Build.SourcesDirectory)'
# Install the pinned Corepack shim. Keep this version in sync with
# COREPACK_VERSION in extension/build.sh and $CorepackVersion in
# extension/build.ps1. The Yarn release itself is pinned in
# extension/package.json via the `packageManager` field, which
# `corepack prepare --activate` reads from the current working directory.
npm install -g corepack@0.34.7
corepack enable
corepack prepare --activate
corepack yarn --version
workingDirectory: '$(Build.SourcesDirectory)/extension'

- task: PowerShell@2
displayName: Install vsce
Expand Down
16 changes: 12 additions & 4 deletions eng/pipelines/azure-pipelines-unofficial.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,21 @@ extends:
script: Write-Host "##vso[task.setvariable variable=NPM_CONFIG_USERCONFIG]$(Build.SourcesDirectory)\.npmrc"

- task: PowerShell@2
displayName: 🟣Install yarn
displayName: 🟣Install Corepack
inputs:
targetType: 'inline'
script: |
npm install -g yarn@1.22.22
yarn --version
workingDirectory: '$(Build.SourcesDirectory)'
# Install the pinned Corepack shim. Keep this version in
# sync with COREPACK_VERSION in extension/build.sh and
# $CorepackVersion in extension/build.ps1. The Yarn release
# itself is pinned in extension/package.json via the
# `packageManager` field, which `corepack prepare --activate`
# reads from the current working directory.
npm install -g corepack@0.34.7
corepack enable
corepack prepare --activate
corepack yarn --version
workingDirectory: '$(Build.SourcesDirectory)\extension'

- task: PowerShell@2
displayName: 🟣Install vsce
Expand Down
16 changes: 12 additions & 4 deletions eng/pipelines/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,21 @@ extends:
script: Write-Host "##vso[task.setvariable variable=NPM_CONFIG_USERCONFIG]$(Build.SourcesDirectory)\.npmrc"

- task: PowerShell@2
displayName: 🟣Install yarn
displayName: 🟣Install Corepack
inputs:
targetType: 'inline'
script: |
npm install -g yarn@1.22.22
yarn --version
workingDirectory: '$(Build.SourcesDirectory)'
# Install the pinned Corepack shim. Keep this version in
# sync with COREPACK_VERSION in extension/build.sh and
# $CorepackVersion in extension/build.ps1. The Yarn release
# itself is pinned in extension/package.json via the
# `packageManager` field, which `corepack prepare --activate`
# reads from the current working directory.
npm install -g corepack@0.34.7
corepack enable
corepack prepare --activate
corepack yarn --version
Comment thread
adamint marked this conversation as resolved.
Resolved
workingDirectory: '$(Build.SourcesDirectory)\extension'

- task: PowerShell@2
displayName: 🟣Install vsce
Expand Down
13 changes: 13 additions & 0 deletions eng/pipelines/common-variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ variables:
- name: _InternalBuildArgs
value: ''

# Corepack provisions the Yarn release pinned in extension/package.json's
# `packageManager` field. Corepack does NOT read .npmrc, so we point it at the
# dnceng `dotnet-public-npm` mirror via its own env var. Without this, Corepack
# would attempt to download the Yarn tarball from https://registry.npmjs.org,
# which is blocked from Helix and most internal agents.
# See https://github.com/nodejs/corepack#environment-variables.
- name: COREPACK_NPM_REGISTRY
value: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/
# Disable the interactive "Do you want to download yarn@x.y.z?" prompt so
# pipeline steps don't hang waiting for stdin.
- name: COREPACK_ENABLE_DOWNLOAD_PROMPT
value: '0'

- ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
- name: _RunAsPublic
value: False
Expand Down
13 changes: 13 additions & 0 deletions eng/pipelines/templates/public-pipeline-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ variables:
- name: _InternalBuildArgs
value: ''

# Corepack provisions the Yarn release pinned in extension/package.json's
# `packageManager` field. Corepack does NOT read .npmrc, so we point it at the
# dnceng `dotnet-public-npm` mirror via its own env var. Without this, Corepack
# would attempt to download the Yarn tarball from https://registry.npmjs.org,
# which is blocked from most internal agents.
# See https://github.com/nodejs/corepack#environment-variables.
- name: COREPACK_NPM_REGISTRY
value: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/
# Disable the interactive "Do you want to download yarn@x.y.z?" prompt so
# pipeline steps don't hang waiting for stdin.
- name: COREPACK_ENABLE_DOWNLOAD_PROMPT
value: '0'

# Set test variants based on parameter or build reason
- ${{ if ne(parameters.testVariants, '') }}:
- name: testVariants
Expand Down
17 changes: 12 additions & 5 deletions extension/CONTRIBUTING.MD
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

## Install Prerequisites

- Node.js (LTS version)
- Yarn accessible in the PATH
- Node.js (LTS version) — `npm` must be on the PATH (it ships with Node.js). The
build scripts (`build.sh` / `build.ps1`) install a pinned [Corepack](https://github.com/nodejs/corepack)
via `npm install -g corepack@<version>` and use it to provision the Yarn release
pinned by the `packageManager` field in `extension/package.json`. You do **not**
need to install Yarn yourself.
- Visual Studio Code (latest) or Visual Studio Code Insiders
- [Aspire CLI](https://aspire.dev/get-started/install-cli/) must be installed and available in the PATH

Expand All @@ -26,12 +29,16 @@ You can use the `Aspire: Extension settings` command to open VS Code settings di

## Updating dependency overrides

The extension is built with **yarn**, so `package.json` uses `resolutions` for transitive dependency pins and `yarn.lock` is the authoritative lockfile.
The extension is built with **yarn**, pinned to the version recorded in `packageManager` of `package.json` (Corepack reads this). `package.json` uses `resolutions` for transitive dependency pins and `yarn.lock` is the authoritative lockfile.

When pinning a transitive dependency (e.g. to address a security advisory), add the pin to `resolutions` and regenerate `yarn.lock` in the same change:

```bash
yarn install
corepack yarn install
```

The build rejects public npm registry URLs in `yarn.lock`; ensure regenerated entries resolve through the internal `dotnet-public-npm` feed.
The build rejects public npm registry URLs in `yarn.lock`; ensure regenerated entries resolve through the internal `dotnet-public-npm` feed.

## Updating the Yarn version

Edit the `"packageManager": "yarn@x.y.z"` field in `extension/package.json`. Corepack picks the new version up automatically the next time `build.sh` / `build.ps1` runs (`corepack prepare --activate` reads `packageManager`). No further changes required in `build.sh`, `build.ps1`, or `extension/Extension.proj` — they all call `corepack yarn …` without an explicit version.
15 changes: 9 additions & 6 deletions extension/Extension.proj
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
<!-- Override package.json version if ExtensionVersionOverride is set, saving original first -->
<Copy SourceFiles="$(_PackageJsonPath)" DestinationFiles="$(_PackageJsonPath).bak"
Condition="'$(ExtensionVersionOverride)' != ''" />
<Exec Command="corepack yarn@1.22.22 version --new-version &quot;$(ExtensionVersionOverride)&quot; --no-git-tag-version"
<Exec Command="corepack yarn version --new-version &quot;$(ExtensionVersionOverride)&quot; --no-git-tag-version"
Condition="'$(ExtensionVersionOverride)' != ''"
WorkingDirectory="$(ExtensionSrcDir)" />

<!-- Install dependencies and compile -->
<Exec Command="corepack yarn@1.22.22 install --frozen-lockfile --non-interactive" WorkingDirectory="$(ExtensionSrcDir)" IgnoreStandardErrorWarningFormat="true" />
<Exec Command="corepack yarn@1.22.22 compile" WorkingDirectory="$(ExtensionSrcDir)" IgnoreStandardErrorWarningFormat="true" />
<Exec Command="corepack yarn install --frozen-lockfile --non-interactive" WorkingDirectory="$(ExtensionSrcDir)" IgnoreStandardErrorWarningFormat="true" />
<Exec Command="corepack yarn compile" WorkingDirectory="$(ExtensionSrcDir)" IgnoreStandardErrorWarningFormat="true" />

<!-- Make extension directory -->
<MakeDir Directories="$(_VscodeOutputDir)" />
Expand Down Expand Up @@ -87,13 +87,16 @@
Condition="'@(_PublicNpmRegistryLine)' != ''" />
</Target>

<Target Name="CheckYarnInstalled">
<Exec Command="corepack yarn@1.22.22 --version" ContinueOnError="true" ConsoleToMSBuild="true" IgnoreStandardErrorWarningFormat="true">
<Target Name="CheckYarnInstalled" DependsOnTargets="ValidateYarnLockRegistries">
<!-- Resolves the Yarn release pinned in extension/package.json (the
packageManager field), via Corepack. WorkingDirectory must be the
extension directory or Corepack will fall back to its default. -->
<Exec Command="corepack yarn --version" ContinueOnError="true" ConsoleToMSBuild="true" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(ExtensionSrcDir)">
<Output TaskParameter="ExitCode" PropertyName="YarnExitCode" />
<Output TaskParameter="ConsoleOutput" PropertyName="YarnVersion" />
</Exec>

<Error Condition="'$(YarnExitCode)' != '0'" Text="Corepack is not installed or cannot run Yarn Classic. To build the extension, install a Node.js version that includes Corepack." />
<Error Condition="'$(YarnExitCode)' != '0'" Text="Corepack is not installed or cannot run the Yarn version pinned in extension/package.json. To build the extension, run extension/build.sh or extension/build.ps1 first, which installs a pinned Corepack via npm." />
Comment thread
adamint marked this conversation as resolved.
Resolved

<Message Importance="high" Text="yarn version: $(YarnVersion)" />
</Target>
Expand Down
70 changes: 64 additions & 6 deletions extension/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

$ErrorActionPreference = "Stop"

# Pinned Corepack shim version. Node.js >= 16.10 bundles a Corepack, but the
# bundled version drifts with each Node release and Corepack is on track to be
# unbundled from Node entirely (see https://github.com/nodejs/node/issues/54647).
# Installing a pinned Corepack from npm makes the build reproducible regardless
# of which Node version a developer or CI runner happens to have.
$CorepackVersion = "0.34.7"

# Yarn version is pinned in extension/package.json via the "packageManager"
# field, which Corepack reads automatically. To change the Yarn release, edit
# packageManager there and update the inline pin in extension/Extension.proj
# if any commands need to predate the working-directory switch.
Comment thread
adamint marked this conversation as resolved.
Resolved

# Point Corepack at the dnceng internal npm mirror unless the caller already
# set a registry. Corepack does NOT read .npmrc, so we have to feed it through
# its own env var. See https://github.com/nodejs/corepack#environment-variables.
# Override locally with `$env:COREPACK_NPM_REGISTRY = '<url>'; ./build.ps1` or
# remove the env var to use the public npm registry.
if (-not $env:COREPACK_NPM_REGISTRY) {
$env:COREPACK_NPM_REGISTRY = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/"
}
if (-not $env:COREPACK_ENABLE_DOWNLOAD_PROMPT) {
$env:COREPACK_ENABLE_DOWNLOAD_PROMPT = "0"
}

Write-Host "Checking prerequisites..."

# Check for Node.js
Expand All @@ -10,9 +34,10 @@ if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
exit 1
}

# Check for Corepack so the build uses the Yarn Classic version that matches extension/yarn.lock.
if (-not (Get-Command corepack -ErrorAction SilentlyContinue)) {
Write-Error "Error: Corepack is not installed. Please install a Node.js version that includes Corepack."
# npm is required to install our pinned Corepack. It ships with every official
# Node.js distribution, so this should only fail on broken installs.
if (-not (Get-Command npm -ErrorAction SilentlyContinue)) {
Write-Error "Error: npm is not available. Reinstall Node.js so npm is on PATH."
exit 1
}

Expand All @@ -35,12 +60,45 @@ if (-not (Get-Command dotnet -ErrorAction SilentlyContinue)) {

Write-Host "All prerequisites satisfied."

# Ensure we run from the extension directory
# Ensure we run from the extension directory so corepack/yarn pick up
# extension/.npmrc and extension/package.json (which holds the packageManager pin).
Set-Location $PSScriptRoot

Write-Host ""
Write-Host "Installing pinned Corepack $CorepackVersion..."
# Reinstall every time so we overwrite any older Corepack shim that Node.js
# may have placed on PATH ahead of npm's global prefix.
npm install --global "corepack@$CorepackVersion"

if ($LASTEXITCODE -ne 0) {
Write-Error "npm install -g corepack@$CorepackVersion failed with exit code $LASTEXITCODE"
exit $LASTEXITCODE
}

Write-Host ""
Write-Host "Enabling Corepack package manager shims..."
corepack enable

if ($LASTEXITCODE -ne 0) {
Write-Error "corepack enable failed with exit code $LASTEXITCODE"
exit $LASTEXITCODE
}

Write-Host ""
Write-Host "Preparing Yarn from packageManager pin in package.json..."
# `corepack prepare --activate` (no args) reads the "packageManager" field from
# the package.json in the current directory and provisions/activates that exact
# version. See https://github.com/nodejs/corepack#corepack-prepare-.
corepack prepare --activate

if ($LASTEXITCODE -ne 0) {
Write-Error "corepack prepare --activate failed with exit code $LASTEXITCODE"
exit $LASTEXITCODE
}

Write-Host ""
Write-Host "Running yarn install..."
corepack yarn@1.22.22 install --frozen-lockfile --non-interactive
corepack yarn install --frozen-lockfile --non-interactive

if ($LASTEXITCODE -ne 0) {
Write-Error "yarn install failed with exit code $LASTEXITCODE"
Expand All @@ -49,7 +107,7 @@ if ($LASTEXITCODE -ne 0) {

Write-Host ""
Write-Host "Running yarn compile..."
corepack yarn@1.22.22 compile
corepack yarn compile

if ($LASTEXITCODE -ne 0) {
Write-Error "yarn compile failed with exit code $LASTEXITCODE"
Expand Down
52 changes: 46 additions & 6 deletions extension/build.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
#!/bin/bash
set -e

# Pinned Corepack shim version. Node.js >= 16.10 bundles a Corepack, but the
# bundled version drifts with each Node release and Corepack is on track to be
# unbundled from Node entirely (see https://github.com/nodejs/node/issues/54647).
# Installing a pinned Corepack from npm makes the build reproducible regardless
# of which Node version a developer or CI runner happens to have.
COREPACK_VERSION="0.34.7"
Comment thread
adamint marked this conversation as resolved.
Resolved

# Yarn version is pinned in extension/package.json via the "packageManager"
# field, which Corepack reads automatically. To change the Yarn release, edit
# packageManager there and update the inline pin in extension/Extension.proj
# if any commands need to predate the working-directory switch.
Comment thread
adamint marked this conversation as resolved.
Resolved

# Point Corepack at the dnceng internal npm mirror unless the caller already
# set a registry. Corepack does NOT read .npmrc, so we have to feed it through
# its own env var. See https://github.com/nodejs/corepack#environment-variables.
# Override locally with `COREPACK_NPM_REGISTRY=<url> ./build.sh` or unset to use
# the public npm registry.
: "${COREPACK_NPM_REGISTRY:=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/}"
: "${COREPACK_ENABLE_DOWNLOAD_PROMPT:=0}"
export COREPACK_NPM_REGISTRY COREPACK_ENABLE_DOWNLOAD_PROMPT

echo "Checking prerequisites..."

# Check for Node.js
Expand All @@ -9,9 +30,10 @@ if ! command -v node &> /dev/null; then
exit 1
fi

# Check for Corepack so the build uses the Yarn Classic version that matches extension/yarn.lock.
if ! command -v corepack &> /dev/null; then
echo "Error: Corepack is not installed. Please install a Node.js version that includes Corepack."
# npm is required to install our pinned Corepack. It ships with every official
# Node.js distribution, so this should only fail on broken installs.
if ! command -v npm &> /dev/null; then
echo "Error: npm is not available. Reinstall Node.js so npm is on PATH."
exit 1
fi

Expand All @@ -31,17 +53,35 @@ fi

echo "All prerequisites satisfied."

# Ensure we run from the extension directory
# Ensure we run from the extension directory so corepack/yarn pick up
# extension/.npmrc and extension/package.json (which holds the packageManager pin).
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

echo ""
echo "Installing pinned Corepack ${COREPACK_VERSION}..."
# Reinstall every time so we overwrite any older Corepack shim that Node.js
# may have placed on PATH ahead of npm's global prefix.
npm install --global "corepack@${COREPACK_VERSION}"

echo ""
echo "Enabling Corepack package manager shims..."
corepack enable

echo ""
echo "Preparing Yarn from packageManager pin in package.json..."
# `corepack prepare --activate` (no args) reads the "packageManager" field from
# the package.json in the current directory and provisions/activates that exact
# version. See https://github.com/nodejs/corepack#corepack-prepare-.
corepack prepare --activate

echo ""
echo "Running yarn install..."
corepack yarn@1.22.22 install --frozen-lockfile --non-interactive
corepack yarn install --frozen-lockfile --non-interactive

echo ""
echo "Running yarn compile..."
corepack yarn@1.22.22 compile
corepack yarn compile

echo ""
echo "Building Aspire CLI..."
Expand Down
1 change: 1 addition & 0 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"engines": {
"vscode": "^1.98.0"
},
"packageManager": "yarn@1.22.22",
"categories": [
"Programming Languages",
"Debuggers",
Expand Down
Loading