Android Snapshot Publisher is a Gradle plugin to prepare and distribute Android Snapshot versions to multiple distribution sources in a simple and common way. Check out our Introducing Android Snapshot Plugin blog post to see what inspired us to build it as well as a brief description of the plugin's main features and how to get started with it.
The main features of the preparation process are:
- Update the Android Version Name to keep track of the distributed versions. The default behavior adds the commit identifier to the Android Version name. It's very helpful to track possible issues, for example if a crash occurs, you'll want to know in which snapshot version of the app it happened.
- Create and customize rich release notes based on git's history.
As an example, the following is an automated release note generated by this project.
1.0.1-67a5893: Added pagination in project requests (#150)
Author: Mirland
Last changes:
• Added ripple effect to buttons (#149)
• Change copies in project details screen (#148)
• Add error message when creating a list with the name of an existing one (#147)
• Added filters to organization repositories (#146)
• Import a project automatically after creation (#145)
• Fixed bug that don't delete cards in the db after deleted in the service (#144)
• Fix dashboard view crash and splash screen issue (#143)
• Added languages colors (#142)
• Added progress bar when fetching repositories (#141)
• Added analytics (#140)
• Fix crash that sometimes happened when removing imported projects (#139)
This plugin is also meant to easily deploy snapshot builds.
Currently the available services are:
Table of content
Installation
The plugin is hosted in the Gradle Plugin Portal.
buildscript {
repositories {
gradlePluginPortal()
google()
}
dependencies {
classpath "com.xmartlabs:snapshot-publisher:2.4.1"
}
}
Apply the plugin to each individual com.android.application
module where you want to use it.
apply plugin: 'com.xmartlabs.snapshot-publisher'
Note that Google's Maven Repository must be added to the project because Android Snapshot Publisher plugin uses Firebase's plugin and it's hosted in Google's Maven Repository.
Setup
The plugin defines a snapshotPublisher
block where you can add the different setup alongside the Android modules.
snapshotPublisher {
version {
// Version customization
}
releaseNotes {
// Release notes customization
}
firebaseAppDistribution {
// Firebase App Distribution setup
}
googlePlay {
// Google Play setup
}
}
The version and releaseNotes blocks are used to perform the preparation process. firebaseAppDistribution and googlePlay blocks are used to perform the distribution process.
Version customization
The version
block allows you to perform version customizations.
The field in that block is optional and its default value is:
snapshotPublisher {
version {
versionNameFormat = '{currentVersionName}-{commitHash}'
}
// ...
}
-
versionNameFormat
defines the Android Version Name for the delivered build. The default value is the current version name and the short-hash commit, joined by a hyphen.The possible variables for this value are:
{currentVersionName}
: The current version name.{commitHash}
: The current git commit hash, in the short format.{branchName}
: The current git branch name.
This value can be updated using these optional variables. For example, if you want to keep the current version name and the hash commit and add a custom suffix such as
-SNAPSHOT
, you must assign the value'{currentVersionName}-{commitHash}-SNAPSHOT'
to theversionNameFormat
variable.
Known Issue: after AGP 4.1 the version name cannot be applied only to specific plugin tasks.
In turn, it's applied in the configuration step, causing all builds to contain versionNameFormat
.
Release notes
The releaseNotes
block allows you to perform build release notes customizations.
All fields in that block are optional and their default values are:
snapshotPublisher {
releaseNotes {
releaseNotesFormat = """{version}: {header}
{history}
"""
versionFormat = '{versionName}'
headerFormat = '%s%n%nAuthor: %an <%ae>'
historyFormat = '\nLast Changes:\n{commitHistory}'
commitHistoryFormat = '• %s (%an - %ci)'
maxCommitHistoryLines = 10
includeLastCommitInHistory = false
includeMergeCommitsInHistory = true
includeHistorySinceLastTag = false
outputFile = null
}
// ...
}
Note: you can test the generated release notes executing the
generateSnapshotReleaseNotes
gradle task and if you also add the--info
flag you will see them in the command's output.
releaseNotesFormat
: Defines the format of the release notes: The possible variables to play with in this case are:
Version
It contains information about the build version.
-
versionFormat
: Specifies the version's variable format.{versionName}
(Android app's Version Name) and{versionCode}
(Android app's Version Code) can be used to create it.
Header
It contains information about the most recent commit.
headerFormat
: Specifies the header's variable format. The plugin uses Git's pretty format to retrieve the information about the current commit. If you want to modify this, you may want to use it.
History
It contains information about the most recent commits, starting from the last -not current- commit to maxCommitHistoryLines
commits before that.
If you want to include the last commit in that range, you can set includeLastCommitInHistory
as true
.
The format of these commits is given by commitHistoryFormat
.
This section is shown only if there is at least one commit history.
-
historyFormat
: Specifies the history's variable format. It contains the{commitHistory}
, which is given by the result of applyingcommitHistoryFormat
to a certain range of commits of commits. -
commitHistoryFormat
: Specifies the{commitHistory}
variable format. AsheaderFormat
does, it uses Git's pretty format to create thecommitHistory
for the previous commits. -
maxCommitHistoryLines
: Indicates the number of commits included in{commitHistory}
. -
includeLastCommitInHistory
: Flag to include the most recent commit in{commitHistory}
. By default this value isfalse
because it's used in{header}
-
includeMergeCommitsInHistory
: Flag to include merge commits in{commitHistory}
. -
includeHistorySinceLastTag
: Indicates the history start point. By default it'sfalse
, which means that all commits are used to get the history. However, if its value istrue
, only the commits after the previous tag will be included in the build history. The previous tag is the latest tag before the current commit. This is useful if you want to include in the history only the changes after the previous release.
Other
outputFile
: The file where the release notes will be saved. By default this value isnull
and that means the release notes will be generated and delivered with the snapshot build but it will not be saved in the file system. If you want to save the release notes in the file system, you can setoutputFile = file("release-notes.txt")
. You can define it using a relative path (where the start point is the Android application module folder) or an absolute path.
Firebase App Distribution
This block defines the configuration needed to deploy the artifacts in Firebase App Distribution's system. This plugin uses Firebase's App Distribution plugin.
snapshotPublisher {
firebaseAppDistribution {
appId = null
distributionEmails = ""
distributionGroupAliases = ""
serviceAccountCredentials = "/path/to/your-service-account-key.json"
}
// ...
}
The only required field is serviceAccountCredentials
.
To release to Firebase you must create a Google service account with Firebase Quality Admin role. If you don't have a service account, you can create one following this guide.
appId
: Your app's Firebase App ID. Required only if you don't have the google services gradle plugin installed. You can find the App ID in the google-services.json file or in the Firebase console on the General Settings page. The value in your build.gradle file overrides the value output from the google-services gradle plugin.distributionEmails
: The list of email addresses of those who'll get the release. This value is built by joining all emails with commas. For example if you want to distribute the build to[email protected]
and[email protected]
,distributionEmails
value should be"[email protected],[email protected]"
.distributionGroupAliases
: The list of names (aliases) of the groups defined inside Firebase's App Distribution that will get the release. As well asdistributionEmails
, all aliases must be joined by commas.serviceAccountCredentials
: The path to your service account private key JSON file.
Google Play
This block defines the configuration needed to deploy the artifacts in Google Play. This plugin uses Gradle Play Publisher.
snapshotPublisher {
googlePlay {
serviceAccountCredentials = "/path/to/your-service-account-key.json"
track = "internal"
releaseStatus = "completed"
defaultToAppBundles = false
resolutionStrategy = "auto"
}
// ...
}
The only required field is serviceAccountCredentials
.
To release to Google Play you must create a service account with access to the Play Developer API.
You can follow the CodePath guide "Automating Publishing to the Play Store".
serviceAccountCredentials
: the path to your service account private key JSON file.track
: refers to the Google play tracks. For example, some possible tracks areinternal
,alpha
,beta
andproduction
.releaseStatus
: the type of the release. The possible values arecompleted
,draft
,inProgress
,halted
.defaultToAppBundles
: if set totrue
, the plugin will generate an App Bundle instead of an APK.resolutionStrategy
: defines the strategy that will take place if a build with the same version code already exists in Google Play (this will throw an error). The possible values areignore
(it will ignore the error and continue) andauto
(it will automatically increase the version code for you).
Note: Google's PlayStore limits your release notes to a maximum of 500 characters. Because of that, the plugin trims them up to the last allowed line.
How to use it?
The plugin defines some tasks that can be run.
The naming convention is as follows: [action][Variant][BuildType]
. For example, publishSnapshotGooglePlayStagingRelease
will be generated if the app has a staging
flavor and release
build type.
To find available tasks, run ./gradlew tasks
and look under the "Snapshot Publishing" section.
The most important tasks are:
publishSnapshotFirebaseAppDistribution[Variant][BuildType]
: it'll publish a snapshot version in Firebase App Distribution.publishSnapshotGooglePlay[Variant][BuildType]
: it'll publish a snapshot version in Google Play.
Some auxiliary tasks are:
generateSnapshotReleaseNotes[Variant][BuildType]
: Generates the release notes file.updateAndroidVersionName[Variant][BuildType]
: Changes the app version name to use the version name defined in theversion
configuration's block.prepareApkSnapshotBuild[Variant][BuildType]
: Prepares the snapshot build and creates an apk version.prepareBundleSnapshotBuild[Variant][BuildType]
: Prepares the snapshot build and creates a bundle version.
Note: Google's PlayStore doesn't allow to upload
debuggable
builds, sodebuggable
build types' gradle tasks are not generated.
Getting involved
- If you want to contribute please feel free to submit pull requests.
- If you have a feature request please open an issue.
- If you found a bug check older issues before submitting a new one.
Before contributing, please check the CONTRIBUTING file.
About
Made with ❤️ by XMARTLABS