build: rebase Nelo publishing overlay onto upstream 0.11.0 - #2
build: rebase Nelo publishing overlay onto upstream 0.11.0#2elliotmjackson wants to merge 2 commits into
Conversation
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Re-cuts the fork's build/publish tooling on top of upstream's 0.11.0 release
(was 0.9.91, 69 commits behind). The SDK source is still 100% upstream; we only
add build and publish tooling.
The fork exists because upstream does not publish com.github.growthbook:lib to
Maven Central and JitPack 403s in CI, so api-v2 cannot consume the SDK as a
binary. We rebuild upstream's tagged release unchanged and republish it to our
own GitHub Packages registry. That rationale now lives in the root build.gradle
header, where the next person to sync will actually read it.
Restructure the patch so it no longer touches lib/build.gradle. Upstream has
since grown its own `GitHubPackages` publishing repository, a release plugin
that drives the version from gradle.properties, and two new optional modules
(growthbook-cache-jcache, growthbook-cache-caffeine). Rather than re-patching
lib/build.gradle on every sync -- the file upstream changes most -- all
fork-specific config now lives in a root build.gradle, which upstream does not
have. The fork modifies exactly one upstream file: an additive .gitignore line.
Artifacts stay vendor-qualified as <upstream version>-nelo.<N>, preserving the
guarantee the previous pin gave us: a Nelo rebuild can never be mistaken for or
collide with a genuine upstream release, and we can re-cut (.2, .3) if a build
needs redoing. The base version now tracks upstream's gradle.properties instead
of being hardcoded, so it cannot go stale on the next sync, and the suffix is
appended unconditionally so no invocation can publish an unqualified version.
Re-cut with -PneloBuild=N; -Pversion=x.y.z is still honoured and still gets
qualified.
Also trim the group in the overlay. Upstream's gradle.properties sets
`group=com.github.growthbook ` with a trailing space; lib/build.gradle
reassigns the group so it escapes, but the cache modules inherit it and Gradle
refuses to publish them at all ("groupId (com.github.growthbook ) is not a
valid Maven identifier"). Trimming it makes `./gradlew publish` work for every
module.
Drop upstream's workflows again, now including release-please.yml, which would
otherwise open release PRs against the fork. The publish workflow takes the
re-cut number plus a choice of `:lib:publish` (default, what api-v2 consumes)
or `publish` for all three modules; deriving the version from the checked-out
tag means it always matches the code being built.
Gradle is still 7.5.1, so the flake's JDK 17 pin stands.
Verified on JDK 17 via the flake: `./gradlew build` green (full test suite);
publishToMavenLocal emits all three modules at 0.11.0-nelo.1 with the jar
manifest and POMs agreeing. The lib POM carries the same seven runtime deps as
before (annotations, commons-math3, guava, gson, okhttp, okhttp-sse,
slf4j-api) with Lombok correctly excluded. Version resolution checked for bare,
-PneloBuild, and -Pversion invocations.
NOTE: consumers get breaking transitive bumps -- okhttp 4.11.0 -> 5.4.0,
guava 31.0.1-jre -> 33.3.1-jre, gson 2.9.1 -> 2.12.1 -- and upstream moved
classes into growthbook.sdk.java.{model,callback}, which api-v2 imports.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Greptile SummaryThe PR rebases the Nelo publishing overlay onto upstream 0.11.0 and adds root-level Gradle, Nix, and manual GitHub Packages publishing configuration.
|
| Filename | Overview |
|---|---|
| build.gradle | Adds the fork overlay for version qualification, Maven group normalization, and GitHub Packages repository redirection; no blocking defect remains established. |
| .github/workflows/publish-github-packages.yml | Adds the manual Nix-based publication workflow, but its privileged steps depend on mutable action references. |
| flake.nix | Pins a JDK 17 development environment compatible with the bundled Gradle wrapper. |
| gradle.properties | Advances the upstream project version to 0.11.0 while retaining the group value normalized by the root overlay. |
Prompt To Fix All With AI
### Issue 1
.github/workflows/publish-github-packages.yml:36
**Mutable actions in publishing job**
The package-write workflow executes `DeterminateSystems/nix-installer-action@main` and `actions/checkout@v4`, so those references can later resolve to unreviewed code and make releases non-reproducible or expose the job token. Pin both actions to reviewed full commit SHAs.
**How this was verified:** Both mutable references execute before Gradle in a job granted `packages: write`.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "build: rebase Nelo publishing overlay on..." | Re-trigger Greptile
| - uses: actions/checkout@v4 | ||
|
|
||
| # Use exact JDK versions pinned with nix | ||
| - uses: DeterminateSystems/nix-installer-action@main |
There was a problem hiding this comment.
Mutable actions in publishing job
The package-write workflow executes DeterminateSystems/nix-installer-action@main and actions/checkout@v4, so those references can later resolve to unreviewed code and make releases non-reproducible or expose the job token. Pin both actions to reviewed full commit SHAs.
How this was verified: Both mutable references execute before Gradle in a job granted packages: write.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/publish-github-packages.yml
Line: 36
Comment:
**Mutable actions in publishing job**
The package-write workflow executes `DeterminateSystems/nix-installer-action@main` and `actions/checkout@v4`, so those references can later resolve to unreviewed code and make releases non-reproducible or expose the job token. Pin both actions to reviewed full commit SHAs.
**How this was verified:** Both mutable references execute before Gradle in a job granted `packages: write`.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Review only — do not merge.
mainis our mirror of upstream, so merging would move it off upstream. Based onmainpurely so the diff is small: the 0.11.0 release commit plus our overlay. This lands by repointing the fork's default branch tonelo-publish-0.11.0once api-v2 is migrated.What this is
Re-cuts the fork's build/publish tooling onto upstream's 0.11.0 (released 2026-08-19). We were on 0.9.91, 69 commits behind. SDK source is 100% upstream; we only add build and publish tooling.
Why the fork exists
Upstream doesn't publish
com.github.growthbook:libto Maven Central and JitPack 403s in CI, so api-v2 can't consume the SDK as a binary. We rebuild upstream's tagged release unchanged and republish it to our own GitHub Packages registry. That rationale now lives in the rootbuild.gradleheader, where whoever syncs next will read it — including the retirement condition: if upstream ever ships to Maven Central, this repo can go away. Their new POM metadata (license/developers/scm) suggests that's plausible.The drift fix
The old patch modified
lib/build.gradle— the file upstream churns most — which is why syncing hurt. Upstream has since grown its ownGitHubPackagespublishing repository, a release plugin driving the version fromgradle.properties, and two new optional modules (growthbook-cache-jcache,growthbook-cache-caffeine).So all fork-specific config now lives in a root
build.gradle, which upstream doesn't have. The fork modifies exactly one upstream file: an additive.gitignoreline. Future syncs should be near-fast-forwards.Versioning
Artifacts stay vendor-qualified as
<upstream version>-nelo.<N>, preserving what the old pin gave us: a Nelo rebuild can't be mistaken for or collide with a genuine upstream release, and we can re-cut (.2,.3). Two improvements: the base version now tracks upstream'sgradle.propertiesinstead of being hardcoded, so it can't go stale on the next sync; and the suffix is appended unconditionally, so no invocation can publish an unqualified version. Re-cut with-PneloBuild=N;-Pversion=x.y.zstill works and still gets qualified.-PpublishVersionis gone in favour of upstream's ownversionproperty. Nothing referenced it, including api-v2.Upstream bug fixed in the overlay
gradle.propertiessetsgroup=com.github.growthbookwith a trailing space.lib/build.gradlereassigns the group so it escapes, but the cache modules inherit it and Gradle refuses to publish them outright:The overlay trims it, so
./gradlew publishworks for every module.Verification
On JDK 17 via the flake (Gradle is still 7.5.1, so the JDK 17 pin stands):
./gradlew buildgreen, full test suitepublishToMavenLocalemits all three modules at0.11.0-nelo.1, jar manifest and POMs agreeinglibPOM carries the same seven runtime deps as before (annotations, commons-math3, guava, gson, okhttp, okhttp-sse, slf4j-api), Lombok correctly excluded-PneloBuild=7,-Pversion=0.11.0-nelo.4, and-Pversion=9.9.9(that last yields9.9.9-nelo.1— unqualified publishing is impossible)Blocks api-v2 — breaking changes
api-v2 pins
0.9.91-nelo.1and will not compile against 0.11.0. Publishing0.11.0-nelo.1is safe meanwhile; nothing consumes it until the pin moves.Upstream moved classes into subpackages — 7 of api-v2's 8 imports:
growthbook.sdk.java.Experiment…java.model.Experimentgrowthbook.sdk.java.ExperimentResult…java.model.ExperimentResultgrowthbook.sdk.java.FeatureResult…java.model.FeatureResultgrowthbook.sdk.java.FeatureResultSource…java.model.FeatureResultSourcegrowthbook.sdk.java.GBContext…java.model.GBContextgrowthbook.sdk.java.TrackingCallback…java.callback.TrackingCallbackgrowthbook.sdk.java.FeatureUsageCallback…java.callback.FeatureUsageCallbackgrowthbook.sdk.java.GrowthBookAlso
GBContext.featureschanged type fromJsonObjecttoMap<String, Feature<?>>, soGrowthBookClientV2.getClient's.features(features)needs the parsed map.Transitive bumps for consumers: okhttp 4.11.0 → 5.4.0 (upstream's own
fix!), guava 31.0.1-jre → 33.3.1-jre, gson 2.9.1 → 2.12.1.Supersedes #1
Draft PR #1 (
perf/cache-parsed-feature-definitions) should be closed as superseded, not forward-ported. Upstream now parses features once into avolatile Map<String, Feature<?>>inGBFeaturesRepositoryandFeatureEvaluatorreads pre-parsed objects — there's noGson.fromJsonin the hot path at all. Same win, at the repository layer, without static mutable state or the reference-identity trick.Caveat: realising that win depends on the
GBContext.featuresmigration above. HavecacheManagerhold the parsedMaprather than the rawJsonObject, so the parse happens once per refresh. Parsing insidegetClientinstead would reintroduce exactly the per-request cost #1 removed.🤖 Generated with Claude Code