fix: migrate PaperMC to v3 API, fix NeoForge beta fallback, add test suite

- Migrate Paper loader from sunset v2 API to v3 (fill.papermc.io)
- Fix NeoForge: fall back to beta versions when no stable exists (set -e + grep)
- Fix setEula/setperms ordering (was writing eula.txt before /data was writable)
- Fix setEula/serverInfoWrite to use absolute paths (/data/server/)
- Add VOLUME directive removal (was shadowing bind mounts)
- Add comprehensive API test suite (110 tests across 6 suites)
- Move test.sh to tests/integration.sh, switch to named volumes
- Add Docker build cache to CI workflows
- Add .editorconfig, expand .gitignore, improve README docs
This commit is contained in:
2026-08-21 12:49:27 -04:00
parent a6f610de28
commit 5688b30892
26 changed files with 2530 additions and 263 deletions
+244
View File
@@ -0,0 +1,244 @@
#!/usr/bin/env bash
# Tests for NeoForge API
# Covers: NeoForge maven metadata, version resolution, download URL
# Usage: ./tests/test_neoforge.sh [mc_version]
source "$(dirname "$0")/test_utils.sh"
MC_VERSION="${1:-$(get_latest_mc_version)}"
if [[ -z "$MC_VERSION" ]]; then
echo "Could not determine MC version"
exit 1
fi
echo -e "\n${BOLD}NeoForge API Tests (MC ${MC_VERSION})${NC}"
echo ""
# ---------- NeoForge Maven metadata ----------------------------------------
test_neoforge_metadata_reachable() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
assert_not_empty "$body" "NeoForge maven metadata should be reachable"
}
test_neoforge_metadata_is_xml() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
assert_contains "$body" "<metadata>" "Should be valid XML"
}
test_neoforge_metadata_has_versions() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
assert_contains "$body" "<versions>" "Should have <versions> element"
}
test_neoforge_metadata_has_latest() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local latest
latest=$(echo "$body" | xmllint --xpath "/metadata/versioning/latest/text()" - 2>/dev/null)
assert_not_empty "$latest" "Metadata should have a latest version"
}
test_neoforge_metadata_has_release() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local release
release=$(echo "$body" | xmllint --xpath "/metadata/versioning/release/text()" - 2>/dev/null)
assert_not_empty "$release" "Metadata should have a release version"
}
# ---------- NeoForge version resolution ------------------------------------
# NeoForge versions start with MC minor version (e.g., MC 1.20.4 -> 20.4.x)
test_neoforge_version_prefix() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local versions
versions=$(echo "$body" | xmllint --xpath "/metadata/versioning/versions/version/text()" - 2>/dev/null)
# Extract MC minor from version (e.g., "1.21.1" -> "21.1")
local mc_minor="${MC_VERSION#1.}"
# Check that there are versions matching this MC minor prefix
local matching
matching=$(echo "$versions" | tr ' ' '\n' | grep "^${mc_minor}\." | head -1)
assert_not_empty "$matching" \
"Should find at least one NeoForge version starting with ${mc_minor}"
}
test_neoforge_stable_versions_exist() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local versions
versions=$(echo "$body" | xmllint --xpath "/metadata/versioning/versions/version/text()" - 2>/dev/null)
local mc_minor="${MC_VERSION#1.}"
local stable_count
stable_count=$(echo "$versions" | tr ' ' '\n' | grep -v -- '-beta\|-alpha' | grep -c "^${mc_minor}\." || true)
if [[ "$stable_count" -gt 0 ]]; then
return 0
else
echo "ASSERT FAILED: No stable NeoForge versions found for MC minor ${mc_minor}"
echo " This may be valid for a very new MC version"
return 1
fi
}
test_neoforge_no_beta_in_stable() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local versions
versions=$(echo "$body" | xmllint --xpath "/metadata/versioning/versions/version/text()" - 2>/dev/null)
local mc_minor="${MC_VERSION#1.}"
local stable_versions
stable_versions=$(echo "$versions" | tr ' ' '\n' | grep -v -- '-beta\|-alpha' | grep "^${mc_minor}\." | sort -V | tail -5)
# None of the stable versions should contain beta or alpha
local bad_count
bad_count=$(echo "$stable_versions" | grep -c -- '-beta\|-alpha' || true)
assert_equals "$bad_count" "0" "Stable versions should not contain beta/alpha"
}
test_neoforge_latest_for_mc_is_stable() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local versions
versions=$(echo "$body" | xmllint --xpath "/metadata/versioning/versions/version/text()" - 2>/dev/null)
local mc_minor="${MC_VERSION#1.}"
local latest_for_mc
latest_for_mc=$(echo "$versions" | tr ' ' '\n' | grep -v -- '-beta\|-alpha' | grep "^${mc_minor}\." | sort -V | tail -1)
if [[ -z "$latest_for_mc" ]]; then
echo "No stable NeoForge version found for MC ${MC_VERSION}"
return 1
fi
local bad=$(echo "$latest_for_mc" | grep -c -- '-beta\|-alpha' || true)
assert_equals "$bad" "0" "Latest stable version for MC ${MC_VERSION} (${latest_for_mc}) should not contain beta/alpha"
}
# ---------- NeoForge download URL ------------------------------------------
_neoforge_latest_for_mc() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local versions
versions=$(echo "$body" | xmllint --xpath "/metadata/versioning/versions/version/text()" - 2>/dev/null)
local mc_minor="${MC_VERSION#1.}"
echo "$versions" | tr ' ' '\n' | grep -v -- '-beta\|-alpha' | grep "^${mc_minor}\." | sort -V | tail -1
}
test_neoforge_download_url_format() {
local latest
latest=$(_neoforge_latest_for_mc)
if [[ -z "$latest" ]]; then
echo "No stable NeoForge version found for MC ${MC_VERSION}"
return 1
fi
local expected_url="https://maven.neoforged.net/releases/net/neoforged/neoforge/${latest}/neoforge-${latest}-installer.jar"
assert_matches "$expected_url" "maven.neoforged.net.*installer\.jar" \
"URL should point to NeoForge maven installer"
}
test_neoforge_download_url_reachable() {
local latest
latest=$(_neoforge_latest_for_mc)
if [[ -z "$latest" ]]; then
echo "No stable NeoForge version found for MC ${MC_VERSION}"
return 1
fi
local url="https://maven.neoforged.net/releases/net/neoforged/neoforge/${latest}/neoforge-${latest}-installer.jar"
assert_http_ok "$url" "NeoForge installer URL should return HTTP 200"
}
# ---------- NeoForge version sort check ------------------------------------
test_neoforge_versions_sorted_ascending() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local versions
versions=$(echo "$body" | xmllint --xpath "/metadata/versioning/versions/version/text()" - 2>/dev/null)
local mc_minor="${MC_VERSION#1.}"
local last_version
last_version=$(echo "$versions" | tr ' ' '\n' | grep -v -- '-beta\|-alpha' | grep "^${mc_minor}\." | sort -V | tail -1)
# The last version after sort -V should be the same as the latest from metadata
local meta_latest
meta_latest=$(echo "$body" | xmllint --xpath "/metadata/versioning/latest/text()" - 2>/dev/null)
if [[ "$last_version" == "$meta_latest" ]]; then
return 0
else
echo "ASSERT FAILED: sort -V last version (${last_version}) != metadata latest (${meta_latest})"
echo " This is informational - metadata latest may include beta"
return 77 # skip
fi
}
# ---------- Specific MC version support ------------------------------------
test_neoforge_supports_1_21_1() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local versions
versions=$(echo "$body" | xmllint --xpath "/metadata/versioning/versions/version/text()" - 2>/dev/null)
local count
count=$(echo "$versions" | tr ' ' '\n' | grep -v -- '-beta\|-alpha' | grep -c "^21.1\." || true)
if [[ "$count" -gt 0 ]]; then
return 0
else
echo "ASSERT FAILED: No NeoForge versions found for MC 1.21.1 (21.1.x)"
return 1
fi
}
test_neoforge_supports_1_20_4() {
local body
body=$(api_get "https://maven.neoforged.net/releases/net/neoforged/neoforge/maven-metadata.xml")
local versions
versions=$(echo "$body" | xmllint --xpath "/metadata/versioning/versions/version/text()" - 2>/dev/null)
local count
count=$(echo "$versions" | tr ' ' '\n' | grep -v -- '-beta\|-alpha' | grep -c "^20.4\." || true)
if [[ "$count" -gt 0 ]]; then
return 0
else
echo "ASSERT FAILED: No NeoForge versions found for MC 1.20.4 (20.4.x)"
return 1
fi
}
# ---------- Run all tests --------------------------------------------------
run_test "NeoForge maven metadata is reachable" test_neoforge_metadata_reachable
run_test "Metadata is valid XML" test_neoforge_metadata_is_xml
run_test "Metadata has <versions> element" test_neoforge_metadata_has_versions
run_test "Metadata has <latest> version" test_neoforge_metadata_has_latest
run_test "Metadata has <release> version" test_neoforge_metadata_has_release
run_test "Versions exist with MC minor prefix" test_neoforge_version_prefix
run_test "Stable versions exist for current MC" test_neoforge_stable_versions_exist
run_test "Stable versions have no beta/alpha tags" test_neoforge_no_beta_in_stable
run_test "Latest stable version for MC is stable" test_neoforge_latest_for_mc_is_stable
run_test "Download URL matches NeoForge maven pattern" test_neoforge_download_url_format
run_test "Download URL returns HTTP 200" test_neoforge_download_url_reachable
run_test "Versions are sorted in ascending order" test_neoforge_versions_sorted_ascending
run_test "NeoForge supports MC 1.21.1 (21.1.x)" test_neoforge_supports_1_21_1
run_test "NeoForge supports MC 1.20.4 (20.4.x)" test_neoforge_supports_1_20_4
print_summary