diff --git a/.github/workflows/deploy-release.yml b/.github/workflows/deploy-release.yml index 03e3791..e2a81d2 100644 --- a/.github/workflows/deploy-release.yml +++ b/.github/workflows/deploy-release.yml @@ -1,26 +1,28 @@ -name: Release Base Minerals +name: Release Base Minerals to CurseForge -run-name: Release Base Minerals ${{ inputs.release_version }} (CurseForge ${{ inputs.curseforge_release_level }}) +run-name: Base Minerals ${{ inputs.release_version }} CurseForge (${{ inputs.confirm_live_publication && 'publish' || 'check only' }}) on: workflow_dispatch: inputs: release_version: - description: Four-component Base Minerals version; the target branch is derived from its fourth component. + description: Base Minerals version ending in .110021 required: true type: string - curseforge_release_level: - description: CurseForge release level only; this does not change the GitHub Release type. + release_sha: + description: Full merged commit SHA on master-1.10.2 required: true - default: release - type: choice - options: - - release - - beta - - alpha - confirm_live_publication: - description: Confirm publication to Maven, CurseForge, and GitHub after the build passes. + type: string + ci_run_id: + description: Successful upstream push run of Base Minerals 1.10 CI + required: true + type: string + player_sha256: + description: SHA-256 of the tested player jar required: true + type: string + confirm_live_publication: + description: Upload the verified player jar to CurseForge default: false type: boolean @@ -29,749 +31,111 @@ permissions: contents: read concurrency: - group: baseminerals-release-${{ inputs.release_version }} + group: baseminerals-curseforge-${{ inputs.release_version }} cancel-in-progress: false jobs: - preflight: - name: Validate release request + release: + name: Verify and release Base Minerals 1.10.2 runs-on: ubuntu-latest - timeout-minutes: 10 - outputs: - target_branch: ${{ steps.route.outputs.target_branch }} - release_sha: ${{ steps.validate.outputs.release_sha }} - release_version: ${{ steps.validate.outputs.release_version }} - release_tag: ${{ steps.validate.outputs.release_tag }} - minecraft_version: ${{ steps.validate.outputs.minecraft_version }} - loader_name: ${{ steps.validate.outputs.loader_name }} - loader_display: ${{ steps.validate.outputs.loader_display }} - java_version: ${{ steps.validate.outputs.java_version }} - java_toolchain_version: ${{ steps.validate.outputs.java_toolchain_version }} - java_setup_version: ${{ steps.validate.outputs.java_setup_version }} - gradle_java_version: ${{ steps.validate.outputs.gradle_java_version }} - gradle_java_setup_version: ${{ steps.validate.outputs.gradle_java_setup_version }} - install_gradle_java: ${{ steps.validate.outputs.install_gradle_java }} - curseforge_project_id: ${{ steps.validate.outputs.curseforge_project_id }} - curseforge_dependencies: ${{ steps.validate.outputs.curseforge_dependencies }} - main_jar: ${{ steps.validate.outputs.main_jar }} - sources_jar: ${{ steps.validate.outputs.sources_jar }} - javadoc_jar: ${{ steps.validate.outputs.javadoc_jar }} + timeout-minutes: 15 steps: - - name: Resolve target branch from version - id: route + - name: Verify the merged source and CI run env: GH_TOKEN: ${{ github.token }} RELEASE_VERSION: ${{ inputs.release_version }} - run: | - set -euo pipefail - - if [[ "$GITHUB_REPOSITORY" != "MinecraftModDevelopmentMods/BaseMinerals" ]]; then - echo "Releases can only run in MinecraftModDevelopmentMods/BaseMinerals" >&2 - exit 1 - fi - if [[ ! "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.([0-9]+)$ ]]; then - echo "release_version must contain four numeric components" >&2 - exit 1 - fi - - target_suffix="${BASH_REMATCH[1]}" - if (( ${#target_suffix} < 6 )); then - echo "Invalid target suffix $target_suffix" >&2 - exit 1 - fi - - if [[ "$target_suffix" != 110021 ]]; then - echo 'Only the qualified Minecraft 1.10.2 Forge target is supported by this dispatcher' >&2; exit 1 - fi - - loader_code="${target_suffix: -1}" - target_digits="${target_suffix::-1}" - mc_patch_padded="${target_digits: -2}" - without_patch="${target_digits::-2}" - mc_minor_padded="${without_patch: -2}" - mc_major="${without_patch::-2}" - - if [[ -z "$mc_major" || ! "$mc_major" =~ ^[0-9]+$ ]]; then - echo "Invalid Minecraft major version in target suffix $target_suffix" >&2 - exit 1 - fi - mc_minor="$((10#$mc_minor_padded))" - mc_patch="$((10#$mc_patch_padded))" - case "$loader_code" in - 1) loader_suffix= ;; - 2) loader_suffix=-neo ;; - *) echo "Unknown loader code $loader_code in target suffix $target_suffix" >&2; exit 1 ;; - esac - - candidates=( - "master-$mc_major.$mc_minor.$mc_patch$loader_suffix" - "master-$mc_major.$mc_minor$loader_suffix" - ) - target_branch= - for candidate in "${candidates[@]}"; do - if gh api "repos/$GITHUB_REPOSITORY/branches/$candidate" >/dev/null 2>&1; then - target_branch="$candidate" - break - fi - done - if [[ -z "$target_branch" ]]; then - echo "No MMD release branch matches target suffix $target_suffix" >&2 - printf 'Checked branch %s\n' "${candidates[@]}" >&2 - exit 1 - fi - - echo "target_branch=$target_branch" >> "$GITHUB_OUTPUT" - echo "Resolved $RELEASE_VERSION to $target_branch" - - - name: Check out derived release branch - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ steps.route.outputs.target_branch }} - fetch-depth: 0 - - - name: Validate version, target, tag, and prior CI - id: validate - env: - GH_TOKEN: ${{ github.token }} - REQUESTED_VERSION: ${{ inputs.release_version }} - run: | - set -euo pipefail - - value() { sed -n "s/^$1=//p" gradle.properties; } - release_version="$(value mod_version)" - minecraft_version="$(value minecraft_version)" - loader_name="$(value loader_name)" - loader_code="$(value loader_code)" - java_version="$(value java_version)" - java_toolchain_version="$(value java_toolchain_version)" - java_setup_version="$(value java_setup_version)" - gradle_java_version="$(value gradle_java_version)" - gradle_java_setup_version="$(value gradle_java_setup_version)" - curseforge_project_id="$(value curseforge_project_id)" - cf_requirements="$(value cf_requirements)" - orespawn_project_id="$(value orespawn_curse_project_id)" - - for required in release_version minecraft_version loader_name loader_code \ - java_version gradle_java_version curseforge_project_id; do - if [[ -z "${!required}" ]]; then - echo "Selected ref is missing required release metadata: $required" >&2 - exit 1 - fi - done - java_toolchain_version="${java_toolchain_version:-$java_version}" - java_setup_version="${java_setup_version:-$java_toolchain_version}" - - java_major() { - local version="$1" - if [[ ! "$version" =~ ^([0-9]+)([._+-].*)?$ ]]; then - echo "Invalid Java toolchain version $version" >&2 - return 1 - fi - printf '%s' "${BASH_REMATCH[1]}" - } - requires_separate_gradle_java() { - local toolchain_major - toolchain_major="$(java_major "$1")" - [[ "$toolchain_major" != "$2" ]] - } - - if [[ "$(java_major "$java_setup_version")" != "$(java_major "$java_toolchain_version")" ]]; then - echo "Hosted Java selector $java_setup_version does not match toolchain $java_toolchain_version" >&2 - exit 1 - fi - - java_setup_contracts=( - '8.0.502+7 17 true' - '16.0.2+7 17 true' - '17.0.1+12 17 false' - '17 17 false' - '21.0.8+9 21 false' - ) - for contract in "${java_setup_contracts[@]}"; do - read -r contract_toolchain contract_gradle expected <<<"$contract" - actual=false - if requires_separate_gradle_java "$contract_toolchain" "$contract_gradle"; then - actual=true - fi - if [[ "$actual" != "$expected" ]]; then - echo "Java setup contract failed for toolchain $contract_toolchain and Gradle $contract_gradle" >&2 - exit 1 - fi - done - - install_gradle_java=false - if requires_separate_gradle_java "$java_toolchain_version" "$gradle_java_version"; then - install_gradle_java=true - echo "Gradle Java $gradle_java_version will be installed separately from toolchain $java_toolchain_version" - else - echo "Pinned toolchain $java_toolchain_version also satisfies Gradle Java $gradle_java_version" - fi - - IFS=. read -r mc_major mc_minor mc_patch extra <<<"$minecraft_version" - if [[ -n "${extra:-}" || -z "${mc_major:-}" || -z "${mc_minor:-}" ]]; then - echo "Invalid minecraft_version=$minecraft_version" >&2 - exit 1 - fi - mc_patch="${mc_patch:-0}" - if [[ ! "$mc_major" =~ ^[0-9]+$ || ! "$mc_minor" =~ ^[0-9]+$ || ! "$mc_patch" =~ ^[0-9]+$ ]]; then - echo "Invalid minecraft_version=$minecraft_version" >&2 - exit 1 - fi - case "$loader_name:$loader_code" in - forge:1) loader_display=Forge ;; - neoforge:2) loader_display=NeoForge ;; - *) echo "Invalid loader metadata $loader_name/$loader_code" >&2; exit 1 ;; - esac - if [[ ! "$java_version" =~ ^[0-9]+$ || ! "$gradle_java_version" =~ ^[0-9]+$ ]]; then - echo "Invalid Java metadata $java_version/$gradle_java_version" >&2 - exit 1 - fi - if [[ "$curseforge_project_id" != "270972" ]]; then - echo "Unexpected Base Minerals CurseForge project $curseforge_project_id" >&2 - exit 1 - fi - - printf -v minor_padded '%02d' "$((10#$mc_minor))" - printf -v patch_padded '%02d' "$((10#$mc_patch))" - target_suffix="${mc_major}${minor_padded}${patch_padded}${loader_code}" - if [[ ! "$release_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.${target_suffix}$ ]]; then - echo "mod_version $release_version does not match $minecraft_version $loader_display target $target_suffix" >&2 - exit 1 - fi - if [[ "$REQUESTED_VERSION" != "$release_version" ]]; then - echo "Requested version $REQUESTED_VERSION does not match ${{ steps.route.outputs.target_branch }} mod_version $release_version" >&2 - exit 1 - fi - if [[ -z "$gradle_java_setup_version" ]]; then - if [[ "$install_gradle_java" == false ]]; then - gradle_java_setup_version="$java_setup_version" - elif [[ "$gradle_java_version" == 17 ]]; then - # Legacy targets keep the same pinned Gradle JDK as their CI builds. - gradle_java_setup_version=17.0.1+12 - else - gradle_java_setup_version="$gradle_java_version" - fi - fi - if [[ "$(java_major "$java_toolchain_version")" != "$java_version" \ - || "$(java_major "$gradle_java_setup_version")" != "$gradle_java_version" ]]; then - echo "Java setup selectors do not match the declared game and Gradle Java versions" >&2 - exit 1 - fi - - if [[ -n "$orespawn_project_id" && "$orespawn_project_id" != 245586 ]]; then - echo "Unexpected OreSpawn CurseForge project $orespawn_project_id" >&2 - exit 1 - fi - if [[ -z "$cf_requirements" && "$orespawn_project_id" == 245586 ]]; then - # MMDLib-free ports declare their required OreSpawn dependency directly. - cf_requirements=mmd-orespawn - fi - - curseforge_dependencies=() - IFS=',' read -ra requirement_slugs <<<"$cf_requirements" - for slug in "${requirement_slugs[@]}"; do - case "$slug" in - mmd-orespawn) curseforge_dependencies+=('245586(required)') ;; - base-metals) curseforge_dependencies+=('240967(required)') ;; - mmdlib) curseforge_dependencies+=('261744(required)') ;; - '') ;; - *) echo "Unsupported required CurseForge relation $slug" >&2; exit 1 ;; - esac - done - if [[ " ${curseforge_dependencies[*]} " != *' 245586(required) '* ]]; then - echo "The required OreSpawn CurseForge relation was not declared" >&2 - exit 1 - fi - - if [[ " ${curseforge_dependencies[*]} " != *' 240967(required) '* ]]; then - echo 'Base Metals must be a required relation for this 1.10 release' >&2; exit 1 - fi - - release_sha="$(git rev-parse HEAD)" - release_tag="$release_version" - echo "release_sha=$release_sha" >> "$GITHUB_OUTPUT" - echo "release_version=$release_version" >> "$GITHUB_OUTPUT" - echo "release_tag=$release_tag" >> "$GITHUB_OUTPUT" - echo "minecraft_version=$minecraft_version" >> "$GITHUB_OUTPUT" - echo "loader_name=$loader_name" >> "$GITHUB_OUTPUT" - echo "loader_display=$loader_display" >> "$GITHUB_OUTPUT" - echo "java_version=$java_version" >> "$GITHUB_OUTPUT" - echo "java_toolchain_version=$java_toolchain_version" >> "$GITHUB_OUTPUT" - echo "java_setup_version=$java_setup_version" >> "$GITHUB_OUTPUT" - echo "gradle_java_version=$gradle_java_version" >> "$GITHUB_OUTPUT" - echo "gradle_java_setup_version=$gradle_java_setup_version" >> "$GITHUB_OUTPUT" - echo "install_gradle_java=$install_gradle_java" >> "$GITHUB_OUTPUT" - echo "curseforge_project_id=$curseforge_project_id" >> "$GITHUB_OUTPUT" - { - echo 'curseforge_dependencies<> "$GITHUB_OUTPUT" - echo "main_jar=BaseMinerals-$release_version.jar" >> "$GITHUB_OUTPUT" - echo "sources_jar=BaseMinerals-$release_version-sources.jar" >> "$GITHUB_OUTPUT" - echo "javadoc_jar=BaseMinerals-$release_version-javadoc.jar" >> "$GITHUB_OUTPUT" - - successful_ci="$(gh api \ - "repos/$GITHUB_REPOSITORY/commits/$release_sha/check-runs?per_page=100" \ - --jq '[.check_runs[] | select(.name == "Build, test, and audit" and .conclusion == "success")] | length')" - if [[ "$successful_ci" -lt 1 ]]; then - echo "The selected commit has no successful Build, test, and audit check" >&2 - exit 1 - fi - - if tag_json="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$release_tag" 2>/dev/null)"; then - tag_sha="$(jq -r '.object.sha' <<<"$tag_json")" - if [[ "$tag_sha" != "$release_sha" ]]; then - echo "Existing tag $release_tag resolves to $tag_sha instead of $release_sha" >&2 - exit 1 - fi - fi - - build: - name: Build immutable release artifact - needs: preflight - runs-on: ubuntu-latest - timeout-minutes: 60 - env: - MAIN_JAR: ${{ needs.preflight.outputs.main_jar }} - SOURCES_JAR: ${{ needs.preflight.outputs.sources_jar }} - JAVADOC_JAR: ${{ needs.preflight.outputs.javadoc_jar }} - outputs: - artifact_name: ${{ steps.artifact.outputs.name }} - - steps: - - name: Check out validated release ref - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ needs.preflight.outputs.release_sha }} - - - name: Install pinned Java 25 Mavenizer runtime - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 - with: - distribution: temurin - java-version: '25.0.3+9.0.LTS' - - - name: Install pinned Java 8 launcher toolchain - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 - with: - distribution: temurin - java-version: '8.0.502+7' - - - name: Install target Java toolchain - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 - with: - distribution: temurin - java-version: ${{ needs.preflight.outputs.java_setup_version }} - - - name: Record target Java toolchain path - shell: bash - run: echo "MODERNMETALS_TARGET_JAVA_HOME=$JAVA_HOME" >> "$GITHUB_ENV" - - - name: Install separate Java for Gradle - if: needs.preflight.outputs.install_gradle_java == 'true' - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 - with: - distribution: temurin - java-version: ${{ needs.preflight.outputs.gradle_java_setup_version }} - - - name: Set up Gradle - uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - - name: Resolve explicit Gradle Java installations - id: java-paths - shell: bash - run: | - set -euo pipefail - candidates=( - "$JAVA_HOME_25_X64" - "$JAVA_HOME_8_X64" - "$MODERNMETALS_TARGET_JAVA_HOME" - "$JAVA_HOME" - ) - paths= - for candidate in "${candidates[@]}"; do - test -x "$candidate/bin/java" - canonical="$(cd "$candidate" && pwd -P)" - if [[ ",$paths," != *",$canonical,"* ]]; then - paths="${paths:+$paths,}$canonical" - fi - done - echo "paths=$paths" >> "$GITHUB_OUTPUT" - - - name: Stage exact target dependencies - id: dependencies - run: | - set -euo pipefail - mirror="$RUNNER_TEMP/dependency-mirror" - if [[ -f gradle/stage-legacy-dependencies.sh ]]; then - bash gradle/stage-legacy-dependencies.sh "$mirror" - property=legacyDependencyVerificationRepository - elif [[ -f gradle/stage-orespawn-release.sh ]]; then - bash gradle/stage-orespawn-release.sh "$mirror" - property=orespawnVerificationRepository - else - echo "Selected target has no checksum-sealed dependency staging script" >&2 - exit 1 - fi - echo "repository=$mirror" >> "$GITHUB_OUTPUT" - echo "property=$property" >> "$GITHUB_OUTPUT" - - - name: Build, test, and audit once - env: - LOADER_NAME: ${{ needs.preflight.outputs.loader_name }} - run: | - set -euo pipefail - chmod +x ./gradlew - java_args=( - "-Dorg.gradle.java.installations.paths=${{ steps.java-paths.outputs.paths }}" - -Dorg.gradle.java.installations.auto-detect=false - -Dorg.gradle.java.installations.auto-download=false - ) - dependency_argument="-P${{ steps.dependencies.outputs.property }}=${{ steps.dependencies.outputs.repository }}" - if [[ "$LOADER_NAME" == neoforge ]]; then - # NeoGradle prepares inputs in build/tmp during configuration. Clean first. - ./gradlew clean "$dependency_argument" \ - --no-daemon --stacktrace --max-workers=2 "${java_args[@]}" - ./gradlew check build javadoc verifyReleaseArtifacts writeReleaseChecksums \ - "$dependency_argument" \ - --no-daemon --stacktrace --max-workers=2 "${java_args[@]}" - else - ./gradlew clean check build javadoc verifyReleaseArtifacts writeReleaseChecksums \ - "$dependency_argument" \ - --no-daemon --stacktrace "${java_args[@]}" - fi - - - name: Stage the immutable release artifact - id: artifact - run: | - set -euo pipefail - bundle="$RUNNER_TEMP/release-bundle" - mkdir -p "$bundle" - cp "build/libs/$MAIN_JAR" "$bundle/" - cp "build/libs/$SOURCES_JAR" "$bundle/" - cp "build/libs/$JAVADOC_JAR" "$bundle/" - cp build/release/SHA256SUMS "$bundle/" - cp CHANGELOG.txt "$bundle/" - (cd "$bundle" && sha256sum --check SHA256SUMS) - echo "name=BaseMinerals-${{ needs.preflight.outputs.minecraft_version }}-${{ needs.preflight.outputs.loader_name }}-${{ needs.preflight.outputs.release_sha }}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_OUTPUT" - - - name: Upload immutable release artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 - with: - name: ${{ steps.artifact.outputs.name }} - if-no-files-found: error - retention-days: 90 - path: ${{ runner.temp }}/release-bundle/* - - - name: Summarize the prepared release candidate - env: - RELEASE_BRANCH: ${{ needs.preflight.outputs.target_branch }} - RELEASE_LEVEL: ${{ inputs.curseforge_release_level }} - RELEASE_SHA: ${{ needs.preflight.outputs.release_sha }} - RELEASE_VERSION: ${{ needs.preflight.outputs.release_version }} - run: | - { - echo "## Prepared release candidate" - echo - echo "- Version: \`$RELEASE_VERSION\`" - echo "- Target branch: \`$RELEASE_BRANCH\`" - echo "- Commit: \`$RELEASE_SHA\`" - echo "- CurseForge release level: \`$RELEASE_LEVEL\`" - echo "- GitHub Release type: ordinary release" - echo - echo "### Public artifact checksums" - echo '```text' - cat build/release/SHA256SUMS - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - - release_confirmation: - name: Confirm ${{ inputs.release_version }} live publication - needs: - - preflight - - build - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Confirm publication and release-secret access - env: - CONFIRM_LIVE_PUBLICATION: ${{ inputs.confirm_live_publication }} - CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} - MAVEN_UPLOAD_URL: ${{ secrets.MAVEN_UPLOAD_URL }} - MAVEN_UPLOAD_USERNAME: ${{ secrets.MAVEN_UPLOAD_USERNAME }} - MAVEN_UPLOAD_PASSWORD: ${{ secrets.MAVEN_UPLOAD_PASSWORD }} - run: | - set -euo pipefail - if [[ "$CONFIRM_LIVE_PUBLICATION" != "true" ]]; then - echo "Confirm live publication in the workflow form before releasing ${{ needs.preflight.outputs.release_tag }}" >&2 - exit 1 - fi - echo "Live publication confirmed for ${{ needs.preflight.outputs.release_tag }}" - missing=() - for name in CURSEFORGE_TOKEN MAVEN_UPLOAD_URL MAVEN_UPLOAD_USERNAME MAVEN_UPLOAD_PASSWORD; do - if [[ -z "${!name:-}" ]]; then - missing+=("$name") - fi - done - if (( ${#missing[@]} > 0 )); then - printf 'Required release secret is unavailable: %s\n' "${missing[@]}" >&2 - exit 1 - fi - echo "All four required release secrets are available." - - create_release_tag: - name: Create validated release tag - needs: - - preflight - - build - - release_confirmation - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - actions: read - contents: write - - steps: - - name: Create or verify the exact tag - env: - GH_TOKEN: ${{ github.token }} - RELEASE_SHA: ${{ needs.preflight.outputs.release_sha }} - RELEASE_TAG: ${{ needs.preflight.outputs.release_tag }} - run: | - set -euo pipefail - - if tag_json="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$RELEASE_TAG" 2>/dev/null)"; then - tag_sha="$(jq -r '.object.sha' <<<"$tag_json")" - if [[ "$tag_sha" != "$RELEASE_SHA" ]]; then - echo "Existing tag $RELEASE_TAG resolves to $tag_sha instead of $RELEASE_SHA" >&2 - exit 1 - fi - echo "Existing tag $RELEASE_TAG already points to $RELEASE_SHA" - else - gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \ - -f ref="refs/tags/$RELEASE_TAG" \ - -f sha="$RELEASE_SHA" >/dev/null - echo "Created tag $RELEASE_TAG at $RELEASE_SHA" - fi - - created_sha="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$RELEASE_TAG" --jq '.object.sha')" - if [[ "$created_sha" != "$RELEASE_SHA" ]]; then - echo "Tag verification returned $created_sha instead of $RELEASE_SHA" >&2 - exit 1 - fi - - publish_maven: - name: Publish Maven - needs: - - preflight - - build - - create_release_tag - runs-on: ubuntu-latest - timeout-minutes: 30 - - steps: - - name: Check out the tagged publication definition - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ needs.preflight.outputs.release_sha }} - - - name: Install pinned Java 25 Mavenizer runtime - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 - with: - distribution: temurin - java-version: '25.0.3+9.0.LTS' - - - name: Install pinned Java 8 launcher toolchain - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 - with: - distribution: temurin - java-version: '8.0.502+7' - - - name: Install target Java toolchain - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 - with: - distribution: temurin - java-version: ${{ needs.preflight.outputs.java_setup_version }} - - - name: Record target Java toolchain path - shell: bash - run: echo "MODERNMETALS_TARGET_JAVA_HOME=$JAVA_HOME" >> "$GITHUB_ENV" - - - name: Install separate Java for Gradle - if: needs.preflight.outputs.install_gradle_java == 'true' - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 - with: - distribution: temurin - java-version: ${{ needs.preflight.outputs.gradle_java_setup_version }} - - - name: Set up Gradle - uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - - name: Resolve explicit Gradle Java installations - id: java-paths + RELEASE_SHA: ${{ inputs.release_sha }} + CI_RUN_ID: ${{ inputs.ci_run_id }} + PLAYER_SHA256: ${{ inputs.player_sha256 }} shell: bash run: | set -euo pipefail - candidates=( - "$JAVA_HOME_25_X64" - "$JAVA_HOME_8_X64" - "$MODERNMETALS_TARGET_JAVA_HOME" - "$JAVA_HOME" - ) - paths= - for candidate in "${candidates[@]}"; do - test -x "$candidate/bin/java" - canonical="$(cd "$candidate" && pwd -P)" - if [[ ",$paths," != *",$canonical,"* ]]; then - paths="${paths:+$paths,}$canonical" - fi - done - echo "paths=$paths" >> "$GITHUB_OUTPUT" - - - name: Download immutable release artifact + repo=MinecraftModDevelopmentMods/BaseMinerals + branch=master-1.10.2 + [[ "$GITHUB_REPOSITORY" == "$repo" && "$GITHUB_REF" == refs/heads/master-1.12 ]] + [[ "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.110021$ ]] + [[ "$RELEASE_SHA" =~ ^[a-f0-9]{40}$ && "$PLAYER_SHA256" =~ ^[a-fA-F0-9]{64}$ && "$CI_RUN_ID" =~ ^[0-9]+$ ]] + + branch_sha="$(gh api "repos/$repo/branches/$branch" --jq .commit.sha)" + if [[ "$RELEASE_SHA" != "$branch_sha" ]]; then + echo "Expected the current upstream $branch SHA, found $branch_sha" >&2 + exit 1 + fi + gh api "repos/$repo/actions/runs/$CI_RUN_ID" | + jq -e --arg sha "$RELEASE_SHA" --arg repo "$repo" --arg branch "$branch" ' + .head_sha == $sha and .head_repository.full_name == $repo + and .head_branch == $branch and .event == "push" + and .status == "completed" and .conclusion == "success" + and .path == ".github/workflows/ci.yml"' >/dev/null + + properties="$(gh api "repos/$repo/contents/gradle.properties?ref=$RELEASE_SHA" --jq .content | base64 --decode)" + grep -Fx "mod_version=$RELEASE_VERSION" <<< "$properties" + grep -Fx 'minecraft_version=1.10.2' <<< "$properties" + grep -Fx 'loader_name=forge' <<< "$properties" + grep -Fx 'curseforge_project_id=270972' <<< "$properties" + gh api "repos/$repo/contents/CHANGELOG.txt?ref=$RELEASE_SHA" --jq .content | + base64 --decode > "$RUNNER_TEMP/merged-changelog.txt" + + - name: Download the audited CI bundle uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: - name: ${{ needs.build.outputs.artifact_name }} + name: BaseMinerals-1.10.2-${{ inputs.release_sha }} path: ${{ runner.temp }}/release-input + github-token: ${{ github.token }} + run-id: ${{ inputs.ci_run_id }} - - name: Stage exact target dependencies - id: dependencies - shell: bash - run: | - set -euo pipefail - mirror="$RUNNER_TEMP/dependency-mirror" - if [[ -f gradle/stage-legacy-dependencies.sh ]]; then - bash gradle/stage-legacy-dependencies.sh "$mirror" - property=legacyDependencyVerificationRepository - elif [[ -f gradle/stage-orespawn-release.sh ]]; then - bash gradle/stage-orespawn-release.sh "$mirror" - property=orespawnVerificationRepository - else - echo "Selected target has no checksum-sealed dependency staging script" >&2 - exit 1 - fi - echo "repository=$mirror" >> "$GITHUB_OUTPUT" - echo "property=$property" >> "$GITHUB_OUTPUT" - - - name: Verify artifact and Maven credentials + - name: Verify the bundle and the tested player jar + id: bundle env: - MAVEN_UPLOAD_URL: ${{ secrets.MAVEN_UPLOAD_URL }} - MAVEN_UPLOAD_USERNAME: ${{ secrets.MAVEN_UPLOAD_USERNAME }} - MAVEN_UPLOAD_PASSWORD: ${{ secrets.MAVEN_UPLOAD_PASSWORD }} + RELEASE_VERSION: ${{ inputs.release_version }} + PLAYER_SHA256: ${{ inputs.player_sha256 }} + CI_RUN_ID: ${{ inputs.ci_run_id }} + RELEASE_SHA: ${{ inputs.release_sha }} + shell: bash run: | set -euo pipefail - (cd "$RUNNER_TEMP/release-input" && sha256sum --check SHA256SUMS) - if [[ -z "$MAVEN_UPLOAD_URL" || -z "$MAVEN_UPLOAD_USERNAME" || -z "$MAVEN_UPLOAD_PASSWORD" ]]; then - echo "Maven upload URL and credentials must all be configured" >&2 - exit 1 - fi - if [[ "$MAVEN_UPLOAD_URL" == file:* ]]; then - echo "Maven publication cannot target a runner-local repository" >&2 - exit 1 - fi - - - name: Publish the prepared Maven artifacts - env: - MAVEN_UPLOAD_URL: ${{ secrets.MAVEN_UPLOAD_URL }} - MAVEN_UPLOAD_USERNAME: ${{ secrets.MAVEN_UPLOAD_USERNAME }} - MAVEN_UPLOAD_PASSWORD: ${{ secrets.MAVEN_UPLOAD_PASSWORD }} - run: | - chmod +x ./gradlew - dependency_argument="-P${{ steps.dependencies.outputs.property }}=${{ steps.dependencies.outputs.repository }}" - ./gradlew publishMavenJavaPublicationToReleaseRepository \ - -PpreparedReleaseDir="$RUNNER_TEMP/release-input" \ - "$dependency_argument" \ - --no-daemon --stacktrace \ - -Dorg.gradle.java.installations.paths="${{ steps.java-paths.outputs.paths }}" \ - -Dorg.gradle.java.installations.auto-detect=false \ - -Dorg.gradle.java.installations.auto-download=false - - publish_curseforge: - name: Publish CurseForge - needs: - - preflight - - build - - publish_maven - runs-on: ubuntu-latest - timeout-minutes: 20 - - steps: - - name: Download immutable release artifact - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - name: ${{ needs.build.outputs.artifact_name }} - path: ${{ runner.temp }}/release-input + cd "$RUNNER_TEMP/release-input" + jar="BaseMinerals-$RELEASE_VERSION.jar" + cmp "$RUNNER_TEMP/merged-changelog.txt" CHANGELOG.txt + ( + cd build/libs + sha256sum --strict --check ../release/SHA256SUMS + printf '%s %s\n' "${PLAYER_SHA256,,}" "$jar" | sha256sum --strict --check + ) + echo "jar=$RUNNER_TEMP/release-input/build/libs/$jar" >> "$GITHUB_OUTPUT" + echo "Verified $jar from CI run $CI_RUN_ID at $RELEASE_SHA." >> "$GITHUB_STEP_SUMMARY" - - name: Verify artifact and CurseForge credential + - name: Check CurseForge credential availability env: CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} + CONFIRM_LIVE: ${{ inputs.confirm_live_publication }} + shell: bash run: | - set -euo pipefail - (cd "$RUNNER_TEMP/release-input" && sha256sum --check SHA256SUMS) if [[ -z "$CURSEFORGE_TOKEN" ]]; then - echo "CURSEFORGE_TOKEN must be configured" >&2 - exit 1 + echo '::warning::CURSEFORGE_TOKEN is unavailable to Base Minerals.' + [[ "$CONFIRM_LIVE" == false ]] + else + echo 'The CurseForge upload credential is available.' fi - - name: Publish Base Minerals + - name: Publish the tested jar to CurseForge + if: inputs.confirm_live_publication uses: Kira-NT/mc-publish@52307b03863581dec6b652b83e597aec02ebb075 # v3.3.1 with: curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} - curseforge-id: ${{ needs.preflight.outputs.curseforge_project_id }} - name: Base Minerals ${{ needs.preflight.outputs.release_version }} for Minecraft ${{ needs.preflight.outputs.minecraft_version }} (${{ needs.preflight.outputs.loader_display }}) - version: ${{ needs.preflight.outputs.release_version }} - version-type: ${{ inputs.curseforge_release_level }} + curseforge-id: 270972 + curseforge-dependencies: | + 240967(required) + 245586(required) + name: Base Minerals ${{ inputs.release_version }} for Minecraft 1.10.2 (Forge) + version: ${{ inputs.release_version }} + version-type: release changelog-file: ${{ runner.temp }}/release-input/CHANGELOG.txt - loaders: ${{ needs.preflight.outputs.loader_name }} - game-versions: ${{ needs.preflight.outputs.minecraft_version }} + loaders: forge + game-versions: 1.10.2 game-version-filter: none environment: client | server - java: Java ${{ needs.preflight.outputs.java_version }} - curseforge-dependencies: ${{ needs.preflight.outputs.curseforge_dependencies }} - fail-mode: fail - files: | - ${{ runner.temp }}/release-input/${{ needs.preflight.outputs.main_jar }} - ${{ runner.temp }}/release-input/${{ needs.preflight.outputs.sources_jar }} - ${{ runner.temp }}/release-input/${{ needs.preflight.outputs.javadoc_jar }} - - publish_github: - name: Publish GitHub Release - needs: - - preflight - - build - - publish_curseforge - runs-on: ubuntu-latest - timeout-minutes: 20 - permissions: - actions: read - contents: write - - steps: - - name: Download immutable release artifact - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - name: ${{ needs.build.outputs.artifact_name }} - path: ${{ runner.temp }}/release-input - - - name: Verify artifact - run: (cd "$RUNNER_TEMP/release-input" && sha256sum --check SHA256SUMS) - - - name: Publish GitHub Release last - uses: Kira-NT/mc-publish@52307b03863581dec6b652b83e597aec02ebb075 # v3.3.1 - with: - github-token: ${{ github.token }} - github-tag: ${{ needs.preflight.outputs.release_tag }} - github-commitish: ${{ needs.preflight.outputs.release_sha }} - github-draft: false - github-prerelease: false - name: Base Minerals ${{ needs.preflight.outputs.release_version }} for Minecraft ${{ needs.preflight.outputs.minecraft_version }} (${{ needs.preflight.outputs.loader_display }}) - version: ${{ needs.preflight.outputs.release_version }} - version-type: release - changelog-file: ${{ runner.temp }}/release-input/CHANGELOG.txt + java: Java 8 fail-mode: fail - files: | - ${{ runner.temp }}/release-input/${{ needs.preflight.outputs.main_jar }} - ${{ runner.temp }}/release-input/${{ needs.preflight.outputs.sources_jar }} - ${{ runner.temp }}/release-input/${{ needs.preflight.outputs.javadoc_jar }} - ${{ runner.temp }}/release-input/SHA256SUMS + files: ${{ steps.bundle.outputs.jar }} diff --git a/.github/workflows/release-on-tag.yml b/.github/workflows/release-on-tag.yml index 0abc0f6..6178058 100644 --- a/.github/workflows/release-on-tag.yml +++ b/.github/workflows/release-on-tag.yml @@ -79,9 +79,7 @@ jobs: echo echo "**Nothing has been published.**" echo - echo "To continue, open [Release Base Minerals]($RELEASE_WORKFLOW_URL), select **Run workflow**, and enter:" - echo - echo "- release_version: \`$GITHUB_REF_NAME\`" - echo "- curseforge_release_level: \`release\`, \`beta\`, or \`alpha\`" - echo "- confirm_live_publication: \`true\`" + echo "For a CurseForge release, open [Release Base Minerals]($RELEASE_WORKFLOW_URL) on master-1.12." + echo "Use the release version, merged SHA, successful upstream CI run ID and tested jar SHA-256." + echo "Leave confirmation off for the first run to verify the release inputs." } >> "$GITHUB_STEP_SUMMARY" diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c0b1fa8..474749f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,13 +1,11 @@ 2.5.1.110021 for 1.10.2 -Move the 1.10.2 build to ForgeGradle 7 and Forge 12.18.3.2511. -Update the Base Metals and OreSpawn dependencies and move the Java packages to zone.moddev.mc.baseminerals. Keep existing registry names and configuration keys. -Use OreSpawn 4 for ore generation, with new depths and deposit shapes for the seven minerals. Existing chunks are not regenerated. -Fix material and fluid switches, charcoal ownership, disabled-content recipes and achievements, and client models and molten textures. -Add restart-required material settings to Forge Mods and OreSpawn Mods, plus automated build, compatibility and world-generation checks. -Use KiriCattus's ore overlays for all seven ores. Generate the models during the build, with support for full ore textures as well. - -Known issues: -- OreSpawn 4.1.2 can add a second lithium rule when an OS1-imported world is moved without its original global import file. -- Published Electric Advantage 2.2.0 and Power Advantage 2.3.0 fail to load with the required Base Metals version. -- Mineralogy's default keeps separate sulfur placement. Reviewed shared-output settings have been tested. +This brings the 1.10.2 build up to date on Forge 12.18.3.2511. It needs Base Metals 2.6.0.110021 and OreSpawn 4.1.6.110021. + +The seven ores have new depths and deposit shapes, and now use KiriCattus's overlays on vanilla stone. Saved ore settings and existing chunks are kept. OreSpawn now preserves the imported lithium rule when you move an old OS1 world and can remove an untouched duplicate left by an earlier version. + +Base Electric shares sulfur and lithium placement with Base Minerals. In a pack with both Base Electric and Mineralogy, Mineralogy places sulfur and Base Minerals places lithium. + +Material settings are available from Forge Mods and OreSpawn Mods and take effect after a restart. This update also fixes disabled material recipes and achievements, charcoal ownership, and molten material textures. + +The old Electric Advantage 2.2.0 and Power Advantage 2.3.0 releases are incompatible with this Base Metals build. diff --git a/README.md b/README.md index ba2d37f..09d481f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ not generate as ore. The seven ores use KiriCattus's overlays on Minecraft's stone texture. This branch targets Minecraft 1.10.2 and Forge 12.18.3.2511 or later. It requires -Base Metals 2.5.1.110021 and OreSpawn 4.1.2.110021, or compatible versions in the +Base Metals 2.6.0.110021 and OreSpawn 4.1.6.110021, or compatible versions in the declared ranges. Mineralogy is optional. Tinkers' Construct adds melting and casting for lithium and silicon. @@ -20,15 +20,14 @@ and deposit shapes for each mineral. Vanilla stone and its variants are valid hosts, and Base Minerals does not replace terrain. Existing registry names and configuration keys are kept. Saved OreSpawn profiles -and OS3 imports keep their settings, and generated chunks are not rewritten. -OS1 imports have a known issue when a world is moved without its original global -import file; see the [known issues](docs/KNOWN_ISSUES.md). Defaults for new worlds -can be changed in `config/baseminerals-orespawn.json`. +and OS1 and OS3 imports keep their settings. OreSpawn 4.1.6 fixes duplicate +lithium placement when an OS1-imported world moves without its provider file. +Defaults for new worlds can be changed in `config/baseminerals-orespawn.json`. See [ore generation](docs/ORE_GENERATION.md), [building](docs/BUILDING.md), [verification](tools/validation/legacy110/README.md) and [release preparation](docs/RELEASING.md). -The published Electric Advantage and Power Advantage versions also have a -compatibility problem with the required Base Metals version. The -[known issues](docs/KNOWN_ISSUES.md) describe both problems and the test results. +The historical Electric Advantage and Power Advantage releases have a +compatibility problem with the required Base Metals version. See the +[known issues](docs/KNOWN_ISSUES.md) for details. diff --git a/docs/KNOWN_ISSUES.md b/docs/KNOWN_ISSUES.md index eb9519d..f5fabea 100644 --- a/docs/KNOWN_ISSUES.md +++ b/docs/KNOWN_ISSUES.md @@ -1,40 +1,21 @@ # Known issues for Minecraft 1.10.2 -The build and fresh-world generation checks pass. Two compatibility problems -remain with the pinned dependencies. +## OS1 profiles with an edited lithium rule -## Moving an OS1-imported world can add a second lithium rule - -Pinned public OreSpawn 4.1.2.110021 converts an OS1 lithium entry to -`baseminerals:legacy/baseminerals_lithium_ore_0`. First import retains its custom -frequency 1.5, quantity 4 and Y=8..39. When only the saved world is copied into a -fresh instance without the original global OS1 file, provider merging adds -`baseminerals:legacy/lithium_ore` with the fresh defaults alongside it. Both -remain active in separate placement channels. A disposable 256-chunk later -sample contained 15,759 lithium blocks, rather than preserving the imported -budget alone. - -This needs a fix in OreSpawn's import and provider merging. Its published API -has no rule-ID migration alias or way to edit an active profile. Turning off -all provider merging would also stop missing rules from being added. Base -Minerals does not rewrite world profiles or call OreSpawn's internal classes. - -Keeping the original global OS1 file lets the importer suppress the extra rule -again on reload; that control passes. A saved world profile alone fails to retain -its budget. The packaged suite now asserts one lithium rule after profile-only -reload. The standalone reproduction fails on this pin, and -`run_continuity_checks.py` also checks that the rule IDs for each imported output -stay the same. The earlier checks verified settings but missed the extra rule. -OS3 imports with matching rule IDs and saved selector-only profiles pass these -checks. +[OreSpawn 4.1.6.110021](https://www.curseforge.com/minecraft/mc-mods/mmd-orespawn/files/9518063) +keeps the imported lithium rule when a world moves without its original +configuration. It backs up an affected profile before removing an untouched +duplicate. The packaged tests cover the move and the repair of a copied 4.1.2 +profile. If the added rule or its source policy was edited, OreSpawn preserves +the edits and flags the rule for review. ## Historical Electric Advantage dependencies -Public Electric Advantage 2.2.0 / Power Advantage 2.3.0 fail before world load -against required Base Metals 2.5.1.110021: Power Advantage references missing -`cyano.basemetals.init.Materials`. The combined Mineralogy case fails too. -Synthetic source-policy tests do not clear this public integration gate. +Electric Advantage 2.2.0 and Power Advantage 2.3.0 fail before world load with +Base Metals 2.6.0.110021 because Power Advantage references the old +`cyano.basemetals.init.Materials` class. The same failure occurs with +Mineralogy installed. -Public Mineralogy 6.0.1.110021 loads and supports reviewed sulfur consolidation. -Its fresh profile retains separate sulfur placement; automatic default -consolidation is not claimed. +Base Electric 2.2.6.110021 and Base Power 2.4.4.110021 passed the fresh and +reload shared-ore checks with the pinned Base Metals and OreSpawn builds. +See [ore generation](ORE_GENERATION.md) for the tested defaults. diff --git a/docs/ORE_GENERATION.md b/docs/ORE_GENERATION.md index cd335c3..c6d2288 100644 --- a/docs/ORE_GENERATION.md +++ b/docs/ORE_GENERATION.md @@ -51,6 +51,10 @@ does not become controllable merely through an Ore Dictionary alias. An existing profile choice remains authoritative even after sources become manageable. Review the resulting source groups in OreSpawn before changing them. +With OreSpawn 4.1.6, fresh worlds using public Base Electric share sulfur and +lithium outputs under one placement source per ore. With Mineralogy installed, +Mineralogy places sulfur. Base Minerals places lithium in the combined pack. + Native global overrides use `config/baseminerals-orespawn.json`. Existing world profiles and native overrides take precedence over legacy imports. Supported OS1/OS3 custom and disabled rules retain their settings rather than adopting this @@ -59,5 +63,6 @@ these are alternative dimension declarations, not two generation passes. Existin ore entries are kept as whole entries, including older selector-only rules. Missing entries follow OreSpawn's normal provider merge behavior. Retrogen stays disabled; generated chunks are unchanged. Keep legacy files until the importer report and resulting settings have been reviewed. -The pinned engine currently reinserts a native rule after an OS1-imported world -reload; that migration gate fails. See [qualification limits](KNOWN_ISSUES.md). +OreSpawn 4.1.6 keeps OS1 placement settings when only the saved world is moved. +It backs up profiles before removing an untouched duplicate and flags edited +duplicates for review. See [qualification limits](KNOWN_ISSUES.md). diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 8cc23e4..21fefe8 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -10,22 +10,18 @@ CI has a cold bootstrap/offline rebuild, build/tests, resource/schema checks, packaged server qualification, Eclipse generation and clean reproducibility check. CodeQL/wrapper checks are separate. Actions use full commit hashes. -Versions use `Major.Minor.Patch.110021`. Tags validate metadata/prior CI without -publishing. The dispatcher requires `confirm_live_publication`, the upstream -repository, matching target/tag/commit and successful hosted checks. It publishes -the same candidate bytes to Maven, CurseForge **270972**, then GitHub. CurseForge -requires Base Metals **240967** and MMD OreSpawn **245586**. Credentials and an -HTTPS Maven target are required. +Run `deploy-release.yml` from MMD's default branch, `master-1.12`. Enter the +`Major.Minor.Patch.110021` version, full merged `master-1.10.2` SHA, successful +upstream push CI run ID and SHA-256 of the tested player jar. Run it once with +confirmation off to verify the source, changelog and CI bundle. -The dispatcher must be installed on the repository's default branch before a -manual release can be started. Merging the 1.10 branch does not install it on the -1.12 default branch. Publication is a separate step and needs approval. If an -upload times out, check its status before trying again. +Set `confirm_live_publication` to upload the verified player jar to CurseForge +project **270972** with Base Metals **240967** and MMD OreSpawn **245586** marked +as required. The workflow needs access to `CURSEFORGE_TOKEN`. Check the public +file and its download checksum after upload. If an upload times out, check its +status before trying again. -The [known issues](KNOWN_ISSUES.md) remain unresolved: a moved OS1-imported world -can gain a second lithium rule, and the published Electric Advantage / Power -Advantage pair fails before world load with the required Base Metals version. -The synthetic source-policy tests do not prove that those public mods load. -Mineralogy's reviewed sulfur settings pass, while its default keeps separate -placement. Keep these results with the release candidate; the full compatibility -suite has not passed. +The historical Electric Advantage and Power Advantage pair fails before world +load with the required Base Metals version. Keep the public compatibility +results and the OS1 migration checks with the release candidate. See the +[known issues](KNOWN_ISSUES.md). diff --git a/gradle.properties b/gradle.properties index 1cb5b11..a909d15 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,8 +26,8 @@ curseforge_project_id=270972 cf_requirements=mmd-orespawn,base-metals orespawn_curse_project_id=245586 coreplugin=zone.moddev.mc.baseminerals.compat.BaseMineralsLoadingPlugin -orespawn_version=4.1.2.110021 -orespawn_version_range=[4.1.2.110021,5.0.0) +orespawn_version=4.1.6.110021 +orespawn_version_range=[4.1.6.110021,5.0.0) -basemetals_version=2.5.1.110021 -basemetals_version_range=[2.5.1.110021,2.6.0) +basemetals_version=2.6.0.110021 +basemetals_version_range=[2.6.0.110021,2.7.0) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 4228676..56df6cd 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -40,14 +40,14 @@ tasks.register('verifyReleaseDependencies') { doLast { def artifacts = configurations.legacyModArtifacts.resolvedConfiguration.resolvedArtifacts def orespawn = specs.find { it.id == 'orespawn' } - if (orespawn.coordinate != 'curse.maven:mmd-orespawn-245586:9276430' - || orespawn.sha256 != '4D4975421FEEBF17505056306D06B0344D7A4553B6275885D7C5C5065B0348A6') { - throw new GradleException('Use the verified OreSpawn 4.1.2.110021 release.') + if (orespawn.coordinate != 'curse.maven:mmd-orespawn-245586:9518063' + || orespawn.sha256 != '05DB7CBFAADC815D6A713DACDFB9F0647BCED49CCFC357FB2FF010E95BD1379F') { + throw new GradleException('Use the verified OreSpawn 4.1.6.110021 release.') } def basemetals = specs.find { it.id == 'basemetals' } - if (basemetals.coordinate != 'curse.maven:base-metals-240967:9280029' - || basemetals.sha256 != '8BB1823592DCD558D17C4848AE917266FE7197B754CA628297DF837CFB3D20A3') { - throw new GradleException('Use the verified Base Metals 2.5.1.110021 release.') + if (basemetals.coordinate != 'curse.maven:base-metals-240967:9524447' + || basemetals.sha256 != '9CA948215549C4A3D30D76339932ED489FB7D2C73A71A5F4F8F68456B8BC276B') { + throw new GradleException('Use the verified Base Metals 2.6.0.110021 release.') } specs.each { spec -> def parts = spec.coordinate.split(':') diff --git a/gradle/dependencies.json b/gradle/dependencies.json index f7d01ee..fb27ed8 100644 --- a/gradle/dependencies.json +++ b/gradle/dependencies.json @@ -1,15 +1,15 @@ [ { "id": "basemetals", - "coordinate": "curse.maven:base-metals-240967:9280029", - "sha256": "8BB1823592DCD558D17C4848AE917266FE7197B754CA628297DF837CFB3D20A3", + "coordinate": "curse.maven:base-metals-240967:9524447", + "sha256": "9CA948215549C4A3D30D76339932ED489FB7D2C73A71A5F4F8F68456B8BC276B", "repository": "https://www.cursemaven.com", "runtime": true }, { "id": "orespawn", - "coordinate": "curse.maven:mmd-orespawn-245586:9276430", - "sha256": "4D4975421FEEBF17505056306D06B0344D7A4553B6275885D7C5C5065B0348A6", + "coordinate": "curse.maven:mmd-orespawn-245586:9518063", + "sha256": "05DB7CBFAADC815D6A713DACDFB9F0647BCED49CCFC357FB2FF010E95BD1379F", "repository": "https://www.cursemaven.com", "runtime": true }, diff --git a/gradle/release/artifacts.gradle b/gradle/release/artifacts.gradle index 0adee2d..73d95e6 100644 --- a/gradle/release/artifacts.gradle +++ b/gradle/release/artifacts.gradle @@ -47,13 +47,15 @@ tasks.register('verifyReleaseConfiguration') { if (!source.contains('VERSION = "' + project.version + '"') || !source.contains('MODID = "baseminerals"')) { throw new GradleException('The mod identity differs from the build metadata.') } - if (project.orespawn_version != '4.1.2.110021' - || project.orespawn_version_range != '[4.1.2.110021,5.0.0)' + if (project.orespawn_version != '4.1.6.110021' + || project.orespawn_version_range != '[4.1.6.110021,5.0.0)' || !source.contains('required-after:orespawn@' + project.orespawn_version_range) || !source.contains('required-after:Forge@[12.18.3.2511,)')) { throw new GradleException('The OreSpawn or Forge runtime requirement changed.') } - if (!source.contains('required-after:basemetals@[2.5.1.110021,2.6.0)')) { + if (project.basemetals_version != '2.6.0.110021' + || project.basemetals_version_range != '[2.6.0.110021,2.7.0)' + || !source.contains('required-after:basemetals@' + project.basemetals_version_range)) { throw new GradleException('The published Base Metals runtime requirement changed.') } } diff --git a/src/main/java/zone/moddev/mc/baseminerals/BaseMinerals.java b/src/main/java/zone/moddev/mc/baseminerals/BaseMinerals.java index a2d313a..2a97d5a 100644 --- a/src/main/java/zone/moddev/mc/baseminerals/BaseMinerals.java +++ b/src/main/java/zone/moddev/mc/baseminerals/BaseMinerals.java @@ -26,7 +26,7 @@ modid = BaseMinerals.MODID, name = BaseMinerals.NAME, version = BaseMinerals.VERSION, - dependencies = "required-after:Forge@[12.18.3.2511,);required-after:basemetals@[2.5.1.110021,2.6.0);required-after:orespawn@[4.1.2.110021,5.0.0);after:tconstruct;after:enderio;before:buildingbricks", + dependencies = "required-after:Forge@[12.18.3.2511,);required-after:basemetals@[2.6.0.110021,2.7.0);required-after:orespawn@[4.1.6.110021,5.0.0);after:tconstruct;after:enderio;before:buildingbricks", acceptedMinecraftVersions = "[1.10.2]", guiFactory = "zone.moddev.mc.baseminerals.client.BaseMineralsGuiFactory", updateJSON = BaseMinerals.UPDATEJSON) diff --git a/tools/validation/legacy110/README.md b/tools/validation/legacy110/README.md index 6c037b0..b7d2f93 100644 --- a/tools/validation/legacy110/README.md +++ b/tools/validation/legacy110/README.md @@ -24,11 +24,11 @@ material is tested through actual generation, rather than registration alone. Seed zero needs explicit fresh metadata because server.properties treats `0` as random. `--quick` is only an early smoke. -The full packaged suite currently fails when it loads an OS1-imported world -without the original global import file: the pinned engine adds a second native -lithium rule. Run `reproduce_os1_reload.py` with `--java`, `--template` and a new -`--output` directory for the shorter reproduction. See the -[known issues](../../../docs/KNOWN_ISSUES.md). This failure is kept in the suite. +The packaged suite requires a single imported lithium rule after moving an OS1 +world without its global import file. Run `reproduce_os1_reload.py` with +`--java`, `--template` and a new `--output` directory for the shorter check. +Keep the assertion when updating OreSpawn. See the +[known issues](../../../docs/KNOWN_ISSUES.md) for edited profiles. `run_overlap_suite.py` stages public sibling jars pinned in `overlap_dependencies.json` and captures their real source policies. Its Electric diff --git a/tools/validation/legacy110/dependency_requirements.py b/tools/validation/legacy110/dependency_requirements.py index d16ff03..0f31c5b 100644 --- a/tools/validation/legacy110/dependency_requirements.py +++ b/tools/validation/legacy110/dependency_requirements.py @@ -9,7 +9,9 @@ OLD = { 'base':('base-metals-240967','2323100','f919cef794c73f02758bbd967346dba0b53f6383153c7e29bd79f211cda8c319'), - 'os':('mmd-orespawn-245586','2533153','d964148c20175e16ccefab02ae43a181a50dc08a1d636a77e59cfe8c8ea8d41a') + 'previous_base':('base-metals-240967','9280029','8bb1823592dcd558d17c4848ae917266fe7197b754ca628297df837cfb3d20a3'), + 'os':('mmd-orespawn-245586','2533153','d964148c20175e16ccefab02ae43a181a50dc08a1d636a77e59cfe8c8ea8d41a'), + 'os4':('mmd-orespawn-245586','9276430','4d4975421feebf17505056306d06b0344d7a4553b6275885d7c5c5065b0348a6') } def verify(java,template,output,base,orespawn,minerals): @@ -22,10 +24,12 @@ def verify(java,template,output,base,orespawn,minerals): assert hashlib.sha256(target.read_bytes()).hexdigest()==expected,'Public fixture checksum mismatch' old[key]=target scenarios={ - 'missing-base':([orespawn,minerals],'basemetals','2.5.1.110021'), - 'old-base':([old['base'],orespawn,minerals],'basemetals','2.5.1.110021'), - 'missing-orespawn':([base,minerals],'orespawn','4.1.2.110021'), - 'old-orespawn':([base,old['os'],minerals],'orespawn','4.1.2.110021') + 'missing-base':([orespawn,minerals],'basemetals','2.6.0.110021'), + 'old-base':([old['base'],orespawn,minerals],'basemetals','2.6.0.110021'), + 'previous-base':([old['previous_base'],orespawn,minerals],'basemetals','2.6.0.110021'), + 'missing-orespawn':([base,minerals],'orespawn','4.1.6.110021'), + 'old-orespawn':([base,old['os'],minerals],'orespawn','4.1.6.110021'), + 'old-orespawn4':([base,old['os4'],minerals],'orespawn','4.1.6.110021') } result={} for name,(jars,modid,version) in scenarios.items():