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
}
}
}
}
Related
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')
}
}
}
}
}
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
I am assigned a task of building a project using gradle and maven. The project consists of a main module and its supporting modules.
The supporting modules must be uploaded to artifact local maven repository as libraries and the main module will access them from there.
How do I upload the modules? How do I convert them to libraries?
Put this in your build.gradle of library/module
apply plugin: 'maven'
artifacts {
//put library path
archives file: file('build/aar/library.aar')
}
// Define maven repository path
def localRepoPath = "file://D:/m2repo"
uploadArchives {
repositories.mavenDeployer
{
repository(url: localRepoPath)
pom.artifactId = "your_artifact_id"
pom.groupId = 'com.your.groupid'
pom.version = android.defaultConfig.versionName
}
}
Run gradlew uploadArchives to deploy to local maven repo.
I am using Android Gradle plugin 0.13.2, Android Studio 0.8.11, Gradle 2.1 and maven plugin.
I would like to install multiple variants (flavour + build type) of my Android Library to local Maven repository all with one command (task).
Currently Android Gradle plugin 0.13.2 allows me to set publishNonDefault flag to publishing all variants, but as the documentation states it will publish the variants with a classifier which is not compatible with Maven Repository.
My workaround right now is to use defaultPublishConfig "myVariant" and change it for every variant I have.
apply plugin: 'com.android.library'
apply plugin: 'maven'
android {
defaultPublishConfig "myVariant"
.
.
.
}
task installArchives(type: Upload) {
repositories.mavenInstaller {
configuration = configurations.getByName(Dependency.DEFAULT_CONFIGURATION)
pom.groupId = "com.company"
pom.artifactId = "mylibrary"
pom.version = "1.0.0-myVariant"
}
}
I would like to have a single task that would properly publish all variants to local Maven repository.
To solve this I had to create one Upload task for each variant and make them depend on each other and on a master task that starts the process.
apply plugin: 'com.android.library'
apply plugin: 'maven'
android {
.
.
.
}
// Master task that will publish all variants
def DefaultTask masterTask = project.tasks.create("installArchives", DefaultTask)
android.libraryVariants.all { variant ->
variant.outputs.each { output ->
// Configuration defines which artifacts will be published, create one configuration for each variant output (artifact)
def Configuration variantConfiguration = project.configurations.create("${variant.name}Archives")
project.artifacts.add(variantConfiguration.name, output.packageLibrary)
// Create one Upload type task for each configuration
def Upload variantTask = project.tasks.create("${variant.name}Install", Upload)
variantTask.configuration = variantConfiguration
variantTask.repositories.mavenInstaller {
pom.groupId = "com.yourcompany"
pom.artifactId = "yourLibrary"
pom.version = "1.0.0-${variant.name}" //Give a different version for each variant
pom.packaging = "aar"
}
// Make all tasks depend on each other and on master task
masterTask.dependsOn variantTask
masterTask = variantTask
}
}
The task installArchives will publish all variants to the local Maven repository.
./gradlew installArchives
What is the preferred way to share some code (E.g. a Utils class) between two projects when building two apps using Gradle to build?
Can I do this without creating extra jar files? I just want my code to sit outside the app projects, be imported/compiled into both app projects. Or is this simply not possible?
I'm familiar with the approach that uses jars or Android library projects, but both seem a bit unwieldy.
My favorite way of doing this is by keeping it in a local Maven repo. The repo can even live in your SCM so it's the same across workspaces.
Create a new Android Studio project and then set it as a maven project your build.gradle config:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
apply plugin: 'android-library'
apply plugin: 'maven'
repositories {
mavenCentral()
}
configurations {
archives {
extendsFrom configurations.default
}
}
group = 'com.mypackage.mylibrary'
version = '1.0.0'
uploadArchives {
configuration = configurations.archives
repositories {
mavenDeployer {
repository(url: uri("relative/path/to/localrepo"))
pom.project {
artifactId 'mylibrary'
name 'My Library'
packaging 'aar'
}
}
}
}
android {
// copy old android config here
}
You'll need to deploy the library before you can use it. Do this by using the uploadArchives task [./gradlew uploadArchives]
Now you should be able to use this library in any project by doing this:
repositories {
maven { url 'relative/path/to/localrepo' }
}
dependencies {
compile ('com.mypackage.mylibrary:1.0.0')
}
When you make changes to your library, you'll have to re-deploy (uploadArchives) with a new version, then update the dependency reference in whatever project needs the new version.