Home » Android » How to publish an Android library as a Maven artifact on Bitbucket?

How to publish an Android library as a Maven artifact on Bitbucket?

Posted by: admin June 15, 2020 Leave a comment

Questions:

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://[email protected]: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?

How to&Answers:
  1. 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: '[email protected]/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!

  1. 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://[email protected]:foragerr/mvn-bitbucket-deploy-test.git")
    

where
releases is branch
foragerr is bitbucket username
mvn-bitbucket-deploy-test is bitbucket repo

  1. 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)
  2. 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://[email protected]:foragerr/mvn-bitbucket-deploy-test.git")
        }
    }

Answer:

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:[email protected]/YOUR_COMPANY/repo-release.git")
        snapshotRepository(url: "git:snapshots://https://YOUR_USERNAME:[email protected]/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.

Answer:

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:

  1. 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://[email protected]:gendalf/repo.git'){
authentication(userName: "gendalf", password: "swordfish") }

  1. 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.
  2. 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.