Android Pro Tip: Generating your app’s changelog from Git inside build.gradle

Git -> Changelog

The benefits of this approach

  • It uses commit messages as the changelog item so nothing is ever missed! We adopted a “Squash & Merge” approach to accommodate this setup so instead of this approach listing every single commit in a PR, which could be numerous & very techincal, we instead title our PR’s appropriately when we squash & merge with a user facing title, such as “Fixed crash when clicking on user profile”. That non-technical user readable string is what ends up in the changelog.
  • Your changelog will always be up to date. This method builds the changelog from the last tagged commit until now. So as long as you tag your release’s appropriately — your changelog will always be up to date.
  • It requires no developer intervention whatsoever. It run’s when you build your APK so every time you commit, a new changelog item will appear in the next build.
  • It’s easily customizable to meet your needs or even ignore commits based on some specific string identified. For example, if you don’t want a specific commit listed in the changelog you could prefix it with “**” & then just ignore commit’s prefixed with that when building the changelog.

The code

git describe --tags --abbrev=0
git log $lastTag..HEAD --oneline --no-merges --pretty=format:"%s"
String generateChangelog() {
println "Generating changelog.."
//Get the last tag
lastTag = "git describe --tags --abbrev=0".execute().text.trim()
//Get all the commits since the last tag
def gitLogCmd = "git log $lastTag..HEAD --oneline --no-merges --pretty=format:\"%s\"".execute().text.trim()
//Loop each line of the commits to build your changelog
def changelog = "\""
gitLogCmd.eachLine { line ->
//Remove surrounding quotation marks generated by the git log comand
def escapedLine = line.substring(1, line.length() - 1)
//Escape backslashes
escapedLine = escapedLine.replaceAll(/(\\)/, "\\/")
//Escape quotation marks
escapedLine = escapedLine.replaceAll('"', '\\\\"')
//Add each item to the changelog as a bullet point
changelog += "• $escapedLine \\n"

//Close the changelog string
changelog = (changelog + "\"").trim()
//Useful log so you can see what was generated in the Gradle output
println "Changelog generated, $changelog, from $lastTag to now."
return changelog

Nearly done

android {
defaultConfig {
buildConfigField "String","CHANGELOG","${generateGitChangelog()}"

Side note

Job done



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store