diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 58209273..7493b7a5 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -8,18 +8,15 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Set up JDK 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v4 with: java-version: 17 distribution: zulu cache: gradle - name: Build with Gradle - env: - USERNAME: ${{ secrets.USERNAME }} - READ_PACKAGES_TOKEN: ${{ secrets.READ_PACKAGES_TOKEN }} - uses: nick-invision/retry@v2 + uses: nick-invision/retry@v3 with: timeout_minutes: 10 max_attempts: 3 @@ -29,10 +26,32 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./gradlew build publish - name: Cleanup old artifacts - uses: actions/delete-package-versions@v3 + uses: actions/delete-package-versions@v5 with: package-name: 'reliquary.reliquary' min-versions-to-keep: 10 + - name: Publish to CurseForge + env: + CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} + run: | + BRANCH_NAME=${GITHUB_REF##*/} + if [[ "$BRANCH_NAME" =~ ^[0-9]+\.[0-9]+\.([0-9]+|x)$ ]]; then + ./gradlew curseforge + else + echo "Branch name does not match the pattern: $BRANCH_NAME. Skipping CurseForge upload." + exit 0 + fi + - name: Publish to Modrinth + env: + MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} + run: | + BRANCH_NAME=${GITHUB_REF##*/} + if [[ "$BRANCH_NAME" =~ ^[0-9]+\.[0-9]+\.([0-9]+|x)$ ]]; then + ./gradlew modrinth + else + echo "Branch name does not match the pattern: $BRANCH_NAME. Skipping Modrinth upload." + exit 0 + fi - name: Code Quality env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -43,7 +62,7 @@ jobs: echo "VERSION_NAME=$(${{github.workspace}}/gradlew -q printVersionName | awk -F "version:" '{printf $2}')" >> $GITHUB_OUTPUT id: version - name : Compile version message - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | const gh = ${{ toJSON(github) }}; @@ -64,11 +83,9 @@ jobs: core.setOutput('EMBED_DESCRIPTION', description); id: embed - name: Send Discord Notification - uses: tsickert/discord-webhook@v5.3.0 + uses: tsickert/discord-webhook@v6.0.0 with: webhook-url: ${{ secrets.DISCORD_WEBHOOK }} - embeds: ${{steps.embed.outputs.EMBEDS}} - content: null embed-title: "${{steps.embed.outputs.EMBED_TITLE}}" embed-url: "${{steps.embed.outputs.EMBED_URL}}" embed-description: "${{steps.embed.outputs.EMBED_DESCRIPTION}}" diff --git a/.gitignore b/.gitignore index 5987ee64..cf5ec747 100755 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ !build.gradle !build.properties !gradle.properties +!settings.gradle !.github/ # include markdowns diff --git a/build.gradle b/build.gradle index 8c8fba82..446f23c7 100755 --- a/build.gradle +++ b/build.gradle @@ -1,26 +1,19 @@ -buildscript { - repositories { - maven { - name = "forge" - url = "https://maven.minecraftforge.net" - } - maven { url = 'https://maven.parchmentmc.org' } - mavenCentral() - } - dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true - classpath group: 'org.parchmentmc', name: 'librarian', version: '1.+', changing: true - } -} - plugins { - id "org.sonarqube" version "3.3" + id 'idea' + id "org.sonarqube" version "4.3.1.3277" id "maven-publish" + id 'net.neoforged.gradle' version '[6.0.18,6.2)' + id 'org.parchmentmc.librarian.forgegradle' version '1.+' + id "net.darkhax.curseforgegradle" version "1.1.15" + id "com.modrinth.minotaur" version "2.+" } -apply plugin: 'net.minecraftforge.gradle' -apply plugin: 'org.parchmentmc.librarian.forgegradle' -apply plugin: 'idea' +idea { + module { + downloadJavadoc = true + downloadSources = true + } +} repositories { mavenCentral() @@ -45,46 +38,33 @@ sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = co minecraft { mappings channel: 'parchment', version: "$parchment_version" + copyIdeResources = true accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') runs { - client { - properties 'forge.logging.markers': 'SCAN,REGISTRIES,REGISTRYDUMP' - properties 'forge.logging.console.level': 'debug' - property 'mixin.env.disableRefMap', 'true' + configureEach { + workingDirectory project.file("run/${it.name}") + property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + property 'forge.logging.console.level', 'debug' + property "mixin.env.disableRefMap", "true" jvmArg '-XX:+AllowEnhancedClassRedefinition' jvmArg '-XX:HotswapAgent=fatjar' - workingDirectory project.file('run') + mods { - reliquary { + "${mod_id}" { source sourceSets.main } } } + client { + } server { - properties 'forge.logging.markers': 'SCAN,REGISTRIES,REGISTRYDUMP' - properties 'forge.logging.console.level': 'debug' - property 'mixin.env.disableRefMap', 'true' - jvmArg '-XX:+AllowEnhancedClassRedefinition' - jvmArg '-XX:HotswapAgent=fatjar' - workingDirectory project.file('run') - mods { - reliquary { - source sourceSets.main - } - } } data { - properties 'forge.logging.markers': 'REGISTRIES,REGISTRYDUMP' - properties 'forge.logging.console.level': 'debug' - property 'mixin.env.disableRefMap', 'true' - properties 'fml.earlyprogresswindow': 'false' + property 'fml.earlyprogresswindow', 'false' + //property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" workingDirectory project.file('run') - mods { - reliquary { - source sourceSets.main - } - } - args '--mod', 'reliquary', '--all', '--output', file('src/generated/resources/') + args '--mod', mod_id, '--all', '--output', file('src/generated/resources/') + } } } @@ -94,7 +74,7 @@ sourceSets.main.resources { } dependencies { - minecraft "net.minecraftforge:forge:${project.minecraft_version}-${project.forge_version}" + minecraft "net.neoforged:forge:${minecraft_version}-${neo_version}" compileOnly fg.deobf("mezz.jei:jei-${jei_mc_version}:${jei_version}") runtimeOnly fg.deobf("mezz.jei:jei-${jei_mc_version}:${jei_version}") @@ -123,26 +103,36 @@ task generateSources(type: Copy) { filter { line -> line.replaceAll('@MOD_VERSION@', '${project.version}') } } -jar { +tasks.named('jar', Jar).configure { + from('/') { + include 'LICENSE' + } + manifest { - attributes(["Specification-Title" : "reliquary", - "Specification-Vendor" : "reliquary", - "Specification-Version" : "1", - "Implementation-Title" : project.name, - "Implementation-Version" : "${version}", - "Implementation-Vendor" : "reliquary", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")],) + attributes([ + 'Specification-Title' : mod_id, + 'Specification-Vendor' : "p3pp3rf1y", + 'Specification-Version' : '1', // We are version 1 of ourselves + 'Implementation-Title' : project.name, + 'Implementation-Version' : project.jar.archiveVersion, + 'Implementation-Vendor' : "p3pp3rf1y", + 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) } } -processResources { - // Exclude datagenerator .cache directory - exclude '.cache' +tasks.withType(ProcessResources).configureEach { + var replaceProperties = [ + minecraft_version : minecraft_version, minecraft_version_range: minecraft_version_range, + neo_version : neo_version, neo_version_range: neo_version_range, + loader_version_range: loader_version_range, + mod_id : mod_id, mod_version: mod_version, + mod_full_version : "${project.mod_version}.${getBuildNumber()}${getStable()}" + ] + inputs.properties replaceProperties - filesMatching('META-INF/mods.toml') { - filter { - it.replaceAll("project_version", project.version.toString()) - } + filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { + expand replaceProperties + [project: project] } } @@ -154,12 +144,16 @@ static def getBuildNumber() { } static def getStable() { - if ((System.getenv("GITHUB_REF") == null || System.getenv("GITHUB_REF").endsWith("-dev"))) { - return "unstable" + if (System.getenv("GITHUB_REF") == null || System.getenv("GITHUB_REF").endsWith("-dev")) { + return "-SNAPSHOT" } return "" } +tasks.named('publish').configure { + dependsOn 'reobfJar' +} + publishing { repositories { maven { @@ -179,6 +173,137 @@ publishing { } } +task generateChangelog { + doLast { + def changelog = new StringBuilder() + + // Function to remove characters with Unicode code points 129 or higher + def removeHighUnicodeChars = { text -> + text.codePoints() + .filter { codePoint -> codePoint <= 0x007F } // Keep only ASCII characters (U+0000 to U+007F) + .collect { codePoint -> new String(Character.toChars(codePoint)) } + .join('') + } + + // Function to format commit messages with nesting + def formatMultilineMessage = { message -> + // Split message by lines, trim whitespace, and create formatted list + def lines = message.split('\n') + def formattedMessage = lines[0].trim() // First line as top-level list item + if (lines.size() > 1) { + formattedMessage += "\n" + lines[1..-1].collect { line -> + // Trim the line and remove leading dash if present + def trimmedLine = line.trim() + if (trimmedLine.startsWith('-')) { + trimmedLine = trimmedLine.substring(1).trim() + } + " - ${trimmedLine}" // Nested list for additional lines + }.join('\n') + } + return formattedMessage + } + + // Function to remove [DEV] section from commit message + def removeDevSection = { message -> + def devIndex = message.indexOf('[DEV]') + if (devIndex != -1) { + return message.substring(0, devIndex).trim() + } + return message + } + + // Get the latest commit hash + def latestCommitHash = "git rev-parse HEAD".execute().text.trim() + + // Check if the latest commit is a merge commit + def parentCommits = "git rev-list --parents -n 1 ${latestCommitHash}".execute().text.split() + logger.info("Parent commits: ${parentCommits}") + + def commitMessages = [] + if (parentCommits.size() > 2) { // Merge commit has more than 2 parents + def firstParent = parentCommits[1] + def secondParent = parentCommits[2] + def gitLogCommand = [ + "bash", "-c", "git log --pretty=format:%B ${firstParent}..${secondParent}" + ] + commitMessages = gitLogCommand.execute().text.split('\n\n') // Split by two newlines for each commit + logger.info("Merge commit, ran git log command: ${gitLogCommand.join(' ')} and got ${commitMessages}") + } else { + // Single commit log + commitMessages = "git log -1 --pretty=%B".execute().text.split('\n\n') + // Split by two newlines for each commit + logger.info("Single commit, ran git log command: git log -1 --pretty=%B and got ${commitMessages}"); + } + + def features = [] + def fixes = [] + commitMessages.each { commitMessage -> + commitMessage = removeHighUnicodeChars(commitMessage) // Remove high Unicode characters + commitMessage = removeDevSection(commitMessage) // Remove [DEV] section + + if (commitMessage.startsWith('feat: ')) { + features.add(commitMessage.replaceFirst('feat: ', '').trim()) + } else if (commitMessage.startsWith('fix: ')) { + fixes.add(commitMessage.replaceFirst('fix: ', '').trim()) + } + } + + if (features) { + changelog.append("### Features\n") + features.each { feature -> changelog.append("- ${formatMultilineMessage(feature)}\n") } + } + + if (fixes) { + changelog.append("### Fixes\n") + fixes.each { fix -> changelog.append("- ${formatMultilineMessage(fix)}\n") } + } + + // Store the changelog in a project property or an environment variable + logger.info("Compiled changelog: " + changelog.toString()) + project.ext.changelog = changelog.toString() + } + project.ext.changelog = "" +} + +task curseforge(type: net.darkhax.curseforgegradle.TaskPublishCurseForge) { + dependsOn 'generateChangelog' + apiToken = System.getenv("CURSEFORGE_TOKEN") + def mainFile = upload(project.curseforge_id, file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) + mainFile.changelogType = 'markdown' + mainFile.changelog = { project.ext.changelog } + mainFile.addModLoader('NeoForge') + mainFile.addModLoader('Forge') + mainFile.releaseType = "${release_type}" + "${release_versions}".split(',').each { + mainFile.addGameVersion("${it}") + } + mainFile.addOptional('jei') + mainFile.addOptional('curios') + mainFile.addOptional('jade') + onlyIf { !project.ext.changelog.isEmpty() } +} + +modrinth { + token = System.getenv("MODRINTH_TOKEN") + projectId = "${modrinth_project_id}" + versionType = "${release_type}" + uploadFile = jar + gameVersions = "${release_versions}".split(',').collect {e -> e} + loaders = ["forge", "neoforge"] + dependencies { + optional.project "jei" + optional.project "jade" + optional.project "curios" + } + changelog = provider { + project.ext.changelog + } +} +tasks.modrinth { + dependsOn(tasks.generateChangelog) + onlyIf { !project.ext.changelog.isEmpty() } +} + sonarqube { properties { property "sonar.projectName", "Reliquary" diff --git a/gradle.properties b/gradle.properties index 5a58fca0..83e6179d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,12 +1,31 @@ -org.gradle.jvmargs=-Xmx2048m +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false + +mod_id=reliquary +mod_group_id=reliquary +mod_version=2.0.42 +sonar_project_key=xreliquary:Reliquary +github_package_url=https://maven.pkg.github.com/P3pp3rF1y/Reliquary + +#neoforge minecraft_version=1.20.1 -forge_version=47.1.5 -mod_version=2.0.41 +minecraft_version_range=[1.20,1.21) +neo_version=47.1.5 +neo_version_range=[47.1,) +loader_version_range=[47,) + +#publish +curseforge_id=241319 +release_type=release +release_versions=1.20.1 +modrinth_project_id=fQO83PId + +#deps jei_mc_version=1.20.1-forge jei_version=15.1.0.19 curios_version=5.2.0-beta.3+1.20.1 # botania_version=1.16.5-415-SNAPSHOT -parchment_version=2023.07.16-1.20.1 jade_cf_file_id=4654448 # hwyla_version = 1.8.20-B35_1.12 -# jer_version = 0.8.7.41 \ No newline at end of file +# jer_version = 0.8.7.41 +parchment_version=2023.07.16-1.20.1 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4c73306d..54ef14c2 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..eaf6f0d1 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,14 @@ +pluginManagement { + repositories { + gradlePluginPortal() + maven { url = 'https://maven.parchmentmc.org' } + maven { + name = 'NeoForged' + url = 'https://maven.neoforged.net/releases' + } + } +} + +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' +} \ No newline at end of file diff --git a/src/main/java/reliquary/items/MobCharmItem.java b/src/main/java/reliquary/items/MobCharmItem.java index 19b090a3..e410fa08 100644 --- a/src/main/java/reliquary/items/MobCharmItem.java +++ b/src/main/java/reliquary/items/MobCharmItem.java @@ -88,7 +88,7 @@ public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantmen } private void onEntityTargetedEvent(LivingChangeTargetEvent event) { - if (!(event.getNewTarget() instanceof Player player) || event.getNewTarget() instanceof FakePlayer || + if (event.getEntity().level().isClientSide() || !(event.getNewTarget() instanceof Player player) || event.getNewTarget() instanceof FakePlayer || !(event.getEntity() instanceof Mob entity)) { return; } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 2e7786ca..b49f5968 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -7,7 +7,7 @@ modLoader="javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the minecraft version (without the 1.) -loaderVersion="[14,)" #mandatory +loaderVersion="${loader_version_range}" #mandatory # A URL to query for updates for this mod. See the JSON update specification #updateJSONURL="" #optional @@ -16,7 +16,7 @@ loaderVersion="[14,)" #mandatory issueTrackerURL="https://github.com/p3pp3rF1y/reliquary/issues" #optional # A URL for the "homepage" for this mod, displayed in the mod UI -displayURL="https://www.curseforge.com/minecraft/mc-mods/reliquary-v1-3" #optional +displayURL="https://www.curseforge.com/minecraft/mc-mods/reliquary-reincarnations" #optional # License license="GNU General Public License v3.0" @@ -37,7 +37,7 @@ authors="x3n0ph0b3, TheMike, P3pp3rF1y" #optional modId="reliquary" #mandatory # The version number of the mod -version="project_version" #mandatory +version="${mod_full_version}" #mandatory # A display name for the mod displayName="Reliquary" #mandatory @@ -51,7 +51,7 @@ Two words: magical swag. Oh, and a gun. [[dependencies.reliquary]] modId="forge" #mandatory mandatory=true #mandatory - versionRange="[36.1.3,)" #mandatory + versionRange="${neo_version_range}" #mandatory # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory ordering="NONE" # Side this dependency is applied on - BOTH, CLIENT or SERVER