How to sign android apk using jenkins - android

I have my keystore release.keystore in the path /home/ankit/keystores/release.keystore. I want to use the keypair aliased as example for signing an app that is built using Jenkins. However, I am unable to feed the address of the keystore in the Jenkins. Below is the screenshot:
As it can be seen, there is a drop down list against the key store label and it has no item. I tried to follow the official doc but I didn't get it.
I think I have to link the existing keypair somehow to Jenkins, so that it shows up in the drop down list. But I can't figure how.

Instead you could configure this all in gradle itself, which will work independent of any CI. First create a build.properties in root of your project and include following:
#Key store
keystore.release=../keys/release.keystore
keystore.debug=../keys/debug.keystore
keystore.key.alias=...
keystore.key.password=...
keystore.password=...
Now in your app modules build.gradle access those props:
final Properties props = new Properties()
props.load(new FileInputStream('build.properties'))
android {
signingConfigs {
release {
keyAlias props['keystore.key.alias']
keyPassword props['keystore.key.password']
storeFile file(props['keystore.release'])
storePassword props['keystore.password']
}
debug {
storeFile file(props['keystore.debug'])
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
debug {
...
signingConfig signingConfigs.debug
}
}
}
Now make sure it works in your local machine with ./gradlew clean assembleRelease (There's something else if you do in PC)
After that commit the changes and update the gradle build settings in your CI. And make sure those keystores are there.

From the Android Signing Jenkins Plugin documentation:
Before adding a Sign Android APKs build step to a job, you must configure a certificate credential using the Credentials Plugin's UI.
If you need more details about how to use the Credentials Plugin in Jenkins, here is the user guide.

Related

Android app - bugs showing only in release bundle

I recently uploaded my first Kotlin-Android app to a closed testing (alpha) track in Google Play Console. The review was complete and I shared my link to some testers. Unfortunately the release bundle has major bugs that are not present in the debug APK! (the one that generates automatically when I hit "Run" in Android Studio). I checked both bundles on my device and the debug version works perfectly fine while the release is unusable. Is there anyway to debug a release version??? Or maybe create a debuggable build that mimics it's behaviour (as a release build is set to be undebugable for safety reasons...). Is there a way to see the app logs? (or are they removed in the release build?)
I think it's important to mention that all bugs are related to Firebase actions. My Firebase project have all the needed "SHA certificate fingerprints" (SAH-1 & SHA-256 for the debug, upload & app-signing keys). Maybe another thing is missing?
Maybe the specific bugs can point to the root of the difference, so these are my 2 biggest bugs:
Each user document holds a list of items which is shown in a recyclerView in one of his screens. In the release version no item is shown. I checked the Firestore console and the items are added successfully (from any version) and they show when I sign in the same user with the debug version.
Can't sign in via phone number (in Firebase auth pre-built UI). The other methods work fine. I can even link a phone to an existing account, but the pre-built sign-in flow stops after I enter a phone number and resets to the initial screen. In the debug version that works fine.
Did someone encounter anything like that?
Any help would be appreciated.
I found the way to debug the release bundle. The problem was that the "release" build variant used the default signing key - the debug key. I had to Configure the build process to automatically sign my app with a secured key. At the end, I have the following code in my "build.gradle (:app)" file:
...
def keystorePropertiesFile = rootProject.file(<keystore.properties file location>)
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
signingConfigs {
ionce {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
...
buildTypes {
release {
...
signingConfig signingConfigs.ionce
}
}
...
}
...
(I choose to Remove signing information from my build files. If you do, pay attention to the "\" orientation in the storeFile field as the error is not very informative. This answer helped me)
If anyone also encounter one of the two issues I mentioned, here are the solutions:
The difference between the build variants was that in my "release" variant I use minifyEnabled true, which changes the attributes' names to minify the code. When getting the document from Firestore it did not match the object structure and failed to load the list. The solution is in this answer.
This one was not related to the difference in build types - seems I didn't check the feature after upgrading firebase-auth library in my gradle. Upgrading the firebase-ui-auth library, like in this answer, did the trick :)
you can add this debuggable true in your gradle file
release {
debuggable true
minifyEnabled false
shrinkResources false
}
this will help you debug the release version, make sure that minifyEnabled and shrinkResources are false
to run the Release version of the app with the Release Keystore use this
signingConfigs {
release {
storeFile file('file location')
storePassword 'your store password'
keyAlias 'your key alias'
keyPassword 'your key password'
}
}
and then add in the variant of release this
release{
signingConfig singingConfigs.release
}

How to make multiple workstations build app compatible on one Android device

I have multiple android dev workstations and I work on them to build Android apk and deploy them on one Android device. Whenever I change a workstation, I have to remove the app from the device and reinstall it with a new one. So all caches are removed after reinstall. I wonder whether there is a way for me to deal with multiple workstations sharing with one android device without reinstall. I think there must be something unique across multiple workstations.
This happens because different workstations have different debug keystore. You can achieve your intended behavior as follows:
You can create your own keystore (follow this SO for creating it), check it in your repository. Place this keystore in your project directory.
Change your debug config to use this new keystore. This will ensure your debug app is signed with same keystore across all your dev workstations
To do that change your build.gradle as follows:
android {
...
signingConfigs {
defaultConfig {
storeFile file(getRootDir().getPath() + "\<file-name>.keystore")
storePassword <your password>
keyAlias <your alias>
keyPassword <your password>
}
}
buildTypes {
debug {
signingConfig signingConfigs.defaultConfig
...
}
}
}
Commit the code and perform pull across all your dev workstations.

app-release-unsigned.apk is not signed

I downloaded the zip file of an Android app on github and I'm trying to run it, but I get a dialog with this message
app-release-unsigned.apk is not signed. Please configure the signing information for the selected flavor using the Project Structure dialog.
I'm using Android Studio.
What am I supposed to do?
If anyone wants to debug release build using Android Studio, follow these steps:
Set build variant to release mode.
Right click on app in left navigation pane, click Open Module Settings.
Go to Signing Tab. Add a signing config and fill in information. Select your keychain as well.
Go to Build Type tab. Select release mode and set:
-Debuggable to true.
-Signing Config to the config. (The one you just created).
Sync your gradle. Enjoy!
Make sure the build variant is set to debug (and not release) in Android Studio (check the build variants panel).
If set to debug, it should automatically sign the app with the auto-generated debug keystore, without editing the build scripts.
However you will need to create and configure a specific keystore for release.
Official documentation, covering debug and release modes: https://developer.android.com/tools/publishing/app-signing.html
Always sign your build using your build.gradle DSL script like this:
android {
signingConfigs {
debug {
storeFile file("debug.keystore")
}
myConfig {
storeFile file("other.keystore")
storePassword "android"
keyAlias "androidotherkey"
keyPassword "android"
}
}
buildTypes {
bar {
debuggable true
jniDebugBuild true
signingConfig signingConfigs.debug
}
foo {
debuggable false
jniDebugBuild false
signingConfig signingConfigs.myConfig
}
}
}
If you want to understand a little more of the Gradle build system associated to Android Studio just pay a visit to:
Gradle Plugin User Guide
If anyone wants to debug and release separate build variant using Android Studio 3.5, follow the below steps:
1. Set build variant to release mode.
Go to File >> Project Structure
Select Modules, then Signing Config
Click in the Plus icon under Signing Config
Select release section and Provide your release App Information then Apply and OK.
Go to your app level build.gradle and change your buildTypes > "release" section like below Screenshot.
Then Run your Project. Happy Coding.
I was successfully able to debug signed APK , Follow this procedure:-
Choose "release" version in "Build Variant" ToolBar
In the Build.gradle for the module set debuggable true for release build type
Go to File->Project Structure->under signing tab fill all info->Under Flavours
tab->Choose signing Config You just created
Set the breakpoints
Run the application in the debug mode
For gradle Kotlin dsl
signingConfigs {
create("releaseConfig") {
storeFile = file("your keystore file path")
storePassword = "storePassword"
keyAlias = "keyAlias"
keyPassword = "keyPassword"
}
}
buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("releaseConfig")
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
signingConfigs should be before buildTypes
signingConfigs {
debug {
storeFile file("debug.keystore")
}
myConfig {
storeFile file("other.keystore")
storePassword "android"
keyAlias "androidotherkey"
keyPassword "android"
}
}
buildTypes {
bar {
debuggable true
jniDebugBuild true
signingConfig signingConfigs.debug
}
foo {
debuggable false
jniDebugBuild false
signingConfig signingConfigs.myConfig
}
}
if you want to run app in debug mode
1) Look at Left Side bottom, above Favorites there is Build Variants
2) Click on Build Variants. Click on release and choose debug
it works perfect !!!
The app project you downloaded may include a signed info in the file of build.gradle. If you saw codes like these:
buildTypes {
debug {
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
}
}
you could delete them and try again.
My problem was solved by changing the build variant as suggested by Stéphane , if anyone was struggling to find the "Build variants" as I did here is a screenshot where you can find it .
For security reasons, you cannot install an unsigned apk on Android. So if you only have the unsigned apk: you must sign it. Here is how to do that : link
Note that you can sign the apk with a self-signed certificate.
An alternative can be either :
to download the signed apk if available.
to download the sources, compile them (with Android-Studio or gradle or ...). It will produce multiple apks and one of them will be signed with your debug-key (and so you will be able to install it)
How i solved this
This error occurs because you have set your build variants to release mode. set it to build mode and run project again.
If you want to run in release mode, just generate a signed apk the way we do it normally when releasing the app
In tool window bar select Build Variants
Change Build Variant from Release to Debug
My solution was to change the name of my signing config from the default "config" to "debug". To verify, I changed it to some other random name and got the error again, and then changed it back to "debug" and the error was gone. So while it seems artificial and I tend to not believe this is the whole story, give this solution a try.
i also appear this problem,and my code below
storeFile file(properties.getProperty("filepath"))
storePassword properties.getProperty("keypassword")
keyAlias properties.getProperty("keyAlias")
keyPassword properties.getProperty("keypassword")
the reason is property name error,it should be keyPassword not keypassword
What finally worked for me, and I have no idea why, is:
Went to LastPass (the service I use to keep all my passwords)
Select my password by putting the cursor on top of the password and double clicking
Once selected I press cmd C to copy
Went to Android study and cmd V to paste
Notice I did try to copy many times by selecting the password by clicking at the end of the password and selecting the password by moving the mouse.
It is strange but it only worked by double clicking on top of the password to copy it.
Also I did use the Open Module Settings > Signing... method explained by #NightFury on this post.
adding below lines of code in build.gradel file worked for me, add them under buildTypes block below release as shown
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix ".debug"
debuggable true
}

Android Studio: how to generate signed APK using Gradle?

I've searched on Google and SO but cannot find my answer.
This is the first time I'm working with the Gradle system and I am now at the point of generating a signed APK to upload to Google Play (project is imported from eclipse).
Now, I've read the part here that you should add signingConfigs to your build.gradle.
I've added these lines and now I saw that you need to run ./gradlew assembleRelease but running this in my CMD returns
'gradle' is not recognized as an internal or external command,
operable program or batch file.
I've also tried to right click on the build.gradle and run it, saying it was sucessful but once I look in the build/apk folder only a file called app-debug-unaligned.apk.
So, how do I generate the signed APK using the Gradle system?
There are three ways to generate your build as per the buildType. (In your case, it's release but it can be named anything you want.)
Go to Gradle Task in right panel of Android Studio and search for assembleRelease or assemble(#your_defined_buildtype) under Module Tasks
Go to Build Variant in Left Panel and select the build from drop down
Go to project root directory in File Explore and open cmd/terminal and run:
Linux: ./gradlew assembleRelease or assemble(#your_defined_buildtype)
Windows: gradlew assembleRelease or assemble(#your_defined_buildtype)
If you want to do a release build (only), you can use Build > Generate Signed apk. For other build types, only the above three options are available.
You can find the generated APK in your module/build directory having the build type name in it.
It is possible to take any existing Android Studio gradle project and build/sign it from the command line without editing any files. This makes it very nice for storing your project in version control while keeping your keys and passwords separate:
./gradlew assembleRelease -Pandroid.injected.signing.store.file=$KEYFILE -Pandroid.injected.signing.store.password=$STORE_PASSWORD -Pandroid.injected.signing.key.alias=$KEY_ALIAS -Pandroid.injected.signing.key.password=$KEY_PASSWORD
You can use this code
android {
...
signingConfigs {
release {
storeFile file("../your_key_store_file.jks")
storePassword "some_password"
keyAlias "alias_name"
keyPassword "key_password"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
...
}
then from your terminal run
./gradlew assembleRelease
you will get the apk at
your-android-app/build/outputs/apk/your-android-app-release.apk
I think this can help you https://www.timroes.de/2013/09/22/handling-signing-configs-with-gradle/ then just select the Release from the Build Variants
If you live in certain countries, be sure to use a VPN.
step1: run this command in the command-line:
keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
it will ask you for some information such as password, name,... and enter them.
step2: create a file name key.properties in your android folder.
write these lines in the created file
storePassword=<password from previous step>
keyPassword=<password from previous step>
keyAlias=key
storeFile=<location of the key store file, such as ~/key.jks>
keep the key.properties file private, always keep a backup of the key.properties file and never publish publicly.
step3: Replace the following lines in app-level Gradle
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
step4:
keytool -list -v -keystore ~/key.jks -alias key -storepass <password> -keypass <password>
step5:
I recommend building APK, using android studio.
Build > Generate Signed Bundle/APK...
This is for Kotlin DSL (build.gradle.kts).
You could either define your properties in local.properties file in the project root directory or define them as environment variables (which is especially useful for CIs like GitHub Actions).
// See https://stackoverflow.com/q/60474010
fun getLocalProperty(key: String) = gradleLocalProperties(rootDir).getProperty(key)
fun String?.toFile() = file(this!!)
// Could also use System.getenv("VARIABLE_NAME") to get each variable individually
val environment: Map<String, String> = System.getenv()
android {
signingConfigs {
create("MyAppSigningConfig") {
keyAlias = getLocalProperty("signing.keyAlias") ?: environment["SIGNING_KEY_ALIAS"] ?: error("Error!")
storeFile = (getLocalProperty("signing.storeFile") ?: environment["SIGNING_STORE_FILE"] ?: error("Error!")).toFile()
keyPassword = getLocalProperty("signing.keyPassword") ?: environment["SIGNING_KEY_PASSWORD"] ?: error("Error!")
storePassword = getLocalProperty("signing.storePassword") ?: environment["SIGNING_STORE_PASSWORD"] ?: error("Error!")
enableV1Signing = true
enableV2Signing = true
}
}
buildTypes {
getByName("release") { // OR simply release { in newer versions of Android Gradle Plugin (AGP)
signingConfig = signingConfigs["MyAppSigningConfig"]
// ...
}
}
}
myProject/local.properties file:
signing.keyAlias=foo
signing.keyPassword=bar
# also called keystore
signing.storePassword=abcdefgh
signing.storeFile=C\:\\my-files\\my-keystore.jks
NOTE: Do NOT add your local.properties file to your version control system (like Git), as it exposes your secret information like passwords etc. to the public (if it's a public repository).
Generate your APK with either of the 3 ways that this answer mentioned.
build menu > generate signed apk

What is the equivalent of Eclipse "Custom debug Keystore" in Android studio?

As I am working with Google Maps API, I have been used to work with a custom debug key in Eclipse (that is in fact my production key)
This manipulation allowed me to use the same API key for Maps and most of Google Play Services (in app billing) in my debug and release build.
This was really convenient because there was no need to change the key in the manifest.
Unfortunately, with the migration to Android Studio, I am missing this feature.
Any idea where I can find this option back?
Thank a lot.
You define a keystore in your build.gradle file. See the Signing Configurations section here: https://developer.android.com/studio/build/index.html
In your case, you want to redefine the keystore for the debug variant:
android {
signingConfigs {
debug {
storeFile file("your.keystore")
}
}
}
However, you should really be using two different keystores for debug and release configurations.
On recent Android Studio 0.8.9 you will find this at a way better place:
File->Project Structure
Add a keystore at "Signing" Tab
Select it for your debug/release "Build types".
Make sure the alias name matchs with your keystore (keytool -list -v shows your alias name)
It creates the gradle stuff, syncrhonizes automatically on "Apply" and worked immediately like a charm.
Hi If you don't want to go for hard code all of this stuff , then go for below easy steps
->Your project
->Your Module
->Right click on your module
->go to open module settings
->Go to Signing section
->Specify all the attribute here and browse your Custom debug key in Store File
Then you will find below code which will be auto-create by android studio in build.gradle
signingConfigs {
debug {
storeFile file('custom_debug_keystore')
keyAlias 'androiddebugkey'
keyPassword 'android'
storePassword 'android'
}
}
Note:
1) Please do not use .keystore in the code manually you go for manual configuration
2) Please specify correct Alias and password
Here is a complete step-by-step that I took to move both of my keys out of the gradle.build file into a file that will not be included in any builds or repository commits.
1) Create a gradle.properties (if you don't already have one).
The location for this file depends on your OS:
/home/<username>/.gradle/ (Linux)
/Users/<username>/.gradle/ (Mac)
C:\Users\<username>\.gradle (Windows)
2) Add an entry pointing to yourprojectname.properties file.
(example for Windows)
yourprojectname.properties=c:\\Users\\<username>\\signing\\yourprojectname.properties
3) Create yourprojectname.properties file in the location you specified in Step 2 with the following information:
keystore=C:\\path\\to\\keystore\\yourapps.keystore
keystore.password=your_secret_password
4) Modify your gradle.build file to point to yourprojectname.properties file to use the variables.
if(project.hasProperty("yourprojectname.properties")
&& new File(project.property("yourprojectname.properties")).exists()) {
Properties props = new Properties()
props.load(new FileInputStream(file(project.property("yourprojectname.properties"))))
android {
signingConfigs {
release {
keyAlias 'release'
keyPassword props['keystore.password']
storeFile file(props['keystore'])
storePassword props['keystore.password']
}
debug {
keyAlias 'debug'
keyPassword props['keystore.password']
storeFile file(props['keystore'])
storePassword props['keystore.password']
}
}
compileSdkVersion 19
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "your.project.app"
minSdkVersion 16
targetSdkVersion 17
}
buildTypes {
release {
}
}
}
}
dependencies {
...
}
5) Enjoy! Now all of your keys will be outside of the root of the directory and yet you still have the joys of automation for each build.
If you get an error in your gradle.build file about the "props" variable it's because you are not executing the "android {}" block inside the very first if condition where the props variable gets assigned so just move the entire android{ ... } section into the condition in which the props variable is assigned then try again.
I pieced these steps together from the information found here and here.
You can specify the debug.keystore for your project independently.
Two steps with the following images: (Android Studio v0.5.2)
Step 1: Click the button of project structure.
Step 2: Add the debug.keystore as follows.
The keystore needs to be in build.gradle, example follows:
android{
signingConfigs {
release {
storeFile file('/path/platform.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
...
buildTypes {
release {
signingConfig signingConfigs.release
}
}
Eclipse didn't really ask for a password or alias, but gradle does. I believe Eclipse just assumed it was password:android and alias:androiddebugkey. This might not be true for your keystore but I would try it like that on gradle.
If you know the password, but you are not sure of the alias you can also run the following command to get the alias:
keytool -list -keystore /path/platform.keystore link
As pointed out, you can use the gradle file to specify it.
I also found very convenient to use the Home folder as part of the path. It makes it easier when working within a team. Here is my suggestion :
android {
signingConfigs {
debug {
storeFile file(System.properties['user.home']+"/.android/custom.debug.keystore")
}
}
}

Categories

Resources