Skip to content

Commit 5ed0e20

Browse files
committed
Restructure the output changelog task to make it support the configuration cache
1 parent 8bee5f5 commit 5ed0e20

File tree

4 files changed

+145
-77
lines changed

4 files changed

+145
-77
lines changed

build.gradle

Lines changed: 23 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import groovy.json.JsonSlurper
66
import mekanism.AllJar
77
import mekanism.MergeModuleResources
88
import mekanism.OptimizePng
9+
import mekanism.OutputChangelog
910
import net.darkhax.curseforgegradle.TaskPublishCurseForge
1011
import net.darkhax.curseforgegradle.UploadArtifact
1112

1213
import java.util.function.Consumer
1314

1415
plugins {
15-
id('org.ajoberstar.grgit.service') version('5.2.2')
16+
id('org.ajoberstar.grgit.service')//Version declared in buildSrc
1617
id('net.darkhax.curseforgegradle') version('1.1.24')
1718
id('com.modrinth.minotaur') version('2.8.7')
1819
id('java')
@@ -589,84 +590,31 @@ publishing {
589590
}
590591
}
591592

592-
def resolvedChangelog = null
593-
594-
//closure to generate the changelog once, and only when needed by CurseGradle or Modrinth
595-
def changeLogResolver = { ->
596-
if (resolvedChangelog != null) {
597-
logger.lifecycle('Using cached changelog')
598-
return resolvedChangelog
599-
}
600-
def generatedChangelog = 'Unable to generate changelog :('
601-
def currentCommit = System.getenv('GIT_COMMIT')
602-
def prevCommit = System.getenv('GIT_PREVIOUS_SUCCESSFUL_COMMIT') ?: System.getenv('GIT_PREVIOUS_COMMIT')
603-
604-
if (currentCommit != null && prevCommit != null) {
605-
generatedChangelog = ''
606-
//Use the service to avoid eagerly instantiating the grgit instance, and only do so when we actually need it
607-
// for usage in generating the changelog for either CF or Modrinth
608-
grgitService.service.get().grgit.log {
609-
range(prevCommit, currentCommit)
610-
}.reverse().each { commit ->
611-
//Use full message rather than short message to get any new lines, and trim it so that any trailing new lines
612-
// get removed so that we don't end up with extra spaces
613-
String message = commit.fullMessage.trim()
614-
if (!message.startsWith('Merge branch') && !message.startsWith('Merge pull request') && !message.contains('[no-changelog]')) {
615-
//Ignore Merges and PR Merges
616-
message = message.replaceAll('#(\\d+)', { match ->//turn issues/prs into links (github currently supports prs being linked as issues)
617-
return "[${match[0]}](https://github.com/mekanism/Mekanism/issues/${match[1]})"
618-
}).replaceAll('\\n', ' \n\t')//convert new lines that are part of a commit message into new lines and a tab
619-
if (generatedChangelog != '') {
620-
//If this isn't the first commit prepend an extra newline
621-
generatedChangelog += ' \n'
622-
}
623-
generatedChangelog += "[${commit.getAbbreviatedId()}](https://github.com/mekanism/Mekanism/commit/${commit.id}) - ${message}"
624-
}
625-
}
626-
logger.lifecycle('Changelog generated')
627-
}
628-
629-
def releaseNotesFile = project.file("docs/release_${mod_version}.md")
630-
if (releaseNotesFile.exists()) {
631-
//Add any version specific changelog stuff
632-
def releaseNotes = releaseNotesFile.text
633-
generatedChangelog = "$releaseNotes\n\n$generatedChangelog"
634-
}
635-
636-
if (release_type == 'alpha') {
637-
//Add a warning at the top about what an alpha build means
638-
generatedChangelog = 'Warning: Mekanism is currently in alpha, and is not recommended for widespread use in modpacks. There are likely to be game breaking bugs, ' +
639-
'and updating from one alpha to the next may cause various mekanism blocks to disappear/void their contents. While we will try to not have this happen/keep ' +
640-
'it to a minimum make sure to make backups. You can read more about the alpha state of this project [here](https://github.com/mekanism/Mekanism#alpha-status).' +
641-
"\n\n$generatedChangelog"
642-
}
643-
resolvedChangelog = generatedChangelog
644-
return generatedChangelog
645-
}
646-
647-
tasks.register('outputChangelog') {
648-
//TODO: Can we make this compatible with the configuration cache?
649-
notCompatibleWithConfigurationCache('Not yet compatible')
650-
doLast {
651-
project.file('build/changelog.md').text = changeLogResolver.call()
652-
}
593+
def outputChangelog = tasks.register('outputChangelog', OutputChangelog, grgitService.service)
594+
outputChangelog.configure { OutputChangelog out ->
595+
out.releaseNotes.value(provider {
596+
//If we have a file specified that exists for the mod version, then we want to use it
597+
// otherwise we want to fall back to not having the value set
598+
def file = layout.projectDirectory.file("docs/release_${mod_version}.md")
599+
return file.asFile.exists() ? file : null
600+
})
653601
}
654602

655-
def mainCfUpload, additionsCfUpload, generatorsCfUpload, toolsCfUpload
656-
657603
if (System.getenv('CURSEFORGE_KEY') != null || project.hasProperty('curseforgeKey')) {
658604
logger.lifecycle('Enabling Curseforge config')
659605
tasks.register('curseforge', TaskPublishCurseForge, { task ->
606+
dependsOn(outputChangelog)
660607
setGroup('publishing')
661608
setDescription('Upload Mekanism to CurseForge')
662609
notCompatibleWithConfigurationCache('Not yet compatible')//TODO: Remove when possible
663610

664-
apiToken = System.getenv('CURSEFORGE_KEY') ?: project.findProperty('curseforgeKey')
611+
def changelog = outputChangelog.flatMap(c -> c.outputFile)
612+
inputs.file(changelog)
665613

666-
def changelog = changeLogResolver.call()
614+
apiToken = System.getenv('CURSEFORGE_KEY') ?: project.findProperty('curseforgeKey')
667615

668616
//Main Mekanism Project
669-
mainCfUpload = task.upload(268560, jar) { main ->
617+
def mainCfUpload = task.upload(268560, jar) { main ->
670618
setGenericCurseArtifactData(main, changelog)
671619
//Include the API jar as a secondary file to the main file
672620
withAdditionalFile(apiJar)
@@ -689,10 +637,10 @@ if (System.getenv('CURSEFORGE_KEY') != null || project.hasProperty('curseforgeKe
689637
}
690638

691639
//Secondary modules/projects
692-
additionsCfUpload = uploadSecondaryCurseProject(task, 345425, changelog, additionsJar)
693-
//uploadSecondaryCurseProject(task, 376939, changelog, defenseJar)
694-
generatorsCfUpload = uploadSecondaryCurseProject(task, 268566, changelog, generatorsJar)
695-
toolsCfUpload = uploadSecondaryCurseProject(task, 268567, changelog, toolsJar)
640+
def additionsCfUpload = uploadSecondaryCurseProject(task, 345425, changelog, additionsJar)
641+
//def defenseCfUpload = uploadSecondaryCurseProject(task, 376939, changelog, defenseJar)
642+
def generatorsCfUpload = uploadSecondaryCurseProject(task, 268566, changelog, generatorsJar)
643+
def toolsCfUpload = uploadSecondaryCurseProject(task, 268567, changelog, toolsJar)
696644

697645
doLast {
698646
//Note: Quiet is the level above warning but below error. We want these to show regardless of logging level
@@ -705,13 +653,13 @@ if (System.getenv('CURSEFORGE_KEY') != null || project.hasProperty('curseforgeKe
705653
})
706654
}
707655

708-
void setGenericCurseArtifactData(UploadArtifact artifact, String changelog) {
656+
void setGenericCurseArtifactData(UploadArtifact artifact, Provider<RegularFile> changelog) {
709657
artifact.changelog = changelog
710658
artifact.changelogType = 'markdown'
711659
artifact.releaseType = "${release_type}"
712660
}
713661

714-
UploadArtifact uploadSecondaryCurseProject(TaskPublishCurseForge task, long projectId, String changelog, TaskProvider<Jar> sourceSetJar) {
662+
UploadArtifact uploadSecondaryCurseProject(TaskPublishCurseForge task, long projectId, Provider<RegularFile> changelog, TaskProvider<Jar> sourceSetJar) {
715663
return task.upload(projectId, sourceSetJar) { artifact ->
716664
setGenericCurseArtifactData(artifact, changelog)
717665
addRequirement('mekanism')
@@ -725,7 +673,7 @@ if (System.getenv('MODRINTH_TOKEN') != null || project.hasProperty('modrinthToke
725673
def generatorsModrinth = createSecondaryModrinthUpload('generators', 'OFVYKsAk', generatorsJar)
726674
def toolsModrinth = createSecondaryModrinthUpload('tools', 'tqQpq1lt', toolsJar)
727675
tasks.named('modrinth').configure {
728-
dependsOn(jar, apiJar)
676+
dependsOn(jar, apiJar, outputChangelog)
729677
finalizedBy(additionsModrinth, /*defenseModrinth,*/ generatorsModrinth, toolsModrinth)
730678
notCompatibleWithConfigurationCache('Not yet compatible')//TODO: Remove when possible
731679
}
@@ -746,7 +694,7 @@ if (System.getenv('MODRINTH_TOKEN') != null || project.hasProperty('modrinthToke
746694
gameVersions.add("${minecraft_version}")
747695
loaders.add('neoforge')
748696
failSilently = true
749-
changelog = changeLogResolver.call()
697+
changelog.value(outputChangelog.flatMap(c -> c.outputFile).map(file -> file.asFile.text))
750698
uploadFile = jar
751699

752700
additionalFiles.value([apiJar.get()])

buildSrc/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repositories {
2+
mavenCentral()
3+
}
4+
5+
dependencies {
6+
implementation('org.ajoberstar.grgit:grgit-gradle:5.2.2')
7+
}

buildSrc/src/main/groovy/mekanism/MergeModuleResources.groovy

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@ package mekanism
33
import groovy.json.JsonOutput
44
import groovy.json.JsonSlurper
55
import org.gradle.api.DefaultTask
6-
import org.gradle.api.file.*
6+
import org.gradle.api.file.Directory
7+
import org.gradle.api.file.DirectoryProperty
8+
import org.gradle.api.file.FileCollection
9+
import org.gradle.api.file.ProjectLayout
10+
import org.gradle.api.file.RegularFile
711
import org.gradle.api.model.ObjectFactory
812
import org.gradle.api.provider.Provider
9-
import org.gradle.api.tasks.*
13+
import org.gradle.api.tasks.InputFiles
14+
import org.gradle.api.tasks.Internal
15+
import org.gradle.api.tasks.OutputDirectory
16+
import org.gradle.api.tasks.OutputFile
17+
import org.gradle.api.tasks.TaskAction
1018
import org.gradle.api.tasks.util.PatternFilterable
1119

1220
import javax.inject.Inject
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package mekanism
2+
3+
import org.ajoberstar.grgit.gradle.GrgitService
4+
import org.gradle.api.DefaultTask
5+
import org.gradle.api.file.ProjectLayout
6+
import org.gradle.api.file.RegularFileProperty
7+
import org.gradle.api.model.ObjectFactory
8+
import org.gradle.api.provider.Provider
9+
import org.gradle.api.provider.ProviderFactory
10+
import org.gradle.api.tasks.Input
11+
import org.gradle.api.tasks.InputFile
12+
import org.gradle.api.tasks.Optional
13+
import org.gradle.api.tasks.OutputFile
14+
import org.gradle.api.tasks.TaskAction
15+
16+
import javax.inject.Inject
17+
18+
abstract class OutputChangelog extends DefaultTask {
19+
20+
private final Provider<GrgitService> grgitService
21+
22+
@Input
23+
final Provider<String> releaseType
24+
@Input
25+
final Provider<String> modVersion
26+
@Input
27+
@Optional
28+
final Provider<String> currentCommit
29+
@Input
30+
@Optional
31+
final Provider<String> previousCommit
32+
@Optional
33+
@InputFile
34+
final RegularFileProperty releaseNotes
35+
@OutputFile
36+
final RegularFileProperty outputFile
37+
38+
@Inject
39+
OutputChangelog(Provider<GrgitService> grgitService) {
40+
this.grgitService = grgitService
41+
usesService(grgitService)
42+
releaseType = providerFactory.gradleProperty('release_type')
43+
modVersion = providerFactory.gradleProperty('mod_version')
44+
currentCommit = providerFactory.environmentVariable('GIT_COMMIT')
45+
previousCommit = providerFactory.environmentVariable('GIT_PREVIOUS_SUCCESSFUL_COMMIT')
46+
.orElse(providerFactory.environmentVariable('GIT_PREVIOUS_COMMIT'))
47+
releaseNotes = objectFactory.fileProperty()
48+
outputFile = objectFactory.fileProperty().convention(projectLayout.buildDirectory.file('changelog.md'))
49+
}
50+
51+
@Inject
52+
protected abstract ProviderFactory getProviderFactory()
53+
54+
@Inject
55+
protected abstract ObjectFactory getObjectFactory()
56+
57+
@Inject
58+
protected abstract ProjectLayout getProjectLayout()
59+
60+
@TaskAction
61+
void execute() {
62+
def generatedChangelog = 'Unable to generate changelog :('
63+
64+
if (currentCommit.isPresent() && previousCommit.isPresent()) {
65+
generatedChangelog = ''
66+
//Use the service to avoid eagerly instantiating the grgit instance, and only do so when we actually need it
67+
// for usage in generating the changelog for either CF or Modrinth
68+
def commits = grgitService.get().grgit.log {
69+
range(previousCommit.get(), currentCommit.get())
70+
}.reverse()
71+
for (def commit : commits) {
72+
//Use full message rather than short message to get any new lines, and trim it so that any trailing new lines
73+
// get removed so that we don't end up with extra spaces
74+
String message = commit.fullMessage.trim()
75+
if (!message.startsWith('Merge branch') && !message.startsWith('Merge pull request') && !message.contains('[no-changelog]')) {
76+
//Ignore Merges and PR Merges
77+
message = message.replaceAll('#(\\d+)', { match ->//turn issues/prs into links (github currently supports prs being linked as issues)
78+
return "[${match[0]}](https://github.com/mekanism/Mekanism/issues/${match[1]})"
79+
}).replaceAll('\\n', ' \n\t')//convert new lines that are part of a commit message into new lines and a tab
80+
if (generatedChangelog != '') {
81+
//If this isn't the first commit prepend an extra newline
82+
generatedChangelog += ' \n'
83+
}
84+
generatedChangelog += "[${commit.getAbbreviatedId()}](https://github.com/mekanism/Mekanism/commit/${commit.id}) - ${message}"
85+
}
86+
}
87+
logger.lifecycle('Changelog generated')
88+
}
89+
90+
if (releaseNotes.isPresent()) {
91+
//Add any version specific changelog stuff
92+
generatedChangelog = releaseNotes.get().asFile.text + '\n\n' + generatedChangelog
93+
}
94+
95+
if (releaseType.get() == 'alpha') {
96+
//Add a warning at the top about what an alpha build means
97+
generatedChangelog = 'Warning: Mekanism is currently in alpha, and is not recommended for widespread use in modpacks. There are likely to be game breaking bugs, ' +
98+
'and updating from one alpha to the next may cause various mekanism blocks to disappear/void their contents. While we will try to not have this happen/keep ' +
99+
'it to a minimum make sure to make backups. You can read more about the alpha state of this project [here](https://github.com/mekanism/Mekanism#alpha-status).\n\n' +
100+
generatedChangelog
101+
}
102+
103+
outputFile.get().asFile.text = generatedChangelog
104+
}
105+
}

0 commit comments

Comments
 (0)