Android - multiple AAR variant Nexus upload - android

I have a project with a structure like below. It has a 'main-module' that is the focus of our development, which should be able to publish AARs for two variants (debug, release) to Nexus. We also have a bunch of other dependency modules and a test app.
project
|
|- app
|- main-module
|- module-a
|- module-b
...
I'm looking to run a build that will package the main-module AARs an then upload both of these to Nexus repos. The debug AAR will go to a snapshots repo, and the release version will go to a release repo. I have some puzzle pieces but I'm not quite sure how to tie it together.
What I have:
Build AARs
gradlew assemble
Publish an AAR
project.uploadArchives {
repositories {
mavenDeployer {
repository(url: "http://localhost:8081/nexus/content/repositories/snapshots/") {
authentication(userName: "deployment", password: "password123")
}
pom.version = "0.0.1-SNAPSHOT"
pom.artifactId = "MainModule"
pom.groupId = "com.myorg.test"
}
}
The build works and I can push a version to Nexus. I don't know how to provide config for the debug and release versions so they have the correct repository (e.g. /snapshots vs /release) and the correct version (release version name won't contain SNAPSHOT).
Once working I'll move the names, versions and credentials out to properties, with the credentials not checked in to source control before someone points that out.
Using:
gradle-wrapper 4.4
gradle plugin 3.1.4

So after several days of digging around I found the solution. This is pretty rough, I haven't optimised it yet, but the solution works. Note it assumes your aar files contain the text 'debug' and 'release' in the name, if they don't then you can adjust to your project. I wouldn't know how this applies to modules that have more than just the debug and release variants, or if product flavours are involved.
android-maven-gradle-plugin
Integrate the android-maven-gradle-plugin. Steps are in the documentation link.
Module build.gradle
apply plugin: 'com.github.dcendents.android-maven'
afterEvaluate {
uploadArchives {
repositories {
mavenDeployer {
addFilter('debug') { artifact, file ->
artifact.name.contains("debug")
}
addFilter('release') { artifact, file ->
artifact.name.contains("release")
}
pom('debug').groupId = 'com.yourgroup'
pom('release').groupId = 'com.yourgroup'
pom('debug').artifactId = "MyArtifact"
pom('release').artifactId = "MyArtifact"
pom('debug').version = android.defaultConfig.versionName + "-SNAPSHOT"
pom('release').version = android.defaultConfig.versionName
pom.packaging = 'aar'
repository(url: "http://localhost:8081/nexus/content/repositories/releases/") {
authentication(userName: 'user'), password: 'pwd')
}
snapshotRepository(url: "http://localhost:8081/nexus/content/repositories/snapshots/") {
authentication(userName: 'user'), password: 'pwd')
}
}
}
}
}

Related

Sharing uploadArchives task across modules

I'm working on a repo with a set of releasable libraries each in a module. The idea is each library should be able to be released individually with i.e., ./gradlew upload.
Currently in each module I have the following code to publish it:
uploadArchives {
repositories {
mavenDeployer {
repository(url: "<url>") {
authentication(userName: System.getenv('USER_NAME'), password: System.getenv('PASSWORD'))
pom.groupId = "$groupId"
pom.artifactId = "$artifactId"
pom.version = android.defaultConfig.versionName
}
}
}
}
afterEvaluate {
publishing {
publications {
library(MavenPublication) {
setGroupId "$groupId"
setArtifactId "$artifactId"
version android.defaultConfig.versionName
artifact bundleReleaseAar
}
}
}
}
I'd love to have a way to share those gradle tasks and to avoid repeating them in each module but haven't found a way to do that. One tricky thing probably is that artifactId would be different in each module so assuming I could extract those gradle tasks there should be a way to set artifactId individually.
Can someone shed me some light? Thanks
You can put all of your code into a simple build.gradle and use apply from: to apply to multiple build.gradle files.
For instance, I have this compile.gradle script that I use in many places: kotlin/build.gradle and java/build.gradle.
Instead of writing your own "publishing" build.gradle, I would suggest you a popular script that is open source and readily available, gradle-mvn-push.gradle.
Here is an example setup for your project:
root
|
| gradle
| --- gradle-mvn-mpp-push.gradle
|
| - module a
| --- build.gradle - apply from: rootProject.file("gradle/gradle-mvn-mpp-push.gradle")
|
| - module b
| --- build.gradle - apply from: rootProject.file("gradle/gradle-mvn-mpp-push.gradle")
|
See the docs here: https://docs.gradle.org/current/userguide/plugins.html#sec:script_plugins

Upload archive for a library with flavors with gradle

