Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 9 additions & 105 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
apply plugin: 'com.android.application'
apply plugin: 'org.ajoberstar.grgit'
apply from: "${rootProject.projectDir}/gradle/prepare_release.gradle"
apply from: "${rootProject.projectDir}/gradle/clean_release.gradle"
apply from: "${rootProject.projectDir}/gradle/perform_release.gradle"
apply from: "${rootProject.projectDir}/gradle/ensure_clean.gradle"

android {
compileSdk 34
Expand Down Expand Up @@ -72,128 +76,28 @@ dependencies {

task ensureCleanRepo {
doLast {
if (!grgit.repository.jgit.status().call().clean) {
throw new GradleException('Git status is not clean, please stash your changes!')
}
ensureClean()
}
}

task releaseClean(dependsOn: ensureCleanRepo) {
doLast {
def clean = true
def applicationId = android.defaultConfig.applicationId

String headCommitMessage = grgit.head().shortMessage
while (headCommitMessage.contains("[gradle-release-task]")) {
clean = false
println "Found git commit: $headCommitMessage"
if (headCommitMessage.indexOf("$applicationId-") > -1) {
def tagName = headCommitMessage.split("$applicationId-")[1]
println "Removing the git tag: $tagName"
try {
grgit.tag.remove {
names = [tagName]
}
} catch (Exception e) {
println "Error while removing git tag:\n $e"
}
}
println "Resetting the git commit permanently!"
grgit.reset(commit: "HEAD~1", mode: "hard")
headCommitMessage = grgit.head().shortMessage

}
if (clean){
println "Repository is already clean"
}
println "Done!"
cleanRelease()
}
}

// Task parameters:
// bumpVersion -> if available will specify new versionName directly and ignores the `bumpType` parameter.
// bumpType[major|minor|patch] -> will specify how the version bumping occurs.

task releasePrepare(dependsOn: ensureCleanRepo) {
doLast {
def applicationId = android.defaultConfig.applicationId
def versionName = android.defaultConfig.versionName

if (versionName.indexOf("-") > -1) {
versionName = versionName.split("-")[0]
}

// Prepare the release commit with the specific tag.
String buildText = buildFile.getText()
buildText = buildText.replaceFirst(/versionName(\s+.*)/, "versionName '$versionName'")
buildFile.setText(buildText) //replace the build file's text
grgit.add(patterns: ['app/build.gradle'])
try {
grgit.commit(message: "[gradle-release-task] prepare release $applicationId-$versionName")
} catch (Exception e) {
throw new GradleException("Failed to commit, error:\n $e")
}
try {
grgit.tag.add {
name = versionName
message = "Release of $versionName"
}
} catch (Exception e) {
throw new GradleException("Failed to tag the repo, error:\n $e")
}

// Set new version name from input parameters.
def newVersionName
if (project.properties.containsKey("bumpVersion")) {
newVersionName = project.properties["bumpVersion"]
println "Bumping the version directly (bumpVersion=$newVersionName)"
} else if (project.properties.containsKey("bumpType")) {
def (major, minor, patch) = versionName.tokenize('.')
switch (bumpType) {
case "major":
major = major.toInteger() + 1
minor = 0
patch = 0
break
case "minor":
minor = minor.toInteger() + 1
break
case "patch":
patch = patch.toInteger() + 1
break
}
newVersionName = "$major.$minor.$patch"
} else {
throw new GradleException('Either bumpType or bumpVersion parameters should be provided')
}

// Prepare for next development iteration.
def versionCode = android.defaultConfig.versionCode
def newVersionCode = versionCode + 1
println "Bumping versionName from $versionName to $newVersionName"
println "Bumping versionCode from $versionCode to $newVersionCode"
buildText = buildFile.getText()
buildText = buildText.replaceFirst(/versionName(\s+.*)/, "versionName '$newVersionName-SNAPSHOT'")
buildText = buildText.replaceFirst(/versionCode(\s+.*)/, "versionCode $newVersionCode")
buildFile.setText(buildText) //replace the build file's text
grgit.add(patterns: ['app/build.gradle'])
grgit.commit(message: "[gradle-release-task] prepare for next development iteration")
println "Done!"
prepareRelease()
}
}

task releasePerform(dependsOn: ensureCleanRepo) {
doLast {
boolean force = false
if (project.properties.containsKey("force")) {
force = project.properties["force"]
}
println "Pushing the newest commits to the remote repository (force: $force)"
try {
grgit.push(force: force, tags: true)
} catch (Exception e) {
throw new GradleException("Failed to push to the repo,\n" +
" you can try using -Pforce=true parameter to force the push, error: \n$e")
}
println "Done!"
performRelease()
}
}
29 changes: 29 additions & 0 deletions gradle/clean_release.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
ext.cleanRelease = {
def clean = true
def applicationId = android.defaultConfig.applicationId

String headCommitMessage = grgit.head().shortMessage
while (headCommitMessage.contains("[gradle-release-task]")) {
clean = false
println "Found git commit: $headCommitMessage"
if (headCommitMessage.indexOf("$applicationId-") > -1) {
def tagName = headCommitMessage.split("$applicationId-")[1]
println "Removing the git tag: $tagName"
try {
grgit.tag.remove {
names = [tagName]
}
} catch (Exception e) {
println "Error while removing git tag:\n $e"
}
}
println "Resetting the git commit permanently!"
grgit.reset(commit: "HEAD~1", mode: "hard")
headCommitMessage = grgit.head().shortMessage

}
if (clean){
println "Repository is already clean"
}
println "Done!"
}
5 changes: 5 additions & 0 deletions gradle/ensure_clean.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ext.ensureClean = {
if (!grgit.repository.jgit.status().call().clean) {
throw new GradleException('Git status is not clean, please stash your changes!')
}
}
14 changes: 14 additions & 0 deletions gradle/perform_release.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ext.performRelease = {
boolean force = false
if (project.properties.containsKey("force")) {
force = project.properties["force"]
}
println "Pushing the newest commits to the remote repository (force: $force)"
try {
grgit.push(force: force, tags: true)
} catch (Exception e) {
throw new GradleException("Failed to push to the repo,\n" +
" you can try using -Pforce=true parameter to force the push, error: \n$e")
}
println "Done!"
}
65 changes: 65 additions & 0 deletions gradle/prepare_release.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
ext.prepareRelease = {
def applicationId = android.defaultConfig.applicationId
def versionName = android.defaultConfig.versionName

if (versionName.indexOf("-") > -1) {
versionName = versionName.split("-")[0]
}

// Prepare the release commit with the specific tag.
String buildText = buildFile.getText()
buildText = buildText.replaceFirst(/versionName(\s+.*)/, "versionName '$versionName'")
buildFile.setText(buildText) //replace the build file's text
grgit.add(patterns: [project.name + '/build.gradle'])
try {
grgit.commit(message: "[gradle-release-task] prepare release $applicationId-$versionName")
} catch (Exception e) {
throw new GradleException("Failed to commit, error:\n $e")
}
try {
grgit.tag.add {
name = versionName
message = "Release of $versionName"
}
} catch (Exception e) {
throw new GradleException("Failed to tag the repo, error:\n $e")
}

// Set new version name from input parameters.
def newVersionName
if (project.properties.containsKey("bumpVersion")) {
newVersionName = project.properties["bumpVersion"]
println "Bumping the version directly (bumpVersion=$newVersionName)"
} else if (project.properties.containsKey("bumpType")) {
def (major, minor, patch) = versionName.tokenize('.')
switch (bumpType) {
case "major":
major = major.toInteger() + 1
minor = 0
patch = 0
break
case "minor":
minor = minor.toInteger() + 1
break
case "patch":
patch = patch.toInteger() + 1
break
}
newVersionName = "$major.$minor.$patch"
} else {
throw new GradleException('Either bumpType or bumpVersion parameters should be provided')
}
Comment on lines +28 to +51
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Parameter Handling for Version Bumping

There is a potential issue in the switch-case block: the variable bumpType is referenced without being explicitly defined. This could lead to runtime errors if bumpType is not already available in the scope. To improve clarity and reliability, extract the property into a local variable before using it. For instance:

-    } else if (project.properties.containsKey("bumpType")) {
-        def (major, minor, patch) = versionName.tokenize('.')
-        switch (bumpType) {
+    } else if (project.properties.containsKey("bumpType")) {
+        def bumpType = project.properties["bumpType"]
+        def (major, minor, patch) = versionName.tokenize('.')
+        switch (bumpType) {

This ensures that bumpType is defined and clarifies its provenance.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Set new version name from input parameters.
def newVersionName
if (project.properties.containsKey("bumpVersion")) {
newVersionName = project.properties["bumpVersion"]
println "Bumping the version directly (bumpVersion=$newVersionName)"
} else if (project.properties.containsKey("bumpType")) {
def (major, minor, patch) = versionName.tokenize('.')
switch (bumpType) {
case "major":
major = major.toInteger() + 1
minor = 0
patch = 0
break
case "minor":
minor = minor.toInteger() + 1
break
case "patch":
patch = patch.toInteger() + 1
break
}
newVersionName = "$major.$minor.$patch"
} else {
throw new GradleException('Either bumpType or bumpVersion parameters should be provided')
}
// Set new version name from input parameters.
def newVersionName
if (project.properties.containsKey("bumpVersion")) {
newVersionName = project.properties["bumpVersion"]
println "Bumping the version directly (bumpVersion=$newVersionName)"
} else if (project.properties.containsKey("bumpType")) {
def bumpType = project.properties["bumpType"]
def (major, minor, patch) = versionName.tokenize('.')
switch (bumpType) {
case "major":
major = major.toInteger() + 1
minor = 0
patch = 0
break
case "minor":
minor = minor.toInteger() + 1
break
case "patch":
patch = patch.toInteger() + 1
break
}
newVersionName = "$major.$minor.$patch"
} else {
throw new GradleException('Either bumpType or bumpVersion parameters should be provided')
}


// Prepare for next development iteration.
def versionCode = android.defaultConfig.versionCode
def newVersionCode = versionCode + 1
println "Bumping versionName from $versionName to $newVersionName"
println "Bumping versionCode from $versionCode to $newVersionCode"
buildText = buildFile.getText()
buildText = buildText.replaceFirst(/versionName(\s+.*)/, "versionName '$newVersionName-SNAPSHOT'")
buildText = buildText.replaceFirst(/versionCode(\s+.*)/, "versionCode $newVersionCode")
buildFile.setText(buildText) //replace the build file's text
grgit.add(patterns: [project.name + '/build.gradle'])
grgit.commit(message: "[gradle-release-task] prepare for next development iteration")
println "Done!"
}
36 changes: 36 additions & 0 deletions utils/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ plugins {
id 'maven-publish'
}

apply from: "${rootProject.projectDir}/gradle/prepare_release.gradle"
apply from: "${rootProject.projectDir}/gradle/clean_release.gradle"
apply from: "${rootProject.projectDir}/gradle/perform_release.gradle"
apply from: "${rootProject.projectDir}/gradle/ensure_clean.gradle"

android {
compileSdk 34
namespace 'ai.elimu.content_provider.utils'
Expand Down Expand Up @@ -53,3 +58,34 @@ publishing {
tasks.named("publishReleasePublicationToMavenLocal") {
mustRunAfter(":utils:bundleReleaseAar")
}

tasks.register('ensureCleanRepo') {
doLast {
ensureClean()
}
}

tasks.register('releaseClean') {
dependsOn ensureCleanRepo
doLast {
cleanRelease()
}
}

// Task parameters:
// bumpVersion -> if available will specify new versionName directly and ignores the `bumpType` parameter.
// bumpType[major|minor|patch] -> will specify how the version bumping occurs.

tasks.register('releasePrepare') {
dependsOn ensureCleanRepo
doLast {
prepareRelease()
}
}

tasks.register('releasePerform') {
dependsOn ensureCleanRepo
doLast {
performRelease()
}
}