diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3945a2d..f0a51dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: ~/.gradle/wrapper key: $${{ runner.os }}-gradle - name: Get Short Identifier - uses: benjlevesque/short-sha@v1.2 + uses: benjlevesque/short-sha@v3.0 id: short-sha - name: Build id: build diff --git a/build.gradle b/build.gradle index bbd4b41..f0ba1d5 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,28 @@ plugins { id 'net.neoforged.moddev' version '1.0.15' } +abstract class TeaConDumpPathToGitHub extends DefaultTask { + @Input + abstract Property getPublishName() + @InputFile + abstract RegularFileProperty getTargetFile() + @TaskAction + void dump() { + if (System.env.GITHUB_ACTIONS) { + File theFile = targetFile.getAsFile().get() + + def outputFile = new File(System.env.GITHUB_OUTPUT) + // Use the env-specific line separator for maximally possible compatibility + def newLine = System.getProperty('line.separator') + + // Write out new env variable for later usage + outputFile << newLine << "artifact_name=${theFile.getName()}" + outputFile << newLine << "artifact_publish_name=${publishName.get()}" + outputFile << newLine << "artifact_path=${theFile.absolutePath}" + } + } +} + tasks.named('wrapper', Wrapper).configure { distributionType = Wrapper.DistributionType.BIN } @@ -174,3 +196,89 @@ idea { downloadJavadoc = true } } + +publishing { PublishingExtension it -> + publications { + // noinspection GroovyAssignabilityCheck + release(MavenPublication) { + // noinspection GroovyAssignabilityCheck + from components.java + // noinspection GroovyAssignabilityCheck + groupId = "org.teacon" + // noinspection GroovyAssignabilityCheck + artifactId = 'PowerTool-1.21-NeoForge' + // noinspection GroovyAssignabilityCheck + version = mod_version + pom { + // noinspection GroovyAssignabilityCheck + name = 'PowerTool' + // noinspection GroovyAssignabilityCheck + url = "https://github.com/teaconmc/PowerTool" + licenses { + license { + // noinspection GroovyAssignabilityCheck + name = 'GPLv3' + // noinspection GroovyAssignabilityCheck + url = "https://github.com/teaconmc/PowerTool/blob/1.21-neoforge/LICENSE" + } + } + organization { + // noinspection GroovyAssignabilityCheck + name = 'TeaConMC' + // noinspection GroovyAssignabilityCheck + url = 'https://github.com/teaconmc' + } + developers { + developer { + id = '3TUSK' + name = '3TUSK' + } + developer { + id = 'xkball' + name = 'xkball' + } + } + issueManagement { + // noinspection GroovyAssignabilityCheck + system = 'GitHub Issues' + // noinspection GroovyAssignabilityCheck + url = "https://github.com/teaconmc/PowerTool/issues" + } + scm { + // noinspection GroovyAssignabilityCheck + url = "https://github.com/teaconmc/PowerTool" + // noinspection GroovyAssignabilityCheck + connection = "scm:git:git://github.com/teaconmc/PowerTool.git" + // noinspection GroovyAssignabilityCheck + developerConnection = "scm:git:git@github.com:teaconmc/PowerTool.git" + } + } + } + } + repositories { + maven { + name = "teacon" + url = "s3://maven/" + credentials(AwsCredentials) { + accessKey = System.env.ARCHIVE_ACCESS_KEY + secretKey = System.env.ARCHIVE_SECRET_KEY + } + } + } +} + +tasks.withType(PublishToMavenRepository).configureEach { + if (repository && repository.name == "archive") { + it.onlyIf { + System.env.MAVEN_USERNAME && System.env.MAVEN_PASSWORD + } + } +} + +tasks.register("githubActionOutput", TeaConDumpPathToGitHub) { task -> + task.onlyIf { + System.env.GITHUB_ACTIONS + } + task.getPublishName().set("${jar.archiveBaseName.get()}-${version}.jar") + task.getTargetFile().set(jar.archiveFile) +} diff --git a/gradle/teacon-forge.gradle b/gradle/teacon-forge.gradle index c64b0bc..807de25 100644 --- a/gradle/teacon-forge.gradle +++ b/gradle/teacon-forge.gradle @@ -1,3 +1,11 @@ +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.bundling.AbstractArchiveTask + interface TeaConExtension { // get the mod id Property getModId() @@ -15,6 +23,8 @@ interface TeaConExtension { Property getModGitHubBranch() // get the mod description Property getModDescription() + // get Minecraft version + Property getMinecraftVersion() // get the platform which should be 'forge-1.1x.x-xx.x.x' Property getPlatform() // get the parchment mapping version which should be either '20xx.xx.xx' or null @@ -23,10 +33,28 @@ interface TeaConExtension { Property getModifyMemberAccess() // check if data generation is used Property getUseDataGeneration() - // get publish jar task (default task is jar) - Property getPublishTask() - // get lazy tokens used in generating runs - MapProperty getLazyTokens() +} + +abstract class TeaConDumpPathToGitHub extends DefaultTask { + @Input + abstract Property getPublishName() + @InputFile + abstract RegularFileProperty getTargetFile() + @TaskAction + void check() { + if (System.env.GITHUB_ACTIONS) { + File theFile = targetFile.getAsFile().get() + + def outputFile = new File(System.env.GITHUB_OUTPUT) + // Use the env-specific line separator for maximally possible compatibility + def newLine = System.getProperty('line.separator') + + // Write out new env variable for later usage + outputFile << newLine << "artifact_name=${theFile.getName()}" + outputFile << newLine << "artifact_publish_name=${publishName.get()}" + outputFile << newLine << "artifact_path=${theFile.absolutePath}" + } + } } gradle.afterProject { Project current -> @@ -34,10 +62,7 @@ gradle.afterProject { Project current -> def teacon = current.extensions.teacon as TeaConExtension - def (platformName, gameVersion, platformVersion) = teacon.getPlatform().get().split('-', 3) - - // check if it is forge - assert platformName == 'forge' + def mcVer = teacon.minecraftVersion.get() def modId = teacon.modId.get() def artifactVersion = teacon.modVersion.get() @@ -63,84 +88,65 @@ gradle.afterProject { Project current -> current.sourceSets.main.resources { it.srcDir 'src/generated/resources' } } - // configure minecraft - current.minecraft { /* net.minecraftforge.gradle.common.util.MinecraftExtension */ it -> - def parchment = teacon.getParchment().getOrElse(null) - def channel = parchment != null ? 'parchment' : 'official' - - it.mappings 'channel': channel, 'version': (parchment != null ? parchment + '-' : '') + gameVersion + current.neoForge { it -> + it.version = teacon.platform.get() def modifyMemberAccess = teacon.modifyMemberAccess.getOrElse(false) - if (modifyMemberAccess) { - it.accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + it.accessTransformers { + file('src/main/resources/META-INF/accesstransformer.cfg') + } + } + it.parchment { + mappingsVersion = teacon.parchment.get() + minecraftVersion = teacon.minecraftVersion.get() + } + it.mods { + // define mod <-> source bindings + // these are used to tell the game which sources are for which mod + // mostly optional in a single mod project + // but multi mod projects should define one per mod + "${modId}" { + sourceSet(sourceSets.main) + } } - - def runtimeLazyTokens = teacon.lazyTokens.getOrElse([:]) - it.runs { client { - workingDirectory current.file('run_client') - property 'forge.logging.markers', 'REGISTRIES' - property 'forge.logging.console.level', 'debug' - property 'forge.enabledGameTestNamespaces', modId - mods { - // noinspection GroovyAssignabilityCheck - create(modId) { it.source sourceSets.main } - } - // noinspection GroovyAssignabilityCheck - runtimeLazyTokens.each { k, v -> lazyToken(k, v) } + client() + gameDirectory = current.file('run_client') + systemProperty 'neoforge.enabledGameTestNamespaces', modId } server { - workingDirectory current.file('run_server') - property 'forge.logging.markers', 'REGISTRIES' - property 'forge.logging.console.level', 'debug' - property 'forge.enabledGameTestNamespaces', modId - mods { - // noinspection GroovyAssignabilityCheck - create(modId) { it.source sourceSets.main } - } - // noinspection GroovyAssignabilityCheck - runtimeLazyTokens.each { k, v -> lazyToken(k, v) } + server() + gameDirectory = current.file('run_server') + programArgument '--nogui' + systemProperty 'neoforge.enabledGameTestNamespaces', modId } + // This run config launches GameTestServer and runs all registered gametests, then exits. + // By default, the server will crash when no gametests are provided. + // The gametest system is also enabled by default for other run configs under the /test command. gameTestServer { - workingDirectory current.file('run_test') - property 'forge.logging.markers', 'REGISTRIES' - property 'forge.logging.console.level', 'debug' - property 'forge.enabledGameTestNamespaces', modId - mods { - // noinspection GroovyAssignabilityCheck - create(modId) { it.source sourceSets.main } - } - // noinspection GroovyAssignabilityCheck - runtimeLazyTokens.each { k, v -> lazyToken(k, v) } + type = "gameTestServer" + gameDirectory = current.file('run_gametest') + systemProperty 'neoforge.enabledGameTestNamespaces', modId } if (useDataGeneration) { data { - workingDirectory current.file('run_data') - property 'forge.logging.markers', 'REGISTRIES' - property 'forge.logging.console.level', 'debug' - // noinspection GroovyAssignabilityCheck - args '--mod', modId, '--all', '--output', - file('src/generated/resources/'), '--existing', file('src/main/resources/') - mods { - // noinspection GroovyAssignabilityCheck - create(modId) { it.source sourceSets.main } - } - // noinspection GroovyAssignabilityCheck - runtimeLazyTokens.each { k, v -> lazyToken(k, v) } + data() + + gameDirectory = current.file('run_data') + + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + programArguments.addAll '--mod', modId, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() } } } } - // configure dependencies - current.dependencies { DependencyHandler it -> - it.minecraft 'net.minecraftforge:forge:' + gameVersion + '-' + platformVersion - } + current.sourceSets.main.resources { srcDir 'src/generated/resources' } // noinspection GroovyAssignabilityCheck def generateArtifactAttributes = { String name, String specVersion, String implVersion -> @@ -151,15 +157,13 @@ gradle.afterProject { Project current -> "Implementation-Title" : name, "Implementation-Version" : implVersion, "Implementation-Vendor" : "TeaConMC", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ] } - def gameVersions = gameVersion.split('\\.') def identifier = System.env.VERSION_IDENTIFIER - def publishJarTask = teacon.publishTask.getOrElse(current.tasks.jar) - def jarArchiveBaseName = "${repoName}-Forge-${gameVersion}" as String + def publishJarTask = current.tasks.jar + def jarArchiveBaseName = "${repoName}-NeoForge-${mcVer}" as String // configure jar and re-obf publishJarTask.configure { Jar it -> @@ -168,19 +172,12 @@ gradle.afterProject { Project current -> it.manifest.attributes(generateArtifactAttributes(repoName, '1', it.archiveVersion.get()) as Map) } - current.reobf { - it.create(publishJarTask.name) { - current.publish.dependsOn it - publishJarTask.finalizedBy it - } - } - def modAuthors = teacon.modAuthors.getOrElse([]) // noinspection GroovyAssignabilityCheck def modName = teacon.modName.getOrElse(repoName) - def publishBranchName = teacon.modGitHubBranch.getOrElse("${gameVersions[0]}.${gameVersions[1]}-forge") - def publishPomName = "${repoName} for Minecraft ${gameVersions[0]}.${gameVersions[1]}" as String + def publishBranchName = teacon.modGitHubBranch.getOrElse("${mcVer}-neoforge") + def publishPomName = "${repoName} for Minecraft ${mcVer}" as String def publishDescription = teacon.modDescription.getOrElse(publishPomName) def publishLicense = teacon.modLicense.get() @@ -267,7 +264,7 @@ gradle.afterProject { Project current -> } } - current.tasks.withType(PublishToMavenRepository) { + current.tasks.withType(PublishToMavenRepository).configureEach { if (repository && repository.name == "archive") { it.onlyIf { System.env.MAVEN_USERNAME && System.env.MAVEN_PASSWORD @@ -276,17 +273,12 @@ gradle.afterProject { Project current -> } // A simple task to pass down the artifact name and path to other GitHub actions - current.tasks.register("githubActionOutput") { - it.onlyIf { + current.tasks.register("githubActionOutput", TeaConDumpPathToGitHub) { task -> + task.onlyIf { System.env.GITHUB_ACTIONS } - it.doLast { - def outputFile = new File(System.env.GITHUB_OUTPUT) - def newLine = System.getProperty('line.separator') - outputFile << newLine << "artifact_name=${publishJarTask.archiveFileName.get()}" - << newLine << "artifact_publish_name=${jarArchiveBaseName}-${artifactVersion}.jar" - << newLine << "artifact_path=${publishJarTask.archiveFile.get().asFile.absolutePath}" - } + task.getPublishName().set("${jarArchiveBaseName}-${artifactVersion}.jar") + task.getTargetFile().set(publishJarTask.archiveFile) } // A task for generating mods.toml @@ -307,7 +299,7 @@ gradle.afterProject { Project current -> // loaders lines += "modLoader=\"javafml\"" - lines += "loaderVersion=\"[${escaped(platformVersion.split('\\.')[0])},)\"" + lines += "loaderVersion=\"1\"" lines += "license=\"${escaped(publishLicense)}\"" lines += "" @@ -320,11 +312,11 @@ gradle.afterProject { Project current -> lines += "displayName=\"${escaped(publishDescription)}\"" lines += "" - // forge dependency + // neoforge dependency lines += "[[dependencies.${modId}]]" - lines += "modId=\"forge\"" - lines += "mandatory=true" - lines += "versionRange=\"[${escaped(platformVersion.split('\\.')[0])},)\"" + lines += "modId=\"neoforge\"" + lines += "type=required" + lines += "versionRange=\"[${escaped(teacon.platform.get())},)\"" lines += "ordering=\"NONE\"" lines += "side=\"BOTH\"" lines += "" @@ -332,8 +324,8 @@ gradle.afterProject { Project current -> // minecraft dependency lines += "[[dependencies.${modId}]]" lines += "modId=\"minecraft\"" - lines += "mandatory=true" - lines += "versionRange=\"[${escaped("${gameVersions[0]}.${gameVersions[1]}")},)\"" + lines += "type=required" + lines += "versionRange=\"[${escaped(mcVer)},)\"" lines += "ordering=\"NONE\"" lines += "side=\"BOTH\"" lines += ""