I'm trying to publish an Android library as a Maven artifact on a Bitbucket repository, starting from this article that was linked in an Android Weekly newsletter issue some time ago. The article describes how to perform publication and how to link the published artifact from another Android project. However, I have not even managed to make the publishing part to correctly work.
Currently, this is the relevant content of the build.gradle file belonging to the library project:
apply plugin: 'maven'
allprojects {
repositories {
jcenter()
maven {
url "https://raw.github.com/synergian/wagon-git/releases"
}
}
}
configurations {
deployerJar
}
dependencies {
deployerJar 'ar.com.synergian:wagon-git:0.2.5'
}
The relevant parts of the build.gradle file of the library module in the project are as follows:
apply plugin: 'maven'
uploadArchives {
configuration = rootProject.configurations.archives
repositories {
configuration = rootProject.configurations.deployerJar
mavenDeployer {
pom.groupId = 'com.example'
pom.artifactId = 'example-library'
pom.version = '1.0.0'
repository(url: "${bitbucketUrl}") {
authentication(userName: bitbucketUsername, password: bitbucketPassword)
}
}
}
}
where bitbucketUrl, bitbucketUsername and bitbucketPassword are included in the gradle.properties file at the root of the project.
So, what's the problem? When I run the uploadArchives task from Android Studio, Gradle shows that the operation has been performed successfully. But nothing appears on the Bitbucket repository.
Nothing is also written about the structure of that repository, except on Wagon Git's website (calling it documentation seems a little bit of a stretch to me) where, given repository URL of the form
git:releases://git#github.com:synergian/wagon-git.git
it is said that releases represent a branch of the repository. I obliged that part about the structure, even tried to add a repository directory (to mimick the local Maven repository on my machine) but with no luck, and, above all, no clue.
An even more severe issue is that, while I was experimentating with different configurations, I noticed I had the repository URL wrong; however, never, ever, during execution, Gradle noticed the error, and warned or informed me with a suitable message. This lead me to suspect that it wasn't even preparing the artifact to upload, nor trying to connect to Bitbucket, but I was not able to find any pointer as to understand why.
Finally, an even more strange thing happens: when I comment out the line:
configuration = rootProject.configurations.deployerJar
in the module build.gradle file and I run the uploadArchives task, Gradle stops with an error saying that it is unable to find a proper wagon to manage the git protocol, which is expected; however, in the process, the Maven artifact appears in the local repository on my machine. So, by making the publishing process crash, at least I am able to work locally with my library from other projects depending on it, through Gradle management of Maven-like dependencies.
What am I doing wrong?
Fails silently, turn on --info. Probably the biggest hurdle in debugging the problem. For some reason, the folks who wrote the wagon-git deployer decided to write out error messages at the info level. So gradle fails silently without showing you any error messages. This is one of the messages I got with --info turned on:
[INFO] [git] fatal: 'git#bitbucket.org/foragerr/mvn-deploy-test.git' does not appear to be a git repository
This is apparently a fatal error, but as far as gradle is concerned, everything is fine and dandy. Once you start reading these error messages, we can make real progress!
git url: The git URL as outlined here, starts with git:. The wagon-git deployer is activated when the url starts with git:. It is possible to use a https: url, but maven plugin will use an internal deployer rather than wagon-git. To explicitly use wagon-git, the url has to start with git:
repository(url: "git:releases://git#bitbucket.org:foragerr/mvn-bitbucket-deploy-test.git")
where
releases is branch
foragerr is bitbucket username
mvn-bitbucket-deploy-test is bitbucket repo
Authentication: wagon-git uses SSH to connect to bitbucket. You need to setup both git on the local end and bitbucket repo on the remote end to use SSH.
Setting up SSH for git (I recommend not using a passcode, less secure, but convenient for automated deployments)
All Set! deploy to your bitbucket repo using gradle uploadArchives. See example repo here.
Sample build.gradle:
group 'net.foragerr.test'
version '1.2-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'maven'
sourceCompatibility = 1.5
repositories {
mavenCentral()
maven {
url "https://raw.github.com/synergian/wagon-git/releases"
}
}
configurations {
deployerJar
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
deployerJar "ar.com.synergian:wagon-git:0.2.3"
}
uploadArchives {
repositories.mavenDeployer {
configuration = configurations.deployerJar;
repository(url: "git:releases://git#bitbucket.org:foragerr/mvn-bitbucket-deploy-test.git")
}
}
Here is all you need to do, you even need to use the git protocol (this examples show how to use the HTTPS instead):
1) create an app password for your app in Bitbucket
https://bitbucket.org/account/user/YOUR_USERNAME_HERE/app-passwords
2) inside build.gradle:
apply plugin: 'java'
apply plugin: 'maven'
// artifact --> rootProject.name at settings.gradle <--
// DOWN HERE just add your artifact INFO
group = 'br.com.fora.temer'
version = '0.1-SNAPSHOT'
description = """Diretas Ja"""
dependencies {
// your dependencies goes here, like this -->
// compile group: 'br.gov.governo', name: 'golpista', version:'2.0'
}
apply from: 'uploadArchives.gradle' // --> deploy configuration
3) inside uploadArchives.gradle (you need to create it):
configurations {
deployerJars
}
dependencies {
deployerJars "ar.com.synergian:wagon-git:0.2.5" // plugin
}
uploadArchives {
configuration = configurations.archives
repositories.mavenDeployer {
configuration = configurations.deployerJars
repository(url: "git:releases://https://YOUR_USERNAME:YOUR_APP_PASSWORD#bitbucket.org/YOUR_COMPANY/repo-release.git")
snapshotRepository(url: "git:snapshots://https://YOUR_USERNAME:YOUR_APP_PASSWORD#bitbucket.org/YOUR_COMPANY/repo-snapshot.git")
}
}
allprojects {
repositories {
mavenCentral()
maven { url "https://raw.github.com/synergian/wagon-git/releases"}
}
}
To deploy use:
gradle uploadArchives
TIP: beware the order of the entries... if you change it, it will break everything.
I know the question is old, but there isn't a lot of information on the topic, so I guess it is the right place to add some clues. I faced the same problems, there seemed to be no way to get it working. So there are some clues which might help:
As already been said, this whole maven plugin wagon thingy uses SSH to connect to repository (Bitbucket in my case). So you need to check a few things:
that Bitbuchet knows about your SSH key.go to your profile settings(not repository settings!) -> SSH keys and put there your public key received by keygen. There is instruction in the little 'insert key' window on Bitbucket to help you out.
that you have added your private key generated by keygen to your ssh agent (type ssh-add ~/.ssh/id_rsa fot Linux and probably mac)
also add credentials to your repository element:
repository(url: 'git:releases://git#bitbucket.org:gendalf/repo.git'){
authentication(userName: "gendalf", password: "swordfish") }
That plugin won't get confuzed about your output file. When I started to try uploading my library to the repository, I had flavors in it, so plugin didn't know which variant to select and selected nothing (apparently).
this stuff doesn't work with flavors as far as I know. So if you have flavors in the library which you are posting to private repository... consider getting rid of flavors. You probably don't need them anyway.
if you tried other publishing plugins before trying out maven (for example maven-publish), comment out all the script related to other stuff or delete it. My gradle was confused because of the additional scripts.
Consider trying out this https://jeroenmols.com/blog/2016/02/05/wagongit/ solution. It's what I used to finally publish, although it is pretty confusing about checking out from your just-created repository. Don't check out. Create the repository and publish right after that.
I hope this helps.
Related
I had a GitHub project forked and some fixes applied to it. Now would like to use it as dependency in a project of mine. Have followed the instructions provided at jitpack.io but gradle build fails to find it.
build.gradle (all projects)
allprojects {
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" }
}
}
build.gradle (module)
dependencies {
implementation 'com.github.user:repo:e91058a'
}
Have tried calling File->Sync in Android Studio and running gradlew build --refresh-dependencies. Also tried defining dev-SNAPSHOT as the version number instead of commit hash. But it always ends up with Failed to resolve error.
What am I missing here?
Check your repositority on jitpack.io, and verify that the snapshot was actually built. (Enter your repo url, select 'branches', you must see a green icon near your commit sha)
Also if your repository is private, you'd need to add access token in build.gradle (you can find it in ur account setting)
I'm using jitpack to in my gradle as follows:
allprojects {
repositories {
jcenter()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
And in my github repo I have a sub-module called authentication
I need to use only this module in my project, so I added this to my module's build.gradle as mentioned here:
compile 'com.github.MotassemJa.MoAuth:authentication:0.0.5'
But I keep getting
Error:(23, 13) Failed to resolve: com.github.MotassemJa.MoAuth:authentication:0.0.5
As you can see at https://jitpack.io/com/github/MotassemJa/MoAuth/0.0.5/build.log, 0.0.5 was built from commit ebb529c949bf7d40815c815d051d45407e8f7f71 which is 0.0.5~2 and there the module was named moauth2.0.
It seems you moved the tag and thus the release after it was compiled and cached by JitPack.
It is always a very bad idea to modify releases after they are done instead of releasing a new version.
I don't know whether you can make JitPack forget the cache and rebuild your application, but maybe it would be best to move the 0.0.5 release back to where it was and create a 0.0.6 release.
You might be able to make JitPack re-build your app if you log into jitpack.io with GitHub and delete the existing build. The FAQ are not too clear on that. It could be that this only works for failed builds.
I have an Android aar library I am using with an Android application. It is working correctly with the aar library included directly in the Android project. I would like to move this library to my internal Nexus maven repository, so that other developers can use the library too.
How do I upload the aar to Nexus (the Maven repository)? There is no apparent option to do so in the web interface:
For Android, we normally have two build.gradle files the one at the top level folder, and another one in the specific module:
app/
---build.gradle
---module/
------build.gradle
In the app/build.gradle file of the clients of this library you will have to add:
repositories {
jcenter()
maven {
url "http://localhost:8081/repository/test-maven-repo/"
}
}
For you library app/module/build.gradle file:
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "http://localhost:8081/repository/test-maven-repo/") {
authentication(userName: "admin", password: "admin123")
pom.groupId = "com.example.test"
pom.artifactId = "myexample.test"
pom.version = '1.0.0'
}
}
}
}
And you might want to run it just with:
./gradlew upload
Link to official documentation:
Maven Publish Plugin.
I used gradle's maven plugin to upload to Nexus by modifying the Android build.gradle file.
apply plugin: 'maven'
dependencies {
deployerJars "org.apache.maven.wagon:wagon-http:2.2"
}
uploadArchives {
repositories.mavenDeployer {
configuration = configurations.deployerJars
repository(url: "https://my.example.com/content/repositories/com.example/") {
authentication(userName: "exampleUser", password: "examplePassword")
pom.groupId = "com.example"
pom.artifactId = "myexample"
pom.version = '1.0.0'
}
}
}
To upload: gradlew upload, using the gradlew script that is provided by the Android Studio project.
You can also move the authentication parameters into a file that is not version controlled.
Use maven deploy plugin. Example command:
mvn deploy
This assumes you have correctly configured your pom.xml with distributonManagement section, telling all it needs to know about your Nexus repo
If you're that kind of people who dislike changing your pom.xml, or worse if your code doesn't even have pom.xml but you still want to upload to Nexus anyway, then you can still do it using
mvn deploy:deploy-file -Durl=http://mycompany/nexus/repo/blah -Dfile=/path/to/my/foo.aar -Dpackaging=aar -DgroupId=com.mycompany -DartifactId=foo -Dversion=1.2.3
Refer to maven deploy plugin doc for more info: https://maven.apache.org/plugins/maven-deploy-plugin/
If you are building your project using Gradle, here there is a good tutorial to push your artifacts to Nexus:
https://medium.com/#scottyab/how-to-publish-your-open-source-library-to-maven-central-5178d9579c5#.acynm6j49
Basically, it adds a new Gradle task (uploadArchives) to push your artifacts. So doing something like:
>gradle clean build uploadArchives
You can upload it with Maven or Gradle or manually.
For the manual upload you can just type the package value in the input to be 'aar' and upload as you desire.
It doesn't make any sense that why nexus package have nothing for #aar file but if you try to upload it as a jar then it will not block you and everything is work as it is..
Can someone explain the meaning of the purpose of this init.gradle file as it seems like just duplicating code to me:
buildscript {
repositories {
maven {
url "https://someEnterpriseURL"
}
}
}
allprojects {
repositories {
maven {
url "https://someEnterpriseURL"
}
}
}
the reason for the confusion is that in the projects build.gradle file its defined like this:
buildscript {
repositories {
maven {
url "https://someEnterpriseURL"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.1'
}
}
allprojects {
repositories {
maven {
url "https://someEnterpriseURL"
}
}
}
so why even have this defined in the init.gradle file ? how does it help developers to have a init.gradle file when im defining the same thing in the build.gradle file?
Your build.gradle files are per-project and per-module. Your init.gradle files are set up on a per-${GRADLE_USER_HOME} basis (default is in ~/.gradle or in Gradle's home directory for local Gradle installations). I would expect to see init.gradle files used more commonly in large organizations, trying to standardize some Gradle build policies across multiple projects and development teams.
Quoting the Gradle documentation:
Here are several possible uses:
Set up enterprise-wide configuration, such as where to find custom plugins.
Set up properties based on the current environment, such as a developer's machine vs. a continuous integration server.
Supply personal information about the user that is required by the build, such as repository or database authentication credentials.
Define machine specific details, such as where JDKs are installed.
Register build listeners. External tools that wish to listen to Gradle events might find this useful.
Register build loggers. You might wish to customize how Gradle logs the events that it generates.
As you know gradle is combination of Ant tool and Maven tool. You might have seen how ant tool works(adding jars or libs locally) and maven tool(adding jars and libs file from cloud and writing script to download it from cloud during building). So basically this init.gradle file is generally used for some jars available globally(generally used for big organisations placed in cloud) which will contain the url or address of server so as to download the jar and cache it in gradle wrapper(you can see those jar files over cloud once downloaded can be seen in .gradle->caches).
Visualize in a prospect like suppose in an organisation which is have one support jar file which keeps updating every now and then and there is another team in that organisation which needs that jar for their application. So here our guy 'init.gradle' help us to solve this problem. Automatically download the latest jar from the server whenever application is build by the later team.
I'm using Gradle in my Android project,and I have added some dependencies in build.gradle file.For some reasons,I want to point to the latest commit for one of my dependencies.For example:
dependencies {
...
compile 'com.github.ozodrukh:CircularReveal:1.1.0#aar'
}
I'm specifying CircularReveal's version to be 1.1.0#aar,and I know currently it has fixed some bugs but have not released it yet.How can I specify a commit in Gradle?I know some basics about Cocoapods,and it can be done like this:
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'
Can it be done in Gradle? Any help would be greatly appreciated.
You can not do this directly from Gradle, but there are Gradle plugins and tools you can use to achieve this.
You can do this using Jitpack, an external tool. All you need to do is specify Jitpack as a repository:
repositories {
maven {
url "https://jitpack.io"
}
// Define your other dependency repositories, if any
}
Then include your dependency:
dependencies {
compile 'com.github.ozodrukh:CircularReveal:25aeca505d'
// Include your other dependencies, if any
}
You can also use use the gradle-git-repo-plugin from Layer, but I haven't tried this one yet. An advantage(?) of this plugin is that it clones the repository on your local machine and adds it as a dependency from there.
Ugo response is probably the correct one, here's an alternative for some specific cases:
dependencies {
...
compile 'com.github.ozodrukh:CircularReveal:1.1.+#aar'
// or 1.+ or even just +
}
That puts you on the latest version, no matter which one it is. Now, if you repository builds on a CI environment and deploys snapshots to Sonatype or a similar service, you can do
repositories {
maven {
url "https://project.sonatype.io"
}
}
And along with the other change you'll end up in the -SNAPSHOT versions. This behaviour reports warnings on build because your builds will not be reproducible, but that's a given if you're targeting CI versions.