Android publishing flavour based artifact on Artifactory - android

I am trying publish flavour based artifact on my Artifactory server. Gradle code looks like this
def GroupId = 'com.example.directory'
def ArtifactId = 'demo
def Version = '0.0.1-IB1''
productFlavors {
extended {
ArtifactId = "extended"
}
mini {
ArtifactId = "mini"
}
}
publishing {
publications {
aar(MavenPublication) {
android.libraryVariants.all { variant ->
groupId GroupId
version Version
artifactId ArtifactId
def filename = "${archivesBaseName}-${variant.baseName}.aar"
artifact("$buildDir/outputs/aar/${filename}")
}
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
def deps = configurations.implementation.allDependencies + configurations.api.allDependencies
deps.each {
if (it.group != null && (it.name != null || "unspecified" == it.name) && it.version != null && "unspecified" != it.version) {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
}
}
artifactory {
contextUrl = 'http://artifactoryUrl/artifactory'
publish {
repository {
repoKey = GroupId
username = "${userName}"
password = "${pass}"
}
defaults {
publications('aar')
publishArtifacts = true
properties = ['qa.level': 'basic', 'dev.team': 'core']
publishPom = true
}
}
}
But when I run gradle command it generates the specific flavour + build type artifact. But while publishing it tries to publish all varient of the library and throws an error for other aar file names.
./gradlew clean && ./gradlew :demo:assembleextendedrelease && ./gradlew :demo:artifactoryPublish

Related

Maven api pulish with Gradle 7.2

I want to publish an Android in jitpack.io but api dependencies are missing, that's why I use with Gradle 7.2 this
project.afterEvaluate {
publishing {
publications {
release(MavenPublication) {
from components.release
pom {
configurations.api.getDependencies().each { dep -> addDependency(dep, "compile") }
configurations.implementation.getDependencies().each { dep -> addDependency(dep, "runtime") }
}
}
}
}
}
This works with Gradle 6.x but with Gradle 7.x it fails
configurations.api.getDependencies().each { dep -> addDependency(dep, "compile") }
with
Could not find method addDependency() for arguments [DefaultProjectDependency{dependencyProject='project ':libs:gvr'', configuration='default'}] on object of type org.gradle.api.publish.maven.internal.publication.DefaultMavenPom.
Does someone knows how to solve it ?
Use this snippet
release(MavenPublication) {
// Applies the component for the release build variant.
from components.release
artifact(sourcesJar)
// You can then customize attributes of the publication as shown below.
groupId = '[group]'
artifactId = '[artifact]'
version = '[version]'
pom.withXml {
def dependenciesNode = (asNode().get("dependencies") as groovy.util.NodeList).get(0) as groovy.util.Node
def configurationNames = ["implementation", "api"]
configurationNames.forEach { configurationName ->
configurations[configurationName].allDependencies.forEach {
if (it.group != null && it.version != "unspecified") {
def dependencyNode = dependenciesNode.appendNode("dependency")
dependencyNode.appendNode("groupId", it.group)
dependencyNode.appendNode("artifactId", it.name)
dependencyNode.appendNode("version", it.version)
}
}
}
}
}
}
}

Could not apply withXml() to generated POM > Could not get unknown property 'implementation'

I am trying to publish an Android library to bintray. I have set it up in both bintray and my Android project.
publish.gradle:
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'
version '1.0'
group 'np.com.ngimasherpa'
publishing {
publications {
Production(MavenPublication) {
artifact("$buildDir/outputs/aar/emptyviewsupportrecyclerview-release.aar")
groupId this.group
artifactId 'emptyviewsupportrecyclerview'
version this.version
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.implementation.allDependencies.each {
if (it.name != 'unspecified') {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
}
}
bintray {
user = project.hasProperty('user') ?: System.getenv('BINTRAY_USER')
key = project.hasProperty('apiKey') ?: System.getenv('BINTRAY_API_KEY')
publications = ['Production']
configurations = ['archives']
dryRun = false
override = false
publish = true
pkg {
repo = 'EmptySupportRecyclerView'
name = 'np.com.ngimasherpa.emptyviewsupportrecyclerview'
version {
name = this.version
released = new Date()
vcsTag = this.version
}
}
}
When I'm trying to upload the library using ./gradlew bintrayUpload, I get:
Execution failed for task ':generatePomFileForProductionPublication'.
- Could not apply withXml() to generated POM
- Could not get unknown property 'implementation' for configuration container of type
org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.

Why Unknown property 'bundleRelease' error occurs on gradle:3.2.1? [duplicate]

When i sync project, android studio warn could not get unknown property 'bundleRelease' for object of type org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication.
I add project.afterEvaluate{//block},but it doesn't work. What should i do to set the artifact
Android Gradle Plugin 3.3.x (at least -alpha releases at the time of writing this answer) has breaking change, task bundleRelease was renamed to bundleReleaseAar
So the solution is to use: bundleReleaseAar instead of bundleRelease.
Note: "release" in the task name is buildType/flavor combination, thus it might be different in your setup.
Generic answer: bundleRelease is a task, to find its new name you can run ./gradlew tasks --all
So the answer from Artem Zunnatullin is correct. Just one addition, the project.afterEvaluate{//block} is necessary to make it work. This information can be overlooked very easily.
Complete example:
project.afterEvaluate {
publishing {
publications {
mavenDebugAAR(MavenPublication) {
artifact bundleDebugAar
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.api.allDependencies.each { ModuleDependency dp ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dp.group)
dependencyNode.appendNode('artifactId', dp.name)
dependencyNode.appendNode('version', dp.version)
if (dp.excludeRules.size() > 0) {
def exclusions = dependencyNode.appendNode('exclusions')
dp.excludeRules.each { ExcludeRule ex ->
def exclusion = exclusions.appendNode('exclusion')
exclusion.appendNode('groupId', ex.group)
exclusion.appendNode('artifactId', ex.module)
}
}
}
}
}
mavenReleaseAAR(MavenPublication) {
artifact bundleReleaseAar
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.api.allDependencies.each { ModuleDependency dp ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dp.group)
dependencyNode.appendNode('artifactId', dp.name)
dependencyNode.appendNode('version', dp.version)
if (dp.excludeRules.size() > 0) {
def exclusions = dependencyNode.appendNode('exclusions')
dp.excludeRules.each { ExcludeRule ex ->
def exclusion = exclusions.appendNode('exclusion')
exclusion.appendNode('groupId', ex.group)
exclusion.appendNode('artifactId', ex.module)
}
}
}
}
}
}
repositories {
maven {
name 'nexusSnapshot'
credentials {
username '<User with deployment rights>'
password '<User password>'
}
url '<URL to nexus>'
}
maven {
name 'nexusRelease'
credentials {
username '<User with deployment rights>'
password '<User password>'
}
url '<URL to nexus>'
}
}
}
}

Kotlin Android Library Module exported with gradle maven-publish plugin not adding dependencies

I'm trying to export an Android Library Module developed in Kotlin using gradle's maven-publish plugin. aar file is successfully generated and exported however no dependency is added to it - at all, not even Kotlin ones. Below is the plugin configuration based on this answer:
apply plugin: 'maven-publish'
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
ext {
releaseRepository = "s3://****/maven/releases"
snapshotsRepository = "s3://****/maven/snapshots"
artifactRepository = "$buildDir/outputs/aar/render-engine-release.aar"
_version = properties.getProperty('lib.version')
_artifact = properties.getProperty('lib.name')
_group = properties.getProperty('lib.group')
}
task sourceJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier "source"
}
publishing {
publications {
maven(MavenPublication) {
groupId _group
artifactId _artifact
version _version
artifact (sourceJar)
artifact artifactRepository
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each {
if(_group != null && (_artifact != null || "unspecified" == _artifact) && _version != null) {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', _group)
dependencyNode.appendNode('artifactId', _artifact)
dependencyNode.appendNode('version', _version)
}
}
}
}
}
repositories {
maven {
if(_version.endsWith('-SNAPSHOT')) {
url snapshotsRepository
} else {
url releaseRepository
}
credentials(AwsCredentials) {
accessKey AWS_ACCESS_KEY
secretKey AWS_SECRET_KEY
}
}
}
}
Ok, so keeping reading the answers on the linked question I've implemented this that solved my problem. My final publish.gradle is like:
apply plugin: 'maven-publish'
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
ext {
releaseRepository = "s3://****/maven/releases"
snapshotsRepository = "s3://****/maven/snapshots"
artifactRepository = "$buildDir/outputs/aar/render-engine-release.aar"
_version = properties.getProperty('lib.version')
_artifact = properties.getProperty('lib.name')
_group = properties.getProperty('lib.group')
}
task sourceJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier "source"
}
publishing {
publications {
maven(MavenPublication) {
groupId _group
artifactId _artifact
version _version
artifact(sourceJar)
artifact artifactRepository
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.getAllDependencies().each { Dependency dep ->
if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified")
return
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dep.group)
dependencyNode.appendNode('artifactId', dep.name)
dependencyNode.appendNode('version', dep.version)
if (!dep.transitive) {
def exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
exclusionNode.appendNode('groupId', '*')
exclusionNode.appendNode('artifactId', '*')
} else if (!dep.properties.excludeRules.empty) {
def exclusionsNode = dependencyNode.appendNode('exclusions')
dep.properties.excludeRules.each { ExcludeRule rule ->
def exclusionNode = exclusionsNode.appendNode('exclusion')
exclusionNode.appendNode('groupId', rule.group ?: '*')
exclusionNode.appendNode('artifactId', rule.module ?: '*')
}
}
}
}
}
}
repositories {
maven {
if (_version.endsWith('-SNAPSHOT')) {
url snapshotsRepository
} else {
url releaseRepository
}
credentials(AwsCredentials) {
accessKey AWS_ACCESS_KEY
secretKey AWS_SECRET_KEY
}
}
}
}

