Skip to content

Commit 967e108

Browse files
authored
Optimize build and CI pipeline, remove redundant or dead code (#7560)
* Enable parallel forks for test and itest tasks Set maxParallelForks to half the available cores for utest and itest. Slowtest and integration test variants intentionally keep the global default of 1 since they share data files and call Main.main() per test. * Refactor build.gradle: update converterJar task and improve parallel test forks calculation Signed-off-by: Vest <Vest@users.noreply.github.com> * Remove commented-out repository declarations Drop the dead Ivy repo for PCGen Base/Formula sourceforge jars (we now get those from project dependencies) and the freehep maven repo, which was already disabled and never re-enabled. * Remove unused localOnly property and stale version comment The localOnly property is not referenced from any Gradle script, source, or properties file. The commented-out 6.09.06-SNAPSHOT version is obsolete history. * Remove calls to undefined commitFile() in release tasks The updateVersionRelease and updateVersionToNext tasks called a commitFile() helper that was never defined anywhere in the build, so they would have failed at runtime. Drop the broken calls and leave a comment that the version change should be committed manually. * Remove dead testZip task and unused jreImage copySpec testZip was registered but never depended on by any other task or workflow, and jreImage was defined but never applied via copySpec.with. Both are leftovers from the pre-jpackage distribution layout. * Remove dead NSIS installer scaffolding from release.gradle The NSIS-based Windows installer was retired in favor of jpackage, but the supporting copySpecs (baseLibs, lib32, lib64, pdfLibs, basePlugins, gmgenPlugins, nonPdfOutput, pdfOutput, baseData, optionalData), the nsisBaseFolder/nsisOptionFolder paths, the installerVerNum derivation, and the genDataList task that wrote installers/win-installer/data.nsh were left behind. None of them are referenced anywhere outside release.gradle. Drop them along with the now-unused FixCrLfFilter and DefaultCopySpec imports. * Remove dead programDistsImage launch4j copySpec programDistsImage copied build/launch4j/pcgen.exe, but the launch4j plugin was removed in favor of jpackage and that directory is never produced. The copySpec contributed zero files to programZip and installDist, so drop both the copySpec and its applications. * Scope TestFX/Monocle JVM args to the test task The TestFX/Monocle-specific flags (testfx.* sysprops, prism.order=sw, the four --add-exports/--add-opens for monocle, prism.verbose) were applied to every Test task via configureEach, even though only the unit test source set (code/src/utest) contains TestFX-based tests. itest and slowtest don't use TestFX and don't need them. Move the TestFX-specific args onto the test task itself. Keep the JavaFX module loading args (--module-path, --add-modules, native access) on configureEach because the production code still requires the JavaFX modules to be on the path for class loading. Also drop -Dprism.verbose=true so test output stays quieter. * Promote testcommon to a dedicated source set code/src/testcommon was listed as a srcDir in three source sets (test, itest, slowtest), so its 22 files were compiled three times. Extract it into its own testcommon source set; have test/itest/slowtest consume its compiled output via classpath instead. Wire testcommonImplementation/RuntimeOnly/CompileOnly to extend the matching test configurations so testcommon picks up the same JUnit and test-helper dependencies. * Use JUnit BOM and align platform/jupiter versions Previously each junit-platform/junit-jupiter coordinate listed its own version, with junit-platform-runner pinned to a stale 1.14.4 while the others moved to 6.0.3. junit-platform-runner is for legacy @RunWith(JUnitPlatform.class) interop and isn't used anywhere, so drop it. Adopt org.junit:junit-bom:6.0.3 to source the version once for all junit-platform / junit-jupiter modules. About 870 tests still use the JUnit 4 API. They were compiling before because junit-platform-runner pulled junit:junit transitively. Add an explicit junit:junit:4.13.2 declaration plus junit-vintage-engine so those tests keep compiling and running on the JUnit Platform. * Loop-generate per-game inttest tasks The five per-game inttest variants (sfinttest, pfinttest, rsrdinttest, srdinttest, msrdinttest) were copy-pasted with only the include pattern differing. Replace them with a map-driven loop. Task names are stable (CI references pfinttest), and the resolved configuration is identical. Pre-existing: the include pattern uses a "slowtest/" path prefix that doesn't exist in compiled classes, so these tasks have always reported NO-SOURCE. Behavior is preserved here; fixing the pattern is a separate change. * Bump CodeQL action versions to v3 and checkout to v4 github/codeql-action v2 has been deprecated; runs emit warnings and will fail once GitHub retires the v2 endpoints. v3 is a drop-in upgrade for init, autobuild, and analyze. actions/checkout is bumped to v4 to match the other workflows in this repo. * Align release workflow cache restore-keys with primary key The primary cache key was prefixed with \${{ runner.os }} (e.g. Linux, macOS, Windows) while the restore-keys used \${{ matrix.os }} (e.g. ubuntu-latest, macos-latest). Restore-keys must be a prefix of the primary key to ever match, so the fallback restore was dead code and every run cold-started build/jre and build/libs. * Rename tag-triggered release workflow to disambiguate from manual Both gradle-release.yml and gradle-release-manual.yml declared the same workflow name "Create Release with Manual Tag", which made them indistinguishable in the Actions UI. The manual one creates a tag on demand; this one fires when a tag is pushed (or dispatched against an existing tag). Renaming this one to reflect that. * Drop redundant 'test' from PR test workflow ./gradlew build already runs the test task via the standard Java lifecycle (build → check → test). The follow-up step then re-invoked test alongside itest/datatest/slowtest. The re-invocation is a no-op under up-to-date checks, but it still spins up a fresh Gradle daemon step and clutters the run summary. Drop it and rename the step to reflect what it actually adds. * Drop default and harmful Gradle cache flags from PR workflow cache-disabled: false and cache-read-only: false are setup-gradle's defaults. cache-overwrite-existing: true is actively harmful for PR workflows: it forces every PR run to overwrite the shared Linux-runner Gradle cache, so concurrent PRs trash each other's warm caches. The intended behavior on PRs is to read the cache populated by master and write back only if the run is on the default branch — which is exactly what setup-gradle does by default. * Split release pipeline into stages and drop redundant tasks The compound was: ./gradlew clean build copyToOutput test compileSlowtest \ datatest pfinttest allReports buildDist prepareRelease pcgenRelease Several entries were already in the dependency graph of pcgenRelease: - pcgenRelease dependsOn prepareRelease, assembleArtifacts, checksum - prepareRelease dependsOn build - assembleArtifacts dependsOn build, jlinkZip, sourcesJar - sourcesJar dependsOn classes, copyToOutput, distTar, distZip, startScripts - build (Java lifecycle) dependsOn check -> test So build, test, copyToOutput, and prepareRelease were all redundant when pcgenRelease was invoked at the end of the same command. The fact that they ran first only meant Gradle short-circuited later invocations under up-to-date checks, which still costs daemon time and obscures the failure point if any single step fails. The split makes each stage's purpose explicit and gives the GitHub Actions UI a real timeline of where time is being spent. * Collapse triple-overlapping CI cache to setup-gradle only Each workflow stacked three caches: 1. actions/setup-java cache: gradle -> caches ~/.gradle/{caches,wrapper} 2. gradle/actions/setup-gradle@v4 -> caches ~/.gradle/{caches,wrapper,configuration-cache} 3. actions/cache@v4 for build/jre + build/libs Layers 1 and 2 cover the same paths; setup-gradle is the canonical choice and adds Gradle-aware features (configuration cache, dep reports, write-once-on-default-branch semantics). Layer 3 caches *build outputs* across runs, which: - is unsafe (stale jars from a different commit can leak in) - is unused (build/jre is no longer produced; the 'jre' task is a no-op aggregator that just dependsOn downloadJavaFXMods) - duplicates Gradle's own up-to-date checks for build/libs Drop layers 1 and 3, keep setup-gradle. Release workflows keep their cache-overwrite-existing: true since they run from tagged commits on master and should refresh the shared cache. * Attach release artifacts to GitHub Release Both release workflows produced artifacts in build/release/ but only uploaded a subset of them as workflow artifacts (and only for macOS), leaving the actual GitHub Release empty. The original intent was sketched out in commented-out softprops/action-gh-release blocks at the bottom of gradle-release.yml. This wires the release.gradle output (sources jar, image zips, jpackage installers) directly to the GitHub Release using the same tag the create_release job used. softprops/action-gh-release is idempotent against an existing release with the same tag_name, so each matrix OS appends its own platform-specific artifacts. Workflow artifacts are kept too, so debugging a failed release run still works without having to publish. * Update README to clarify test suite commands and remove redundancy Signed-off-by: Vest <Vest@users.noreply.github.com> * Cache downloaded JDK and JavaFX archives in release workflows The release pipeline downloads ~1.5 GB of cross-platform JDK and JavaFX jmod archives on every CI run (5 platforms, on each of 4 OS runners). The downloads are pinned by javaVersion in gradle.properties and the URL templates in build.gradle, so they are perfectly cacheable between runs. Add an actions/cache@v4 step keyed on the hash of those two files, so the cache invalidates exactly when the JDK or JavaFX version changes and never serves stale archives otherwise. Only the archive files are cached (.tar.gz / .zip) -- extracted JDK directories are 5x larger and Gradle's extractJdk_* tasks have proper up-to-date checks, so we let extraction run locally each time. Scoped to the two release workflows; the PR test workflow does not run jpackage and never populates jdks/. --------- Signed-off-by: Vest <Vest@users.noreply.github.com>
1 parent 0da501f commit 967e108

9 files changed

Lines changed: 154 additions & 469 deletions

File tree

.github/workflows/codeql-analysis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ jobs:
3939

4040
steps:
4141
- name: Checkout repository
42-
uses: actions/checkout@v3
42+
uses: actions/checkout@v4
4343

4444
# Initializes the CodeQL tools for scanning.
4545
- name: Initialize CodeQL
46-
uses: github/codeql-action/init@v2
46+
uses: github/codeql-action/init@v3
4747
with:
4848
languages: ${{ matrix.language }}
4949
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -54,7 +54,7 @@ jobs:
5454
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
5555
# If this step fails, then you should remove it and run the build manually (see below)
5656
- name: Autobuild
57-
uses: github/codeql-action/autobuild@v2
57+
uses: github/codeql-action/autobuild@v3
5858

5959
# ℹ️ Command-line programs to run using the OS shell.
6060
# 📚 https://git.io/JvXDl
@@ -68,4 +68,4 @@ jobs:
6868
# make release
6969

7070
- name: Perform CodeQL Analysis
71-
uses: github/codeql-action/analyze@v2
71+
uses: github/codeql-action/analyze@v3

.github/workflows/gradle-release-manual.yml

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,8 @@ jobs:
150150
with:
151151
java-version: '25'
152152
distribution: 'temurin'
153-
cache: gradle
154-
cache-dependency-path: |
155-
build.gradle
156-
code/gradle/autobuild.gradle
157-
code/gradle/distribution.gradle
158-
code/gradle/release.gradle
159-
code/gradle/reporting.gradle
160-
code/gradle/plugins.gradle
161-
162-
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
153+
154+
# setup-gradle@v4 is the canonical Gradle cache for GitHub Actions.
163155
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
164156
- name: Setup Gradle
165157
uses: gradle/actions/setup-gradle@v4
@@ -168,36 +160,48 @@ jobs:
168160
cache-read-only: false
169161
cache-overwrite-existing: true
170162

171-
- uses: actions/cache@v4
163+
# Cache cross-platform JDK and JavaFX jmod archives downloaded by
164+
# downloadJdk_* / downloadJavaFXMods_* tasks. These are pinned by
165+
# javaVersion (gradle.properties) and the URL templates (build.gradle),
166+
# so keying on those file hashes invalidates correctly when we bump
167+
# the JDK or JavaFX version. We cache only the archives (.tar.gz / .zip)
168+
# and let Gradle re-extract them each run via its own up-to-date checks.
169+
- name: Cache downloaded JDK and JavaFX archives
170+
uses: actions/cache@v4
172171
with:
173172
path: |
174-
${{ github.workspace }}/build/jre
175-
${{ github.workspace }}/build/libs
176-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
173+
jdks/jdk_*.tar.gz
174+
jdks/jdk_*.zip
175+
jdks/jfx_jmods_*.zip
176+
key: jdks-${{ hashFiles('gradle.properties', 'build.gradle') }}
177177
restore-keys: |
178-
${{ matrix.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
179-
${{ matrix.os }}-gradle
178+
jdks-
180179
181-
- name: Build the image
182-
if: success()
183-
run: ./gradlew clean build copyToOutput test compileSlowtest datatest pfinttest allReports buildDist prepareRelease pcgenRelease
180+
- name: Compile and run unit tests
181+
run: ./gradlew clean build
184182

185-
- name: Upload zip based release assets for all platforms
186-
uses: actions/upload-artifact@v4
187-
with:
188-
name: ${{ matrix.os }}-zip
189-
path: ${{ github.workspace }}/build/release/image-*.zip
183+
- name: Run data and integration tests
184+
run: ./gradlew compileSlowtest datatest pfinttest
185+
186+
- name: Run static analysis reports
187+
run: ./gradlew allReports
188+
189+
- name: Build distribution zips
190+
run: ./gradlew buildDist
190191

191-
- name: Upload DMG release asset for macos
192+
- name: Build release artifacts
193+
run: ./gradlew pcgenRelease
194+
195+
- name: Upload release artifacts as workflow artifacts
192196
uses: actions/upload-artifact@v4
193-
if: matrix.os == 'macos-latest'
194197
with:
195-
name: ${{ matrix.os }}-dmg
196-
path: ${{ github.workspace }}/build/release/*.dmg
198+
name: ${{ matrix.release_suffix }}-release
199+
path: ${{ github.workspace }}/build/release/*
200+
if-no-files-found: error
197201

198-
- name: Upload PKG release asset for macos
199-
uses: actions/upload-artifact@v4
200-
if: matrix.os == 'macos-latest'
202+
- name: Attach release artifacts to GitHub Release
203+
uses: softprops/action-gh-release@v2
201204
with:
202-
name: ${{ matrix.os }}-pkg
203-
path: ${{ github.workspace }}/build/release/*.pkg
205+
tag_name: ${{ inputs.tag_name }}
206+
files: ${{ github.workspace }}/build/release/*
207+
fail_on_unmatched_files: true

.github/workflows/gradle-release.yml

Lines changed: 38 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Create Release with Manual Tag
1+
name: Create Release on Tag Push
22

33
on:
44
push:
@@ -120,16 +120,8 @@ jobs:
120120
with:
121121
java-version: '25'
122122
distribution: 'temurin'
123-
cache: gradle
124-
cache-dependency-path: |
125-
build.gradle
126-
code/gradle/autobuild.gradle
127-
code/gradle/distribution.gradle
128-
code/gradle/release.gradle
129-
code/gradle/reporting.gradle
130-
code/gradle/plugins.gradle
131-
132-
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
123+
124+
# setup-gradle@v4 is the canonical Gradle cache for GitHub Actions.
133125
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
134126
- name: Setup Gradle
135127
uses: gradle/actions/setup-gradle@v4
@@ -138,57 +130,48 @@ jobs:
138130
cache-read-only: false
139131
cache-overwrite-existing: true
140132

141-
- uses: actions/cache@v4
133+
# Cache cross-platform JDK and JavaFX jmod archives downloaded by
134+
# downloadJdk_* / downloadJavaFXMods_* tasks. These are pinned by
135+
# javaVersion (gradle.properties) and the URL templates (build.gradle),
136+
# so keying on those file hashes invalidates correctly when we bump
137+
# the JDK or JavaFX version. We cache only the archives (.tar.gz / .zip)
138+
# and let Gradle re-extract them each run via its own up-to-date checks.
139+
- name: Cache downloaded JDK and JavaFX archives
140+
uses: actions/cache@v4
142141
with:
143142
path: |
144-
${{ github.workspace }}/build/jre
145-
${{ github.workspace }}/build/libs
146-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
143+
jdks/jdk_*.tar.gz
144+
jdks/jdk_*.zip
145+
jdks/jfx_jmods_*.zip
146+
key: jdks-${{ hashFiles('gradle.properties', 'build.gradle') }}
147147
restore-keys: |
148-
${{ matrix.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
149-
${{ matrix.os }}-gradle
148+
jdks-
150149
151-
- name: Build the image
152-
if: success()
153-
run: ./gradlew clean build copyToOutput test compileSlowtest datatest pfinttest allReports buildDist prepareRelease pcgenRelease
150+
- name: Compile and run unit tests
151+
run: ./gradlew clean build
154152

155-
- name: Upload zip based release assets for all platforms
156-
uses: actions/upload-artifact@v4
157-
if: matrix.os == 'macos-latest'
158-
with:
159-
name: ${{ matrix.os }}-zip
160-
path: ${{ github.workspace }}/build/release/image-*.zip
153+
- name: Run data and integration tests
154+
run: ./gradlew compileSlowtest datatest pfinttest
155+
156+
- name: Run static analysis reports
157+
run: ./gradlew allReports
158+
159+
- name: Build distribution zips
160+
run: ./gradlew buildDist
161161

162-
- name: Upload DMG release asset for macos
162+
- name: Build release artifacts
163+
run: ./gradlew pcgenRelease
164+
165+
- name: Upload release artifacts as workflow artifacts
163166
uses: actions/upload-artifact@v4
164-
if: matrix.os == 'macos-latest'
165167
with:
166-
name: ${{ matrix.os }}-dmg
167-
path: ${{ github.workspace }}/build/release/*.dmg
168+
name: ${{ matrix.release_suffix }}-release
169+
path: ${{ github.workspace }}/build/release/*
170+
if-no-files-found: error
168171

169-
- name: Upload PKG release asset for macos
170-
uses: actions/upload-artifact@v4
171-
if: matrix.os == 'macos-latest'
172+
- name: Attach release artifacts to GitHub Release
173+
uses: softprops/action-gh-release@v2
172174
with:
173-
name: ${{ matrix.os }}-pkg
174-
path: ${{ github.workspace }}/build/release/*.pkg
175-
176-
# - name: Upload release assets for ubuntu
177-
# uses: actions/upload-artifact@v4
178-
# if: matrix.os == 'ubuntu-latest'
179-
# with:
180-
# name: ${{ matrix.os }}
181-
# path: ${{ github.workspace }}/build/jpackage/*.deb
182-
#
183-
# - name: Upload release assets for windows
184-
# uses: actions/upload-artifact@v4
185-
# if: matrix.os == 'windows-latest'
186-
# with:
187-
# name: ${{ matrix.os }}
188-
# path: ${{ github.workspace }}/build/jpackage/*.msi
189-
#
190-
# - name: Release - ${{ matrix.os }}
191-
# uses: softprops/action-gh-release@v2
192-
# with:
193-
# tag_name: ${{ needs.create_release.outputs.tag-name }}
194-
# files: ${{ github.workspace }}/build/release/pcgen-*.*
175+
tag_name: ${{ inputs.tag_name || github.ref_name }}
176+
files: ${{ github.workspace }}/build/release/*
177+
fail_on_unmatched_files: true

.github/workflows/gradle-test.yml

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,39 +22,17 @@ jobs:
2222
with:
2323
java-version: '25'
2424
distribution: 'temurin'
25-
cache: gradle
26-
cache-dependency-path: |
27-
build.gradle
28-
code/gradle/autobuild.gradle
29-
code/gradle/distribution.gradle
30-
code/gradle/release.gradle
31-
code/gradle/reporting.gradle
32-
code/gradle/plugins.gradle
3325

34-
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
26+
# setup-gradle@v4 is the canonical Gradle cache for GitHub Actions.
3527
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
3628
- name: Setup Gradle
3729
uses: gradle/actions/setup-gradle@v4
38-
with:
39-
cache-disabled: false
40-
cache-read-only: false
41-
cache-overwrite-existing: true
42-
43-
- uses: actions/cache@v4
44-
with:
45-
path: |
46-
${{ github.workspace }}/build/jre
47-
${{ github.workspace }}/build/libs
48-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
49-
restore-keys: |
50-
${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
51-
${{ runner.os }}-gradle
5230

5331
- name: Build with Gradle Wrapper
5432
run: ./gradlew build
5533

56-
- name: Run tests
57-
run: ./gradlew test itest datatest slowtest
34+
- name: Run integration, data, and slow tests
35+
run: ./gradlew itest datatest slowtest
5836

5937
- name: Publish Test Results
6038
uses: EnricoMi/publish-unit-test-result-action@v2

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,12 @@ substitute `./gradlew` for `gradle` on the command line.
193193

194194
### Run Full Test Suite
195195
Do this primarily __before__ pull requests.
196-
This is almost exactly the command Travis runs to verify, if it fails locally you will fail the build, and your PR will not be merged.
196+
This mirrors what GitHub Actions runs to verify a PR; if it fails locally your CI build will also fail and your PR will not be merged.
197197

198-
./gradlew clean build copyToOutput test compileSlowtest datatest pfinttest allReports buildDist
198+
./gradlew build
199+
./gradlew itest datatest slowtest
200+
201+
`build` already runs the unit `test` task via the standard Java lifecycle, so it is not repeated. The second command runs the integration, data, and slow test suites.
199202

200203
### Clean All Build Files
201204
./gradlew clean

0 commit comments

Comments
 (0)