Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ee8a7ef
chore(deps-dev): bump brace-expansion from 1.1.18 to 1.1.21 in /api (…
dependabot[bot] Oct 2, 2026
8002f6b
CI: Drop Python 3.9 and add Python 3.15 (#1847)
edvilme Oct 2, 2026
52f6ace
chore(deps-dev): bump markdown-it from 14.2.0 to 14.3.2 (#1850)
dependabot[bot] Oct 3, 2026
30810b2
Preserve other projects' selections when a venv cannot resolve (#1854)
eleanorjboyd Oct 6, 2026
7b69d86
fix: refresh venvs when a venv folder is deleted outside VS Code (Fix…
karthiknadig Oct 6, 2026
8dc7343
activation: respect integration setting precedence (#1897)
eleanorjboyd Oct 6, 2026
67e0a50
venv: preserve newer interpreter selections during refresh (#1860)
eleanorjboyd Oct 6, 2026
ab8e95f
uv: continue Python installation after bootstrapping uv (#1872)
eleanorjboyd Oct 6, 2026
69d9624
conda: keep inferred local environments scoped to their project (#1862)
eleanorjboyd Oct 6, 2026
4faeedf
bump main to 1.40 then 1.41 (#1902)
eleanorjboyd Oct 7, 2026
d44725a
Add noninteractive, isolated Python environment tooling for agents (#…
StellaHuang95 Oct 7, 2026
803879b
fix: prefer a project's own .venv over nested venvs (Fixes #1878) (#1…
karthiknadig Oct 7, 2026
e4f9939
Keep PEP 723 inline script CodeLens live and persistent (#1906)
StellaHuang95 Oct 8, 2026
c93000b
Update shell-startup activation after global interpreter changes (#1904)
Copilot Oct 8, 2026
fe8ecda
Temporarily skip inline CodeLens integration tests on Windows (#1912)
eleanorjboyd Oct 8, 2026
9ee9e22
Preserve shell-startup activation when environment files change (#1903)
Copilot Oct 8, 2026
84d667e
Stabilize inline CodeLens test cleanup on Windows (#1913)
StellaHuang95 Oct 8, 2026
7c894fc
Group Dependabot updates with a 14-day cooldown (#1907)
bschnurr Oct 9, 2026
95f7baf
fix: list uv-installed Python as a Global interpreter (Fixes #1877) (…
karthiknadig Oct 9, 2026
67eedfe
fix: resolve command names in python.defaultInterpreterPath on PATH (…
karthiknadig Oct 9, 2026
56ccb9d
Handle live metadata and uppercase PEP 723 scripts (#1916)
StellaHuang95 Oct 9, 2026
720981a
PipPackageManager: Refactor package availability check (#1914)
edvilme Oct 9, 2026
ff37709
Fix unanswered settings warning blocking setup (#1905)
Copilot Oct 12, 2026
f6aec34
API: Add `getVersion` method to `EnvironmentManager` (#1923)
edvilme Oct 12, 2026
21b205a
CI: Stabilize discovery test and capture Linux startup diagnostics (#…
eleanorjboyd Oct 12, 2026
4c1f9f3
Add interpreter path entry to the project-view environment selector (…
Copilot Oct 12, 2026
deb05b8
Sync manually resolved virtual environments with the environment list…
Copilot Oct 12, 2026
cc8f6ac
uv: install uv before listing Python versions (#1834)
eleanorjboyd Oct 12, 2026
9f1e63d
Skip directory `.env` / `python.envFile` paths when resolving environ…
Copilot Oct 14, 2026
61aeb25
build: bump extension version to 1.39.1
eleanorjboyd Oct 6, 2026
e6a89ad
build: bump extension version to 1.40.0 (#1899)
eleanorjboyd Oct 6, 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
39 changes: 39 additions & 0 deletions .github/actions/run-linux-tests/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: 'Run Linux extension tests'
description: 'Run tests under Xvfb and retain startup diagnostics on failure'

inputs:
script:
description: 'npm test script to run'
required: true
artifact-name:
description: 'Unique diagnostic artifact name for this job'
required: true

runs:
using: 'composite'
steps:
- name: Install Xvfb
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y xvfb x11-xserver-utils

- name: Run tests with diagnostics
id: tests
shell: bash
env:
TEST_SCRIPT: ${{ inputs.script }}
VSCODE_TEST_DIAGNOSTICS_DIR: ${{ runner.temp }}/vscode-test-diagnostics
run: |
mkdir -p "$VSCODE_TEST_DIAGNOSTICS_DIR"
xvfb-run --auto-servernum --error-file="$VSCODE_TEST_DIAGNOSTICS_DIR/xvfb.log" \
npm run "$TEST_SCRIPT" 2>&1 | tee "$VSCODE_TEST_DIAGNOSTICS_DIR/launcher.log"

- name: Upload failure diagnostics
if: ${{ failure() && steps.tests.outcome == 'failure' }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ${{ inputs.artifact-name }}
path: ${{ runner.temp }}/vscode-test-diagnostics
if-no-files-found: error
retention-days: 7
3 changes: 2 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ updates:
schedule:
interval: "weekly"
cooldown:
default-days: 7
# Delay updates beyond the highest-risk window after a release.
default-days: 14
3 changes: 3 additions & 0 deletions .github/instructions/testing-workflow.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ This guide covers the full testing lifecycle:

- Pip commands that return JSON must pass `--disable-pip-version-check`; the process helper combines stderr with stdout, so update notices can otherwise make valid JSON unparseable (1).
- When a view subscribes to a newly added provider event, TypeMoq-based view tests must return a real `EventEmitter.event`; an unstubbed event yields an undefined disposable and fails during teardown (1).
- Test agent selections across a full reload with `python.defaultInterpreterPath` set. An effective manager value equal to the extension default does not prove a workspace value was saved; tool-owned persistence must inspect `workspaceValue` or startup can restore the global interpreter (1).
- `vscode.executeCodeLensProvider` verifies provider output, not visible editor refresh. VS Code cancels its debounced CodeLens refresh when the editor loses focus; account for background UI automation restoring focus to another app before diagnosing a stale rendered lens (1).

### When to Use This Guide

Expand Down Expand Up @@ -614,3 +616,4 @@ envConfig.inspect
- **pet binary is required for environment manager registration**: The smoke/E2E/integration tests require the `pet` binary from `microsoft/python-environment-tools` to be built and placed in `python-env-tools/bin/`. Without it, `waitForApiReady()` will timeout because managers never register. CI must build pet from source using `cargo build --release --package pet` (2)
- **Check exact project registration with `getPythonProjects()`**: `getPythonProject(uri)` can return a containing parent project, so it cannot prove that a nested project was registered or unregistered (1)
- **Use controlled fixture providers for package lifecycle integration tests**: Discovering an existing Conda environment does not guarantee API quick-create can succeed. Use `createEnvironmentFixture()` so creation prerequisites and cleanup are deterministic (1)
- **Retry Windows integration-test cleanup at the filesystem operation, not the suite**: After closing VS Code editors, use bounded `fs.rm(..., { recursive: true, force: true, maxRetries, retryDelay })` for temporary workspaces because Windows can briefly return `EBUSY`; keep final failures visible instead of adding sleeps or Mocha retries (1)
32 changes: 20 additions & 12 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.9', '3.12', '3.14']
python-version: ['3.10', '3.12', '3.14', '3.15']

steps:
- name: Checkout
Expand Down Expand Up @@ -141,6 +141,7 @@ jobs:
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install Dependencies
run: npm ci
Expand All @@ -153,9 +154,10 @@ jobs:

- name: Run Smoke Tests (Linux)
if: runner.os == 'Linux'
uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
uses: ./.github/actions/run-linux-tests
with:
run: npm run smoke-test
script: smoke-test
artifact-name: smoke-${{ matrix.os }}-${{ matrix.python-version }}-${{ github.run_attempt }}

- name: Run Smoke Tests (non-Linux)
if: runner.os != 'Linux'
Expand All @@ -169,7 +171,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.12', '3.14']
python-version: ['3.10', '3.12', '3.14', '3.15']

steps:
- name: Checkout
Expand Down Expand Up @@ -228,6 +230,7 @@ jobs:
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install Dependencies
run: npm ci
Expand All @@ -240,9 +243,10 @@ jobs:

- name: Run E2E Tests (Linux)
if: runner.os == 'Linux'
uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
uses: ./.github/actions/run-linux-tests
with:
run: npm run e2e-test
script: e2e-test
artifact-name: e2e-${{ matrix.os }}-${{ matrix.python-version }}-${{ github.run_attempt }}

- name: Run E2E Tests (non-Linux)
if: runner.os != 'Linux'
Expand All @@ -259,7 +263,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.12', '3.14']
python-version: ['3.10', '3.12', '3.14', '3.15']

steps:
- name: Checkout
Expand Down Expand Up @@ -318,6 +322,7 @@ jobs:
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install Dependencies
run: npm ci
Expand All @@ -336,9 +341,10 @@ jobs:

- name: Run Integration Tests (Linux)
if: runner.os == 'Linux'
uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
uses: ./.github/actions/run-linux-tests
with:
run: npm run integration-test
script: integration-test
artifact-name: integration-${{ matrix.os }}-${{ matrix.python-version }}-${{ github.run_attempt }}

- name: Run Integration Tests (non-Linux)
if: runner.os != 'Linux'
Expand All @@ -352,7 +358,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.12', '3.14']
python-version: ['3.10', '3.12', '3.14', '3.15']

steps:
- name: Checkout
Expand All @@ -368,6 +374,7 @@ jobs:
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install Dependencies
run: npm ci
Expand All @@ -380,9 +387,10 @@ jobs:

- name: Run Integration Tests Multi-Root (Linux)
if: runner.os == 'Linux'
uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
uses: ./.github/actions/run-linux-tests
with:
run: npm run integration-test-multiroot
script: integration-test-multiroot
artifact-name: integration-multiroot-${{ matrix.os }}-${{ matrix.python-version }}-${{ github.run_attempt }}

- name: Run Integration Tests Multi-Root (non-Linux)
if: runner.os != 'Linux'
Expand Down
24 changes: 15 additions & 9 deletions .github/workflows/push-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.12', '3.14']
python-version: ['3.10', '3.12', '3.14', '3.15']

steps:
- name: Checkout
Expand Down Expand Up @@ -142,6 +142,7 @@ jobs:
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install Dependencies
run: npm ci
Expand All @@ -154,9 +155,10 @@ jobs:

- name: Run Smoke Tests (Linux)
if: runner.os == 'Linux'
uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
uses: ./.github/actions/run-linux-tests
with:
run: npm run smoke-test
script: smoke-test
artifact-name: smoke-${{ matrix.os }}-${{ matrix.python-version }}-${{ github.run_attempt }}

- name: Run Smoke Tests (non-Linux)
if: runner.os != 'Linux'
Expand All @@ -170,7 +172,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.12', '3.14']
python-version: ['3.10', '3.12', '3.14', '3.15']

steps:
- name: Checkout
Expand Down Expand Up @@ -229,6 +231,7 @@ jobs:
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install Dependencies
run: npm ci
Expand All @@ -241,9 +244,10 @@ jobs:

- name: Run E2E Tests (Linux)
if: runner.os == 'Linux'
uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
uses: ./.github/actions/run-linux-tests
with:
run: npm run e2e-test
script: e2e-test
artifact-name: e2e-${{ matrix.os }}-${{ matrix.python-version }}-${{ github.run_attempt }}

- name: Run E2E Tests (non-Linux)
if: runner.os != 'Linux'
Expand All @@ -260,7 +264,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.12', '3.14']
python-version: ['3.10', '3.12', '3.14', '3.15']

steps:
- name: Checkout
Expand Down Expand Up @@ -319,6 +323,7 @@ jobs:
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install Dependencies
run: npm ci
Expand All @@ -337,9 +342,10 @@ jobs:

- name: Run Integration Tests (Linux)
if: runner.os == 'Linux'
uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
uses: ./.github/actions/run-linux-tests
with:
run: npm run integration-test
script: integration-test
artifact-name: integration-${{ matrix.os }}-${{ matrix.python-version }}-${{ github.run_attempt }}

- name: Run Integration Tests (non-Linux)
if: runner.os != 'Linux'
Expand Down
15 changes: 15 additions & 0 deletions .vscode-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import * as path from 'path';
// VS Code creates `<userDataDir>/<x.y>-main.sock`. An in-workspace location
// (e.g. /Users/runner/work/<repo>/<repo>/.vscode-test/user-data) overflows.
const userDataDir = path.join(os.tmpdir(), 'vsct-ud');
const diagnosticsDir = process.env.VSCODE_TEST_DIAGNOSTICS_DIR;
const diagnosticArgs = diagnosticsDir
? [`--logsPath=${path.join(diagnosticsDir, 'vscode')}`, '--verbose']
: [];
const diagnosticMocha = diagnosticsDir
? { require: [path.resolve('out', 'test', 'diagnostics.js')] }
: {};

// Seed user settings.json so the extension actually activates: without
// `python.useEnvironmentsExtension=true` it short-circuits during activation
Expand All @@ -23,13 +30,15 @@ export default defineConfig([
label: 'smokeTests',
files: 'out/test/smoke/**/*.smoke.test.js',
mocha: {
...diagnosticMocha,
ui: 'tdd',
timeout: 120000,
},
env: {
VSC_PYTHON_SMOKE_TEST: '1',
},
launchArgs: [
...diagnosticArgs,
`--user-data-dir=${userDataDir}`,
// Don't open any folder with Python files to prevent premature activation
'--disable-workspace-trust',
Expand All @@ -43,13 +52,15 @@ export default defineConfig([
label: 'e2eTests',
files: 'out/test/e2e/**/*.e2e.test.js',
mocha: {
...diagnosticMocha,
ui: 'tdd',
timeout: 180000,
},
env: {
VSC_PYTHON_E2E_TEST: '1',
},
launchArgs: [
...diagnosticArgs,
`--user-data-dir=${userDataDir}`,
'--disable-workspace-trust',
],
Expand All @@ -62,13 +73,15 @@ export default defineConfig([
files: 'out/test/integration/*.integration.test.js',
workspaceFolder: 'src/test/integration/test-workspace/project-a',
mocha: {
...diagnosticMocha,
ui: 'tdd',
timeout: 60000,
},
env: {
VSC_PYTHON_INTEGRATION_TEST: '1',
},
launchArgs: [
...diagnosticArgs,
`--user-data-dir=${userDataDir}`,
'--disable-workspace-trust',
],
Expand All @@ -81,6 +94,7 @@ export default defineConfig([
files: 'out/test/integration/multiroot/*.integration.test.js',
workspaceFolder: 'src/test/integration/test-workspace/integration-tests.code-workspace',
mocha: {
...diagnosticMocha,
ui: 'tdd',
timeout: 60000,
retries: 1,
Expand All @@ -89,6 +103,7 @@ export default defineConfig([
VSC_PYTHON_INTEGRATION_TEST: '1',
},
launchArgs: [
...diagnosticArgs,
`--user-data-dir=${userDataDir}`,
'--disable-workspace-trust',
],
Expand Down
Loading
Loading