I'm developing an SDK with multiple libraries and an example app to show how to use it. The libraries are uploaded in a local maven repo that the app uses to import them.
Everything works fine until I try to use different flavors for one of the libraries (and for the app).
When I have flavors, the uploadArchive task does not show any error but the library is not uploaded. All the other libraries are uploaded successfully.
I have found this: https://discuss.gradle.org/t/pom-files-for-multi-flavored-android-lib-not-published-on-uploadarchives-task/898
It is an old post but it does not have any answer.
Is it possible to upload one of the flavors of a library?
This is my archive.gradle file:
apply plugin: 'maven'
apply from: "../maven-repo.gradle"
uploadArchives {
repositories {
mavenDeployer {
def folder = "file://localhost" + myMavenRepoDir()
repository(url: folder)
pom.groupId = GROUP
pom.artifactId = POM_ARTIFACT_ID
pom.version = VERSION_NAME
pom.project {
name POM_NAME
packaging POM_PACKAGING
description POM_DESCRIPTION
}
}
}
}

Publishing multiple productFlavors and buildTypes to Artifactory

What is the best way to publish multiple Flavor to artifactory based on buildTypes?
Basically in the project I have 3 buildsTypes (dev, stage and production) and 2 productFlavors (androidPublic and androidPrivate) and I want to publish to the Artifactory
I'm using gitlabci to build my android project and I have basically 3 major stages: build, tests (unit and func), publish. Where the build stage is different from the publish stage, ie when I'm in the stage of publish my script gradle should consider that the artifacts are already generated.
Example: I build dev and two packages are generated
  - app-androidprivate-dev.apk
  - app-androidpublic-dev.apk
I want to send the two to the artifactory on stage Publish.
A short example of my build.gradle:
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.artifactory'
buildscript {
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.4.12"
}
}
publishing {
publications {
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
create("${variant.name.capitalize()}Apk", MavenPublication) {
groupId "app.android"
artifactId "app-${output.baseName}"
version '1.0.0'
artifact(output.outputFile)
}
}
}
}
repositories {
maven {
name 'artifactory'
url "${ARTIFACTORY_URL}/apks"
credentials {
username = "${ARTIFACTORY_USER}"
password = "${ARTIFACTORY_PWD}"
}
}
}
}
And on command line I run:
# gradle publishAndroidPrivateDebugApkPublicationToArtifactoryRepository -P....
# gradle publishAndroidPublicDebugApkPublicationToArtifactoryRepository -P....

distribute Android library in jCenter to use in gradle

