Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/instructions/testing-workflow.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -606,3 +606,4 @@ envConfig.inspect
- **Never skip tests to hide infrastructure problems**: If tests require native binaries (like `pet`), the CI workflow must build/download them. Skipping tests when infrastructure is missing gives false confidence. Build from source (like vscode-python does) rather than skipping. Tests should fail clearly when something is wrong (2)
- **No retries for masking flakiness**: Mocha `retries` should not be used to mask test flakiness. If a test is flaky, fix the root cause. Retries hide real issues and slow down CI (1)
- **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)
8 changes: 8 additions & 0 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,14 @@ jobs:
if: runner.os != 'Linux'
run: npm run integration-test

- name: Run Package Manager Network Integration Tests
if: runner.os == 'Linux' && matrix.python-version == '3.12'
uses: GabrielBB/xvfb-action@86d97bde4a65fe9b290c0b3fb92c2c4ed0e5302d # v1.6
env:
VSC_PYTHON_PACKAGE_NETWORK_TEST: '1'
with:
run: npm run integration-test -- --grep "Package Manager"

integration-tests-multiroot:
name: Integration Tests (Multi-Root)
runs-on: ${{ matrix.os }}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning · Non-blocking recommendation

This cache-cleanup PR also includes API 1.2, package-management behavior, network integration, pip parsing, and logo changes. Split these feature streams so cache lifecycle changes can be reviewed, reverted, and released independently.

Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/push-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,11 @@ jobs:
- name: Run Integration Tests (non-Linux)
if: runner.os != 'Linux'
run: npm run integration-test

- name: Run Package Manager Network Integration Tests
if: runner.os == 'Linux' && matrix.python-version == '3.12'
uses: GabrielBB/xvfb-action@86d97bde4a65fe9b290c0b3fb92c2c4ed0e5302d # v1.6
env:
VSC_PYTHON_PACKAGE_NETWORK_TEST: '1'
with:
run: npm run integration-test -- --grep "Package Manager"
7 changes: 7 additions & 0 deletions api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to the `@vscode/python-environments` API package are documen
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0]

### Added

- Added `PackageManagementInteractionOptions` with an optional `runHeadless?: boolean` property, mixed into `PackageManagementOptions`. When `true`, package management operations run without any user prompts or interaction — steps that would normally require input, such as selecting packages to install when none are specified, are skipped instead of prompting — for automated or headless scenarios such as integration tests.
- Added `RemoveEnvironmentOptions` with an optional `runHeadless?: boolean` property to remove environments without a confirmation prompt in automated or headless scenarios.

## [1.1.0]

### Added
Expand Down
4 changes: 2 additions & 2 deletions api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@vscode/python-environments",
"description": "An API facade for the Python Environments extension in VS Code",
"version": "1.1.0",
"version": "1.2.0",
"author": {
"name": "Microsoft Corporation"
},
Expand Down
111 changes: 68 additions & 43 deletions examples/sample1/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,17 @@ export interface QuickCreateConfig {
readonly detail?: string;
}

/**
* Options controlling environment removal.
*/
export interface RemoveEnvironmentOptions {
/**
* When `true`, removes the environment without prompting for confirmation.
* Intended for automated or headless scenarios. Defaults to `false`.
*/
runHeadless?: boolean;
}

/**
* Interface representing an environment manager.
*/
Expand Down Expand Up @@ -392,7 +403,7 @@ export interface EnvironmentManager {
* @param environment - The Python environment to remove.
* @returns A promise that resolves when the environment is removed.
*/
remove?(environment: PythonEnvironment): Promise<void>;
remove?(environment: PythonEnvironment, options?: RemoveEnvironmentOptions): Promise<void>;

/**
* Refreshes the list of Python environments within the specified scope.
Expand Down Expand Up @@ -739,49 +750,62 @@ export interface GetPackagesOptions {
}

/**
* Options for package management.
* Options controlling user interaction during package management operations.
*/
export type PackageManagementOptions =
| {
/**
* Upgrade the packages if it is already installed.
*/
upgrade?: boolean;

/**
* Show option to skip package installation
*/
showSkipOption?: boolean;
/**
* The list of packages to install.
*/
install: string[];

/**
* The list of packages to uninstall.
*/
uninstall?: string[];
}
| {
/**
* Upgrade the packages if it is already installed.
*/
upgrade?: boolean;

/**
* Show option to skip package installation
*/
showSkipOption?: boolean;
/**
* The list of packages to install.
*/
install?: string[];
export interface PackageManagementInteractionOptions {
/**
* When `true`, the package management operation runs without any user prompts or
* interaction and relies solely on the packages provided in the options. Any step
* that would normally require user input — such as selecting packages to install
* when none are specified — is skipped instead of prompting the user. Intended for
* automated or headless scenarios such as integration tests. Defaults to `false`.
*/
runHeadless?: boolean;
}

/**
* The list of packages to uninstall.
*/
uninstall: string[];
};
export type PackageManagementOptions = PackageManagementInteractionOptions &
(
| {
/**
* Upgrade the packages if it is already installed.
*/
upgrade?: boolean;

/**
* Show option to skip package installation or uninstallation.
*/
showSkipOption?: boolean;
/**
* The list of packages to install.
*/
install: string[];

/**
* The list of packages to uninstall.
*/
uninstall?: string[];
}
| {
/**
* Upgrade the packages if it is already installed.
*/
upgrade?: boolean;

/**
* Show option to skip package installation or uninstallation.
*/
showSkipOption?: boolean;
/**
* The list of packages to install.
*/
install?: string[];

/**
* The list of packages to uninstall.
*/
uninstall: string[];
}
);

/**
* Options for creating a Python environment.
Expand Down Expand Up @@ -881,9 +905,10 @@ export interface PythonEnvironmentManagementApi {
* Remove a Python environment.
*
* @param environment The Python environment to remove.
* @param options Optional parameters controlling environment removal.
* @returns A promise that resolves when the environment has been removed.
*/
removeEnvironment(environment: PythonEnvironment): Promise<void>;
removeEnvironment(environment: PythonEnvironment, options?: RemoveEnvironmentOptions): Promise<void>;
}

