Skip to content

ci: collapse 5 sequential gradle invocations into 1#7575

Merged
karianna merged 9 commits into
PCGen:masterfrom
Vest:ci_optimize
Jun 3, 2026
Merged

ci: collapse 5 sequential gradle invocations into 1#7575
karianna merged 9 commits into
PCGen:masterfrom
Vest:ci_optimize

Conversation

@Vest
Copy link
Copy Markdown
Contributor

@Vest Vest commented Jun 2, 2026

Summary

Stacks on top of #7568 — please review and merge that PR first.

Each ./gradlew invocation pays ~5–10s of configuration overhead and ~2–3s of daemon startup, plus a fresh task-graph build. The release workflows ran 5 of them in series:

Step Notes
./gradlew clean build clean does nothing on a fresh CI runner — build/ doesn't exist yet
./gradlew compileSlowtest datatest pfinttest data/integration tests
./gradlew allReports = checkstyleMain + pmdMain + spotbugsMain, all already executed by build (verified in the previous run's log: > Task :spotbugsMain ran during build, then again as UP-TO-DATE here)
./gradlew buildDist already a transitive dep of pcgenRelease
./gradlew pcgenRelease umbrella

Collapse to a single invocation, drop the redundant clean and allReports, and drop buildDist. Also set fail-fast: false on the matrix so a transient runner preemption (seen on the partner-supplied ubuntu-24.04-arm image — see #7568 verification run) doesn't kill the other three OS jobs.

Measured impact

Identical input (same fix_packaging HEAD with PR #7568 applied), back-to-back runs on Vest/pcgen with warm caches:

OS Baseline (5 invocations) This PR (1 invocation) Saving % faster
ubuntu-24.04-arm 10m50s 9m56s -54s 8%
ubuntu-latest 13m21s 11m40s -1m41s 13%
macOS 16m04s 13m16s -2m48s 17%
windows 25m04s 18m33s -6m31s 26%
Wall-clock ~25 min ~19 min -6 min 24%

Windows benefited the most because each gradlew startup is dominated by JVM warmup + slower disk I/O on that runner image.

Test plan

  • All 4 OS matrix entries green on the optimized run (Vest/pcgen run 26779067448).
  • Same 15 release artifacts produced as the baseline run — installers (.dmg, .exe), portable zips, jlinkZip images, sources jar, SHA256 manifests.
  • Failure semantics preserved: a failed task still aborts the build (no --continue flag).

Vest added 7 commits May 31, 2026 22:04
- NameList/RuleSet: precompute a cumulative-weight array at
  construction so pick() is O(log n) via binarySearch instead of two
  linear passes. Zero-weight entries are filtered into a parallel
  positives array, which keeps binarySearch correct when duplicates
  would otherwise let it land on a zero-weight index. Both records
  become final classes since cached state can't live on a record.
- DataValue: drop the hand-rolled DataSubValue linked list in favour
  of a lazily-allocated LinkedHashMap. putIfAbsent preserves the
  first-write-wins semantics the old recursive get() relied on.
- NameGenLazyData.gendersForRuleset: read directly from the ruleset's
  RuleSetMeta.categoryTitles() instead of scanning every Sex: bucket.
- NameGenerator.assemble: defer meaning/pronunciation StringBuilder
  allocation until a part actually overrides one, seeding from the
  name built so far. Avoids two builders' worth of churn on the
  common path where no part has sub-values.
The jlink plugin's `additive = true` mode emits both the auto-derived
and the user-listed `requires` blocks without dedup. asm 9.10 (pulled
in by jlink 4.0.1) parses Java 25 class files that 9.9.1 silently
skipped, growing the auto-derived set enough to collide with our
explicit list and breaking `createMergedModule` with duplicate-requires
errors. Bump to 4.0.2 and keep only the modules the scanner can't
infer on its own.
Brief description of each overload's contract (direct Element children,
optional tag-name filter) so future readers don't have to re-derive it
from the stream pipeline.
Drop the Os.FAMILY_MAC || Os.FAMILY_UNIX predicate that excluded
Windows from fullJpackage. The carve-out dates from when Windows
shipped via NSIS (`buildNsis`); that path was retired in be48763
but the release-side hookup to invoke jpackage on Windows was never
added, leaving Windows release artifacts as the runtime zip only.
fullJpackage was wired to assembleJpackageImage (Mac: patchMacJpackage),
not the jpackage installer task — so each release shipped only the
jlinkZip runtime image, never a .dmg/.deb/.exe. Make jpackage depend on
the data-bundling step so it packages an image that already contains
data/plugins/preview/outputsheets, then point fullJpackage at jpackage.

Pin one installerType per OS (dmg / deb / exe) — without it jpackage
emits both formats per platform, doubling build time and (on Linux)
requiring rpmbuild that isn't installed on the Ubuntu runner.
Add --win-shortcut / --win-menu so the .exe creates Start-menu and
desktop entries; the existing --linux-shortcut and Mac-specific opts
were already in place. WiX 3.14 needed for the .exe is preinstalled
on the windows-latest runner.
Same self-contained app the installer ships, but as an unzip-and-run
archive — useful for users who don't want to run an installer (USB sticks,
locked-down environments, etc.). Per-platform: pcgen-<version>-<os>-<arch>-portable.zip.

The zip captures whatever fullJpackage left in build/jpackage/PcGen[.app],
so it includes data/plugins/preview/outputsheets and (on Mac) the patched
Info.plist + MacDirLauncher.
jpackage names Debian packages pcgen_<version>_<arch>.deb (underscore),
which the existing pcgen-*.* glob (hyphen) misses. Linux release runs
were uploading everything except the .deb. Add a second include for
the underscore form. .rpm uses pcgen-<version>.<arch>.rpm so it was
already covered.
@Vest
Copy link
Copy Markdown
Contributor Author

Vest commented Jun 2, 2026

@karianna , please merge #7568 first, you can squash it! The same can be done here.
after this commit, you can release artifacts.

Vest added 2 commits June 2, 2026 18:10
The image-*.zip artifacts (output of jlinkZip) are a JVM runtime image,
not a runnable PcGen — no launcher, no /data, /plugins, /preview, or
/outputsheets. Users who tried to run them got the "missing required
folders" dialog. Now that fullJpackage produces real installers and a
portable zip with the same .app the installer ships, image-*.zip is
just a confusing leftover. Drop it from the release upload (autobuild
keeps it via buildDist).

The SHA256-digests-*.txt files are also redundant: GitHub computes a
SHA-256 for every release asset automatically and exposes it via the
API. Anyone verifying integrity can shasum the file locally.
Each ./gradlew invocation pays ~5-10s of configuration overhead and
~2-3s of daemon startup, plus a fresh task-graph build. The release
workflows ran 5 of them in series:

  ./gradlew clean build           # `clean` does nothing on a fresh runner
  ./gradlew compileSlowtest datatest pfinttest
  ./gradlew allReports            # = checkstyleMain + pmdMain + spotbugsMain,
                                  #   all already executed by `build`
  ./gradlew buildDist             # already a transitive dep of pcgenRelease
  ./gradlew pcgenRelease

Collapse to one invocation, drop the redundant `clean` and `allReports`,
and drop `buildDist` (which pcgenRelease already depends on transitively
via assembleArtifacts → jlinkZip).

Also set fail-fast: false on the matrix so a transient runner preemption
(seen on the partner-supplied ubuntu-24.04-arm image) doesn't kill the
other three OS jobs.
@Vest Vest force-pushed the ci_optimize branch 2 times, most recently from 3661257 to 03fcb9f Compare June 2, 2026 16:16
@karianna karianna merged commit 561a8b7 into PCGen:master Jun 3, 2026
5 checks passed
@Vest Vest deleted the ci_optimize branch June 3, 2026 04:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants