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
29 changes: 20 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
build:
name: Build, test, and audit
runs-on: ubuntu-latest
timeout-minutes: 45
timeout-minutes: 60

steps:
- name: Check out source
Expand All @@ -30,7 +30,7 @@ jobs:
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '8'
java-version: '8.0.502+7'

- name: Install Java 17 for Gradle
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
Expand All @@ -39,15 +39,24 @@ jobs:
java-version: '17'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@4733eaac7c1b0da527e4206b7671e0061de1ce37 # v6
uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6

- name: Make the wrapper executable
run: chmod +x ./gradlew

- name: Stage exact OreSpawn release dependency
id: orespawn
run: |
mirror="$RUNNER_TEMP/orespawn-mirror"
bash gradle/stage-orespawn-release.sh "$mirror"
echo "repository=$mirror" >> "$GITHUB_OUTPUT"

- name: Build, test, and audit release artifacts
run: >-
./gradlew clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts
writeReleaseChecksums --no-daemon --stacktrace
writeReleaseChecksums verifyEclipseProductionClasspath
-PorespawnVerificationRepository=${{ steps.orespawn.outputs.repository }}
--no-daemon --stacktrace

- name: Upload audited release candidate
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
Expand All @@ -60,15 +69,17 @@ jobs:
build/libs/Mineralogy-6.0.1.110021-sources.jar
build/libs/Mineralogy-6.0.1.110021-javadoc.jar
build/release/SHA256SUMS
CHANGELOG.txt