export interface PythonEnvironmentsApi {
Expand Down
20 changes: 9 additions & 11 deletions files/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
112 changes: 70 additions & 42 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,17 @@ export interface QuickCreateConfig {
readonly detail?: string;
}

/**
* Options controlling environment removal.
*/
export interface RemoveEnvironmentOptions {
/**
* When `true`, removes the environment without prompting for confirmation.
* Intended for automated or headless scenarios. Defaults to `false`.
*/
runHeadless?: boolean;
}

/**
* Interface representing an environment manager.
*
Expand Down Expand Up @@ -425,7 +436,7 @@ export interface EnvironmentManager {
* Invoked to delete the given environment. Typical triggers include an explicit user
* action (such as a "Delete Environment" command) and programmatic removal via the API.
*/
remove?(environment: PythonEnvironment): Promise<void>;
remove?(environment: PythonEnvironment, options?: RemoveEnvironmentOptions): Promise<void>;

/**
* Refreshes the list of Python environments within the specified scope.
Expand Down Expand Up @@ -872,47 +883,63 @@ export interface GetPackagesOptions {
skipCache?: boolean;
}

export type PackageManagementOptions =
| {
/**
* Upgrade the packages if they are already installed.
*/
upgrade?: boolean;

/**
* Show option to skip package installation or uninstallation.
*/
showSkipOption?: boolean;
/**
* The list of packages to install.
*/
install: string[];

/**
* The list of packages to uninstall.
*/
uninstall?: string[];
}
| {
/**
* Upgrade the packages if they are already installed.
*/
upgrade?: boolean;

/**
* Show option to skip package installation or uninstallation.
*/
showSkipOption?: boolean;
/**
* The list of packages to install.
*/
install?: string[];
/**
* Options controlling user interaction during package management operations.
*/
export interface PackageManagementInteractionOptions {
/**
* When `true`, the package management operation runs without any user prompts or
* interaction and relies solely on the packages provided in the options. Any step
* that would normally require user input — such as selecting packages to install
* when none are specified — is skipped instead of prompting the user. Intended for
* automated or headless scenarios such as integration tests. Defaults to `false`.
*/
runHeadless?: boolean;
}

/**
* The list of packages to uninstall.
*/
uninstall: string[];
};
export type PackageManagementOptions = PackageManagementInteractionOptions &
(
| {
/**
* Upgrade the packages if they are already installed.
*/
upgrade?: boolean;

/**
* Show option to skip package installation or uninstallation.
*/
showSkipOption?: boolean;
/**
* The list of packages to install.
*/
install: string[];

/**
* The list of packages to uninstall.
*/
uninstall?: string[];
}
| {
/**
* Upgrade the packages if they are already installed.
*/
upgrade?: boolean;

/**
* Show option to skip package installation or uninstallation.
*/
showSkipOption?: boolean;
/**
* The list of packages to install.
*/
install?: string[];

/**
* The list of packages to uninstall.
*/
uninstall: string[];
}
);

/**
* Options for creating a Python environment.
Expand Down Expand Up @@ -1011,9 +1038,10 @@ export interface PythonEnvironmentManagementApi {
* Remove a Python environment.
*
* @param environment The Python environment to remove.
* @param options Optional parameters controlling environment removal.
* @returns A promise that resolves when the environment has been removed.
*/
removeEnvironment(environment: PythonEnvironment): Promise<void>;
removeEnvironment(environment: PythonEnvironment, options?: RemoveEnvironmentOptions): Promise<void>;
}

export interface PythonEnvironmentsApi {
Expand Down
Loading
Loading