diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfdb8b7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5e1dab..31fd7bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,3 +32,79 @@ jobs: java-version: "17" node-version: "24" working-directory: "./example_plugin" + + test-example-plugin-stand: + if: "!contains(github.event.head_commit.message, 'skip-ci')" + runs-on: ubuntu-latest + env: + # Test-only credentials for the Paper server this job starts and tears down itself. + PLUGWRIGHT_RCON_PASSWORD: plugwright + PLUGWRIGHT_BOT_PASSWORD: plugwright + + steps: + - uses: actions/checkout@v4 + # Same duplicated build as test-example-plugin: this job runs on its own runner, in + # parallel with it, so it can't share that job's npm install/build output. + - name: Build the local npm packages + run: | + npm run install:packages + npm run build:packages + # Running in parallel with test-example-plugin means this job can't reuse its + # generated/local/run/ either - provision the same Paper server here instead of just + # running plugwrightTest, which would also run (and duplicate) the local suite. + # plugwrightCompileTests is the other half: plugwrightPingStand/plugwrightTestStand + # don't depend on it themselves (ExternalMode assumes the stand is already up, nothing + # to provision - see registerTasks in ExternalMode.kt), they just expect node_modules + # to already have what npm(...) plugin refs and console { rcon {} } need. + - uses: drownek/plugwright-action@v1 + with: + java-version: "17" + node-version: "24" + working-directory: "./example_plugin" + gradle-args: plugwrightProvisionLocal plugwrightCompileTests + # The provisioning above resolves a Java 21 toolchain for itself (build.gradle.kts pins + # languageVersion 21 for Paper 1.21.11), but that's Gradle's own on-demand download, not + # something start.sh can reach - it just runs whatever "java" is on PATH, which + # plugwright-action pinned to 17 above for the Gradle daemon. Put a real JDK 21 there. + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + # generated/ is gitignored, so start.sh - the launcher example_plugin/README.md tells + # developers to hand-write - never made it into the provisioned run dir. Copy in the + # tracked copy. + - name: Start the stand Paper server + working-directory: ./example_plugin/src/test/e2e/generated/local/run + run: | + cp "$GITHUB_WORKSPACE/example_plugin/src/test/e2e/stand-run/start.sh" . + chmod +x start.sh + nohup ./start.sh > stand-server.log 2>&1 & + echo $! > stand-server.pid + - name: Wait for the stand server + working-directory: ./example_plugin + run: | + for i in $(seq 1 30); do + if ./gradlew plugwrightPingStand; then + exit 0 + fi + sleep 2 + done + echo "stand server did not come up in time" >&2 + exit 1 + - name: Run the stand suite + working-directory: ./example_plugin + run: ./gradlew plugwrightTestStand + - name: Stop the stand Paper server + if: always() + working-directory: ./example_plugin/src/test/e2e/generated/local/run + run: | + [ -f stand-server.pid ] && kill "$(cat stand-server.pid)" 2>/dev/null || true + - name: Upload stand server log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: stand-server-log + path: | + example_plugin/src/test/e2e/generated/local/run/stand-server.log + example_plugin/build/reports/plugwright/stand.* + if-no-files-found: ignore diff --git a/example_plugin/README.md b/example_plugin/README.md index 30f425d..344d3b4 100644 --- a/example_plugin/README.md +++ b/example_plugin/README.md @@ -24,7 +24,7 @@ This one connects to a server that is already running and leaves it running. Pro cd src/test/e2e/generated/local/run && ./start.sh ``` -`generated/` is not in version control, so `start.sh` is yours to write. Anything that starts the jar with Java 21 will do: +`generated/` is not in version control, so `start.sh` is yours to write. Anything that starts the jar with Java 21 will do — CI keeps a tracked copy at `src/test/e2e/stand-run/start.sh` and copies it in before starting the server: ```sh #!/usr/bin/env sh diff --git a/example_plugin/src/test/e2e/stand-run/start.sh b/example_plugin/src/test/e2e/stand-run/start.sh new file mode 100755 index 0000000..481c160 --- /dev/null +++ b/example_plugin/src/test/e2e/stand-run/start.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh +# Tracked copy of the launcher example_plugin/README.md tells you to write yourself for a local +# `stand` run. CI copies this into generated/local/run/ (see ci.yml) since that directory is +# gitignored and can't hold a script of its own. Keep this in sync with the README snippet. +set -e + +cd "$(dirname "$0")" + +JAVA_BIN="${JAVA_BIN:-java}" +JVM_ARGS="${JVM_ARGS:--Xmx2G}" + +exec "$JAVA_BIN" $JVM_ARGS -Dcom.mojang.eula.agree=true -jar server.jar --nogui