|
| 1 | +# Contributing to PyVenvManage |
| 2 | + |
| 3 | +## Development Setup |
| 4 | + |
| 5 | +You'll need JDK 21 and Python 3.10+ (for creating test virtual environments). Build the plugin with: |
| 6 | + |
| 7 | +```bash |
| 8 | +./gradlew buildPlugin |
| 9 | +``` |
| 10 | + |
| 11 | +## Testing |
| 12 | + |
| 13 | +The project uses two complementary testing strategies: fast unit tests that mock IntelliJ platform dependencies, and |
| 14 | +end-to-end UI tests that interact with a running IDE. |
| 15 | + |
| 16 | +### Unit Tests |
| 17 | + |
| 18 | +Unit tests cover business logic, action update logic, and error paths. They run quickly and don't require a running |
| 19 | +IDE: |
| 20 | + |
| 21 | +```bash |
| 22 | +./gradlew test |
| 23 | +``` |
| 24 | + |
| 25 | +### UI Tests |
| 26 | + |
| 27 | +UI tests validate full user workflows by interacting with a running PyCharm instance via RemoteRobot. Start the IDE |
| 28 | +with robot-server in one terminal: |
| 29 | + |
| 30 | +```bash |
| 31 | +./gradlew runIdeForUiTests |
| 32 | +``` |
| 33 | + |
| 34 | +Wait for the IDE to fully start and the robot-server to be ready at http://localhost:8082, then run the tests in |
| 35 | +another terminal: |
| 36 | + |
| 37 | +```bash |
| 38 | +./gradlew uiTest |
| 39 | +``` |
| 40 | + |
| 41 | +### Coverage |
| 42 | + |
| 43 | +Unit tests achieve full line coverage. The CI enforces this with `./gradlew test koverVerify`. UI tests are excluded |
| 44 | +from coverage collection since they test end-to-end workflows already covered by unit tests. |
| 45 | + |
| 46 | +To generate an HTML coverage report showing overall percentage, package breakdown, and line-by-line highlighting: |
| 47 | + |
| 48 | +```bash |
| 49 | +./gradlew test koverHtmlReport |
| 50 | +open build/reports/kover/html/index.html |
| 51 | +``` |
| 52 | + |
| 53 | +For per-test coverage analysis (which test covered which line), generate a binary report with |
| 54 | +`./gradlew test koverBinaryReport`, then in IntelliJ IDEA go to **Run → Show Coverage Data**, click **+**, select |
| 55 | +`build/kover/bin-reports/test.ic`, and click **Show selected**. Right-click any covered line and choose **Show Covering |
| 56 | +Tests** to see which tests hit it. |
| 57 | + |
| 58 | +## Code Quality |
| 59 | + |
| 60 | +Check code style with `./gradlew ktlintCheck` or auto-fix issues with `./gradlew ktlintFormat`. Run all checks together |
| 61 | +(lint, unit tests, coverage verification) with `./gradlew check`. |
| 62 | + |
| 63 | +## Continuous Integration |
| 64 | + |
| 65 | +The CI pipeline in `.github/workflows/check.yaml` builds the plugin, runs linting, executes unit tests with coverage |
| 66 | +verification followed by UI tests, verifies the plugin against PyCharm Community and PyCharm Professional, and creates |
| 67 | +a release draft on the main branch. |
| 68 | + |
| 69 | +The test job runs unit tests with `koverVerify`, then starts Xvfb and the IDE with robot-server, and finally runs UI |
| 70 | +tests for end-to-end validation. |
| 71 | + |
| 72 | +## Making Code Changes |
| 73 | + |
| 74 | +Before committing, run `./gradlew ktlintFormat` to fix style issues, then `./gradlew test koverVerify` to ensure tests |
| 75 | +pass with full coverage. If you modified action classes, run UI tests for end-to-end validation by starting |
| 76 | +`./gradlew runIdeForUiTests` in one terminal and `./gradlew uiTest` in another. |
| 77 | + |
| 78 | +Follow conventional commit style: use `feat:` for new features, `fix:` for bug fixes, `refactor:` for code |
| 79 | +refactoring, `test:` for test changes, `docs:` for documentation, and `chore:` for maintenance tasks. |
| 80 | + |
| 81 | +## Troubleshooting |
| 82 | + |
| 83 | +If UI tests timeout or fail to connect, ensure no other IDE instance is using port 8082. Kill any running IDE processes |
| 84 | +with `pkill -f runIdeForUiTests`, delete old test projects with `rm -rf ~/projects/ui-test*`, then restart the IDE and |
| 85 | +wait for full initialization before running tests. |
| 86 | + |
| 87 | +If `koverVerify` fails due to coverage below 100%, generate the HTML report with `./gradlew koverHtmlReport` and open |
| 88 | +`build/reports/kover/html/index.html` to see which lines are uncovered. Add unit tests for those code paths, or if the |
| 89 | +code requires IntelliJ platform services that can't be mocked, add UI test coverage instead. |
| 90 | + |
| 91 | +## Releasing |
| 92 | + |
| 93 | +The plugin version is defined in `gradle.properties` as `pluginVersion`. To release, update the version in that file |
| 94 | +and merge your PR to main. The CI automatically creates a draft release on GitHub with the version from |
| 95 | +`gradle.properties`. |
| 96 | + |
| 97 | +Review the draft release on the [Releases page](https://github.com/pyvenvmanage/PyVenvManage/releases) and edit the |
| 98 | +release notes if needed. Click "Publish release" (not pre-release) to trigger the release workflow, which builds and |
| 99 | +signs the plugin, publishes to [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/20536-pyvenv-manage-2), |
| 100 | +uploads the plugin ZIP to the GitHub release, and creates a PR to update CHANGELOG.md. Merge that changelog PR after |
| 101 | +the release workflow completes. |
| 102 | + |
| 103 | +The release workflow requires repository secrets configured by maintainers: `PUBLISH_TOKEN` for JetBrains Marketplace |
| 104 | +upload, and `CERTIFICATE_CHAIN`, `PRIVATE_KEY`, and `PRIVATE_KEY_PASSWORD` for plugin signing. |
| 105 | + |
| 106 | +Follow [semantic versioning](https://semver.org/): increment MAJOR for breaking changes, MINOR for new backward |
| 107 | +compatible features, and PATCH for backward compatible bug fixes. |
0 commit comments