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.

62 lines · 3.6 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## Self-hosted Diffinery
13
14The server is `server` in the IDE's `diffinery.xml` (`Accounts.setServer`), `https://diffinery.com` by default. People
15change it from the Diffinery page of **Get from Version Control**: **Use another server…** under the sign-in button
16(`SignInDialogs.chooseServer`, which checks that `/-/jetbrains/updatePlugins.xml` answers there first), or one click on
17**Use git.example.com** when the IDE's plugin repositories include a Diffinery's `updatePlugins.xml`
18(`Util.pluginRepositoryServers`). **Share Project on Diffinery…** offers the same choice before signing in, and
19**Settings → Version Control → Diffinery → Server** remains. Changing the server signs out of the old one.
20
21## Build
22
23Gradle 9 through the wrapper, with a JDK 21 or later (the IDE's own JetBrains Runtime works):
24
25```sh
26./gradlew dist # builds and copies the plugin to dist/diffinery-jetbrains-<version>.zip
27./gradlew test # unit tests
28./gradlew verifyPlugin
29```
30
31`-PideaHome=/path/to/idea` builds against an IDE already on disk instead of downloading IntelliJ IDEA, and
32`-Porg.gradle.java.installations.paths=/path/to/idea/jbr` uses its runtime as the JDK.
33
34## How diffinery.com serves it
35
36`dist/` is checked in, because Diffinery's server build has no JDK. `apps/diffinery/scripts/build-docs.mjs` reads it
37through `scripts/plugin.mjs`, which refuses a zip whose version isn't `pluginVersion` in `gradle.properties` or that
38was built from other sources than `src/main` now (the build puts a fingerprint of them in the jar). So after changing
39the plugin, run `./gradlew dist` and commit the new zip with the change; the zip is byte-for-byte reproducible.
40
41The Worker serves:
42
43| Path | What |
44| --- | --- |
45| `/-/jetbrains/updatePlugins.xml` | The custom plugin repository the IDEs install and update from |
46| `/-/jetbrains/diffinery-jetbrains-<version>.zip` | That version |
47| `/-/jetbrains/diffinery-jetbrains.zip` | The current version, for **Install Plugin from Disk…** |
48
49## Release
50
511. Bump `pluginVersion` in `gradle.properties` and add a `CHANGELOG.md` entry.
522. `./gradlew test verifyPlugin dist`, then run the real-IDE check (below).
533. Commit with the new `dist/` zip. Once deployed, IDEs with the plugin repository offer the update.
54
55## Real-IDE check
56
57`apps/diffinery/test/e2e/jetbrains-smoke.mjs` drives IntelliJ IDEA against a local Worker through JetBrains' Remote
58Robot server: it installs the plugin from the Worker's plugin repository in **Settings → Plugins**, signs in through
59the consent page in Chromium, lists, searches and clones a private repository, shares a project, signs out, and signs
60in with a token. See the comment at its top for how to run it. `DOCS=1` retakes the pictures in the guide.
61
62For listing the plugin on the JetBrains Marketplace, see [PUBLISHING.md](PUBLISHING.md).