How to use artifactoryPublish to publish release and debug artifacts

I have Android Studio projects that build AARs or APKs in both release and debug versions. I'd like to publish these to different to different repositories on my Artifactory server. The JFrog examples don't appear to cover this case.
Does this mean that it's considered best practice to simply build either only the release or only the debug version, and choose what and where to upload based on the type of build?
I configured my android library build.gradle file that compiled aar file could be uploaded in different repos, dependent on build type.
For example you want to publish debug artifats to 'libs-debug-local' repository and release artifacts to 'libs-release-local' repository.
//First you should configure all artifacts you want to publish
publishing {
publications {
//Iterate all build types to make specific
//artifact for every build type
android.buildTypes.all { variant ->
//it will create different
//publications ('debugAar' and 'releaseAar')
"${variant.name}Aar"(MavenPublication) {
def manifestParser = new com.android.builder.core.DefaultManifestParser()
//Set values from Android manifest file
groupId manifestParser.getPackage(android.sourceSets.main.manifest.srcFile)
version = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
artifactId project.getName()
// Tell maven to prepare the generated "*.aar" file for publishing
artifact("$buildDir/outputs/aar/${project.getName()}-${variant.name}.aar")
}
}
}
}
//After configuring publications you should
//create tasks to set correct repo key
android.buildTypes.all { variant ->
//same publication name as we created above
def publicationName = "${variant.name}Aar"
//new task name
def taskName = "${variant.name}Publication"
//in execution time setting publications and repo key, dependent on build type
tasks."$taskName" << {
artifactoryPublish {
doFirst {
publications(publicationName)
clientConfig.publisher.repoKey = "libs-${variant.name}-local"
}
}
}
//make tasks assembleDebug and assembleRelease dependent on our new tasks
//it helps to set corrent values for every task
tasks."assemble${variant.name.capitalize()}".dependsOn(tasks."$taskName")
}
//Inside artifactory block just set url and credential, without setting repo key and publications
artifactory {
contextUrl = 'http://artifactory.cooperok.com:8081/artifactory'
publish {
repository {
username = "username"
password = "password"
}
defaults {
publishArtifacts = true
// Properties to be attached to the published artifacts.
properties = ['qa.level': 'basic', 'dev.team': 'core']
}
}
}
That's all. Now if you run command
Win : gradlew assembleRelease artifactoryPublish
Mac : ./gradlew assembleRelease artifactoryPublish
aar file will be uploaded to 'libs-release-local' repository.
And if you ran
Win : gradlew assembleDebug artifactoryPublish
Mac : ./gradlew assembleDebug artifactoryPublish
it will be uploaded to 'libs-debug-local' repository
One minus of this configuration is that you should always run artifactoryPublish task with assembleDebug/Release tasks
try this:-
def runTasks = gradle.startParameter.taskNames
artifactory {
contextUrl = "${artifactory_contextUrl}"
publish {
repository {
if ('assembleRelease' in runTasks)
repoKey = "${artifactory_repository_release}"
else if ('assembleDebug' in runTasks)
repoKey = "${artifactory_repository_debug}"
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
defaults {
publishArtifacts = true
if ('assembleRelease' in runTasks)
publications("${artifactory_publication_release}")
else if ('assembleDebug' in runTasks)
publications("${artifactory_publication_debug}")
publishPom = true
publishIvy = false
}
}
}
where artifactory_repository_release=libs-release-local and artifactory_repository_debug=libs-debug-local
artifactory repo on which you want to publish your library arr.
After a gradle update to 'com.android.tools.build:gradle:3.x.x'
this no longer works for me.
My final solution was:
artifactory {
contextUrl = ARTIFACTORY_URL
//The base Artifactory URL if not overridden by the publisher/resolver
publish {
repository {
File debugFile = new File("$buildDir/outputs/aar/${SDK_NAME}-debug.aar");
if ( debugFile.isFile() )
repoKey = 'libs-snapshot-local'
else
repoKey = 'libs-release-local'
username = ARTIFACTORY_USER
password = ARTIFACTORY_PWD
maven = true
}
defaults {
File debugFile = new File("$buildDir/outputs/aar/${SDK_NAME}-debug.aar");
if ( debugFile.isFile() )
publications("debugAar")
else
publications("releaseAar")
publishArtifacts = true
// Properties to be attached to the published artifacts.
properties = ['qa.level': 'basic', 'dev.team': 'core']
// Is this even necessary since it's TRUE by default?
// Publish generated POM files to Artifactory (true by default)
publishPom = true
}
}
}
publishing {
publications {
//Iterate all build types to make specific
//artifact for every build type
android.buildTypes.all {variant ->
//it will create different
//publications ('debugAar' and 'releaseAar')
"${variant.name}Aar"(MavenPublication) {
writeNewPom(variant.name)
groupId GROUP_NAME
artifactId SDK_NAME
version variant.name.endsWith('debug') ? VERSION_NAME + "-SNAPSHOT" : VERSION_NAME
// Tell maven to prepare the generated "*.aar" file for publishing
artifact("$buildDir/outputs/aar/${SDK_NAME}-${variant.name}.aar")
}
}
}
}
def writeNewPom(def variant) {
pom {
project {
groupId GROUP_NAME
artifactId SDK_NAME
version variant.endsWith('debug') ? VERSION_NAME + "-SNAPSHOT" : VERSION_NAME
packaging 'aar'
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
distribution 'repo'
}
}
}
}.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.api.allDependencies.each {dependency ->
if (dependency.group != null) {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}.writeTo("$buildDir/publications/${variant}Aar/pom-default.xml")
}
You do not need to do complex Groovy code to achieve this. I have this for the project build.gradle:
artifactory {
contextUrl = 'https://artifactory.test.com/artifactory'
publish {
repository {
repoKey = 'gradle-testing-local'
username = artifactory_username
password = artifactory_password
}
defaults {
publications('debugAar')
publications('releaseAar')
publishArtifacts = true
properties = ['qa.level': 'basic', 'q.os': 'android', 'dev.team': 'core']
publishPom = true
}
}
}
This is my module build.gradle:
publishing {
publications {
android.buildTypes.all { variant ->
"${variant.name}Aar"(MavenPublication) {
groupId libraryGroupId
version libraryVersion
artifactId "library-${variant.name}"
artifact("$buildDir/outputs/aar/library-${variant.name}.aar")
}
}
}
}
A key to note here, whatever you put in the project build.gradle's artifactory.publish.defaults, under publications() has to match the module build.gradle's loop: "${variant.name}Aar"(MavenPublication).
Another thing is you also set the artifactory_username and artifactory_password
(encrypted version from Artifactory) in ~/.gradle/gradle/gradle.properties.
For snapshots + release versions, you can use sonatype (aka mavencentral). I did up a short guide couple of weeks back which you might find of some use. How to publish Android AARs - snapshots/release to Mavencentral
Can't get publishing work with #cooperok answer otherwise it help me alots.
Here is my code:
apply plugin: 'com.android.library'
apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
versionCode 1
versionName "0.0.1"
}
publishNonDefault true
buildTypes {
debug {
minifyEnabled false
debuggable true
}
release {
minifyEnabled false
debuggable false
}
snapshot {
minifyEnabled false
debuggable false
}
}
}
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
artifacts {
archives androidSourcesJar
archives androidJavadocsJar
}
publishing {
publications {
android.buildTypes.all { variant ->
"${variant.name}"(MavenPublication) {
def manifestParser = new com.android.builder.core.DefaultManifestParser()
groupId manifestParser.getPackage(android.sourceSets.main.manifest.srcFile)
if("${variant.name}".equalsIgnoreCase("release")){
version = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
}else if ("${variant.name}".equalsIgnoreCase("debug")){
version = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile).concat("-${variant.name}".toUpperCase().concat("-SNAPSHOT"))
}else{
version = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile).concat("-${variant.name}".toUpperCase())
}
artifactId project.getName()
artifact("$buildDir/outputs/aar/${project.getName()}-${variant.name}.aar")
artifact androidJavadocsJar
pom.withXml {
def dependencies = asNode().appendNode('dependencies')
configurations.getByName("_releaseCompile").getResolvedConfiguration().getFirstLevelModuleDependencies().each {
def dependency = dependencies.appendNode('dependency')
dependency.appendNode('groupId', it.moduleGroup)
dependency.appendNode('artifactId', it.moduleName)
dependency.appendNode('version', it.moduleVersion)
}
}
}
}
}
}
android.buildTypes.all { variant ->
model {
tasks."generatePomFileFor${variant.name.capitalize()}Publication" {
destination = file("$buildDir/publications/${variant.name}/generated-pom.xml")
}
}
def publicationName = "${variant.name}"
def taskName = "${variant.name}Publication"
task "$taskName"() << {
artifactoryPublish {
doFirst {
tasks."generatePomFileFor${variant.name.capitalize()}Publication".execute()
publications(publicationName)
clientConfig.publisher.repoKey = "${variant.name}".equalsIgnoreCase("release") ? "libs-release-local" :
"libs-snapshot-local"
}
}
}
tasks."assemble${variant.name.capitalize()}".dependsOn(tasks."$taskName")
}
artifactory {
contextUrl = 'http://172.16.32.220:8081/artifactory'
publish {
repository {
username = "admin"
password = "password"
}
defaults {
publishPom = true
publishArtifacts = true
properties = ['qa.level': 'basic', 'dev.team': 'core']
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}
artifactory {
contextUrl = "${artifactory_contextUrl}"
publish {
repository {
repoKey = 'your repo key'
username = "${artifactory_user}"
password = "${artifactory_password}"
mavenCompatible = true
}
defaults {
publications('mavenJava')
publishBuildInfo = true
publishArtifacts = true
publishPom = true
}
}
resolve {
repository {
repoKey = 'yourrepokey'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId = "$group"
artifactId = "$rootProject.name"
version = "${ver}"
from components.java
artifact jar
artifact javadocJar
artifact sourcesJar
}
}
}

Categories

Resources