Gradle Crittercism on-build mapping upload not working - android

I'm trying to upload to Crittercism on build, and I put this at the bottom of my gradle file. However, it doesn't seem to be working when I build debug. What am I doing wrong?
task uploadMappingToProd() << {
def critterAppId = "abcde"
def appVersionName = "1.0.1"
def appVersionCode = "DEBUG"
def critterKey = "12345"
commandLine 'curl',
"https://app.crittercism.com/api_beta/proguard/$critterAppId",
'-F', 'proguard=#build/outputs/mapping/production/release/mapping.txt',
'-F', "app_version=$appVersionName-$appVersionCode",
'-F', "key=$critterKey"
type Exec
dependsOn 'assembleDebug'
}

The way you've done it, the task that you have defined, uploadMappingToProd, will if invoked by some reason also invoke assembleDebug. Because you have asked uploadMappingToProd to depend on assembleDebug - not the reverse. Therefore assembleDebug will happily finish without getting anywhere close to uploadMappingToProd.
If you want the reverse dependency i.e. assembleDebug to depend on uploadMappingToProd then you need to add this line after defining your task.
afterEvaluate {
tasks.assembleDebug.dependsOn uploadMappingToProd
}
This will guarantee uploadMappingToProd is invoked everytime and before assembleDebug is invoked.

My solution is working fine.(local build and jenkins build)
for me, only working when build is from jenkins
make sure your APPID, APPKEY, and path(release_jenkins.... normally release)
build.gradle (app) (add at the end)
task uploadPro << {
logger.error("Uploading mapping.txt file to crittercism")
String temp = projectDir;
temp = temp.replace("\\", "/");
String[] cmd = ["curl", "-k", "https://app.crittercism.com/api_beta/proguard/AppIDSting",
"-F", "proguard=#" + temp + "/build/outputs/mapping/release_jenkins/mapping.txt",
"-F", "app_version=" + VERSION_NAME + '-' + VERSION_CODE,
"-F", "key=API_KEY"]
logger.error("CMD : " + cmd)
ProcessBuilder builder = new ProcessBuilder(cmd);
Process process = builder.start();
process.waitFor()
println process.err.text
println process.text
}
gradle.buildFinished {
//check your build type. I am not sure it's the best way to do it.
logger.error("JSC : 이름 ! - " + gradle.startParameter.taskNames);
if (gradle.startParameter.taskNames.contains("assembleRelease_jenkins")) {
logger.error("JSC : 올리기 시작 ! - " + gradle.startParameter.taskNames);
tasks.uploadPro.execute()
} else {
logger.error("JSC : PASS")
}
}
sample project -> https://github.com/SinsangMarket/CrittercismMappingTXT

Related

Could not get unknown property 'apkNames' in android gradle plugin 4.1.0

I am using this code in build.gradle:
android {
applicationVariants.all { variant ->
variant.packageApplicationProvider.configure { packageApplicationTask ->
doLast {
packageApplicationTask.apkNames.each { apkName ->
def apkDir = "./build/outputs/apk/${flavorName}/${buildType.name}"
def apkDestName = apkName.replace("app-", "stickerly-android-" + variant.versionName + "-").replace(".apk", "-" + getDate() + ".apk")
println "#####Rename ${variant.name} Apk File"
copy {
from("$apkDir/$apkName").into(apkDir).rename { String fileName -> apkDestName }
}
println "#####Copy mapping File"
def mappingDir = "./build/outputs/mapping/${flavorName}${buildType.name.capitalize()}"
copy {
from("$mappingDir/mapping.txt").into(mappingDir).rename {
"mapping-stickerly-${variant.versionName}.txt"
}
}
}
}
}
}
}
With this code I rename apk file and copy mapping file. I worked in android gradle plugin 4.0, but it does not work in 4.1 with this message
Where:
Script '/Users/snow/workspace/stickerly-android/app/build-android-extra.gradle' line: 5
What went wrong:
Execution failed for task ':app:packageExternalArm8Debug'.
Could not get unknown property 'apkNames' for task ':app:packageExternalArm8Debug' of type com.android.build.gradle.tasks.PackageApplication.
I think API has changed but I can not find any documents. Someone can help me?
Thanks.
property apkNames is removed in AGP 4.1
you can try this
gradle.taskGraph.afterTask { Task task, TaskState state ->
if (!state.failure
&& task.project.name == project.name
&& task.name.startsWith("package")
&& !task.name.endsWith("UnitTest")) {
def outputDir = task.outputDirectory.getAsFile().get()
task.variantOutputs.getOrNull()?.each { variant ->
println "" + outputDir + "/" + variant.outputFileName.get()
}
}
}
add this at the end of your build.gradle file.
change println to whatever logic you want.
by the way, if you want to check the properties you may use, just add gradle plugin as a dependency of your project, click Sync in Android Stuido, then you can find it in External Librarys (key map: Command + 1, and switch to project view).
like this
dependencies {
implementation 'com.android.tools.build:gradle:4.1.0'
}
and these properties and tasks are intentionally invisible in lib com.android.tools.build:gradle-api, modifications in future releases are expected.

