How to run a unit test task before uploadArchives - android

I've got this config to upload artifact to local maven repository.
uploadArchives {
repositories {
mavenDeployer {
pom {
groupId = 'group'
artifactId = 'android'
version = android.defaultConfig.versionName
}
repository(url: 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath)
}
}
}
I want it to run all the unit tests before uploading the artifact. I'm tired of running the unit tests task manually every time, so I thought uploadArchives task should depend on testDebugUnitTest. The test tasks comes from Android library plugin.
uploadArchives {
dependsOn testDebugUnitTest
}
Unfortunately this configuration doesn't work. Is it possible to configure it the way I want?

I do this to automate my tests. The basic syntax here is <your task> dependsOn '<this task>' in order for your entire build process to finish successfully.
You want something like this:
uploadArchives.dependsOn 'testDebugUnitTest'

Related

How to GPG sign and publish an aar directly to Maven Central?

I'm working on properly setting up my Gradle scripts for publishing an .aar directly to Maven Central (with JFrog sunsetting Bintray, numerous resources about publishing to Bintray are no longer relevant). One of the prerequisites is to have all artifacts (aar, sources jar, java-doc jar, pom.xml) uploaded alongside corresponding GPG-signature files (e.g. sources.jar.asc).
Following these two guides (which are very much alike), I've largely managed to do so:
https://medium.com/#nmauti/sign-and-publish-on-maven-central-a-project-with-the-new-maven-publish-gradle-plugin-22a72a4bfd4b
https://www.albertgao.xyz/2018/01/18/how-to-publish-artifact-to-maven-central-via-gradle/
However, though well describing the solution using Gradle, both guides seem to focus on plain .jar's rather than .aar's. In particular, I wasn't sure about what to set up as a project archive in order to put on the automated sign+publish list, as suggested:
project.artifacts {
archives sourceJar // Ok, I have a sourceJar task - will be signed and uploaded
archives javadocJar // I use Dokka, but got that to work by registering my dokka task
archives jar // What's "jar"? this doesn't help much!... :-/
}
I even tried registering the output .aar file, explicitly:
publications {
android.libraryVariants.all { variant ->
if (shouldPublishVariant(variant)) {
// ...
// ...
variant.outputs.forEach { output ->
project.artifacts {
archives output.outputFile // The full path of the .aar to publish!
}
}
}
}
}
But that seemed to have resulted in this flaky error:
Execution failed for task ':detox:publishMavenFullReleaseAarPublicationToMavenRepository'.
> Failed to publish publication 'mavenFullReleaseAar' to repository 'maven'
> Invalid publication 'mavenFullReleaseAar': artifact file does not exist: '.../build/outputs/aar/library-full-release.aar.asc'
I'm looking for a stable, bullet-proof solution that would sort this out end-to-end, with no flaky errors.
As a solution, I've found that registering the task generating the .aar as a project archive -- rather than registering the file itself, does the trick (much like as done for the sources and javadoc jars):
publications {
android.libraryVariants.all { variant ->
if (shouldPublishVariant(variant)) {
// ...
// ...
variant.outputs.forEach { output ->
project.artifacts {
// For example: bundleProdReleaseAar is the task that generates library-prod-release.aar
archives project.tasks["bundle${variant.name.capitalize()}Aar"]
}
}
}
}
}

maven-publish plugin gradle only publish specific module

I'm developing a multi-module android project using gradle build.
I'm using maven-publish plugin to publish artifact to sonartype nexus.
The current setup is inside every module there is a publication job
plugins{
id(Plugins.kotlinAndroidApplication)
id(Plugins.kotlinAndroid)
id(Plugins.kotlinAndroidExtensions)
id(Plugins.mavenPublish)
id(Plugins.dokkaAndroid)
}
publishing {
repositories {
maven {
credentials {
username = project.properties["mavenUser"] as? String
password = project.properties["mavenPassword"] as? String
}
url = https://mynexus
}
}
publications {
create<MavenPublication>("mavenAar") {
groupId = rootProject.extra.get("groupId") as String
artifactId = rootProject.extra.get("artifactId") as String
version = (rootProject.extra.get("versionName") as String) + (if (project.hasProperty("release")) "" else "-SNAPSHOT")
from(components["android"])
//artifact(tasks["javadocJar"])
artifact(tasks["dokkaJar"])
}
}
}
When my Jenkin CI build the project with deploy = true, every module will be published. The problem is some module depend on other, so the dependency module will be published twice. Re-deploy module with same version is not allowed on release nexus maven repo.
Anyway to only publish certain module only or to ensure every module is only deploy once?

