diff --git a/.github/maven-release/README.md b/.github/maven-release/README.md index 98461cba..34aa0e66 100644 --- a/.github/maven-release/README.md +++ b/.github/maven-release/README.md @@ -13,7 +13,8 @@ If CurseForge has accepted the file but it isn't public yet, wait for approval. Start a new run with the recorded CurseForge file ID so it verifies that upload without submitting the jar again. The release workflow sets Java 8 through Minecraft 1.16.5, Java 16 for Minecraft 1.17.1, Java 17 through Minecraft 1.20.1, -and Java 21 for Minecraft 1.20.6 and 1.21.1. +Java 21 for Minecraft 1.20.6 through 1.21.11, and Java 25 for Minecraft 26.1.2. +Unknown version branches are rejected until their release target is reviewed. ## Existing CurseForge releases diff --git a/.github/maven-release/test_verify.py b/.github/maven-release/test_verify.py new file mode 100644 index 00000000..bfea9e1d --- /dev/null +++ b/.github/maven-release/test_verify.py @@ -0,0 +1,26 @@ +import unittest + +import verify + + +class ReleaseTargetTests(unittest.TestCase): + def test_released_minecraft_lines_keep_their_runtime(self): + for java, versions in { + 8: ("1.10.2", "1.12.2", "1.13.2", "1.14.4", "1.15.2", "1.16.5"), + 16: ("1.17.1",), + 17: ("1.18.2", "1.19.4", "1.20.1"), + 21: ("1.20.6", "1.21.1", "1.21.11"), + 25: ("26.1.2",), + }.items(): + for version in versions: + with self.subTest(version=version): + self.assertEqual((version, f"Java {java}"), verify.release_target(f"master-{version}")) + + def test_unqualified_or_malformed_targets_are_rejected(self): + for branch in ("master-26.2", "master-26.1.2-extra", "feature/26.1.2", "26.1.2", "master-main", "master-26.1.2\n"): + with self.subTest(branch=branch), self.assertRaises(ValueError): + verify.release_target(branch) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/maven-release/verify.py b/.github/maven-release/verify.py index b7b5eebc..fda046d5 100644 --- a/.github/maven-release/verify.py +++ b/.github/maven-release/verify.py @@ -27,6 +27,19 @@ def digest(data): return hashlib.sha256(data).hexdigest() +def release_target(branch): + require(branch.startswith("master-"), "Release requires a version master branch") + minecraft = branch.removeprefix("master-") + java_versions = { + "1.10.2": 8, "1.12.2": 8, "1.13.2": 8, "1.14.4": 8, + "1.15.2": 8, "1.16.5": 8, "1.17.1": 16, "1.18.2": 17, + "1.19.4": 17, "1.20.1": 17, "1.20.6": 21, "1.21.1": 21, + "1.21.11": 21, "26.1.2": 25, + } + require(minecraft in java_versions, f"Unsupported Minecraft version: {minecraft}") + return minecraft, f"Java {java_versions[minecraft]}" + + def read_url(url, allow_absent=False): if url.startswith(MAVEN + "/"): # The CDN can cache pre-upload 404s even with a no-cache request header. @@ -161,7 +174,10 @@ def main(): manifest = json.loads(MANIFEST.read_text(encoding="utf-8")) require(version in manifest["releases"], f"Version is not approved: {version}") release, work = manifest["releases"][version], Path(folder) - if mode in ("stage", "stage-candidate"): + if mode == "target": + minecraft, java = release_target(release["branch"]) + print(f"minecraft={minecraft}\njava={java}") + elif mode in ("stage", "stage-candidate"): stage(manifest, version, release, work, candidate=mode == "stage-candidate") elif mode == "verify-curseforge": verify_curseforge(manifest, version, release, int(os.environ["CURSEFORGE_FILE_ID"]), diff --git a/.github/workflows/deploy-release.yml b/.github/workflows/deploy-release.yml index bc48f7d3..deb362b9 100644 --- a/.github/workflows/deploy-release.yml +++ b/.github/workflows/deploy-release.yml @@ -60,6 +60,7 @@ jobs: set -euo pipefail [[ "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] [[ -z "$EXISTING_CF_FILE" || "$EXISTING_CF_FILE" =~ ^[1-9][0-9]*$ ]] + python3 -m unittest discover -s .github/maven-release -p 'test_*.py' release_work="$RUNNER_TEMP/release" python3 .github/maven-release/verify.py stage-candidate "$RELEASE_VERSION" "$release_work" bash gradlew -p .github/maven-release generatePomFileForMavenJavaPublication \ @@ -69,19 +70,11 @@ jobs: echo "Maven already has this release. Supply its existing CurseForge file ID." >&2 exit 1 fi - mc=$(jq -er --arg v "$RELEASE_VERSION" '.releases[$v].branch | capture("^master-(?1\\.[0-9]+\\.[0-9]+)$").mc' .github/maven-release/releases.json) - case "$mc" in - 1.10.2|1.12.2|1.13.2|1.14.4|1.15.2|1.16.5) java="Java 8" ;; - 1.17.1) java="Java 16" ;; - 1.18.2|1.19.4|1.20.1) java="Java 17" ;; - 1.20.6|1.21.1|1.21.11) java="Java 21" ;; - *) echo "Unsupported Minecraft version for this publisher: $mc" >&2; exit 1 ;; - esac - echo "minecraft=$mc" >> "$GITHUB_OUTPUT" - echo "java=$java" >> "$GITHUB_OUTPUT" + target=$(python3 .github/maven-release/verify.py target "$RELEASE_VERSION" "$release_work") + printf '%s\n' "$target" >> "$GITHUB_OUTPUT" echo "state=$state" >> "$GITHUB_OUTPUT" echo "RELEASE_WORK=$release_work" >> "$GITHUB_ENV" - echo "Verified $RELEASE_VERSION for Minecraft $mc. Maven: $state." >> "$GITHUB_STEP_SUMMARY" + echo "Verified $RELEASE_VERSION. $target. Maven: $state." >> "$GITHUB_STEP_SUMMARY" - name: Check publication credentials if: inputs.mode == 'publish'