From 6565f10fe50adeb1280c8fe22bda1c19686698ed Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Fri, 29 Sep 2023 12:04:07 +0200 Subject: [PATCH] build: Use GitHub Actions to run tests --- .github/workflows/test.yml | 136 ++++++++++++++++++ stage0/build.gradle | 16 ++- .../stage2/jvm/ForkedJvmLoaderSwingUI.java | 10 ++ 3 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..da2ef81 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,136 @@ +name: Run Tests +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: | + 8 + 16 + 17 + + # Can't use setup-java for this because https://github.com/actions/setup-java/issues/366 + - uses: actions/cache@v3 + with: + path: ~/.gradle/wrapper + key: gradle-wrapper-${{ hashFiles('**/gradle-wrapper.properties') }} + - uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: gradle-caches-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle.properties', 'gradle/*.versions.toml') }} + restore-keys: | + gradle-caches-${{ hashFiles('**/*.gradle*') }} + gradle-caches- + + - run: ./gradlew build -x integrationTest setupDownloadsApi --stacktrace + + - uses: actions/upload-artifact@v3 + if: ${{ failure() || success() }} + with: + name: Raw Test Results + path: "**/build/test-results/**/*.xml" + retention-days: 1 # only for the report at the end + + - uses: actions/upload-artifact@v3 + if: ${{ failure() }} + with: + name: Unit Test Results + path: "**/build/reports/" + + - uses: actions/cache/save@v3 + with: + path: | + **/.gradle + **/build + key: test-build-${{ github.run_id }}-${{ github.run_attempt }} + + prepare_integration_test_matrix: + needs: build # don't even bother with tests if it doesn't even build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/github-script@v6 + id: create-matrix + with: + script: | + const tests = [] + for (platform of ["launchwrapper", "fabric"]) { + const prefix = `integrationTest/${platform}/src/main/java/` + for await (const file of (await glob.create(`${prefix}/**/*Tests.java`)).globGenerator()) { + const cls = file.slice(file.indexOf(prefix) + prefix.length, file.length - 5).replaceAll("/", ".") + tests.push({ platform, "class": cls }) + } + } + return tests + github-token: dummy # we don't need one but it'll complain without one (when running locally via act) + outputs: + matrix: ${{ steps.create-matrix.outputs.result }} + + integration_tests: + needs: + - prepare_integration_test_matrix + - build # we'll want to re-use the caches it produces + strategy: + fail-fast: false + max-parallel: 1 + matrix: + test: ${{ fromJson(needs.prepare_integration_test_matrix.outputs.matrix) }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: | + 8 + 16 + 17 + + - uses: actions/cache/restore@v3 + with: + path: ~/.gradle/wrapper + key: gradle-wrapper-${{ hashFiles('**/gradle-wrapper.properties') }} + - uses: actions/cache/restore@v3 + with: + path: ~/.gradle/caches + key: gradle-caches-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle.properties', 'gradle/*.versions.toml') }} + - uses: actions/cache/restore@v3 + with: + path: | + **/.gradle + **/build + key: test-build-${{ github.run_id }}-${{ github.run_attempt }} + + - run: ./gradlew :integrationTest:${{ matrix.test.platform }}:integrationTest --tests ${{ matrix.test.class }} --stacktrace --info + + - uses: actions/upload-artifact@v3 + if: ${{ failure() || success() }} + with: + name: Raw Test Results + path: integrationTest/${{ matrix.test.platform }}/build/test-results/**/*.xml + retention-days: 1 # only for the report at the end + + - uses: actions/upload-artifact@v3 + if: ${{ failure() }} + with: + name: ${{ matrix.test.platform }}:${{ matrix.test.class }} Results + path: integrationTest/${{ matrix.test.platform }}/build/reports/ + + test_report: + runs-on: ubuntu-latest + needs: [build, integration_tests] + if: ${{ !cancelled() }} + steps: + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + path: artifacts + - name: Publish test report + uses: EnricoMi/publish-unit-test-result-action@d93dbc08d265e4653da0c0af544bee2a851d3e38 # v2.10.0 + with: + junit_files: "artifacts/**/*.xml" diff --git a/stage0/build.gradle b/stage0/build.gradle index 5d443a6..3364493 100644 --- a/stage0/build.gradle +++ b/stage0/build.gradle @@ -40,13 +40,15 @@ configure(subprojects.findAll { it.name != "common" && it.name != "modlauncher" } repositories { - maven { - name 'nexus' - url "https://repo.sk1er.club/repository/maven-${this.properties.getOrDefault("IS_CI", false) ? "snapshots" : "releases"}/" - - credentials { - username project.nexus_user - password project.nexus_password + if (project.hasProperty("nexus_user")) { + maven { + name 'nexus' + url "https://repo.sk1er.club/repository/maven-${this.properties.getOrDefault("IS_CI", false) ? "snapshots" : "releases"}/" + + credentials { + username project.nexus_user + password project.nexus_password + } } } } diff --git a/stage2/common/src/main/java/gg/essential/loader/stage2/jvm/ForkedJvmLoaderSwingUI.java b/stage2/common/src/main/java/gg/essential/loader/stage2/jvm/ForkedJvmLoaderSwingUI.java index 8382cf0..45cd881 100644 --- a/stage2/common/src/main/java/gg/essential/loader/stage2/jvm/ForkedJvmLoaderSwingUI.java +++ b/stage2/common/src/main/java/gg/essential/loader/stage2/jvm/ForkedJvmLoaderSwingUI.java @@ -2,9 +2,19 @@ import gg.essential.loader.stage2.LoaderSwingUI; +import java.awt.*; import java.io.IOException; public class ForkedJvmLoaderSwingUI extends ForkedJvmLoaderUI { + @Override + public void start() { + // Skip actual GUI for integration tests if we're in a headless environment + if (System.getProperty("essential.integration_testing") != null && GraphicsEnvironment.isHeadless()) { + return; + } + super.start(); + } + public static void main(String[] args) throws IOException { forked(new LoaderSwingUI()); }