Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
257 changes: 251 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up JDK 21
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '21'

- name: Cache Maven local repository
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.m2/repository
key: ${{ runner.os }}-m2-${{ matrix.paper-version }}-${{ hashFiles('**/pom.xml') }}
Expand All @@ -47,16 +47,16 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up JDK 21
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '21'

- name: Cache Maven local repository
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.m2/repository
key: ${{ runner.os }}-m2-feature-${{ matrix.paper-version }}-${{ hashFiles('**/pom.xml') }}
Expand All @@ -65,3 +65,248 @@ jobs:

- name: Run feature tests
run: mvn -B -Dpaper.version=${{ matrix.paper-version }} -Dmockbukkit.artifactId=${{ matrix.mockbukkit-artifactId }} -Dmockbukkit.version=${{ matrix.mockbukkit-version }} -Pfeature-tests -Dtest=*FeatureTest test

# ─────────────────────────────────────────────────────────────────────────
# Smoke tests — Paper & Folia (downloaded from api.papermc.io)
# Matrix: platform × mc-prefix × java
# ─────────────────────────────────────────────────────────────────────────
smoke-papermc:
name: "Smoke · ${{ matrix.platform }} / MC ${{ matrix.mc-prefix }} / Java ${{ matrix.java }}"
runs-on: ubuntu-latest
needs: [unit-tests, feature-tests]
strategy:
fail-fast: false
matrix:
platform: [paper, folia]
mc-prefix: ["1.21", "26.1"]
java: [21, 25]
exclude:
# MC 26.1 requires Java 25+
- mc-prefix: "26.1"
java: 21

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: ${{ matrix.java }}
cache: maven

- name: Build plugin JAR
run: mvn -B -ntp -DskipTests package

- name: Resolve latest ${{ matrix.platform }} build for MC ${{ matrix.mc-prefix }}.x
id: server
run: |
PLATFORM="${{ matrix.platform }}"
PREFIX="${{ matrix.mc-prefix }}"
VERSIONS_JSON=$(curl -fsSL "https://fill.papermc.io/v3/projects/${PLATFORM}")
MC_VERSION=$(PREFIX="${PREFIX}" python3 -c "import sys,os,json;d=json.loads(sys.stdin.read());p=os.environ['PREFIX'];vs=d.get('versions',{});fam=p if p in vs else next((f for f in vs if f.startswith(p+'.')),None);print(vs[fam][0] if fam and vs.get(fam) else '')" <<< "$VERSIONS_JSON")
if [[ -z "$MC_VERSION" ]]; then
echo "::error::No ${PLATFORM} builds found matching MC ${PREFIX}.x."
echo "available=false" >> "$GITHUB_OUTPUT"
exit 1
fi
BUILDS_JSON=$(curl -fsSL "https://fill.papermc.io/v3/projects/${PLATFORM}/versions/${MC_VERSION}/builds")
BUILD_INFO=$(python3 -c "import sys,json;bs=json.loads(sys.stdin.read());st=[b for b in bs if b.get('channel')=='STABLE'];c=st[0] if st else (bs[0] if bs else None);[print(c['id']),print(c['downloads']['server:default']['url'])] if c else None" <<< "$BUILDS_JSON")
BUILD=$(echo "$BUILD_INFO" | sed -n '1p')
DOWNLOAD_URL=$(echo "$BUILD_INFO" | sed -n '2p')
JAR_NAME=$(basename "$DOWNLOAD_URL")
if [[ -z "$BUILD" || -z "$DOWNLOAD_URL" ]]; then
echo "::error::No builds found for ${PLATFORM} ${MC_VERSION}."
echo "available=false" >> "$GITHUB_OUTPUT"
exit 1
fi
echo "mc_version=${MC_VERSION}" >> "$GITHUB_OUTPUT"
echo "build=${BUILD}" >> "$GITHUB_OUTPUT"
echo "jar_name=${JAR_NAME}" >> "$GITHUB_OUTPUT"
echo "download_url=${DOWNLOAD_URL}" >> "$GITHUB_OUTPUT"
echo "available=true" >> "$GITHUB_OUTPUT"
echo "Resolved: ${PLATFORM} ${MC_VERSION} build ${BUILD} (${JAR_NAME})"

