I have an Android project using two firebase instances per build variant (e.g. staging -> Firebase Project 1 and release -> Firebase Project 2). I'd like to be able to upload the mapping.txt whenever I invoke assemble so the crashes would be deobfuscated. Is there a way to dynamically set FirebaseServiceAccountFilePath property for each build variant? Thanks
Currently, you will have to invoke two different builds on the command line with the two different paths for your service account. So, something like this, if you have variants foo and bar:
./gradlew -PFirebaseServiceAccountFilePath=/path/to/foo.json firebaseUploadFooReleaseProguardMapping
./gradlew -PFirebaseServiceAccountFilePath=/path/to/bar.json firebaseUploadBarReleaseProguardMapping
There isn't currently a way to specify a different service account for both builds in a single invocation. However, if both variants use the same mapping, you can upload them both in the same invocation.
I faced this problem too today. After spending some time on this I simply wrote .sh file copied both the ./gradlew statements.
It is simply running both the statements one by one and I am able build apk and upload mapping file programmatically for both the firebase projects in single invocation.
Related
I have been trying to make devops build of android apk and my pipeline fails in Signing and aligning Apk Stage.
I am getting the following error
##[error]Error: No matching files were found with search pattern: D:\a\1\s***.apk
PIPELINE Definition Snapshot_2
[error]Error: No matching files were found with search pattern: D:\a\1\s***.apk
This error indicates that you don't have a xx.apk file generated in default working directory. You can follow steps below to locate the root cause of the issue and resolve that:
Leave gradlew build task's working directory blank and make sure this task succeeds to generate the xx.apk file.
In Android signing task, use the **\*.apk pattern.
Make sure the gradlew build and Signing and aligning APK tasks are in same Job. If you're using hosted agent to run those tasks, they must be in same job within same pipeline/stage so that the Signing and aligning APK task can directly access the outputs of gradlew build task.
Please make sure these two tasks are in same job. If you have specific reason that you have to make them in separate jobs/stages/pipelines, consider using Artifacts-related tasks to share the files between jobs/stages/pipelines.
Since a job is a series of steps that run sequentially as a unit, different jobs will run in different machines though those agents are called hosted windows/linux. So it's recommended to put the two tasks in same job.
If the tasks are in same job while the issue persists, set the system.debug variable to true and run the pipeline again, then you can check the details about the gradlew build task.
Then you can find the output path where the xx.apk files are generated. After that copy those files to Default working directory ($(System.DefaultWorkingDirectory)) and the signing task can find the file.
It looks like .apk file is not found under working directory of the build agent. Please check code checkout step of the build pipeline and make sure the .apk file is being checked out as part of the build step. You can view the log as well to confirm this.
When i use ViewBinding, it always generate xxxxxBinding.
I know android use Android Gradle Plugin build apk with code and resources。
And they're going to split some task (or transform).
I know task(transform) will build some file into ./build .
But the ViewBinding makes me confused,He doesn't appear to be generating files(Because every time I create layout file, I can access it directly)(Or I can just delete the build folder and it won't be created again,But he can still get it right(No error) in the code)。
Were some files secretly generated?
If so, where will it be generated?
If not, how can I do the same? For example, use a markdown file to generate code in real time.
Is there a way in Jenkins to not only read but also write global parameters from a job?
To achieve reading I used this plugin: Global Variable String Parameter
However, I have found nothing yet to support write access to global parameters. I see that this could be seen critical as it can create race conditions.
What I actually want to do:
I have two Jenkins Jobs - each publishing my Android APK to the Google Play Store but into different release tracks (e.g. "release" and "beta").
I want the build number to be incremented automatically via gradle. But gradle needs to access the build number of the last build from anywhere outside of my VCS (to avoid requiring another commit). I want to guarantee that the build numbers are chronologically in order. Hence, keeping a separate build number for every Jenkins Job (e.g. in a "version.properties" file) is not a solution.
A plan B could be to switch to a date encoded build number. But I'm curious if there is a way for the incremental approach.
you can use "version.properties" file located in the jenkins workspace and not the job workspace.
1- inject environment variable from the file
2- build the apk
3- increment the version from the shell script
version=$(($version+1))
echo version=$version > ${JENKINS_HOME}/workspace/module.properties
I'm trying to customize the behavior of my Gradle build to be Android-Wear friendly.
I am bundling manually my wear apk in my handled apk (because i didnt managed to do it automagically).
This means that if I want to build a new version of the handled apk, i have to manually build my wear apk, copy/past the generated wear-apk insinde my res/raw of the handled project then build the new handled apk.
I want all this to be automatized.
So, what I need to do is :
Launch app:assembleRelease from cmd line
Gradle first do a wear:assembleRelease
At the end, Gradle take the apk from wear/output/apk/wear-apk.apk and copy it in app/src/main/res/raw
Then Gradle can procede to do app:assembleRelease
I dont find how to launch a task (wear:assembleRelease) from another task.
Any help is welcome !
I found a solution that may not be optimal but it is working for what I need.
In my handled app, i first have to say that the assembleRelease depends on my wear:assembleRelease:
app/build.gradle
project.afterEvaluate {
preReleaseBuild.dependsOn(':wear:assembleRelease')
}
preReleaseBuildis one of the very first task of the build but this task is created dynamically, that's why you have to wrap it after the project is evaluated.
Then, in my wear build.gradle, I have to specify the copy at the end of the build:
wear/build.gradle
assembleRelease << {
println "Copying the Wear APK"
copy {
from 'build/outputs/apk'
into '../app/src/main/assets'
include '**/wear-release.apk'
}
}
With only theses modifications, i managed to have the workflow explained in the question.
This could be enhanced because it is only working for the release build but it's a good first step.
Feel free to comment this solution.
I have several options - both in code and in the manifest file - that I would like to easily toggle on and off based on whether it's a debug build or release build.
What's the best way to handle things like this in an Android application?
You could use properties files, e.g. one for prod and one for dev. Then you could create an Ant script with two targets, a prod build and a dev build, where the appropriate properties file is copied prior to the APK being built. Make sure that the properties files are copied using the same name, then you can access the deployed one, irrespective of the environment you built for.
In addition to what Tyler mentioned, if you are looking at including optional code in case it is a Debug and not having that code if its a release, then you could look at using the BuildConfig file that is generated by the ADT.
As per the docs: " Added a feature that allows you to run some code only in debug mode. Builds now generate a class called BuildConfig containing a DEBUG constant that is automatically set according to your build type. You can check the (BuildConfig.DEBUG) constant in your code to run debug-only functions such as outputting debug logs."
You will find this file in the Project/gen folder, the same place where the R.java is generated.
Now with Android Studio and Gradle it is easy to do this using the auto generated flag BuildConfig.DEBUG. Like:
if (BuildConfig.DEBUG) {
// Debug code
} else {
// Resease code
}