Skip to content

Commit e4ce5fe

Browse files
authored
Default changelog generation option (#24)
1 parent b79b969 commit e4ce5fe

File tree

2 files changed

+90
-22
lines changed

2 files changed

+90
-22
lines changed

build.gradle

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,12 @@ propertyDefaultIfUnset("forceEnableMixins", false)
6767
propertyDefaultIfUnset("usesShadowedDependencies", false)
6868
propertyDefaultIfUnset("minimizeShadowedDependencies", true)
6969
propertyDefaultIfUnset("relocateShadowedDependencies", true)
70-
propertyDefaultIfUnset("modrinthProjectId", "")
70+
propertyDefaultIfUnsetWithEnvVar("modrinthProjectId", "", "MODRINTH_PROJECT_ID")
7171
propertyDefaultIfUnset("modrinthRelations", "")
72-
propertyDefaultIfUnset("curseForgeProjectId", "")
72+
propertyDefaultIfUnsetWithEnvVar("curseForgeProjectId", "", "CURSEFORGE_PROJECT_ID")
7373
propertyDefaultIfUnset("curseForgeRelations", "")
7474
propertyDefaultIfUnset("releaseType", "release")
75+
propertyDefaultIfUnset("generateDefaultChangelog", false)
7576
propertyDefaultIfUnset("customMavenPublishUrl", "")
7677
propertyDefaultIfUnset("enableModernJavaSyntax", false)
7778
propertyDefaultIfUnset("enableSpotless", false)
@@ -190,7 +191,7 @@ if (enableSpotless.toBoolean()) {
190191
}
191192
}
192193

193-
// Git submodules
194+
// Git version checking, also checking for if this is a submodule
194195
if (project.file('.git/HEAD').isFile() || project.file('.git').isFile()) {
195196
apply plugin: 'com.palantir.git-version'
196197
}
@@ -698,8 +699,6 @@ idea {
698699
// Deployment
699700

700701
final boolean isCIEnv = providers.environmentVariable('CI').getOrElse('false').toBoolean()
701-
def final changelogEnv = providers.environmentVariable('CHANGELOG_LOCATION')
702-
File changelogFile = new File(changelogEnv.getOrElse('CHANGELOG.md'))
703702

704703
if (isCIEnv || deploymentDebug.toBoolean()) {
705704
artifacts {
@@ -712,16 +711,43 @@ if (isCIEnv || deploymentDebug.toBoolean()) {
712711
}
713712
}
714713

714+
// Changelog generation
715+
tasks.register('generateChangelog') {
716+
group = 'GT Buildscript'
717+
description = 'Generate a default changelog of all commits since the last tagged git commit'
718+
onlyIf {
719+
generateDefaultChangelog.toBoolean()
720+
}
721+
doLast {
722+
def lastTag = getLastTag()
723+
724+
def changelog = runShell(([
725+
"git",
726+
"log",
727+
"--date=format:%d %b %Y",
728+
"--pretty=%s - **%an** (%ad)",
729+
"${lastTag}..HEAD"
730+
] + (sourceSets.main.java.srcDirs + sourceSets.main.resources.srcDirs)
731+
.collect { ['--', it] }).flatten())
732+
733+
if (changelog) {
734+
changelog = "Changes since ${lastTag}:\n${{("\n" + changelog).replaceAll("\n", "\n* ")}}"
735+
}
736+
def f = getFile('build/changelog.md')
737+
f.write(changelog ?: 'There have been no changes.', 'UTF-8')
738+
}
739+
}
740+
715741
// Curseforge
716742
def final cfApiKey = providers.environmentVariable('CURSEFORGE_API_KEY')
717743
if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
718744
apply plugin: 'net.darkhax.curseforgegradle'
719745
//noinspection UnnecessaryQualifiedReference
720746
tasks.register('curseforge', net.darkhax.curseforgegradle.TaskPublishCurseForge) {
721-
apiToken = cfApiKey.get()
722-
def projectIdVar = providers.environmentVariable('CURSEFORGE_PROJECT_ID')
747+
apiToken = cfApiKey.getOrElse('debug_token')
723748

724-
def mainFile = upload(projectIdVar.getOrElse(curseForgeProjectId), reobfJar)
749+
def mainFile = upload(curseForgeProjectId, reobfJar)
750+
def changelogFile = getChangelog()
725751
def changelogRaw = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
726752

727753
mainFile.releaseType = getReleaseType()
@@ -754,17 +780,18 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
754780
debugMode = deploymentDebug.toBoolean()
755781
}
756782
tasks.curseforge.dependsOn(build)
783+
tasks.curseforge.dependsOn('generateChangelog')
757784
}
758785

759786
// Modrinth
760787
def final modrinthApiKey = providers.environmentVariable('MODRINTH_API_KEY')
761788
if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
762789
apply plugin: 'com.modrinth.minotaur'
763-
def final projectIdVar = providers.environmentVariable('MODRINTH_PROJECT_ID')
790+
def final changelogFile = getChangelog()
764791

765792
modrinth {
766-
token = modrinthApiKey.get()
767-
projectId = projectIdVar.getOrElse(modrinthProjectId)
793+
token = modrinthApiKey.getOrElse('debug_token')
794+
projectId = modrinthProjectId
768795
changelog = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
769796
versionType = getReleaseType()
770797
versionNumber = modVersion
@@ -786,6 +813,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
786813
}
787814
}
788815
tasks.modrinth.dependsOn(build)
816+
tasks.modrinth.dependsOn('generateChangelog')
789817
}
790818