- name: Download ${{ matrix.platform }} server JAR
if: steps.server.outputs.available == 'true'
run: |
mkdir -p smoke-server/plugins
curl -fsSL "${{ steps.server.outputs.download_url }}" -o smoke-server/server.jar

- name: Copy plugin JAR
if: steps.server.outputs.available == 'true'
run: cp target/EzCountdown-*.jar smoke-server/plugins/EzCountdown.jar

- name: Configure server
if: steps.server.outputs.available == 'true'
run: |
echo "eula=true" > smoke-server/eula.txt
printf '%s\n' \
"online-mode=false" \
"level-type=flat" \
"generate-structures=false" \
"max-players=0" \
> smoke-server/server.properties

- name: Run server and wait for ready
if: steps.server.outputs.available == 'true'
run: |
cd smoke-server
java -Xms512m -Xmx1g -jar server.jar --nogui > server.log 2>&1 &
SERVER_PID=$!
ELAPSED=0
while [ $ELAPSED -lt 120 ]; do
sleep 2; ELAPSED=$((ELAPSED + 2))
if grep -q "Done (" server.log 2>/dev/null; then
echo "Server ready after ${ELAPSED}s"; break
fi
if ! kill -0 $SERVER_PID 2>/dev/null; then
echo "Server process exited after ${ELAPSED}s"; break
fi
done
kill $SERVER_PID 2>/dev/null || true
wait $SERVER_PID 2>/dev/null || true

- name: Assert no EzCountdown errors
if: steps.server.outputs.available == 'true'
run: |
LOG=smoke-server/server.log
if grep -qiE "SEVERE.*EzCountdown|Could not load.*EzCountdown|Error initialising.*EzCountdown" "$LOG"; then
echo "::error::EzCountdown logged errors on ${{ matrix.platform }} MC ${{ matrix.mc-prefix }} (Java ${{ matrix.java }}):"
grep -iE "SEVERE.*EzCountdown|Could not load.*EzCountdown|Error initialising.*EzCountdown" "$LOG"
exit 1
fi
if grep -qiE "Enabling EzCountdown|EzCountdown.*enabled" "$LOG"; then
echo "Smoke test passed — EzCountdown loaded on ${{ matrix.platform }} MC ${{ steps.server.outputs.mc_version }} (Java ${{ matrix.java }})."
else
echo "::warning::Plugin load confirmation not found — server may not have finished loading within the timeout."
fi

- name: Upload server log
if: always()
uses: actions/upload-artifact@v7
with:
name: smoke-log-${{ matrix.platform }}-mc${{ matrix.mc-prefix }}-java${{ matrix.java }}
path: smoke-server/server.log
if-no-files-found: ignore
retention-days: 7

# ─────────────────────────────────────────────────────────────────────────
# Smoke tests — Spigot (compiled via BuildTools, result cached by MC+Java)
# Matrix: mc-prefix × java
# ─────────────────────────────────────────────────────────────────────────
smoke-spigot:
name: "Smoke · spigot / MC ${{ matrix.mc-prefix }} / Java ${{ matrix.java }}"
runs-on: ubuntu-latest
needs: [unit-tests, feature-tests]
strategy:
fail-fast: false
matrix:
mc-prefix: ["1.21"]
java: [21, 25]

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: ${{ matrix.java }}
cache: maven

- name: Configure Git for BuildTools
run: |
git config --global user.email "ci@github.com"
git config --global user.name "CI"

- name: Build plugin JAR
run: mvn -B -ntp -DskipTests package

- name: Restore cached Spigot JAR (MC ${{ matrix.mc-prefix }}, Java ${{ matrix.java }})
id: spigot-cache
uses: actions/cache@v5
with:
path: spigot-build/spigot-${{ matrix.mc-prefix }}.jar
key: spigot-jar-mc${{ matrix.mc-prefix }}-java${{ matrix.java }}-v1