common task for Uploading Build Artifacts, Multiple Apps

I have 5 different apps in my monorepo, the build.gradle for each of these apps contains a nearly indentical task, which along with an upload script is in charge of uploading files matching to our Jenkins file server.
we can call this task releaseBuilds()
This code is in a file called artifactUploads.gradle, this file also contains a custom plugin called UploadPlugin. Now my concern is with the System.out.println() line in the task.
apply plugin: UploadPlugin
task copyReleaseBuilds() {
doLast {
def dir = project.file('build/outputs/apk')
dir.eachFileRecurse(FILES) { file ->
if (file.getName().contains(".apk") && file.getName().contains("release")) {
System.out.println("uploading ${file.getName()}")
def rootDir = project.getRootDir().path
def filePath = file.path
def fileName = file.name.replace('app-', '')
exec {
workingDir rootDir
commandLine "./uploadBuild.sh", filePath, "$dirPath" + fileName
}.assertNormalExitValue()
}
}
}
}
class UploadPlugin implements Plugin<Project> {
void apply(Project project) {
//Create container instance for config object
//plugin stuff
NamedDomainObjectContainer<Config> configContainer =
project.container(Config)
project.extensions.add('directory', configContainer)
project.task('uploadConfig') << {
def uploadConfig = project.extensions.getByName('directory')
}
}
class Config{
String name
String dirPath
Config(final String name){
this.name = name
}
}
In the build.gradle file for each of my apps/projects. I have the line
apply from: "${rootDir}/artifactUploads.gradle
along with
directory{
name{
dirPath = "hca/"
println "stuff"
}
}
directory is some object that is created in my CustomPlugin.
Now when I build the line println "Stuff" is output to the gradle log, however I can not find any console outputs that are put in artifactUploads.gradle which contains my CustomPlugin and the task that all my apps share.
From what I understand, since each of my apps build.gradle has
apply from: artifactUploads.gradle, each app should now run the copyReleaseBuilds() task, with the custom parameter dirPath which is set in the DSL part of each app build.gradle.
Is there another reason the build would not be hitting that System.out.println()? I'm very new to gradle in general so thanks for your help

Copy file based on flavor at the start of Android gradle build

I have two flavors in the gradle file for an Android app:
productFlavors {
production { }
devel { }
}
I have a configuration file that I need to copy to the app/ directory before any other tasks run when building the project. The is a configuration file per flavor, i.e.:
etc/configuration-production.json
etc/configuration-devel.json
When building devel I need to do essentially this:
cp etc/configuration-devel.json app/configuration.json
When building production:
cp etc/configuration-production.json app/configuration.json
How do I automate this in gradle? This copy needs to happen first and foremost when executing a build since some of the tasks need that app/configuration.json file to be there.
I tried:
task copyConfig(type: Copy) {
from "etc/configuration-${Flavor.name}.json"
into "app/configuration.json"
}
build.dependsOn copyConfig
But didn't work. The copyConfig task didn't run.
You can add the following to your app build.gradle for copying your file from etc/configuration-XXX.json to app/configuration.json in the first statement of the respective tasks assembleDevel.* & assembleProduction.* :
def cp(copyType) {
println "copying " + "../etc/configuration-" + copyType + ".json"
copy {
from "../etc/configuration-" + copyType + ".json"
into '.'
rename { String fileName ->
fileName.replace("configuration-" + copyType + ".json", "configuration.json")
}
}
}
tasks.whenTaskAdded { task ->
if (task.name ==~ /assembleDevel.*/) {
task.doFirst() {
cp("devel")
}
} else if (task.name ==~ /assembleProduction.*/) {
task.doFirst() {
cp("production")
}
}
}
This is the required configuration :
app/
├── build.gradle
etc/
├── configuration-production.json
└── configuration-devel.json
If assembleDevel.*/assembleProduction.* are not the tasks you are looking for, you can replace them with for instance : prepareDevel.*Dependencies/prepareProduction.*Dependencies

How install and run Android app on device by gradle task?

Gradle 2.14
android {
dev {
}
}
task runAppDev(type: Exec, dependsOn: 'installDev') {
description "Install and run app (dev env)"
android.applicationVariants.all { variant ->
if ("installDev".toUpperCase().endsWith(variant.getName().toUpperCase())) {
commandLine getRunAppCommandLine(variant)
}
}
}
def getRunAppCommandLine(variant) {
List<String> commandLine = ["adb", "shell", "am", "start", "-n", variant.getApplicationId() + "/.activity.SplashActivity"]
return commandLine
}
Run my task by: gradlew runAppDev
Result:
Installing APK 'app-dev.apk' on 'Nexus 5 - 6.0.1' for app:dev
Installed on 1 device.
:app:runAppDev
BUILD SUCCESSFUL
So, my application success installed on device, but NOT run on device.
I found bug. I send incorrect adb arg. Here fix:
def getRunAppCommandLine(variant) {
List<String> commandLine = ["adb", "shell", "monkey", "-p", variant.getApplicationId() + " 1"]
return commandLine
}

Package name does not correspond to the file path - Gradle configuration

I'm trying migrating a normal Android Studio (IntelliJ) project to Gradle project recently. And currently I'm encounter a problem: IntelliJ gives me a warning on the beginning of every file says that my 'package name does not correspond to the file path'. e.g.
The first line of my some/prefixes/a/b/c/d/E.java is:
package a.b.c.d;
....
IntelliJ thinks the package name should be 'c.d' instead of 'a.b.c.d'. Because I set
SourceSets {
main.java.srcDirs = ["some/prefixes/a/b"]
}
in the module's build.gradle.
I know I could do the change below to make IntelliJ happy:
SourceSets {
main.java.srcDirs = ['some/prefixes']
}
But I can't do that because there're huge numbers of projects under 'some/prefixes' and I definitely don't want to introduce all of them into this module.
I used to add a packagePrefix="a.b" in my 'module.iml' in my original Android studio project and it works well:
https://www.jetbrains.com/idea/help/configuring-content-roots.html#d2814695e312
But I don't know how to accomplish similar fix after migrating to Gradle project.
I end up to write a task for gradle.
The task add the famous packagePrefix to the *.iml file.
This solution only work for intelliJ, I hope someone have a better solution.
task addPackagePrefix << {
println 'addPackagePrefix'
def imlFile = file(MODULE_NAME+".iml")
if (!imlFile.exists()) {
println 'no module find '
return
}
def parsedXml = (new XmlParser()).parse(imlFile)
if(parsedXml.component[1] && parsedXml.component[1].content){
parsedXml.component[1].content.findAll { Node node ->
node.sourceFolder.findAll { Node s ->
def url = s.attribute("url").toString()
if (url.endsWith(SRC_DIR)) {
println 'Node founded '
def attr = s.attribute('packagePrefix')
if (attr == null) {
// add prefix
println 'Adding package prefix'
s.attributes().put('packagePrefix', PACKAGE_NAME)
println s.toString()
// writing
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml)
imlFile.text = writer.toString()
}
}
}
}
}

Categories

Resources