791819
def addModrinthDep(String scope, String type, String name) {
@@ -839,6 +867,37 @@ if (customMavenPublishUrl) {
839867
}
840868
}
841869

870+
def getSecondaryArtifacts() {
871+
def secondaryArtifacts = [usesShadowedDependencies.toBoolean() ? tasks.shadowJar : tasks.jar]
872+
if (!noPublishedSources.toBoolean()) secondaryArtifacts += [sourcesJar]
873+
if (apiPackage) secondaryArtifacts += [apiJar]
874+
return secondaryArtifacts
875+
}
876+
877+
def getReleaseType() {
878+
String type = project.releaseType
879+
if (!(type in ['release', 'beta', 'alpha'])) {
880+
throw new Exception("Release type invalid! Found \"" + type + "\", allowed: \"release\", \"beta\", \"alpha\"")
881+
}
882+
return type
883+
}
884+
885+
/*
886+
* If CHANGELOG_LOCATION env var is set, that takes highest precedence.
887+
* Next, if 'generateDefaultChangelog' option is enabled, use that.
888+
* Otherwise, try to use a CHANGELOG.md file at root directory.
889+
*/
890+
def getChangelog() {
891+
def final changelogEnv = providers.environmentVariable('CHANGELOG_LOCATION')
892+
if (changelogEnv.isPresent()) {
893+
return new File(changelogEnv.get())
894+
}
895+
if (generateDefaultChangelog.toBoolean()) {
896+
return getFile('build/changelog.md')
897+
}
898+
return getFile('CHANGELOG.md')
899+
}
900+
842901

843902
// Buildscript updating
844903

@@ -971,17 +1030,22 @@ def propertyDefaultIfUnsetWithEnvVar(String propertyName, defaultValue, String e
9711030
}
9721031
}
9731032

974-
def getSecondaryArtifacts() {
975-
def secondaryArtifacts = [usesShadowedDependencies.toBoolean() ? tasks.shadowJar : tasks.jar]
976-
if (!noPublishedSources.toBoolean()) secondaryArtifacts += [sourcesJar]
977-
if (apiPackage) secondaryArtifacts += [apiJar]
978-
return secondaryArtifacts
979-
}
1033+
static runShell(command) {
1034+
def process = command.execute()
1035+
def outputStream = new StringBuffer()
1036+
def errorStream = new StringBuffer()
1037+
process.waitForProcessOutput(outputStream, errorStream)
9801038

981-
def getReleaseType() {
982-
String type = project.releaseType
983-
if (!(type in ['release', 'beta', 'alpha'])) {
984-
throw new Exception("Release type invalid! Found \"" + type + "\", allowed: \"release\", \"beta\", \"alpha\"")
1039+
errorStream.toString().with {
1040+
if (it) {
1041+
throw new GradleException("Error executing ${command}:\n> ${it}")
1042+
}
9851043
}
986-
return type
1044+
return outputStream.toString().trim()
1045+
}
1046+
1047+
def getLastTag() {
1048+
def githubTag = providers.environmentVariable('GITHUB_TAG')
1049+
return runShell('git describe --abbrev=0 --tags ' +
1050+
(githubTag.isPresent() ? runShell('git rev-list --tags --skip=1 --max-count=1') : ''))
9871051
}

gradle.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ curseForgeRelations =
110110
# Allowed types: release, beta, alpha
111111
releaseType = release
112112

113+
# Generate a default changelog for releases. Requires git to be installed, as it uses it to generate a changelog of
114+
# commits since the last tagged release.
115+
generateDefaultChangelog = false
116+
113117
# Prevent the source code from being published
114118
noPublishedSources = false
115119

0 commit comments

Comments
 (0)