- name: Build Spigot via BuildTools
if: steps.spigot-cache.outputs.cache-hit != 'true'
id: buildtools
run: |
mkdir -p spigot-build/work
cd spigot-build/work
curl -fsSL \
"https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar" \
-o BuildTools.jar
java -jar BuildTools.jar --rev "${{ matrix.mc-prefix }}" 2>&1 | tee buildtools.log || {
echo "::warning::BuildTools failed for MC ${{ matrix.mc-prefix }} on Java ${{ matrix.java }} — version may not be supported yet. Spigot smoke test will be skipped."
echo "failed=true" >> "$GITHUB_OUTPUT"
exit 0
}
SPIGOT_JAR=$(ls spigot-${{ matrix.mc-prefix }}*.jar 2>/dev/null | head -1)
if [[ -z "$SPIGOT_JAR" ]]; then
SPIGOT_JAR=$(ls spigot*.jar 2>/dev/null | grep -v craftbukkit | head -1)
fi
if [[ -n "$SPIGOT_JAR" ]]; then
cp "$SPIGOT_JAR" "../spigot-${{ matrix.mc-prefix }}.jar"
echo "::notice::Cached ${SPIGOT_JAR} as spigot-${{ matrix.mc-prefix }}.jar"
else
echo "::warning::BuildTools completed but no Spigot JAR found — smoke test will be skipped."
echo "failed=true" >> "$GITHUB_OUTPUT"
fi

- name: Run Spigot smoke test
run: |
SPIGOT_JAR="spigot-build/spigot-${{ matrix.mc-prefix }}.jar"
if [[ ! -f "$SPIGOT_JAR" ]]; then
echo "::warning::Spigot JAR not available for MC ${{ matrix.mc-prefix }} — BuildTools could not build this version. Smoke test skipped."
exit 0
fi
mkdir -p smoke-server/plugins
cp "$SPIGOT_JAR" smoke-server/server.jar
cp target/EzCountdown-*.jar smoke-server/plugins/EzCountdown.jar
echo "eula=true" > smoke-server/eula.txt
printf '%s\n' \
"online-mode=false" \
"level-type=flat" \
"generate-structures=false" \
"max-players=0" \
> smoke-server/server.properties
cd smoke-server
java -Xms512m -Xmx1g -jar server.jar --nogui > server.log 2>&1 &
SERVER_PID=$!
ELAPSED=0
while [ $ELAPSED -lt 120 ]; do
sleep 2; ELAPSED=$((ELAPSED + 2))
if grep -q "Done (" server.log 2>/dev/null; then
echo "Server ready after ${ELAPSED}s"; break
fi
if ! kill -0 $SERVER_PID 2>/dev/null; then
echo "Server process exited after ${ELAPSED}s"; break
fi
done
kill $SERVER_PID 2>/dev/null || true
wait $SERVER_PID 2>/dev/null || true
LOG=server.log
if grep -qiE "SEVERE.*EzCountdown|Could not load.*EzCountdown|Error initialising.*EzCountdown" "$LOG"; then
echo "::error::EzCountdown logged errors on Spigot MC ${{ matrix.mc-prefix }} (Java ${{ matrix.java }}):"
grep -iE "SEVERE.*EzCountdown|Could not load.*EzCountdown|Error initialising.*EzCountdown" "$LOG"
exit 1
fi
if grep -qiE "Enabling EzCountdown|EzCountdown.*enabled" "$LOG"; then
echo "Smoke test passed — EzCountdown loaded on Spigot MC ${{ matrix.mc-prefix }} (Java ${{ matrix.java }})."
else
echo "::warning::Plugin load confirmation not found — server may not have finished loading within the timeout."
fi

- name: Upload Spigot server log
if: always()
uses: actions/upload-artifact@v7
with:
name: smoke-log-spigot-mc${{ matrix.mc-prefix }}-java${{ matrix.java }}
path: smoke-server/server.log
if-no-files-found: ignore
retention-days: 7
4 changes: 2 additions & 2 deletions .github/workflows/maven-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ jobs:
packages: write

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up JDK 21
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
Expand Down
Loading
Loading