I have a library project with a module that is just for library classes and views. I've been searching over the internet how to distribute it in jCenter to use as a gradle dependency but nothing works.
While this isn't done yet, how can I use this module in others projects?
PS: I use Android Studio on Windows 10.
Many of the tutorials and directions online are out of date or are very hard to follow. I just learned how to do this myself, so I am adding what will hopefully be a quick solution for you. It includes the following points
Start with your Android library
Set up a Bintray account
Edit your project's gradle files
Upload your project to Bintray
Link it to jCenter
The library you want to share
By now you probably already have a library set up. For the sake of this example I made a new project with one demo-app application module and one my-library library module in Android Studio.
Here is what it looks like using both the Project and Android views:
Set up a Bintray account
Bintray hosts the jCenter repositories. Go to Bintray and set up a free account.
After you sign in click Add New Repository
Name the repository maven. (You can call it something else, though, if you want to group several library projects together. If you do you will also need to change the bintrayRepo name in the gradle file below.)
Chose Maven as the repository type.
You can add a description if you want. Then click Create. That's all we need to do in Bintray for now.
Edit the gradle files
I'm going to make this as cut-and-paste as possible, but don't forget to edit the necessary parts. You don't need to do anything with the demo app module's build.gradle file, only the gradle files for the project and the library.
Project build.gradle
Add the Bintray and Mavin plugins to your project build.gradle file. Here is my whole file:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2'
// Add these lines (update them to whatever the newest version is)
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
The newest version for Bintray is here and Maven is here.
Library build.gradle
Edit everything you need to in the ext block below.
apply plugin: 'com.android.library'
// change all of these as necessary
ext {
bintrayRepo = 'maven' // this is the same as whatever you called your repository in Bintray
bintrayName = 'my-library' // your bintray package name. I am calling it the same as my library name.
publishedGroupId = 'com.example'
libraryName = 'my-library'
artifact = 'my-library' // I'm calling it the same as my library name
libraryDescription = 'An example library to make your programming life easy'
siteUrl = 'https://github.com/example/my-library'
gitUrl = 'https://github.com/example/my-library.git'
libraryVersion = '1.0.0'
developerId = 'myID' // Maven plugin uses this. I don't know if it needs to be anything special.
developerName = 'My Name'
developerEmail = 'myemail#example.com'
licenseName = 'The MIT License (MIT)'
licenseUrl = 'https://opensource.org/licenses/MIT'
allLicenses = ["MIT"]
}
// This next section is your normal gradle settings
// There is nothing special that you need to change here
// related to Bintray. Keep scrolling down.
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 9
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
}
// Maven section
// You shouldn't need to change anything. It just uses the
// values you set above.
apply plugin: 'com.github.dcendents.android-maven'
group = publishedGroupId // Maven Group ID for the artifact
install {
repositories.mavenInstaller {
// This generates POM.xml with proper parameters
pom {
project {
packaging 'aar'
groupId publishedGroupId
artifactId artifact
// Add your description here
name libraryName
description libraryDescription
url siteUrl
// Set your license
licenses {
license {
name licenseName
url licenseUrl
}
}
developers {
developer {
id developerId
name developerName
email developerEmail
}
}
scm {
connection gitUrl
developerConnection gitUrl
url siteUrl
}
}
}
}
}
// Bintray section
// As long as you add bintray.user and bintray.apikey to the local.properties
// file, you shouldn't have to change anything here. The reason you
// don't just write them here is so that they won't be publicly visible
// in GitHub or wherever your source control is.
apply plugin: 'com.jfrog.bintray'
version = libraryVersion
if (project.hasProperty("android")) { // Android libraries
task sourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
} else { // Java libraries
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives javadocJar
archives sourcesJar
}
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {
user = properties.getProperty("bintray.user")
key = properties.getProperty("bintray.apikey")
configurations = ['archives']
pkg {
repo = bintrayRepo
name = bintrayName
desc = libraryDescription
websiteUrl = siteUrl
vcsUrl = gitUrl
licenses = allLicenses
publish = true
publicDownloadNumbers = true
version {
desc = libraryDescription
gpg {
// optional GPG encryption. Default is false.
sign = false
//passphrase = properties.getProperty("bintray.gpg.password")
}
}
}
}
local.properties
The library build.gradle file above referenced some values in the local.properties file. We need to add those now. This file is located in the root of your project. It should be included in .gitignore. (If it isn't then add it.) The point of putting your username, api key, and encryption password here is so that it won't be publicly visible in version control.
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/home/yonghu/Android/Sdk
# Add these lines (but change the values according to your situation)
bintray.user=myusername
bintray.apikey=1f2598794a54553ba68859bb0bf4c31ff6e71746
There is a warning about not modifying this file but it seems to work well anyway. Here is how you get the values:
bintray.user: This is your Bintray username.
bintray.apikey: Go to Edit Profile in the Bintray menu and choose API Key. Copy it from here.
Upload project to Bintray
Open a terminal and go to your project's root folder. Or just use the terminal in Android Studio.
Enter the following commands
./gradlew install
./gradlew bintrayUpload
If everything is set up right it should upload your library to Bintray. If it fails then Google the solution. (I had to update my JDK the first time I tried.)
Go to your account in Bintray and you should see the library entered under your repository.
Link to jCenter
In your library in Bintray there is an Add to jCenter button.
Click it and send your request. If you are approved (which takes a day or two), then your library will be a part of jCenter and developers around the world can add your library to their projects simply by adding one line to the app build.gradle dependencies block.
dependencies {
compile 'com.example:my-library:1.0.0'
}
Congratulations!
Notes
You may want to add PGP encryption, especially if you are linking it to Maven Central. (jCenter has replaced Maven Central as the default in Android Studio, though.) See this tutorial for help with that. But also read this from Bintray.
How to add a new version
You will eventually want to add a new version to your Bintray/jCenter library. See this answer to directions on how to do it.
Further Reading
How to distribute your own Android library through jCenter and Maven Central from Android Studio
Creating and Publishing an Android Library

Library uploaded - But gradle download only pom and aar.asc from Maven Central

This is my build.gradle uploadArchives method within I upload my library
version = "1.2.1"
group = "com.atooma"
archivesBaseName = "atooma-android-sdk"
signing {
sign configurations.archives
}
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
authentication(userName: sonatypeUsername, password: sonatypePassword)
}
snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
authentication(userName: sonatypeUsername, password: sonatypePassword)
}
pom.project {
name 'Atooma Android SDK'
packaging 'aar'
// optionally artifactId can be defined here
description 'Atooma Software Development Kit allows you to write your own modules for Atooma app'
url 'https://github.com/atooma/atooma-android-sdk'
scm {
url 'https://github.com/atooma/atooma-android-sdk.git'
connection 'scm:git#github.com:atooma/atooma-android-sdk.git'
developerConnection 'scm:git#github.com:atooma/atooma-android-sdk.git'
}
licenses {
license {
name 'LGPL V3'
url 'https://www.gnu.org/licenses/lgpl.html'
}
}
developers {
developer {
id 'monossido'
name 'Lorenzo Braghetto'
email 'l.braghetto#atooma.com'
}
}
}
}
}
}
I've tried pagkaging 'aar' and 'jar' as well.
In sonatype site from "nexus" i can see aar
And the pom here https://oss.sonatype.org/service/local/repositories/releases/content/com/atooma/atooma-android-sdk/1.2.1/atooma-android-sdk-1.2.1.pom
says aar
But when I download it from Android Studio (compile 'com.atooma:atooma-android-sdk:1.2.1') it download only the aar.asc and pom files. In pom file I see
aar.asc
and I can't understand why... :(
Obviously it I set compile 'com.atooma:atooma-android-sdk:1.2.1#aar' it works
As far as I know you are doing everything correctly. If you look at
https://oss.sonatype.org/content/repositories/releases/com/atooma/atooma-android-sdk/1.2.1/ both the pom and the aar file are there. The problem lies with Android Studio does not yet support aar files like that properly. I would suggest to file a bug with the Android SDK team and the Android Studio project as Jetbrains.

Categories

Resources