- name: Upload test reports on failure
- name: Upload diagnostics on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: Mineralogy-1.10.2-test-reports-${{ github.sha }}
name: Mineralogy-1.10.2-diagnostics-${{ github.sha }}
if-no-files-found: ignore
retention-days: 14
path: |
build/test-results/test/**
build/reports/tests/test/**
build/reports/problems/**
build/test-results/**
build/reports/**
build/*-run/logs/**
build/problems/**
53 changes: 53 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CodeQL

on:
push:
branches:
- master-1.10.2
- 'feature/**'
pull_request:
branches:
- master-1.10.2

permissions:
actions: read
contents: read
security-events: write

jobs:
analyze:
name: Analyze Java
runs-on: ubuntu-latest
timeout-minutes: 45

steps:
- name: Check out source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Install Java 8 toolchain
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '8.0.502+7'

- name: Install Java 17 for Gradle
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: microsoft
java-version: '17'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6

- name: Initialize CodeQL
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4
with:
languages: java-kotlin

- name: Compile production code
run: |
chmod +x ./gradlew
./gradlew clean classes --rerun-tasks --no-build-cache --no-daemon --stacktrace

- name: Analyze
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4
77 changes: 50 additions & 27 deletions .github/workflows/release-on-tag.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
name: Start Mineralogy release from tag
name: Validate Mineralogy release tag

on:
push:
tags:
- '1.10.2-*'
- '*.*.*.*'

permissions:
actions: write
actions: read
contents: read

concurrency:
group: mineralogy-release-starter-${{ github.ref_name }}
group: mineralogy-release-tag-${{ github.ref_name }}
cancel-in-progress: false

jobs:
dispatch-release:
name: Validate tag and start guarded release
validate-release-tag:
name: Validate tag for manual release confirmation
if: github.repository == 'MinecraftModDevelopmentMods/MinecraftMineralogy'
runs-on: ubuntu-latest
timeout-minutes: 10
Expand All @@ -26,44 +26,67 @@ jobs:
with:
fetch-depth: 0

- name: Validate release tag and prior CI
id: validate
- name: Validate release tag, target metadata, and prior CI
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail

release_version="$(sed -n 's/^mod_version=//p' gradle.properties)"
if [[ ! "$release_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.110021$ ]]; then
echo "mod_version must use the four-part 1.10.2 Forge target format; found $release_version" >&2
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)"

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|neoforge:2) ;;
*) echo "Invalid loader metadata $loader_name/$loader_code" >&2; exit 1 ;;
esac
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}"

expected_tag="1.10.2-$release_version"
if [[ "$GITHUB_REF_NAME" != "$expected_tag" ]]; then
echo "Release tag must be $expected_tag; found $GITHUB_REF_NAME" >&2
if [[ ! "$release_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.${target_suffix}$ ]]; then
echo "mod_version $release_version does not match $minecraft_version $loader_name target $target_suffix" >&2
exit 1
fi
if [[ "$GITHUB_REF_NAME" != "$release_version" ]]; then
echo "Release tag must equal mod_version $release_version; found $GITHUB_REF_NAME" >&2
exit 1
fi

successful_ci="$(gh api \
"repos/$GITHUB_REPOSITORY/commits/$GITHUB_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 tagged commit has no successful Mineralogy 1.10 CI check" >&2
echo "The tagged commit has no successful Build, test, and audit check" >&2
exit 1
fi

echo "version=$release_version" >> "$GITHUB_OUTPUT"

- name: Start default-branch release workflow
- name: Record the manual publication interface
env:
GH_TOKEN: ${{ github.token }}
RELEASE_VERSION: ${{ steps.validate.outputs.version }}
RELEASE_WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/workflows/deploy-release.yml
run: |
gh workflow run deploy-release.yml \
--repo "$GITHUB_REPOSITORY" \
--ref master-1.12 \
-f mode=publish \
-f release_ref="$GITHUB_REF_NAME" \
-f curseforge_channel=release \
-f confirm_version="$RELEASE_VERSION"
{
echo "## Release tag validated"
echo
echo "Tag \`$GITHUB_REF_NAME\` matches the selected target and has a successful Build, test, and audit check."
echo
echo "If this tag was created outside the release workflow, nothing has been published."
echo
echo "To start or recover publication, open [Release Mineralogy]($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: checked"
} >> "$GITHUB_STEP_SUMMARY"
23 changes: 23 additions & 0 deletions .github/workflows/validate-gradle-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Validate Gradle Wrapper

on:
push:
branches:
- master-1.10.2
- 'feature/**'
pull_request:
branches:
- master-1.10.2

permissions:
contents: read

jobs:
validation:
name: Validation
runs-on: ubuntu-latest
steps:
- name: Check out source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Validate wrapper integrity
uses: gradle/actions/wrapper-validation@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
[![Discord](https://img.shields.io/badge/Discord-MMD-green.svg?style=flat&logo=Discord)](https://discord.moddev.zone)
[![CurseForge downloads](https://cf.way2muchnoise.eu/full_minecraft-mineralogy_downloads.svg)](https://www.curseforge.com/minecraft/mc-mods/minecraft-mineralogy)
[![Supported Minecraft versions](https://cf.way2muchnoise.eu/versions/Minecraft_minecraft-mineralogy_all.svg)](https://www.curseforge.com/minecraft/mc-mods/minecraft-mineralogy)
[![Build, test, and audit](https://github.com/MinecraftModDevelopmentMods/MinecraftMineralogy/actions/workflows/ci.yml/badge.svg?branch=master-1.10.2)](https://github.com/MinecraftModDevelopmentMods/MinecraftMineralogy/actions/workflows/ci.yml?query=branch%3Amaster-1.10.2)

# Mineralogy

Mineralogy 6 brings real-world rock types, mineral ores, construction blocks, and crude oil to Minecraft 1.10.2.
Expand Down
43 changes: 37 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ if (versionParts[3] != expectedTargetVersion) {

ext.functional_version = versionParts[0..2].join('.')
ext.display_version = project.mod_version
ext.release_tag = "${project.mc_version}-${project.mod_version}"
ext.release_tag = project.mod_version

java {
toolchain.languageVersion = JavaLanguageVersion.of(8)
Expand Down Expand Up @@ -120,6 +120,17 @@ repositories {
maven fg.forgeMaven
maven fg.minecraftLibsMaven

// Optional exact-coordinate mirror populated by CI from the official
// CurseForge file endpoint, avoiding transient CurseMaven throttling.
if (providers.gradleProperty('orespawnVerificationRepository').isPresent()) {
maven {
name = 'OreSpawnReleaseVerificationMirror'
url = uri(providers.gradleProperty('orespawnVerificationRepository').get())
metadataSources { artifact() }
content { includeGroup('curse.maven') }
}
}

exclusiveContent {
forRepository {
maven {
Expand All @@ -137,10 +148,13 @@ repositories {
name = 'MinecraftLibraries'
url = 'https://libraries.minecraft.net/'
}
maven {
name = 'CurseMaven'
url = 'https://www.cursemaven.com'
content { includeGroup('curse.maven') }
if (!providers.gradleProperty('orespawnVerificationRepository').isPresent()) {
maven {
name = 'CurseMaven'
url = 'https://www.cursemaven.com'
metadataSources { artifact() }
content { includeGroup('curse.maven') }
}
}
maven {
name = 'ModDevZone'
Expand Down Expand Up @@ -280,9 +294,19 @@ tasks.register('verifyReleaseConfiguration') {
if (project.mc_version != '1.10.2' || project.forge_version != '12.18.3.2511') {
throw new GradleException('Unexpected Minecraft or Forge target')
}
if (project.minecraft_version != project.mc_version
|| project.loader_name != 'forge'
|| project.loader_code != '1'
|| project.java_version != '8'
|| project.java_toolchain_version != '8.0.502+7'
|| project.gradle_java_version != '17'
|| project.curseforge_project_id != project.cf_project_id) {
throw new GradleException('Unexpected generic release dispatcher metadata')
}
if (project.orespawn_version != '4.0.6.110021'
|| project.orespawn_curse_project_id != '245586'
|| project.orespawn_curse_file_id != '8681675') {
|| project.orespawn_curse_file_id != '8681675'
|| project.orespawn_sha256 != '9FD6F2D6C5513A45C2B1CBE62F352A4F804FC7EE3EE30C44A6E5266BBF813E6D') {
throw new GradleException('Unexpected released OreSpawn dependency')
}
if (project.cf_project_id != '240974'
Expand Down Expand Up @@ -331,6 +355,13 @@ tasks.register('verifyReleaseDependencies') {
+ oreSpawnArtifacts.collect { it.moduleVersion.id })
}

String actualOreSpawnSha256 = MessageDigest.getInstance('SHA-256')
.digest(oreSpawnArtifacts.first().file.bytes).encodeHex().toString().toUpperCase()
if (actualOreSpawnSha256 != project.orespawn_sha256) {
throw new GradleException("Released OreSpawn SHA-256 is ${actualOreSpawnSha256}, expected "
+ project.orespawn_sha256)
}

ZipFile oreSpawn = new ZipFile(oreSpawnArtifacts.first().file)
try {
def metadataEntry = oreSpawn.getEntry('mcmod.info')
Expand Down
10 changes: 10 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ mod_group=zone.moddev.mc
# Major.Minor.Bug.Target; 110021 means Minecraft 1.10.2 on Forge.
mod_version=6.0.1.110021

# Release metadata consumed by the generic dispatcher.
minecraft_version=1.10.2
loader_name=forge
loader_code=1
java_version=8
java_toolchain_version=8.0.502+7
gradle_java_version=17
curseforge_project_id=240974

#Minumum Minecraft Version Mod will be built with
mc_version=1.10.2
#Forge version to use (Required)
Expand Down Expand Up @@ -53,6 +62,7 @@ dep_has_ats=false
orespawn_curse_project_id=245586
orespawn_curse_file_id=8681675
orespawn_version=4.0.6.110021
orespawn_sha256=9FD6F2D6C5513A45C2B1CBE62F352A4F804FC7EE3EE30C44A6E5266BBF813E6D
#File name of this mod's Access Transformers (If any)
#at_file = _at.cfg

Expand Down
Loading
Loading