Having android gradle open windows cmd and run a command after build done?

I'm building an android module with this standard build script:
buildscript {// top-level
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
I've googled a lot to know how to have gradle to open windos cmd (I'm on win7) and run a command. I found tasks Exec and added, but it didn't work for me, perhaps I don't still understand groovy and gradle. Please make me clear how to do it.
Edit
By using a forum post mentioned in comments, I added this to android{..} section:
task testingit(type:Exec) {
println('try open cmd...............')
commandLine "cmd","/k",'node', '-v'
}
I get the string output but cmd does not open and no error message.
If you want to execute this task at the end of build, you can use build.finalizedBy.
task endBuildTask(type: Exec) {
commandLine 'cmd','/c','start', 'cmd.exe' ,'#cmd' , '/k', 'echo', 'Hello'
}
build.finalizedBy(endBuildTask)
// or gradle.buildFinished{endBuildTask.execute()}
This will create a new command line at the end of build, pass the command after #cmd to the newly created command line. If you want this new command line to close after command executes, use '/c' instead of '/k'.
I just post back how I put the accepted answer from above in my application, in case useful for anyone (because build.finalizedBy(endBuildTask) didn't work and I can't understand why, but gradle.buildFinished(...) did the job)
This is how I got it working:
task endBuildTask(type: Exec) {
workingDir 'C:\\tmp\\1\\'
commandLine 'cmd','/c','node', '%FILE_JS%'
}
gradle.buildFinished{
endBuildTask.execute()
}
I had a nodejs app that I wanted to execute after android build is over.

How to copy debug assets for unit tests

I have an android library gradle project. And I need to copy some files to assets folder for robolectric unit tests.
To do it I've defined a copy task:
task copyDebugAssets(type: Copy) {
from "${projectDir}/somewhere"
into "${buildDir}/intermediates/bundles/debug/assets"
}
but I can't add this task as a dependency for processDebugResources task:
processDebugResources.dependsOn copyDebugAssets
because of this error:
Could not get unknown property 'processDebugResources' for object of type com.android.build.gradle.LibraryExtension.
Now I have to manually execute this task before unit test:
./gradlew clean copyDebugAssets test
How can I solve it?
The android plugin adds several tasks dynamically. Your .dependsOn line doesn't work because at the time gradle is trying to process this line, processDebugResources task yet available. You should tell gradle to add the dependency as soon as the upstream task is available:
tasks.whenTaskAdded { task ->
if (task.name == 'processDebugResources') {
task.dependsOn copyDebugAssets
}
}
Why copy? Configure where the assets should be pulled from:
android {
// other cool stuff here
sourceSets {
androidTest {
assets.srcDirs = ['../testAssets']
}
}
}
(replacing ../testAssets with a path to where the assets should come from)
I have used this successfully with androidTest for instrumentation testing. AFAIK, it should work for test or any other source set.

gradle snapshot not resolved in local repository when uniqueVersion=false

For my Android Library I'm using the "UploadArchives" task to deploy the AAR :
uploadArchives {
repositories.mavenDeployer {
configuration = configurations.deployLibrary
pom.groupId = groupId
pom.artifactId = artifactId
pom.version = version
uniqueVersion = false
repository(url: "${RemoteReleaseDest}")
snapshotRepository(url: 'file://' + "${localReleaseDest}") { }
}
}
Where "RemoteReleaseDest" is a remote Repository and "localReleaseDest" point to my Local maven repository (C:/User/me/.m2.repository).
this work pretty well for release version ex: myaar:2.0.0 ( I can as well set the "RemoteReleaseDest" to my local .m2 repository to force to deploy the release on it.
Then when I configure the dependency in my android project like this :
compile 'mygroupId:myartefact:2.0.0'
the dependency is correctly resolved (even from my local repository).
but if I try with snaptshot :
compile 'mygroupId:myartefact:2.0.0-SNAPSHOT'
gradle cannot resolve the dependency. while in the gradle log I can see that it is seaching in my .m2 local repository.
But if I Upload the snapshot archives with the parameter :
uniqueVersion = true
the gradle can resolve the dependency !
The problem in this case is that every time I launch the task "uploadArchives" I will create new AAR, xml, md5 etc... files under the local SNAPSHOT directory.
So why gradle cannot resolve the snapshot dependency when the snapshot is deployed with the param uniqueVersion = falseand how can I manage this issue ?

Categories

Resources