| 1 | # Diffinery plugin for JetBrains IDEs |
| 2 | |
| 3 | Adds **Diffinery** to **Get from Version Control** in IntelliJ IDEA, PyCharm, WebStorm, GoLand and the other |
| 4 | JetBrains IDEs (2024.3 and later), with the browser sign-in Diffinery's other apps use (OAuth with PKCE on a |
| 5 | `127.0.0.1` redirect, client `/oauth/clients/jetbrains.json`). Git asks the plugin for the password when it talks to |
| 6 | the server, and **Git → Share Project on Diffinery…** publishes a local repository. The guide people read is |
| 7 | [Clone in JetBrains IDEs](https://diffinery.com/docs/repositories/clone-in-jetbrains-ides). |
| 8 | |
| 9 | It's plain Java (no Kotlin), against the platform's stable API only: `./gradlew verifyPlugin` runs JetBrains' Plugin |
| 10 | Verifier against IntelliJ IDEA 2024.3, 2025.2 and the version the plugin builds with, and fails on internal API use. |
| 11 | |
| 12 | ## Build |
| 13 | |
| 14 | Gradle 9 through the wrapper, with a JDK 21 or later (the IDE's own JetBrains Runtime works): |
| 15 | |
| 16 | ```sh |
| 17 | ./gradlew dist # builds and copies the plugin to dist/diffinery-jetbrains-<version>.zip |
| 18 | ./gradlew test # unit tests |
| 19 | ./gradlew verifyPlugin |
| 20 | ``` |
| 21 | |
| 22 | `-PideaHome=/path/to/idea` builds against an IDE already on disk instead of downloading IntelliJ IDEA, and |
| 23 | `-Porg.gradle.java.installations.paths=/path/to/idea/jbr` uses its runtime as the JDK. |
| 24 | |
| 25 | ## How diffinery.com serves it |
| 26 | |
| 27 | `dist/` is checked in, because Diffinery's server build has no JDK. `apps/diffinery/scripts/build-docs.mjs` reads it |
| 28 | through `scripts/plugin.mjs`, which refuses a zip whose version isn't `pluginVersion` in `gradle.properties` or that |
| 29 | was built from other sources than `src/main` now (the build puts a fingerprint of them in the jar). So after changing |
| 30 | the plugin, run `./gradlew dist` and commit the new zip with the change; the zip is byte-for-byte reproducible. |
| 31 | |
| 32 | The Worker serves: |
| 33 | |
| 34 | | Path | What | |
| 35 | | --- | --- | |
| 36 | | `/-/jetbrains/updatePlugins.xml` | The custom plugin repository the IDEs install and update from | |
| 37 | | `/-/jetbrains/diffinery-jetbrains-<version>.zip` | That version | |
| 38 | | `/-/jetbrains/diffinery-jetbrains.zip` | The current version, for **Install Plugin from Disk…** | |
| 39 | |
| 40 | ## Release |
| 41 | |
| 42 | 1. Bump `pluginVersion` in `gradle.properties` and add a `CHANGELOG.md` entry. |
| 43 | 2. `./gradlew test verifyPlugin dist`, then run the real-IDE check (below). |
| 44 | 3. Commit with the new `dist/` zip. Once deployed, IDEs with the plugin repository offer the update. |
| 45 | |
| 46 | ## Real-IDE check |
| 47 | |
| 48 | `apps/diffinery/test/e2e/jetbrains-smoke.mjs` drives IntelliJ IDEA against a local Worker through JetBrains' Remote |
| 49 | Robot server: it installs the plugin from the Worker's plugin repository in **Settings → Plugins**, signs in through |
| 50 | the consent page in Chromium, lists, searches and clones a private repository, shares a project, signs out, and signs |
| 51 | in with a token. See the comment at its top for how to run it. `DOCS=1` retakes the pictures in the guide. |
| 52 | |
| 53 | For listing the plugin on the JetBrains Marketplace, see [PUBLISHING.md](PUBLISHING.md). |