Diffinery

codician/diffinerypublic

Open-source, agent-first GitHub and GitHub Actions alternative that runs on your own Cloudflare account: git hosting, pull requests, code review and drop-in GitHub Actions YAML on Workers, Durable Objects, R2 and Containers.

53 lines · 2.9 KBRaw History
1# Diffinery plugin for JetBrains IDEs
2
3Adds **Diffinery** to **Get from Version Control** in IntelliJ IDEA, PyCharm, WebStorm, GoLand and the other
4JetBrains 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
6the 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
9It's plain Java (no Kotlin), against the platform's stable API only: `./gradlew verifyPlugin` runs JetBrains' Plugin
10Verifier against IntelliJ IDEA 2024.3, 2025.2 and the version the plugin builds with, and fails on internal API use.
11
12## Build
13
14Gradle 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
28through `scripts/plugin.mjs`, which refuses a zip whose version isn't `pluginVersion` in `gradle.properties` or that
29was built from other sources than `src/main` now (the build puts a fingerprint of them in the jar). So after changing
30the plugin, run `./gradlew dist` and commit the new zip with the change; the zip is byte-for-byte reproducible.
31
32The 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
421. Bump `pluginVersion` in `gradle.properties` and add a `CHANGELOG.md` entry.
432. `./gradlew test verifyPlugin dist`, then run the real-IDE check (below).
443. 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
49Robot server: it installs the plugin from the Worker's plugin repository in **Settings → Plugins**, signs in through
50the consent page in Chromium, lists, searches and clones a private repository, shares a project, signs out, and signs
51in with a token. See the comment at its top for how to run it. `DOCS=1` retakes the pictures in the guide.
52
53Publishing on the JetBrains Marketplace waits until Diffinery is public: see [PUBLISHING.md](PUBLISHING.md).