Last active
November 27, 2019 08:45
-
-
Save tomasznajda/5c3574cbff663f4e2db61545ad07fa83 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum BuildType { | |
PROD, | |
RC, | |
SNAPSHOT, | |
TASK, | |
DEV | |
} | |
/* | |
-------------------- PRODUCTION BUILD -------------------- | |
command: ./gradlew assembleProdRelease -Ptype=PROD | |
branch: master | |
----------------- RELEASE CANDIDATE BUILD ---------------- | |
command: ./gradlew assembleProdRelease -Ptype=RC | |
branch: release or hotfix | |
--------------------- SNAPSHOT BUILD --------------------- | |
command: ./gradlew assemble -Ptype=SNAPSHOT | |
branch: develop | |
----------------------- TASK BUILD ----------------------- | |
command: ./gradlew assemble -Ptype=TASK | |
branch: feature or bugfix | |
------------------------- OTHER -------------------------- | |
Q: How to debug versioning scripts? | |
A: Add -Pdebug=true to the build command | |
*/ | |
ext { | |
printVersionDetails = { -> | |
println("----------------------------------") | |
println("VERSION CODE: " + provideVersionCode()) | |
println("VERSION NAME: " + provideVersionName()) | |
println("RELEASE NOTES:") | |
println(provideReleaseNotes()) | |
println("----------------------------------") | |
} | |
provideVersionCode = { -> | |
switch (getBuildType()) { | |
case BuildType.PROD: | |
case BuildType.RC: | |
return prodVersionCode | |
case BuildType.SNAPSHOT: | |
return getMergesCountOnCurrentBranch().toInteger() | |
default: | |
return 1 | |
} | |
} | |
provideVersionName = { -> | |
def suffix | |
switch (getBuildType()) { | |
case BuildType.PROD: | |
suffix = "" | |
break | |
case BuildType.RC: | |
suffix = "-rc" + getCommitsCountOnCurrentBranch() | |
break | |
case BuildType.SNAPSHOT: | |
suffix = "-SNAPSHOT" | |
break | |
case BuildType.TASK: | |
suffix = "-" + getCurrentTaskId() + "-c" + getCommitsCountOnCurrentBranch() | |
break | |
default: | |
suffix = "-dev" | |
} | |
return prodVersionName + suffix | |
} | |
provideReleaseNotes = { -> | |
def branch = getCurrentBranchName().toString() | |
switch (getBuildType()) { | |
case BuildType.PROD: | |
return getProdVariantNotes() | |
case BuildType.RC: | |
if (branch.contains("hotfix")) return getHotfixBranchNotes() | |
else return getReleaseBranchNotes() | |
case BuildType.SNAPSHOT: | |
return getSnapshotVariantNotes() | |
case BuildType.TASK: | |
return getTaskVariantNotes() | |
default: | |
return "" | |
} | |
} | |
provideTestersGroup = { -> | |
switch (getBuildType()) { | |
case BuildType.PROD: | |
return "prod-testers" | |
case BuildType.RC: | |
return "rc-testers" | |
case BuildType.SNAPSHOT: | |
return "snapshot-testers" | |
case BuildType.TASK: | |
return "task-testers" | |
default: | |
return "" | |
} | |
} | |
getBuildType = { -> | |
if (project.hasProperty("type")) { | |
def branch = getCurrentBranchName().toString() | |
if (type as BuildType == BuildType.PROD && branch != "master") throw new IllegalArgumentException("Cannot build PROD version from " + branch) | |
else if (type as BuildType == BuildType.RC && !(branch.contains("release") || branch.contains("hotfix"))) throw new IllegalArgumentException("Cannot build RC version from " + branch) | |
else if (type as BuildType == BuildType.SNAPSHOT && branch != "develop") throw new IllegalArgumentException("Cannot build SNAPSHOT version from " + branch) | |
else if (type as BuildType == BuildType.TASK && !(branch.contains("feature") || branch.contains("bugfix"))) throw new IllegalArgumentException("Cannot build SNAPSHOT version from " + branch) | |
type as BuildType | |
} else { | |
BuildType.DEV | |
} | |
} | |
getCurrentTaskId = { -> | |
def parts = getCurrentBranchName().split("-") | |
if (parts.length > 1) return parts[parts.length - 1] | |
else return "UNKNOWN" | |
} | |
getCurrentBranchName = { -> | |
logd("Method", "getCurrentBranchName") | |
return git(["rev-parse", "--abbrev-ref", "HEAD"]) | |
} | |
getCommitsCountOnCurrentBranch = { -> | |
logd("Method", "getCommitsCountOnCurrentBranch") | |
return git(["rev-list", "--count", "HEAD", "^origin/develop", "^origin/master"]).trim() | |
} | |
getMergesCountOnCurrentBranch = { -> | |
logd("Method", "getMergesCountOnCurrentBranch") | |
return git(["rev-list", "--merges", "--count", "HEAD"]).trim() | |
} | |
getProdVariantNotes = { -> | |
def tag = getAllTagsDescending().split('\n')[0] | |
def tagCommitHash = getCommitHashForTag(tag) | |
def latestReleaseCandidateCommit = getCommitParentsAndBody(tagCommitHash)[0].split(' ')[1] | |
def notes = new ArrayList<String>() | |
notes.addAll(getMessagesSinceBranchWasCreated(latestReleaseCandidateCommit)) | |
notes.addAll(getDevelopMergeMessagesSinceLastRelease(latestReleaseCandidateCommit)) | |
return notes.join("\n") | |
} | |
getReleaseBranchNotes = { -> | |
def latestCurrentBranchCommit = getCommitHash(0, "HEAD") | |
def notes = new ArrayList<String>() | |
notes.add(getCurrentBranchName()) | |
notes.addAll(getMessagesSinceBranchWasCreated(latestCurrentBranchCommit)) | |
notes.addAll(getDevelopMergeMessagesSinceLastRelease(latestCurrentBranchCommit)) | |
return notes.join("\n") | |
} | |
getHotfixBranchNotes = { -> | |
def latestCurrentBranchCommit = getCommitHash(0, "HEAD") | |
def notes = new ArrayList<String>() | |
notes.add(getCurrentBranchName()) | |
notes.addAll(getMessagesSinceBranchWasCreated(latestCurrentBranchCommit)) | |
return notes.join("\n") | |
} | |
getSnapshotVariantNotes = { -> | |
def latestCurrentBranchCommit = getCommitHash(0, "HEAD") | |
def notes = new ArrayList<String>() | |
notes.add(getCurrentBranchName()) | |
notes.addAll(getDevelopMergeMessagesSinceLastRelease(latestCurrentBranchCommit)) | |
return notes.join("\n") | |
} | |
getTaskVariantNotes = { -> | |
def latestCurrentBranchCommit = getCommitHash(0, "HEAD") | |
def notes = new ArrayList<String>() | |
notes.add(getCurrentBranchName()) | |
notes.addAll(getMessagesSinceCurrentBranchWasCreated(latestCurrentBranchCommit)) | |
return notes.join("\n") | |
} | |
getDevelopMergeMessagesSinceLastRelease = { startCommitHash -> | |
def latestTag = getAllTagsDescending().split('\n')[0] | |
def endCommitHash = findFirstCommitHashOnParentPath(getCommitHashForTag(latestTag)) | |
return getMergeCommitsMessages(startCommitHash, endCommitHash) | |
.split('\n') | |
.findAll { it.contains("feature") || it.contains("bugfix") } | |
.collect { it.substring(it.indexOf('/') + 1, it.length()) } | |
.collect { "- " + it } | |
} | |
getMessagesSinceBranchWasCreated = { startCommitHash -> | |
def endCommitHash = findFirstCommitHashOnParentPath(startCommitHash) | |
return getAllCommitsMessages(startCommitHash, endCommitHash) | |
.split('\n') | |
.findAll { !it.contains("Merge branch") && !isVersionBumpMessage(it) && it.length() > 0 } | |
.collect { "- " + it } | |
} | |
getMessagesSinceCurrentBranchWasCreated = { | |
return git(["log", "--pretty=format:'%s'", "HEAD", "^origin/master", "^origin/develop"]) | |
.split('\n') | |
.findAll { !it.contains("Merge branch") && !isVersionBumpMessage(it) && it.length() > 0 } | |
.collect { "- " + it } | |
} | |
getCommitHashForTag = { tag -> | |
logd("Method", "getCommitHashForTag") | |
return git(["rev-list", "-n 1", tag]) | |
} | |
getAllTagsDescending = { -> | |
logd("Method", "getAllTagsDescending") | |
return git(["tag", "--sort=-refname"]) | |
} | |
getCommitHash = { index, branch -> | |
logd("Method", "getCommitHash") | |
return git(["rev-list", "--max-count=1", "--skip=" + index, branch]) | |
} | |
getMergeCommitsMessages = { startCommitHash, endCommitHash -> | |
logd("Method", "getMergeCommitsMessages") | |
return git(["log", "--merges", "--first-parent", "--pretty=format:'%s'", endCommitHash + ".." + startCommitHash]) | |
} | |
getAllCommitsMessages = { startCommitHash, endCommitHash -> | |
logd("Method", "getAllCommitsMessages") | |
return git(["log", "--pretty=format:'%s'", endCommitHash + ".." + startCommitHash]) | |
} | |
findFirstCommitHashOnParentPath = { initialCommitHash -> | |
def commitHash = initialCommitHash | |
while (true) { | |
def info = getCommitParentsAndBody(commitHash) | |
if (info[1] != null && (info[1].contains("develop") || info[1].contains("master"))) return commitHash | |
commitHash = info[0].split(' ')[0] | |
} | |
} | |
getCommitParentsAndBody = { commit -> | |
logd("Method", "getCommitParentsAndBody") | |
def result = git(["show", "--quiet", "--pretty=format:'%P%n%b'", commit]).split('\n') | |
if(result.size() > 1) | |
return [result[result.size() - 2], result[result.size() - 3]] | |
else | |
return [result[result.size() - 1], ""] | |
} | |
isVersionBumpMessage = { message -> | |
return (message =~ /v\d+\.\d+\.\d+\s\(\d+\)/).size() > 0 | |
} | |
git = { arguments -> | |
new ByteArrayOutputStream().withStream { os -> | |
logd("Git", "--> git " + arguments.join(' ')) | |
exec { | |
executable = "git" | |
args = arguments | |
standardOutput = os | |
} | |
def output = formatOutput(os.toString()) | |
logd("Git", output) | |
return output | |
} | |
} | |
logd = { tag, message -> | |
if (project.hasProperty("debug") && debug) { | |
message.split('\n').each { println("D/" + tag + ": " + it) } | |
} | |
} | |
formatOutput = { stream -> | |
return stream.toString().split('\n').collect { formatLine(it) }.join('\n') | |
} | |
formatLine = { line -> | |
if (line.startsWith("'")) | |
line = line.substring(1) | |
if (line.endsWith("'")) | |
line = line.substring(0, line.length() - 1) | |
return line.trim() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment