diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 034648eff4b..e38727632b4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,11 +39,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -54,7 +54,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -68,4 +68,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/gradle-release-manual.yml b/.github/workflows/gradle-release-manual.yml index 3688e8f0553..c9effb7c8a6 100644 --- a/.github/workflows/gradle-release-manual.yml +++ b/.github/workflows/gradle-release-manual.yml @@ -150,16 +150,8 @@ jobs: with: java-version: '25' distribution: 'temurin' - cache: gradle - cache-dependency-path: | - build.gradle - code/gradle/autobuild.gradle - code/gradle/distribution.gradle - code/gradle/release.gradle - code/gradle/reporting.gradle - code/gradle/plugins.gradle - - # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + + # setup-gradle@v4 is the canonical Gradle cache for GitHub Actions. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 @@ -168,36 +160,48 @@ jobs: cache-read-only: false cache-overwrite-existing: true - - uses: actions/cache@v4 + # Cache cross-platform JDK and JavaFX jmod archives downloaded by + # downloadJdk_* / downloadJavaFXMods_* tasks. These are pinned by + # javaVersion (gradle.properties) and the URL templates (build.gradle), + # so keying on those file hashes invalidates correctly when we bump + # the JDK or JavaFX version. We cache only the archives (.tar.gz / .zip) + # and let Gradle re-extract them each run via its own up-to-date checks. + - name: Cache downloaded JDK and JavaFX archives + uses: actions/cache@v4 with: path: | - ${{ github.workspace }}/build/jre - ${{ github.workspace }}/build/libs - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + jdks/jdk_*.tar.gz + jdks/jdk_*.zip + jdks/jfx_jmods_*.zip + key: jdks-${{ hashFiles('gradle.properties', 'build.gradle') }} restore-keys: | - ${{ matrix.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - ${{ matrix.os }}-gradle + jdks- - - name: Build the image - if: success() - run: ./gradlew clean build copyToOutput test compileSlowtest datatest pfinttest allReports buildDist prepareRelease pcgenRelease + - name: Compile and run unit tests + run: ./gradlew clean build - - name: Upload zip based release assets for all platforms - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.os }}-zip - path: ${{ github.workspace }}/build/release/image-*.zip + - name: Run data and integration tests + run: ./gradlew compileSlowtest datatest pfinttest + + - name: Run static analysis reports + run: ./gradlew allReports + + - name: Build distribution zips + run: ./gradlew buildDist - - name: Upload DMG release asset for macos + - name: Build release artifacts + run: ./gradlew pcgenRelease + + - name: Upload release artifacts as workflow artifacts uses: actions/upload-artifact@v4 - if: matrix.os == 'macos-latest' with: - name: ${{ matrix.os }}-dmg - path: ${{ github.workspace }}/build/release/*.dmg + name: ${{ matrix.release_suffix }}-release + path: ${{ github.workspace }}/build/release/* + if-no-files-found: error - - name: Upload PKG release asset for macos - uses: actions/upload-artifact@v4 - if: matrix.os == 'macos-latest' + - name: Attach release artifacts to GitHub Release + uses: softprops/action-gh-release@v2 with: - name: ${{ matrix.os }}-pkg - path: ${{ github.workspace }}/build/release/*.pkg + tag_name: ${{ inputs.tag_name }} + files: ${{ github.workspace }}/build/release/* + fail_on_unmatched_files: true diff --git a/.github/workflows/gradle-release.yml b/.github/workflows/gradle-release.yml index dd9c6081f9b..704e4656018 100644 --- a/.github/workflows/gradle-release.yml +++ b/.github/workflows/gradle-release.yml @@ -1,4 +1,4 @@ -name: Create Release with Manual Tag +name: Create Release on Tag Push on: push: @@ -120,16 +120,8 @@ jobs: with: java-version: '25' distribution: 'temurin' - cache: gradle - cache-dependency-path: | - build.gradle - code/gradle/autobuild.gradle - code/gradle/distribution.gradle - code/gradle/release.gradle - code/gradle/reporting.gradle - code/gradle/plugins.gradle - - # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + + # setup-gradle@v4 is the canonical Gradle cache for GitHub Actions. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 @@ -138,57 +130,48 @@ jobs: cache-read-only: false cache-overwrite-existing: true - - uses: actions/cache@v4 + # Cache cross-platform JDK and JavaFX jmod archives downloaded by + # downloadJdk_* / downloadJavaFXMods_* tasks. These are pinned by + # javaVersion (gradle.properties) and the URL templates (build.gradle), + # so keying on those file hashes invalidates correctly when we bump + # the JDK or JavaFX version. We cache only the archives (.tar.gz / .zip) + # and let Gradle re-extract them each run via its own up-to-date checks. + - name: Cache downloaded JDK and JavaFX archives + uses: actions/cache@v4 with: path: | - ${{ github.workspace }}/build/jre - ${{ github.workspace }}/build/libs - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + jdks/jdk_*.tar.gz + jdks/jdk_*.zip + jdks/jfx_jmods_*.zip + key: jdks-${{ hashFiles('gradle.properties', 'build.gradle') }} restore-keys: | - ${{ matrix.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - ${{ matrix.os }}-gradle + jdks- - - name: Build the image - if: success() - run: ./gradlew clean build copyToOutput test compileSlowtest datatest pfinttest allReports buildDist prepareRelease pcgenRelease + - name: Compile and run unit tests + run: ./gradlew clean build - - name: Upload zip based release assets for all platforms - uses: actions/upload-artifact@v4 - if: matrix.os == 'macos-latest' - with: - name: ${{ matrix.os }}-zip - path: ${{ github.workspace }}/build/release/image-*.zip + - name: Run data and integration tests + run: ./gradlew compileSlowtest datatest pfinttest + + - name: Run static analysis reports + run: ./gradlew allReports + + - name: Build distribution zips + run: ./gradlew buildDist - - name: Upload DMG release asset for macos + - name: Build release artifacts + run: ./gradlew pcgenRelease + + - name: Upload release artifacts as workflow artifacts uses: actions/upload-artifact@v4 - if: matrix.os == 'macos-latest' with: - name: ${{ matrix.os }}-dmg - path: ${{ github.workspace }}/build/release/*.dmg + name: ${{ matrix.release_suffix }}-release + path: ${{ github.workspace }}/build/release/* + if-no-files-found: error - - name: Upload PKG release asset for macos - uses: actions/upload-artifact@v4 - if: matrix.os == 'macos-latest' + - name: Attach release artifacts to GitHub Release + uses: softprops/action-gh-release@v2 with: - name: ${{ matrix.os }}-pkg - path: ${{ github.workspace }}/build/release/*.pkg - -# - name: Upload release assets for ubuntu -# uses: actions/upload-artifact@v4 -# if: matrix.os == 'ubuntu-latest' -# with: -# name: ${{ matrix.os }} -# path: ${{ github.workspace }}/build/jpackage/*.deb -# -# - name: Upload release assets for windows -# uses: actions/upload-artifact@v4 -# if: matrix.os == 'windows-latest' -# with: -# name: ${{ matrix.os }} -# path: ${{ github.workspace }}/build/jpackage/*.msi -# -# - name: Release - ${{ matrix.os }} -# uses: softprops/action-gh-release@v2 -# with: -# tag_name: ${{ needs.create_release.outputs.tag-name }} -# files: ${{ github.workspace }}/build/release/pcgen-*.* + tag_name: ${{ inputs.tag_name || github.ref_name }} + files: ${{ github.workspace }}/build/release/* + fail_on_unmatched_files: true diff --git a/.github/workflows/gradle-test.yml b/.github/workflows/gradle-test.yml index 4034f333f3b..acc144d5617 100644 --- a/.github/workflows/gradle-test.yml +++ b/.github/workflows/gradle-test.yml @@ -22,39 +22,17 @@ jobs: with: java-version: '25' distribution: 'temurin' - cache: gradle - cache-dependency-path: | - build.gradle - code/gradle/autobuild.gradle - code/gradle/distribution.gradle - code/gradle/release.gradle - code/gradle/reporting.gradle - code/gradle/plugins.gradle - # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + # setup-gradle@v4 is the canonical Gradle cache for GitHub Actions. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - with: - cache-disabled: false - cache-read-only: false - cache-overwrite-existing: true - - - uses: actions/cache@v4 - with: - path: | - ${{ github.workspace }}/build/jre - ${{ github.workspace }}/build/libs - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - ${{ runner.os }}-gradle - name: Build with Gradle Wrapper run: ./gradlew build - - name: Run tests - run: ./gradlew test itest datatest slowtest + - name: Run integration, data, and slow tests + run: ./gradlew itest datatest slowtest - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 diff --git a/README.md b/README.md index 86677ddba73..668778cdcc9 100644 --- a/README.md +++ b/README.md @@ -193,9 +193,12 @@ substitute `./gradlew` for `gradle` on the command line. ### Run Full Test Suite Do this primarily __before__ pull requests. -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. +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. - ./gradlew clean build copyToOutput test compileSlowtest datatest pfinttest allReports buildDist + ./gradlew build + ./gradlew itest datatest slowtest + +`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. ### Clean All Build Files ./gradlew clean diff --git a/build.gradle b/build.gradle index de6aeb033e5..cc397503894 100644 --- a/build.gradle +++ b/build.gradle @@ -96,31 +96,12 @@ repositories { // Maven Central as a default mavenCentral() - // Use Ant Ivy Plugin to reference our own hosted repos - // for PCGen Base and PCGen Formula JARs - //ivy { - // TODO Enable HTTPS (e.g., add letsencrypt) for that location - //url "http://pcgen.sourceforge.net/mvnrepo" - //allowInsecureProtocol = true - //patternLayout { - //artifact "[organisation]/jars/[artifact]-[revision].[ext]" - //} - //} ivy { // TODO Enable HTTPS (e.g., add letsencrypt) for that location name = 'fileRepo' url = 'http://pc-gen.org/librepo/' allowInsecureProtocol = true } - // Use Maven plugin to reference freehep (https://java.freehep.org/) artifact repository - // TODO Which libs do we pull from here? - /* - maven { - name = 'free' - url = 'https://java.freehep.org/maven2' - } - - */ maven { name = 'local' url = 'installers' @@ -146,13 +127,21 @@ sourceSets { srcDirs = ['code/src/resources'] } } - // Running regular tests - test { + // Shared test utilities — compiled once, consumed by test/itest/slowtest. + testcommon { java { - srcDirs = ['code/src/utest', 'code/src/testcommon'] + srcDirs = ['code/src/testcommon'] } compileClasspath += sourceSets.main.output runtimeClasspath += sourceSets.main.output + } + // Running regular tests + test { + java { + srcDirs = ['code/src/utest'] + } + compileClasspath += sourceSets.main.output + sourceSets.testcommon.output + runtimeClasspath += sourceSets.main.output + sourceSets.testcommon.output resources { srcDirs = ['code/src/testResources'] } @@ -160,7 +149,7 @@ sourceSets { // Integration Tests itest { java { - srcDirs = ['code/src/itest', 'code/src/testcommon'] + srcDirs = ['code/src/itest'] } resources { srcDirs = ['code/src/testResources'] @@ -171,7 +160,7 @@ sourceSets { // Running Slow Tests slowtest { java { - srcDirs = ['code/src/test', 'code/src/testcommon'] + srcDirs = ['code/src/test'] } resources { srcDirs = ['code/src/testResources'] @@ -181,6 +170,13 @@ sourceSets { } } +// Make the testcommon source set use the same dependency configurations as test. +configurations { + testcommonImplementation.extendsFrom testImplementation + testcommonRuntimeOnly.extendsFrom testRuntimeOnly + testcommonCompileOnly.extendsFrom testCompileOnly +} + /* Copy 'master' outputsheets into different genre folders */ tasks.register("copyMasterSheets", Copy) { def filesToCopy = copySpec { @@ -258,11 +254,14 @@ dependencies { compileOnly 'com.yuvimasory:orange-extensions:1.3.0' compileOnly 'com.github.spotbugs:spotbugs-annotations:4.9.8' - testImplementation 'org.junit.platform:junit-platform-runner:1.14.4' - testImplementation 'org.junit.platform:junit-platform-launcher:6.0.3' - testImplementation 'org.junit.jupiter:junit-jupiter-api:6.0.3' - testImplementation 'org.junit.jupiter:junit-jupiter-params:6.0.3' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:6.0.3' + testImplementation platform('org.junit:junit-bom:6.0.3') + testImplementation 'org.junit.platform:junit-platform-launcher' + testImplementation 'org.junit.jupiter:junit-jupiter-api' + testImplementation 'org.junit.jupiter:junit-jupiter-params' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + // JUnit 4 is still used by ~870 legacy tests; pulled in via vintage engine + junit jar. + testImplementation 'junit:junit:4.13.2' + testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' testImplementation 'org.hamcrest:hamcrest:3.0' testImplementation 'org.testfx:testfx-junit5:4.0.18' @@ -449,7 +448,9 @@ if (Os.isFamily(Os.FAMILY_MAC)) { } } -// Create the Data Convertor JAR +// Create the Data Convertor JAR. +// This is a thin jar containing only a manifest that points at pcgen.jar +// (and the rest of the runtime classpath) via Class-Path. tasks.register("converterJar", Jar) { dependsOn jar manifest { @@ -460,12 +461,6 @@ tasks.register("converterJar", Jar) { } archiveClassifier.set('batch-convert') - from { - configurations.runtimeClasspath.collect { it.directory ? it : zipTree(it) } - } - - from sourceSets.main.output - include 'none' } tasks.named("assemble") { @@ -733,9 +728,25 @@ tasks.register("testCoverage", JacocoReport) { executionData.from = fileTree(dir: layout.buildDirectory.dir("jacoco")).include("*.exec") } +// https://docs.gradle.org/current/userguide/performance.html#a_run_tests_in_parallel +def parallelTestForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 + tasks.named("test", Test) { exclude 'test/pcgen/testsupport/**' useJUnitPlatform() + maxParallelForks = parallelTestForks + // TestFX/Monocle setup — only the unit test source set has TestFX-based tests. + jvmArgs += [ + '-Dtestfx.robot=glass', + '-Dtestfx.headless=true', + '-Dprism.order=sw', + // Workaround for TestFX modularity issue. https://github.com/TestFX/TestFX/issues/638 + '--add-exports', 'javafx.graphics/com.sun.javafx.application=ALL-UNNAMED', + // Required for Monocle. + '--add-exports', 'javafx.graphics/com.sun.javafx.util=ALL-UNNAMED', + '--add-exports', 'javafx.base/com.sun.javafx.logging=ALL-UNNAMED', + '--add-opens', 'javafx.graphics/com.sun.glass.ui=ALL-UNNAMED', + ] } tasks.register("itest", Test) { @@ -744,6 +755,7 @@ tasks.register("itest", Test) { testClassesDirs = sourceSets.itest.output.classesDirs classpath = sourceSets.itest.runtimeClasspath systemProperties['jar.path'] = jar.getArchiveFile().get().getAsFile() + maxParallelForks = parallelTestForks } tasks.register("slowtest", Test) { @@ -771,44 +783,23 @@ tasks.register("inttest", Test) { include 'slowtest/pcgen/inttest/**/*Test.class' } -tasks.register("sfinttest", Test) { - dependsOn jar - testClassesDirs = sourceSets.slowtest.output.classesDirs - classpath = sourceSets.slowtest.runtimeClasspath - forkEvery = 1 - include 'slowtest/pcgen/inttest/game_starfinder/*Test.class' -} - -tasks.register("pfinttest", Test) { - dependsOn jar - testClassesDirs = sourceSets.slowtest.output.classesDirs - classpath = sourceSets.slowtest.runtimeClasspath - forkEvery = 1 - include 'slowtest/pcgen/inttest/game_pathfinder/*Test.class' -} - -tasks.register("rsrdinttest", Test) { - dependsOn jar - testClassesDirs = sourceSets.slowtest.output.classesDirs - classpath = sourceSets.slowtest.runtimeClasspath - forkEvery = 1 - include 'slowtest/pcgen/inttest/game_35e/*Test.class' -} - -tasks.register("srdinttest", Test) { - dependsOn jar - testClassesDirs = sourceSets.slowtest.output.classesDirs - classpath = sourceSets.slowtest.runtimeClasspath - forkEvery = 1 - include 'slowtest/pcgen/inttest/game_3e/*Test.class' -} - -tasks.register("msrdinttest", Test) { - dependsOn jar - testClassesDirs = sourceSets.slowtest.output.classesDirs - classpath = sourceSets.slowtest.runtimeClasspath - forkEvery = 1 - include 'slowtest/pcgen/inttest/game_modern/*Test.class' +// Per-game-mode inttest variants. Each runs only the inttest classes for one +// game directory under code/src/test/pcgen/inttest. CI references these names +// (e.g. pfinttest) so the task names are stable. +[ + sfinttest : 'game_starfinder', + pfinttest : 'game_pathfinder', + rsrdinttest: 'game_35e', + srdinttest : 'game_3e', + msrdinttest: 'game_modern', +].each { taskName, gameDir -> + tasks.register(taskName, Test) { + dependsOn jar + testClassesDirs = sourceSets.slowtest.output.classesDirs + classpath = sourceSets.slowtest.runtimeClasspath + forkEvery = 1 + include "slowtest/pcgen/inttest/${gameDir}/*Test.class" + } } allprojects { @@ -826,22 +817,12 @@ allprojects { } jvmArgs += [ '-Djava.awt.headless=true', - '-Dtestfx.robot=glass', - '-Dtestfx.headless=true', - '-Dprism.order=sw', - '-Dprism.verbose=true', '-Djavafx.macosx.embedded=true', '-Djava.security.manager=disallow', "--module-path", layout.projectDirectory.dir("mods/lib"), "--add-modules", "javafx.controls,javafx.web,javafx.swing,javafx.fxml,javafx.graphics", - // Needed to fix issue with testfx test crashing due to issue with modularity of whole program. Slightly related issue. https://github.com/TestFX/TestFX/issues/638 - '--add-exports', 'javafx.graphics/com.sun.javafx.application=ALL-UNNAMED', - // Next two needed to support monocle testing - '--add-exports', 'javafx.graphics/com.sun.javafx.util=ALL-UNNAMED', - '--add-exports', 'javafx.base/com.sun.javafx.logging=ALL-UNNAMED', - '--add-opens', 'javafx.graphics/com.sun.glass.ui=ALL-UNNAMED', '--enable-native-access=javafx.graphics', ] } diff --git a/code/gradle/distribution.gradle b/code/gradle/distribution.gradle index 4327effce6f..204706e0f4a 100644 --- a/code/gradle/distribution.gradle +++ b/code/gradle/distribution.gradle @@ -40,12 +40,6 @@ ext { } } - programDistsImage = copySpec { - from(layout.buildDirectory.dir("launch4j")) { - include 'pcgen.exe' - } - } - programScriptImage = copySpec { from('.') { include 'pcgen_low_mem.bat' @@ -75,12 +69,6 @@ ext { include 'characters/*.pcg' } } - - jreImage = copySpec { - from('.') { - include 'jdks/jdk_windows_x64/**' - } - } } application { @@ -93,7 +81,6 @@ application { applicationDistribution.with(autobuildSpec) applicationDistribution.with(charactersImage) applicationDistribution.with(programScriptImage) - applicationDistribution.with(programDistsImage) } tasks.named("run") { @@ -119,19 +106,6 @@ tasks.named("installDist") { } } -tasks.register("testZip", Zip) { - dependsOn converterJar, copyToLibs, copyToOutput - archiveClassifier.set('test') - into(zipRootFolder) { - with dataDistsImage - with docsDistsImage - with programDistsImage - with libsDistsImage - with autobuildSpec - with charactersImage - } -} - tasks.register("dataZip", Zip) { dependsOn copyMasterSheets archiveClassifier.set('data') @@ -153,7 +127,6 @@ tasks.register("programZip", Zip) { dependsOn converterJar archiveClassifier.set('program') into(zipRootFolder) { - with programDistsImage with programScriptImage with autobuildSpec } diff --git a/code/gradle/release.gradle b/code/gradle/release.gradle index 77b7f76aca1..8b1079210d6 100644 --- a/code/gradle/release.gradle +++ b/code/gradle/release.gradle @@ -22,245 +22,13 @@ apply from: "code/gradle/releaseUtils.groovy" apply plugin: 'java' -import org.apache.tools.ant.filters.FixCrLfFilter import org.apache.tools.ant.taskdefs.condition.Os -import org.gradle.api.internal.file.copy.DefaultCopySpec ext { // Work out the path to the release notes for our current version. plainVerNum = version.replaceAll('-SNAPSHOT', '') shortVerNum = plainVerNum.replaceAll(/\./, '') releaseNotes = "${projectDir}/installers/release-notes/pcgen-release-notes-${shortVerNum}.html" - - nsisBaseFolder = layout.buildDirectory.dir("nsis/PCGen_${shortVerNum}_base") - nsisOptionFolder = layout.buildDirectory.dir("nsis/PCGen_${shortVerNum}_opt") - - // specifications for what to copy to the NSIS base and optional folders - baseLibs = copySpec { - from(layout.buildDirectory.dir("libs")) { - exclude 'pcgen-*.jar' - exclude 'fop*.jar' - exclude 'batik*.jar' - } - into ('/libs') - } as DefaultCopySpec - - lib32 = copySpec { - from(layout.buildDirectory.dir("image/pcgen-windows-x32/lib")) { - exclude 'fop*.jar' - exclude 'batik*.jar' - } - into('/lib32') - } as DefaultCopySpec - - lib64 = copySpec { - from(layout.buildDirectory.dir("image/pcgen-windows-x64/lib")) { - exclude 'fop*.jar' - exclude 'batik*.jar' - exclude 'javafx*.jar' - } - into('/lib64') - } as DefaultCopySpec - - pdfLibs = copySpec { - from(layout.buildDirectory.dir("libs")) { - include 'fop*.jar' - include 'batik*.jar' - } - into ('/plugin/pdf/libs') - } as DefaultCopySpec - - basePlugins = copySpec { - from(layout.projectDirectory.dir("plugins")) { - include '*plugins/**' - include 'Random Names/**' - include 'DoomsdayBook.jar' - } - into ('/plugins') - } as DefaultCopySpec - - gmgenPlugins = copySpec { - from(layout.projectDirectory.dir("plugins")) { - exclude '*plugins/**' - exclude 'Random Names/**' - exclude 'DoomsdayBook.jar' - } - into ('/plugin/gmgen/plugins') - } as DefaultCopySpec - - nonPdfOutput = copySpec { - from(layout.projectDirectory.dir("outputsheets")) { - exclude '**/pdf/**' - } - into ('/outputsheets') - } as DefaultCopySpec - - pdfOutput = copySpec { - from(layout.projectDirectory.dir("outputsheets")) { - include '**/pdf/**' - } - into ('/plugin/pdf/outputsheets') - } as DefaultCopySpec - - baseData = copySpec { - from(layout.projectDirectory.dir("data")) { - include 'customsources/**' - include 'homebrew/**' - } - into ('/data') - } as DefaultCopySpec - - optionalData = copySpec { - from(layout.projectDirectory.dir("data")) { - exclude 'customsources/**' - exclude 'homebrew/**' - } - into ('/data') - } as DefaultCopySpec - - List result = plainVerNum.replaceAll('-DEV', '').tokenize('.') - installerVerNum = result[0].toInteger() + "." + result[1].toInteger() + "." + result[2].take(2).toInteger() + ".0" -} - -// Generate the publisher/data list for the Windows installer script -tasks.register("genDataList") { - - notCompatibleWithConfigurationCache("File manipulation involved in genDataList") - - inputs.dir layout.projectDirectory.dir("data") - - def dataNsh = layout.projectDirectory.file("installers/win-installer/includes/data.nsh") - outputs.file dataNsh - - // TODO: find a way to move it to ext section. - // The list of publishers - add an entry here to correct a reported missing publisher - def publisherMap = ["12_to_midnight" : "12 to Midnight", - "4_winds_fantasy_gaming" : "4 Winds Fantasy Gaming", - "alderac_entertainment_group": "Alderac Entertainment Group", - "alderac_ent_group" : "Alderac Entertainment Group", - "alea_publishing_group" : "Alea Publishing Group", - "alluria_publishing" : "Alluria Publishing", - "ascension_games" : "Ascension Games", - "atlas_games" : "Atlas Games", - "auran_d20" : "Auran d20", - "avalanche_press" : "Avalanche Press", - "badaxe_games" : "Bad Axe Games", - "bards_and_sages" : "Bards and Sages", - "bastion_press" : "Bastion Press", - "battlefield_press" : "Battlefield Press", - "behemoth3" : "Behemoth3", - "big_finger_games" : "Big Finger Games", - "bloodstone_press" : "Bloodstone Press", - "blue_devil_games" : "Blue Devil Games", - "broken_ruler_games" : "Broken Ruler Games", - "crafty_games" : "Crafty Games", - "creativemountaingames" : "Creative Mountain Games", - "distant_horizons_games" : "Distant Horizons Games", - "doghouse_rules" : "Dog House Rules", - "dragonwing_games" : "DragonWing Games", - "dreamscarred_press" : "Dreamscarred Press", - "en_publishing" : "EN Publishing", - "everyman_gaming" : "Everyman Gaming", - "fantasy_community_council" : "Fantasy Community Council", - "fantasy_flight_games" : "Fantasy Flight Games", - "gallantry_productions" : "Gallantry Productions", - "goodman_games" : "Goodman Games", - "green_ronin" : "Green Ronin", - "kobold_press" : "Kobold Press", - "legendary_games" : "Legendary Games", - "lions_den_press" : "Lions Den Press", - "lone_wanderer_entertainment": "Lone Wanderer Entertainment", - "malhavoc_press" : "Malhavoc Press", - "minotaur_games" : "Minotaur Games", - "mongoose" : "Mongoose", - "mongoose_publishing" : "Mongoose Publishing", - "msrd" : "MSRD", - "mythic_dream_studios" : "Mythic Dreams Studios", - "necromancer_games" : "Necromancer Games", - "nitehawk_interactive" : "Nitehawk Interactive Games", - "pandahead" : "Pandahead", - "paradigm_concepts" : "Paradigm Concepts Inc", - "paizo" : "Paizo Publishing", - "parents_basement_games" : "Parents Basement Games", - "pcgen" : "PCGen OGL", - "pfsrd_publishing" : "Open Game Network (d20pfsrd,", - "pinnacle_entertainment" : "Pinnacle Entertainment", - "reality_deviant" : "Reality Deviant Publications", - "rite" : "Rite Publishing", - "rite_publishing" : "Rite Publishing", - "rpg_objects" : "RPG Objects", - "sagaborn" : "Sagaborn", - "secular_games" : "Secular Games", - "silven_publishing" : "Silven Publishing", - "silverthorne_games" : "Silverthorne Games", - "skirmisher_publishing" : "Skirmisher Publishing LLC", - "sovereign_press" : "Sovereign Press", - "srd" : "SRD", - "srd35" : "SRD35", - "st_cooley_publishing" : "S T Cooley Publishing", - "storm_bunny_studios" : "Storm Bunny Studios", - "super_genius_games" : "Super Genius Games", - "sword_and_sorcery_studios" : "Sword and Sorcery Studios", - "swords_edge_publishing" : "Swords Edge Publishing", - "the_game_mechanics" : "The Game Mechanics Inc", - "vigilance_press" : "Vigilance Press", - "wizards_of_the_coast" : "Wizards of the Coast", - "lpj_design" : "Louis Porter Jr. Design", - "tripod_machine" : "Tripod Machine", - "total_party_kill_games" : "Total Party Kill Games", - "starfinder" : "Starfinder"] - - doLast { - project.delete(dataNsh) - def out = new StringBuilder() - - // List of folder names to ignore. - def ignoreList = ["homebrew", "zen_test", "customsources", "_universal", "_images", "publisher_logos"] - - // List of sections - def sectionsIn = [msrd: "3 6", pcgen: "3 4 5", srd: "3 4", srd35: "3 5", necromancergames: "3 5", paizo: "3"] - - layout.projectDirectory.dir("data").asFile.eachDir { - if (ignoreList.contains(it.name)) - { - return - } - out.append("SubSection \"$it.name\"\n") - def dir = it.name - def subFolders = 0 - it.eachDir { - if (ignoreList.contains(it.name)) - { - return - } - def pubname = publisherMap.getOrDefault(it.name, it.name) - def sectionIn = sectionsIn.getOrDefault(it.name, "") - - out.append("""\tSection "$pubname" -\t\tSectionIn 1 2 ${sectionIn} -\t\tSetOutPath "\$INSTDIR\\\${APPDIR}\\data\\${dir}\\${it.name}" -\t\tFile /r "\${SrcDir}\\PCGen_\${SIMPVER}_opt\\data\\${dir}\\${it.name}\\*.*" -\tSectionEnd - -""") - subFolders++ - } - if (subFolders == 0){ - def pubname = publisherMap.getOrDefault(it.name, it.name) - out.append("""\tSection "$pubname" -\t\tSectionIn 1 2 -\t\tSetOutPath "\$INSTDIR\\\${APPDIR}\\data\\${dir}" -\t\tFile /r "\${SrcDir}\\PCGen_\${SIMPVER}_opt\\data\\${dir}\\*.*" -\tSectionEnd - -""") - } - out.append("SubSectionEnd\n\n") - } - - println("Writing data to: ${outputs.files.singleFile}") - outputs.files.singleFile.text = out - } } tasks.register("sourcesJar", Jar) { @@ -351,7 +119,6 @@ tasks.register("checksum") { } } -// genDataList removed as it causes release errors, 'genDataList' tasks.register("prepareRelease") { dependsOn build description = """Prepare PCGen for release. This will update and commit the version, \ @@ -364,11 +131,10 @@ tasks.register("pcgenRelease") { // Installer is placed in outputDir } -// Update the PCGen version to indicate a release, then commit the new version +// Update the PCGen version to indicate a release. Commit the change manually. tasks.register("updateVersionRelease") { doLast { unSnapshotVersion() - commitFile(file("gradle.properties"), "Update version for release ${project.version}") } } @@ -377,10 +143,9 @@ tasks.register("pcgenReleaseOfficial") { description = "Release a new official version of PCGen." } -// Update the PCGen version for development of the next release, then commit the new version +// Update the PCGen version for development of the next release. Commit the change manually. tasks.register("updateVersionToNext") { doLast { updateVersion() - commitFile(file("gradle.properties"), "Update version for dev work ${project.version}") } } diff --git a/gradle.properties b/gradle.properties index 517decc5f7d..31b1c1dc2c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,4 @@ -#version=6.09.06-SNAPSHOT version=6.09.08.RC1 -localOnly=false org.gradle.jvmargs=-Xmx4096m org.gradle.configuration-cache=true