Gradle plugin to deploy Android Snapshot Versions

Overview

android-snapshot-publisher

codebeat badge

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.2.0"
  }
}

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 the versionNameFormat 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. AGP 4.2 fixes this issue but is still in alpha. If you're using a lower version of AGP, you can use the version of 2.1.0.

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} given by versionFormat.
    • {header} given by headerFormat. By default it contains information about the most recent commit and their author.
    • {history} given by historyFormat. It contains information about the most recent history of the build.

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 applying commitHistoryFormat to a certain range of commits of commits.

  • commitHistoryFormat: Specifies the {commitHistory} variable format. As headerFormat does, it uses Git's pretty format to create the commitHistory 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 is false because it's used in {header}

  • includeMergeCommitsInHistory: Flag to include merge commits in {commitHistory}.

  • includeHistorySinceLastTag: Indicates the history start point. By default it's false, which means that all commits are used to get the history. However, if its value is true, 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 is null 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 set outputFile = 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 as distributionEmails, 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 are internal, alpha, beta and production.
  • releaseStatus: the type of the release. The possible values are completed, draft, inProgress, halted.
  • defaultToAppBundles: if set to true, 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 are ignore (it will ignore the error and continue) and auto (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 the version 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, so debuggable 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

Comments
  • Option to choose buildType

    Option to choose buildType

    Hello,

    thanks for your contribution on this plugin. However I have a question regarding buildType: As far as I understood currently only the release buildType is used. Can this be configured to e.g. use debug or a different buildType?

    Thanks!

    enhancement 
    opened by Plinzen 4
  • Getting This exception on Google Play Publish Release Apk

    Getting This exception on Google Play Publish Release Apk

    Execution failed for task ':app:publishReleaseApk'.
     A failure occurred while executing com.github.triplet.gradle.play.tasks.PublishApk$Processor
       > There was a failure while executing work items
          > A failure occurred while executing com.github.triplet.gradle.play.tasks.PublishApk$ApkUploader
             > 410 Gone
               {
                 "code" : 410,
                 "errors" : [ {
                   "domain" : "androidpublisher",
                   "message" : "This Edit has been deleted.",
                   "reason" : "editDeleted"
                 } ],
                 "message" : "This Edit has been deleted."
               }
    

    Config:

            googlePlay {
                serviceAccountCredentials = "../.config/misc/GooglePlayAndroidDeveloper.json"
                track = "internal"
                releaseStatus = "completed"
                defaultToAppBundles = false
                resolutionStrategy = "auto"
            }
    

    Seems like this can solve this issue

    opened by anjalsaneen 2
  • Update gradle-play-publisher

    Update gradle-play-publisher

    This library causes some errors in gradle imports, and it unables the project to use compose. Here's a link to the issue, that was apparently solved. Issue #787 gradle-play-publisher

    opened by sante 0
  • Use credential service account file path instead of a credential file

    Use credential service account file path instead of a credential file

    Comments

    • The main change is to validate the credentials only when the deploy task is executed.
    • serviceAccountCredentials = file("your-key.json") or serviceAccountCredentials = "your-key.json" can be used in the same way
    opened by mirland 0
  • Incompatible because this component declares an API of a component compatible with Java 11 and the consumer needed a runtime of a component compatible with Java 8

    Incompatible because this component declares an API of a component compatible with Java 11 and the consumer needed a runtime of a component compatible with Java 8

    Have anyone encountered such an issue, Is it a build Gradle 7.0.+ issue?!

    * What went wrong:
    A problem occurred configuring project ':app'.
    > Could not resolve all artifacts for configuration ':app:classpath'.
       > Could not resolve com.xmartlabs:snapshot-publisher:2.4.0.
         Required by:
             project :app
          > No matching variant of com.xmartlabs:snapshot-publisher:2.4.0 was found. The consumer was configured to find a runtime of a library compatible with Java 8, packaged as a jar, and its dependencies declared externally, as well as attribute 'org.gradle.plugin.api-version' with value '7.1.1' but:
              - Variant 'apiElements' capability com.xmartlabs:snapshot-publisher:2.4.0 declares a library, packaged as a jar, and its dependencies declared externally:
                  - Incompatible because this component declares an API of a component compatible with Java 11 and the consumer needed a runtime of a component compatible with Java 8
                  - Other compatible attribute:
                      - Doesn't say anything about org.gradle.plugin.api-version (required '7.1.1')
              - Variant 'runtimeElements' capability com.xmartlabs:snapshot-publisher:2.4.0 declares a runtime of a library, packaged as a jar, and its dependencies declared externally:
                  - Incompatible because this component declares a component compatible with Java 11 and the consumer needed a component compatible with Java 8
                  - Other compatible attribute:
                      - Doesn't say anything about org.gradle.plugin.api-version (required '7.1.1')
    
    
    opened by aya-salama1989 1
Releases(v2.4.1)
  • v2.4.1(Feb 1, 2022)

  • v2.4.0(Oct 6, 2021)

  • v2.3.0-AGP7.0(Jun 21, 2021)

  • v2.3.0(Jun 12, 2021)

  • v2.2.0(Oct 29, 2020)

    Changes

    • Upgrade Google Play Publisher dependency to v3.0.0.
    • Change min required gradle version to 6.5.0.
    • Change min Android Gradle plugin gradle version to 4.1.0.

    Breaking changes

    • 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. AGP 4.2 fixes this issue but is still in alpha. If you're using a lower version of AGP, you can use the version of 2.1.0.

    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Jan 31, 2020)

  • v2.0.0(Oct 15, 2019)

    Changes

    Firebase app distribution migration

    Google deprecated and migrated Fabric Craslytics Beta to Firebase app distribution.
    The documentation specifies the required changes to use the new tool.

    Migration:

    Change plugin dependency setup:

    • Version 1x:
    buildscript {
      repositories {
        maven { url "https://plugins.gradle.org/m2/" }
        maven { url 'https://maven.fabric.io/public' } // Remove it
      }
      dependencies {
         classpath "com.xmartlabs:snapshot-publisher:1.0.4" // Replace version
      }
    }
    
    • Version 2x:
    buildscript {
      repositories {
        gradlePluginPortal()
        google() // Add it
      }
      dependencies {
         classpath "com.xmartlabs:snapshot-publisher:2.0.0" // Replace version
      }
    }
    

    Change the previous fabric block to the new firebaseAppDistribution block:

    • Version 1x:
    snapshotPublisher {
        fabric {
            distributionEmails = "[email protected]"
            distributionGroupAliases = "tester-group"
            distributionNotifications = true // Must be deleted
        }
        // ...
    }
    
    • Version 2x:
    snapshotPublisher {
        firebaseAppDistribution {
            distributionEmails =  "[email protected]"
            distributionGroupAliases = "tester-group"
            appId = null // New parameter
            serviceAccountCredentials = "/path/to/your-service-account-key.json" // new parameter
        }
        // ...
    }
    
    • 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.
    • serviceAccountCredentials: The path to your service account private key JSON file. 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.

    Breaking changes

    • Fabric Craslytics Beta integration was removed
    • Google Play's service credential account file path was changed to a credential file path.

    Migration:

    • Version 1x:
    snapshotPublisher {
        googlePlay {
           serviceAccountCredentials = file("/path/to/your-service-account-key.json")
        }
        // ...
    }
    
    • version 2x:
    snapshotPublisher {
        googlePlay {
           serviceAccountCredentials = "/path/to/your-service-account-key.json"
        }
        // ...
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v1.0.4(Oct 2, 2019)

  • v1.0.3(May 20, 2019)

  • v1.0.2(Apr 30, 2019)

  • v1.0.1(Apr 17, 2019)

    New Features

    • Added new history variable to use in releaseNotesFormat given by historyFormat. It's shown only if the {commitHistory} is not empty. (#25)
    • Added includeHistorySinceLastTag release notes setup variable. It enables to generate the history only for the commits after the latest git's tag. It's useful to show only the changes that changed since the last build. (#25)

    Fixes

    • Fix version name issue in generated release notes. (#24)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Apr 12, 2019)

    New Features

    • Add the ability to include the last commit in the release notes history. (#16)
    • Create preparation tasks. It enables you to create snapshot builds and test them locally without the necessity of deploy it. (#17)
    • Include git branch name in the app custom version name options (#18)

    Fixes

    • Truncate Fabric Beta's release notes if its length is greater than 16384 characters. (#21)

    Breaking changes

    • distributionEmails and distributionGroupAliases in Fabric's Beta configuration block are changed to strings instead of a list of strings. These values are built by joining all emails or aliases with commas. This change was made in order to make the setup process easier. (#19)
    Source code(tar.gz)
    Source code(zip)
  • v0.0.1(Mar 8, 2019)

Owner
xmartlabs
xmartlabs
Android part of the Android Studio(IntellijIDEA) OkHttp Profiler plugin

OkHttpProfiler Android Library Created by LocaleBro.com - Android Localization Platform The OkHttp Profiler plugin can show requests from the OkHttp l

Ievgenii 261 Dec 8, 2022
A plugin system that runs like a browser, but instead of load web pages, it load apk plugins which runs natively on Android system.

Android Dynamic Loader Android Dynamic Loader is a plugin system. The host application is like a browser, but instead of load web pages, it load plugi

Tu Yimin 1.4k Dec 28, 2022
🚀Plugin for Android Studio And IntelliJ Idea to generate Kotlin data class code from JSON text ( Json to Kotlin )

JsonToKotlinClass Hi, Welcome! This is a plugin to generate Kotlin data class from JSON string, in another word, a plugin that converts JSON string to

Seal 2.8k Jan 3, 2023
Android Plugin Framework

Android Plugin Framework This project is pre-mature and may be changed very frequently. Introduction Android Plugin Framework (APF) aims to providing

Umeng Limited 322 Nov 17, 2022
Intellij Idea, Android Studio plugin for generating Kotlin data classes from JSON. Helps to avoid writing boilerplate code for model classes. Supports annotations for Gson, Moshi, Jackson.

JSONToKotlinClass Intellij Idea, Android Studio plugin. Plugin generates Kotlin data classes from JSON text. It can find inner classes in nested JSON.

Vasily 139 Dec 21, 2022
Small Warp Plugin developed in Kotlin

Warps A small warps plugin for the 1.17 SMP. Minecraft 1.17 Spigot Contributing Install Java 16 Fork this repo Clone your fork Make your changes Use h

MenuDocs 6 Feb 19, 2022
Android common lib, include ImageCache, HttpCache, DropDownListView, DownloadManager, Utils and so on

android-common-lib 关于我,欢迎关注 微博:Trinea 主页:trinea.cn 邮箱:trinea.cn#gmail.com 微信:codek2 主要包括:缓存(图片缓存、预取缓存、网络缓存)、公共View(下拉及底部加载更多ListView、底部加载更多ScrollView、

Trinea 5k Dec 30, 2022
A Model-View-Presenter / Model-View-Intent library for modern Android apps

Mosby A Model-View-Presenter and Model-View-Intent library for Android apps. Dependency dependencies { compile 'com.hannesdorfmann.mosby3:mvi:3.1.1

Hannes Dorfmann 5.5k Dec 25, 2022
dexposed enable 'god' mode for single android application.

What is it? Dexposed is a powerful yet non-invasive runtime AOP (Aspect-oriented Programming) framework for Android app development, based on the work

Alibaba 4.5k Dec 28, 2022
A small, yet full-featured framework that allows building View-based Android applications

Conductor A small, yet full-featured framework that allows building View-based Android applications. Conductor provides a light-weight wrapper around

BlueLine Labs 3.9k Jan 6, 2023
A Job Queue specifically written for Android to easily schedule jobs (tasks) that run in the background, improving UX and application stability.

This Project is Deprecated! Thanks to everybody who've used Android Priority JobQueue. It was designed in a world where there was no JobScheduler, RxJ

Yigit Boyar 3.4k Dec 31, 2022
Nucleus is an Android library, which utilizes the Model-View-Presenter pattern to properly connect background tasks with visual parts of an application.

Nucleus Deprecation notice Nucleus is not under develpment anymore. It turns out that Redux architecture scales way better than MVP/MVI/MVVM/MVxxx and

Konstantin Mikheev 2k Nov 18, 2022
LiteOrm is a fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line of code efficiently.

#LiteOrm:Android高性能数据库框架 A fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line

马天宇 1.5k Nov 19, 2022
Kick-starts Android application development.

Synopsis If you've made it here, chances are you are not quite as satisfied with the Android application framework as you could be. Same for us, that'

Matthias Käppler 1.3k Dec 4, 2022
Rosie is an Android framework to create applications following the principles of Clean Architecture.

Rosie The only way to make the deadline—the only way to go fast—is to keep the code as clean as possible at all times. — Robert C. Martin in Clean Cod

Karumi 1.8k Dec 28, 2022
Create kotlin android project with one line of command.

README This is an android application template project built with kotlin language and some useful libraries. It provides a creator script to quickly c

nekocode 1.6k Dec 20, 2022
Moxy is MVP library for Android

Moxy This Moxy repository is deprecated and no longer supported. Please migrate to the actual version of the Moxy framework at Moxy communuty repo. De

Arello Mobile 1.6k Dec 28, 2022
A data-binding Presentation Model(MVVM) framework for the Android platform.

PLEASE NOTE, THIS PROJECT IS NO LONGER BEING MAINTAINED. As personal time contraints, I am currently unable to keep up. Please use official android da

RoboBinding open source 1.3k Dec 9, 2022
Minimal UI library for Android inspired by React

Anvil - reactive views for Android Anvil is a small Java library for creating reactive user interfaces. Originally inspired by React, it suits well as

null 1.4k Dec 23, 2022