I don't really know how to word this issue which is probably why i can't find any answers online.
in react-native we can do
./gradlew assembleRelease
and it will read ~/.gradle/gradle.properties and the SigningConfig in android/app/build.gradle
signingConfigs {
release {
storeFile file(BLAH_RELEASE_STORE_FILE)
storePassword BLAH_RELEASE_STORE_PASSWORD
keyAlias BLAH_RELEASE_KEY_ALIAS
keyPassword BLAH_RELEASE_KEY_PASSWORD
}
}
to produce a signed apk.
I'd like to create signed apks but using a different keystore file from a single command
so ideally
./gradlew assembleDev
and it would create an signed apk with a different output name and signed with a different key. Ideally with a different identifier so that the app can be installed side by side with the release version of the app.
I know i need to make changes to gradle config, but searching around i can't figure out how to do this. Is there a ready made tutorial that walks someone how to do this?
I'm thinking i can't possibly be the first person to want this.
You could use the buildType as the prefix for the property names
android {
signingConfigs {
release {
storeFile file(property('release.storeFile'))
storePassword property('release.storePassword')
...
}
dev {
storeFile file(property('dev.storeFile'))
storePassword property('dev.storePassword')
...
}
}
buildTypes {
release {
signingConfig signingConfigs.release
...
}
dev {
signingConfig signingConfigs.dev
...
}
}
}
Related
I'm using a code analysis tool called "errorprone" in my builds. It runs for every release type, but I'd like to only use it for release builds (or more specifically, non-debug builds). The relevant parts of my gradle config look like this:
plugins {
id "net.ltgt.errorprone" version "0.0.14"
}
...
tasks.withType(JavaCompile) {
options.compilerArgs += [
'-Xep:DefaultCharset:OFF',
}
...
dependencies {
errorprone 'com.google.errorprone:error_prone_core:2.3.1'
}
I've already configured buildTypes for debug and release. How do I configure errorprone dependency to only use release?
Barry, Add your dependency as
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
android.productFlavors.each {
flavor ->
if (flavor.name.contains("debug")) {
implementation 'com.google.android.exoplayer:exoplayer:2.8.4'
// add("ReleaseImplementation", ('com.android.support:leanback-v17:' + supportLibraryVersion))
//add("${flavor.name}DebugImplementation", (fileTree(include: 'vgdrm.jar', dir: "${vgdrmRootDir}/${flavor.ext.vgdrmVersion}-debug")))
}
}
Can I convince Gradle to produce multiple binaries? I have several Kotlin packages with files that have a proper "fun main(...)" but the default IntelliJ build.gradle file only allows me to specifiy one "compilations.main.entryPoint".
I could put the main functions into Kotlin classes or objects if that would help.
Changing the entryPoint argument to an array did not work :)
If it's not currently possible, is it a general limitation of Gradle or only of the "kotlin-multiplatform" plugin?
plugins {
id 'kotlin-multiplatform' version '1.3.11'
}
repositories {
mavenCentral()
}
kotlin {
targets {
// For ARM, preset should be changed to presets.iosArm32 or presets.iosArm64
// For Linux, preset should be changed to e.g. presets.linuxX64
// For MacOS, preset should be changed to e.g. presets.macosX64
fromPreset(presets.mingwX64, 'mingw')
configure([mingw]) {
// Comment to generate Kotlin/Native library (KLIB) instead of executable file:
compilations.main.outputKinds('executable')
// Change to specify fully qualified name of your application's entry point:
compilations.main.entryPoint = 'hello.main'
}
}
sourceSets {
// Note: To enable common source sets please comment out 'kotlin.import.noCommonSourceSets' property
// in gradle.properties file and re-import your project in IDE.
mingwMain {
}
mingwTest {
}
}
}
task runProgram {
def buildType = 'debug' // 'release' - Change to 'debug' to run application with debug symbols.
dependsOn "link${buildType.capitalize()}ExecutableMingw"
doLast {
def programFile = kotlin.targets.mingw.compilations.main.getBinary('EXECUTABLE', buildType)
exec {
executable programFile
args ''
}
}
}
In https://github.com/JetBrains/kotlin-native/issues/2505 I've just got the answer that this will be possible with Kotlin Native 1.3.20!
I'm using the new Play Framework support in Gradle 2.7.
Ironically, Play 2.3.x explicitly depends on org.scala-sbt:io:0.13.8.
Gradle is able to resolve the JAR (not the sources, just the classes) from typesafe's repository if I add
model {
components {
play {
platform play: "2.3.7", scala: "2.10", java: "1.7"
}
}
}
repositories {
maven {
name "typesafe-maven-release"
url "https://repo.typesafe.com/typesafe/maven-releases"
}
ivy {
name "typesafe-ivy-release"
url "https://repo.typesafe.com/typesafe/ivy-releases"
layout "ivy"
}
}
dependencies {
play group: "org.scala-sbt", name: "io", version: "0.13.8", classifier: "jar", configuration: "compile"
}
however it seems that it cannot resolve the io-sources.jar. I get this:
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':runPlayBinary'.
Could not find io-sources.jar (org.scala-sbt:io:0.13.8).
Searched in the following locations:
https://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/io/0.13.8/srcs/io.jar
I actually don't care about these sources, I just want to avoid this runtime exception when running gradlew runPlay
Execution exception
[RuntimeException: java.lang.NoClassDefFoundError: sbt/Path$]
Any advice? I can't seem to figure out how to exclude or resolve the sources dependency.
I ran into the same RuntimeException (NoClassDefFound sbt/Path$) with Play 2.4 and Gradle 2.7. In my case the root problem was to not define all repositories correctly (didn't include typesafe-ivy -> sbt-io was not resolved -> thought i need to state sbt-io-dependency -> wrong sbt-io led to mentioned Exception...).
I would advise you to add jcenter() as repository, remove the explicit dependency on sbt and state the play version in your build.gradle. As an example my working gradle.build:
plugins {
id 'play'
}
dependencies {
repositories {
jcenter()
maven {
name "typesafe-maven-release"
url "https://repo.typesafe.com/typesafe/maven-releases"
}
ivy {
name "typesafe-ivy-release"
url "https://repo.typesafe.com/typesafe/ivy-releases"
layout "ivy"
}
}
play 'com.typesafe.play:play-jdbc_2.11:2.4.3'
[...other dependencies - but not "org.scala-sbt"!]
}
model {
components {
play {
platform play: '2.4.3', scala: '2.11'
injectedRoutesGenerator = true
}
}
}
In your case the last part should be:
model {
components {
play {
platform play: '2.3.7', scala: '2.10'
}
}
}
A kind Gradle dev answered my question on the Gradle forums
TL;DR - Gradle/Play bug specific to 2.3.7 that can be resolved by using
repositories {
ivy {
url "https://repo.typesafe.com/typesafe/ivy-releases/"
layout "pattern", {
ivy "[organisation]/[module]/[revision]/ivys/ivy.xml"
artifact "[organisation]/[module]/[revision]/jars/[artifact].[ext]"
}
}
}
In my case, upgrading to Play 2.3.9 fixed my problem.
I added the signing settings as the guide says. Now when I run ./gradlew assembleDebug, it requires my keystore and key passwords, and there are two APK files at the end:
./Main/build/outputs/apk/Main-debug.apk
./Main/build/outputs/apk/Main-debug-unaligned.apk
So Gradle builds a debug version of my module but requires the release key.
The build.gradle file of the built module is below.
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion '19.1.0'
signingConfigs {
release {
storeFile file("my-release-key.keystore")
storePassword System.console().readLine("\nKeystore password: ")
keyPassword System.console().readLine("Key password: ")
keyAlias "my_key"
}
}
defaultConfig {
minSdkVersion 9
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.release
}
}
}
dependencies {
compile 'com.android.support:support-v4:19.0.1'
compile 'com.android.support:appcompat-v7:19.0.1'
compile project(':Log-Wrapper')
compile 'com.google.android.gms:play-services:+'
}
Update #1.
The solution on https://stackoverflow.com/a/24281294/1065835 works, and I accepted the answer. But I personally prefer using the approach described here. Release keys are stored locally and safely, and there is no need to type passwords every time when compiling a release version.
Seems I could merge some suggestions picked up here and there.. ..and I got it working.
The problem seems to be the fact that writing ANYWHERE in build.gradle something like:
storePassword System.console().readLine("\nKeystore password: ")
it will be executed ANYTIME.
The solution I put together was, creating a signingCongif block BEFORE buildTypes block:
signingConfigs {
release {
storeFile file("c://my.keystore")
storePassword "" // REQUIRED otherwise cannot be overwritten
keyAlias "myAlias"
keyPassword "" // REQUIRED otherwise cannot be overwritten
}
}
buildTypes {
[...]
and tweaking gradle configuration with this:
gradle.taskGraph.whenReady { taskGraph ->
if(taskGraph.hasTask(assembleRelease) || taskGraph.hasTask(installRelease)) {
// Only execute when we are trying to assemble a release build
def passKeystore = System.console().readLine("\nKeystore password: ")
def passKey = System.console().readLine("\nKey password: ")
android.signingConfigs.release.storePassword = passKeystore
android.signingConfigs.release.keyPassword = passKey
}
}
Note that:
1. This block was outside and before the "android {}" one.
2. This was tested in COMMAND LINE execution only. Seems some fixes are needed where no console is available.
It appears as though there are only 3 options:
Extract my signing config to a separate pseduo-project
Automate the signature, but sign EVERYTHING with release keys
Enter the passwords manually on the command line
This is my workaround and your 4th option to achieve a perfect balance:
apply plugin: 'com.android.application'
gradle.taskGraph.whenReady { taskGraph ->
if(taskGraph.hasTask(':app:assembleRelease')) {
android.signingConfigs.release.storeFile = file(KEYSTORE)
android.signingConfigs.release.storePassword = STOREPASS
android.signingConfigs.release.keyAlias = KEY_ALIAS
android.signingConfigs.release.keyPassword = KEYPASS
}
}
android {
...
defaultConfig {
...
}
signingConfigs {
debug {
}
release {
}
}
buildTypes {
debug {
...
}
release {
...
//signingConfig signingConfigs.release
}
}
}
This allows you to use a stored key and signature ONLY on release builds
NOTE: i can't post links, so i guess you'll need to go here to follow the references. sorry, not my rule.
i'm getting the following error when attempting to import a project into Android Studio 0.2.9:
Could not execute build using Gradle distribution
'http://services.gradle.org/distributions-snapshots/
gradle-1.8-20130830160653+0000-bin.zip'.
A problem occurred configuring project ':library'.
A problem occurred configuring project ':library'.
Failed to notify project evaluation listener.
Neither path nor baseDir may be null or empty
string. path='' basedir='<projects folder>/
drag-sort-listview/library'
Consult IDE log for more details (Help | Show Log)
the project was originally a Maven project (1). i opened it in Eclipse ADT, generated a /librabry/build.gradle file per the instructions at (2).
the Eclipse ADT generated build.gradle looked like:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4'
}
}
apply plugin: 'android-library'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}
android {
compileSdkVersion 7
buildToolsVersion "17.0.0"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['']
resources.srcDirs = ['']
aidl.srcDirs = ['']
renderscript.srcDirs = ['']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
instrumentTest.setRoot('tests')
}
}
i had to change line 6 from
classpath 'com.android.tools.build:gradle:0.4'
to
classpath 'com.android.tools.build:gradle:0.5+'
to get Android Studio to stop saying the versions were miss-matched. i also added a /settings.gradle file containing
include ':library'
and a /local.properties file with the contents
# This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/Applications/Android Studio.app/sdk
i then attempted to import the /settings.gradle file by selecting it in the 'File | Import Project...' dialog. i have 'Use Auto-import' checked and 'Use gradle wrapper with verification' option selected in the dialog (3). the full idea.log entry can be viewed at (4).
any help would be greatly appreciated, thanks.
This will happen if you are using Environment Variables like so:
android {
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
And you have not defined those variables in your gradle.properties file located at the root of your project.
To fix this, make sure your variables are defined, here is an example from my gradle.properties file:
RELEASE_STORE_FILE=app_keystore.jks
RELEASE_STORE_PASSWORD=password
RELEASE_KEY_ALIAS=MyAppKey
RELEASE_KEY_PASSWORD=password
The error may be referring to your keystore's path. If the keystore's path doesn't work, it will think it's null. If you just want to use your keystore's file name (instead of the full path), make sure the keystore is in the root directory of your project.
android {
signingConfigs {
release {
storeFile file(**DoubleCheckPath**)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
(Answered by the OP in a question edit. Converted to a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
ok, solved it. the issue is with the empty lists under android.sourceSets in build.gradle, I commented them out to resolve the error. Here's my current build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4'
}
}
apply plugin: 'android-library'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}
android {
compileSdkVersion 7
buildToolsVersion "17.0.0"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
// java.srcDirs = ['']
// resources.srcDirs = ['']
// aidl.srcDirs = ['']
// renderscript.srcDirs = ['']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
instrumentTest.setRoot('tests')
}
}
hope that helps y'all.
you may miss a file in project, for "gradle.properties" file, because this file is include some varies, for example , our custom var, such key.storefile key.keypassword, you should check this file is exists or not.
Modify file(String.valueOf(RELEASE_STORE_FILE)) in
android {
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}