Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
9664d8e
Fix needs new version
gaborbernat Oct 8, 2025
47c07a5
[pre-commit.ci] pre-commit autoupdate (#61)
pre-commit-ci[bot] Oct 13, 2025
23bde30
Fix dependabot errors
gaborbernat Oct 15, 2025
98d8e7f
Bump actions/checkout from 4 to 5 (#65)
dependabot[bot] Oct 15, 2025
c649fd5
Bump gradle/actions from 4 to 5 (#64)
dependabot[bot] Oct 15, 2025
dea5f99
Bump actions/setup-java from 4 to 5 (#63)
dependabot[bot] Oct 15, 2025
01f6a77
Bump org.jetbrains.kotlinx.kover from 0.8.3 to 0.9.2 (#67)
dependabot[bot] Oct 15, 2025
eaee6a5
Upgrade Gradle Wrapper to 9.1.0 (#62)
gaborbernat Oct 15, 2025
72fdacc
Bump jupiter from 5.14.0 to 6.0.0 (#71)
dependabot[bot] Oct 20, 2025
6a66072
Bump org.jetbrains.kotlinx.kover from 0.9.2 to 0.9.3 (#73)
dependabot[bot] Oct 20, 2025
9cacbee
Bump org.jetbrains.intellij.platform from 2.10.0 to 2.10.1 (#74)
dependabot[bot] Oct 20, 2025
8b2c707
Bump org.junit.platform:junit-platform-launcher from 1.14.0 to 6.0.0 …
dependabot[bot] Oct 20, 2025
a73e4e7
Bump org.jetbrains.intellij.platform from 2.10.1 to 2.10.2 (#75)
dependabot[bot] Oct 23, 2025
3b98099
Fix python version display (#77)
andrask Oct 23, 2025
9eabc54
Release 2.1.2
gaborbernat Oct 23, 2025
c255490
Do not add bots to release changelog
gaborbernat Oct 23, 2025
73f699d
Changelog update - v2.1.2 (#78)
github-actions[bot] Oct 23, 2025
bd3ced9
Bump org.jetbrains.kotlin.jvm from 2.2.20 to 2.2.21 (#79)
dependabot[bot] Oct 24, 2025
2c4cb6e
Bump actions/upload-artifact from 4 to 5 (#80)
dependabot[bot] Oct 27, 2025
decab6d
Bump jupiter from 6.0.0 to 6.0.1 (#81)
dependabot[bot] Nov 3, 2025
8c1efb3
Bump org.jlleitschuh.gradle.ktlint from 13.1.0 to 14.0.1 (#84)
dependabot[bot] Nov 11, 2025
7f3a665
[pre-commit.ci] pre-commit autoupdate (#85)
pre-commit-ci[bot] Nov 20, 2025
c4e6459
Bump org.jetbrains.intellij.platform from 2.10.2 to 2.10.4 (#83)
dependabot[bot] Nov 20, 2025
9f4b945
Bump actions/checkout from 5 to 6 (#86)
dependabot[bot] Nov 21, 2025
3e4300a
[pre-commit.ci] pre-commit autoupdate (#90)
pre-commit-ci[bot] Dec 1, 2025
bd2f4f5
Bump org.barfuin.gradle.taskinfo from 2.2.0 to 2.2.1 (#88)
dependabot[bot] Dec 8, 2025
5708539
[pre-commit.ci] pre-commit autoupdate (#91)
pre-commit-ci[bot] Dec 8, 2025
48383b3
Bump org.jetbrains.intellij.platform from 2.10.4 to 2.10.5 (#89)
dependabot[bot] Dec 8, 2025
2aac1dd
Bump org.jetbrains.changelog from 2.4.0 to 2.5.0 (#87)
dependabot[bot] Dec 8, 2025
fd40b19
Bump org.barfuin.gradle.taskinfo from 2.2.1 to 3.0.0 (#93)
dependabot[bot] Dec 10, 2025
c3277a9
Bump org.jetbrains.kotlinx.kover from 0.9.3 to 0.9.4 (#92)
dependabot[bot] Dec 10, 2025
340b81a
Bump actions/cache from 4 to 5 (#94)
dependabot[bot] Dec 13, 2025
f272203
Bump actions/upload-artifact from 5 to 6 (#95)
dependabot[bot] Dec 16, 2025
867b1b7
Bump org.jetbrains.kotlin.jvm from 2.2.21 to 2.3.0 (#96)
dependabot[bot] Jan 2, 2026
beed218
[pre-commit.ci] pre-commit autoupdate (#97)
pre-commit-ci[bot] Jan 2, 2026
7d6bdcd
Bump org.barfuin.gradle.taskinfo from 3.0.0 to 3.0.1 (#98)
dependabot[bot] Jan 2, 2026
0771894
Optimize GitHub Actions: parallelize verification and fix disk space …
gaborbernat Jan 3, 2026
3cc75d1
Refactor to modern Kotlin idioms and fix deprecated API (#100)
gaborbernat Jan 3, 2026
f610fc5
Add cache invalidation with file watcher (#101)
gaborbernat Jan 3, 2026
2325f38
Improve error UX with notifications (#102)
gaborbernat Jan 3, 2026
5056485
Add plugin settings page (#103)
gaborbernat Jan 3, 2026
c683eec
Improve plugin description and documentation (#105)
gaborbernat Jan 3, 2026
ca77ec6
Enhance project view decorations and add 100% test coverage
gaborbernat Jan 3, 2026
eb0045d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 4, 2026
f416e0c
Fix Gradle transforms cache corruption in CI
gaborbernat Jan 4, 2026
478cb3e
Fix Gradle transforms cache corruption in CI
gaborbernat Jan 4, 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
4 changes: 2 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ version: 2
updates:
- package-ecosystem: "gradle"
directory: "/"
target-branch: "next"
target-branch: "main"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "next"
target-branch: "main"
schedule:
interval: "daily"
5 changes: 5 additions & 0 deletions .github/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
changelog:
exclude:
authors:
- dependabot[bot]
- pre-commit-ci[bot]
113 changes: 75 additions & 38 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,23 @@ jobs:
outputs:
version: ${{ steps.properties.outputs.version }}
changelog: ${{ steps.properties.outputs.changelog }}
pluginVerifierHomeDir: ${{ steps.properties.outputs.pluginVerifierHomeDir }}qq
pluginVerifierHomeDir: ${{ steps.properties.outputs.pluginVerifierHomeDir }}
platformVersion: ${{ steps.properties.outputs.platformVersion }}
steps:
- name: Maximize Build Space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
large-packages: false
- name: Checkout git repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: 17
java-version: 21
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v5
- name: Build plugin
run: ./gradlew --console=plain buildPlugin
- name: Prepare Plugin Artifact
Expand All @@ -42,7 +43,7 @@ jobs:
unzip "$FILENAME" -d content
echo "filename=${FILENAME:0:-4}" >> $GITHUB_OUTPUT
- name: Upload artifact for later download
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: ${{ steps.artifact.outputs.filename }}
path: ./build/distributions/content/*/*
Expand All @@ -53,86 +54,122 @@ jobs:
PROPERTIES="$(./gradlew properties --console=plain -q)"
VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT
echo "pluginVerifierHomeDir=$HOME/.pluginVerifier" >> $GITHUB_OUTPUT
echo "platformVersion=$(echo "$PROPERTIES" | grep "^platformVersion:" | cut -f2- -d ' ')" >> $GITHUB_OUTPUT
CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)"
echo "changelog<<EOF" >> $GITHUB_OUTPUT
echo "$CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

verify:
name: Verify plugin
name: Verify (${{ matrix.ide }})
needs: [build]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ide: [PC, PY]
steps:
- name: Maximize Build Space
- name: Free disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
large-packages: false
android: true
dotnet: true
- name: Checkout git repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: 17
java-version: 21
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v5
with:
validate-wrappers: false
- name: Set up verifier cache
uses: actions/cache@v4
cache-read-only: false
- name: Cache plugin verifier IDEs
uses: actions/cache@v5
with:
path: ${{ needs.build.outputs.pluginVerifierHomeDir }}/ides
key: plugin-verifier-${{ hashFiles('build/listProductsReleases.txt') }}
path: ~/.pluginVerifier/ides
key: plugin-verifier-ides-${{ matrix.ide }}-${{ needs.build.outputs.platformVersion }}
- name: Clean corrupted Gradle transforms
run: rm -rf ~/.gradle/caches/*/transforms
- name: Run verification
run: ./gradlew verifyPlugin -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }}
run: ./gradlew verifyPlugin -PverifyIde=${{ matrix.ide }}
- name: Collect verification result
if: ${{ always() }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: pluginVerifier-result
name: pluginVerifier-result-${{ matrix.ide }}
path: ${{ github.workspace }}/build/reports/pluginVerifier

lint:
name: Lint
needs: [build]
runs-on: ubuntu-latest
steps:
- name: Checkout git repository
uses: actions/checkout@v6
- name: Set up Java
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: 21
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v5
with:
cache-read-only: false
- name: Clean corrupted Gradle transforms
run: rm -rf ~/.gradle/caches/*/transforms
- name: Run linter
run: ./gradlew ktlintCheck

test:
name: Run tests
needs: [build]
runs-on: ubuntu-latest
steps:
- name: Maximize Build Space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
large-packages: false
- name: Checkout git repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: 17
java-version: 21
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v5
with:
validate-wrappers: false
- name: Run linter
run: ./gradlew ktlintCheck
cache-read-only: false
- name: Clean corrupted Gradle transforms
run: rm -rf ~/.gradle/caches/*/transforms
- name: Run unit tests
run: ./gradlew test
- name: Verify 100% coverage
run: ./gradlew koverVerify
- name: Run UI tests
run: |
export DISPLAY=:99.0
Xvfb :99 -screen 0 1920x1080x24 &
./gradlew runIdeForUiTests &
echo "Waiting for IDE to start..."
timeout 180 bash -c 'until curl -s http://127.0.0.1:8082 > /dev/null 2>&1; do sleep 2; done' || { echo "IDE failed to start"; exit 1; }
echo "IDE is ready"
./gradlew uiTest
kill %1 %2 || true

releaseDraft:
name: Create release draft
if: github.event_name != 'pull_request'
needs: [build, test, verify]
needs: [build, lint, test, verify]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Maximize Build Space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
large-packages: false
- name: Checkout git repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Remove old release drafts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
url: https://plugins.jetbrains.com/plugin/20536-pyvenv-manage-2
steps:
- name: Checkout git repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{ github.event.release.tag_name }}
- name: Maximize Build Space
Expand All @@ -24,12 +24,12 @@ jobs:
tool-cache: false
large-packages: false
- name: Set up Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: 17
java-version: 21
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v5
- name: Extract plugin properties
id: properties
shell: bash
Expand Down
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.34.0
rev: 0.36.0
hooks:
- id: check-github-workflows
args: ["--verbose"]
- repo: https://github.com/rbubley/mirrors-prettier
rev: "v3.6.2"
rev: "v3.7.4"
hooks:
- id: prettier
additional_dependencies:
- prettier@3.3.3
- "@prettier/plugin-xml@3.4.1"
- prettier@3.6.2
- "@prettier/plugin-xml@3.4.2"
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

## [2.1.2] - 2025-10-23

- Fix python version display (#76) by @andrask in https://github.com/tox-dev/PyVenvManage/pull/77

## [2.1.0] - 2025-06-25

- Add support for showing python version in tree view by @andrask in https://github.com/tox-dev/PyVenvManage/pull/51
Expand Down Expand Up @@ -69,7 +73,8 @@

- Removed the usage of the deprecated PythonSdkType.getPythonExecutable API

[Unreleased]: https://github.com/pyvenvmanage/PyVenvManage/compare/v2.1.0...HEAD
[Unreleased]: https://github.com/pyvenvmanage/PyVenvManage/compare/v2.1.2...HEAD
[2.1.2]: https://github.com/pyvenvmanage/PyVenvManage/compare/v2.1.0...v2.1.2
[2.1.0]: https://github.com/pyvenvmanage/PyVenvManage/compare/v2.0.1...v2.1.0
[2.0.1]: https://github.com/pyvenvmanage/PyVenvManage/compare/v2.0.0...v2.0.1
[2.0.0]: https://github.com/pyvenvmanage/PyVenvManage/compare/v1.4.0...v2.0.0
Expand Down
107 changes: 107 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Contributing to PyVenvManage

## Development Setup

You'll need JDK 21 and Python 3.10+ (for creating test virtual environments). Build the plugin with:

```bash
./gradlew buildPlugin
```

## Testing

The project uses two complementary testing strategies: fast unit tests that mock IntelliJ platform dependencies, and
end-to-end UI tests that interact with a running IDE.

### Unit Tests

Unit tests cover business logic, action update logic, and error paths. They run quickly and don't require a running
IDE:

```bash
./gradlew test
```

### UI Tests

UI tests validate full user workflows by interacting with a running PyCharm instance via RemoteRobot. Start the IDE
with robot-server in one terminal:

```bash
./gradlew runIdeForUiTests
```

Wait for the IDE to fully start and the robot-server to be ready at http://localhost:8082, then run the tests in
another terminal:

```bash
./gradlew uiTest
```

### Coverage

Unit tests achieve full line coverage. The CI enforces this with `./gradlew test koverVerify`. UI tests are excluded
from coverage collection since they test end-to-end workflows already covered by unit tests.

To generate an HTML coverage report showing overall percentage, package breakdown, and line-by-line highlighting:

```bash
./gradlew test koverHtmlReport
open build/reports/kover/html/index.html
```

For per-test coverage analysis (which test covered which line), generate a binary report with
`./gradlew test koverBinaryReport`, then in IntelliJ IDEA go to **Run → Show Coverage Data**, click **+**, select
`build/kover/bin-reports/test.ic`, and click **Show selected**. Right-click any covered line and choose **Show Covering
Tests** to see which tests hit it.

## Code Quality

Check code style with `./gradlew ktlintCheck` or auto-fix issues with `./gradlew ktlintFormat`. Run all checks together
(lint, unit tests, coverage verification) with `./gradlew check`.

## Continuous Integration

The CI pipeline in `.github/workflows/check.yaml` builds the plugin, runs linting, executes unit tests with coverage
verification followed by UI tests, verifies the plugin against PyCharm Community and PyCharm Professional, and creates
a release draft on the main branch.

The test job runs unit tests with `koverVerify`, then starts Xvfb and the IDE with robot-server, and finally runs UI
tests for end-to-end validation.

## Making Code Changes

Before committing, run `./gradlew ktlintFormat` to fix style issues, then `./gradlew test koverVerify` to ensure tests
pass with full coverage. If you modified action classes, run UI tests for end-to-end validation by starting
`./gradlew runIdeForUiTests` in one terminal and `./gradlew uiTest` in another.

Follow conventional commit style: use `feat:` for new features, `fix:` for bug fixes, `refactor:` for code
refactoring, `test:` for test changes, `docs:` for documentation, and `chore:` for maintenance tasks.

## Troubleshooting

If UI tests timeout or fail to connect, ensure no other IDE instance is using port 8082. Kill any running IDE processes
with `pkill -f runIdeForUiTests`, delete old test projects with `rm -rf ~/projects/ui-test*`, then restart the IDE and
wait for full initialization before running tests.

If `koverVerify` fails due to coverage below 100%, generate the HTML report with `./gradlew koverHtmlReport` and open
`build/reports/kover/html/index.html` to see which lines are uncovered. Add unit tests for those code paths, or if the
code requires IntelliJ platform services that can't be mocked, add UI test coverage instead.

## Releasing

The plugin version is defined in `gradle.properties` as `pluginVersion`. To release, update the version in that file
and merge your PR to main. The CI automatically creates a draft release on GitHub with the version from
`gradle.properties`.

Review the draft release on the [Releases page](https://github.com/pyvenvmanage/PyVenvManage/releases) and edit the
release notes if needed. Click "Publish release" (not pre-release) to trigger the release workflow, which builds and
signs the plugin, publishes to [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/20536-pyvenv-manage-2),
uploads the plugin ZIP to the GitHub release, and creates a PR to update CHANGELOG.md. Merge that changelog PR after
the release workflow completes.

The release workflow requires repository secrets configured by maintainers: `PUBLISH_TOKEN` for JetBrains Marketplace
upload, and `CERTIFICATE_CHAIN`, `PRIVATE_KEY`, and `PRIVATE_KEY_PASSWORD` for plugin signing.

Follow [semantic versioning](https://semver.org/): increment MAJOR for breaking changes, MINOR for new backward
compatible features, and PATCH for backward compatible bug fixes.
Loading