Publish local jars to nexus repository through gradle - gradle

I have some jar files in my local system which I wanted to publish using Gradle script but I could not find any solution till now.
I am able to publish artifacts which my build generates but I want to publish jars which are there in my local system.
I tried to declare the artifact something like following but it is throwing error:
publishing {
publications {
mavenJava(MavenPublication) {
artifact projJar
//This is jar file other than my built file which I want to upload (there are same files more in number to be uploaded):
artifact 'D:/myworkspace/Test/LocalJar.jar'
artifact source: projJar, classifier: 'src', extension: 'jar'
}
}
repositories {
maven {
credentials {
username 'user'
password 'password'
}
url "http://IP:Port/repository/RepoName/"
}
}
}
Error msg is:
*What went wrong:
Execution failed for task:publishMavenJavaPublicationToMaven2Repository'.
> Failed to publish publication 'mavenJava' to repository 'maven2'
> Invalid publication 'mavenJava': multiple artifacts with the identical extension and classifier ('jar', 'null').
Please guide me with some example how I can publish my local jar files to nexus repository (there are a lot of files there in my local which I want to publish)

Related

Can the gradle artifactory plugin publish plain binary files instead of MavenPublication?

I want to upload a binary file to a local artifactory instance. The binary file is not a maven artifact so I do not want to use the maven-publish plugin, but that doesn't seem to be possible. Pseudo-code:
artifactory {
contextUrl = artifactoryConfig.context
publish {
repository {
// Credentials and context path
}
defaults {
publications (someSimpleFilePublication)
}
}
}
There doesn't seem to exist anything else than IvyPublication and MavenPublication as valid publications in Gradle by default. I tried creating my custom Publication like below, but that yielded a new error:
interface FilePublication extends Publication {
PublicationArtifact artifact(Object source)
}
publishing {
publications {
filePub(FilePublication) {
}
}
}
error:
Cannot create a FilePublication because this type is not known
to this container. Known types are: MavenPublication
I've read both the artifactory plugin docs and the maven plugin docs but am none the wiser.
Please don't suggest to make my binary a Maven entity - there are a couple of reasons why I don't want to.
Clarification
With "plain" binary file as opposed to "Maven artifact" I mean a file that does not have a POM file, does not have a Maven Group ID, Artifact or Version String. It's just a file with a file system path.
I know it's possible to upload Plain Binary Files to Artifactory because I've done so through a plain HTTP PUT command from command line using the Artifactory API

Gradle publish RPM to Nexus Yum Repo fails on sha1 file

I am trying to publish an RPM artifact from our project into a Yum Repo on Nexus via Gradle:
publishing {
repositories {
ivy {
url 'http://myrepo:8081/repository/myproject'
credentials {
username "aaa"
password "xxx"
}
layout "pattern", {
artifact "${buildRpm.outputs.getFiles().getSingleFile().getName()}"
}
}
publications {
rpm(IvyPublication) {
artifact buildRpm.outputs.getFiles().getSingleFile()
}
}
}
}
When I run ./gradlew publish this task gets picked up and starts to upload the main .rpm artifact of 90MB. It then fails after this with the following error:
> Task :search:publishRpmPublicationToIvyRepository FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':search:publishRpmPublicationToIvyRepository'.
> Failed to publish publication 'rpm' to repository 'ivy'
> Could not write to resource 'http://myrepo/repository/myproject/myproject-1.23.4.noarch.rpm.sha1'.
> Could not PUT 'http://myrepo/repository/myproject/myproject-1.23.4.noarch.rpm.sha1'. Received status code 400 from server: Invalid path for a Yum repository
How can I prevent the .sha1 file to be uploaded? I only want the RPM to be uploaded (which is apparently the only thing allowed on this repo).
I also tried using maven-publish instead of ivy-publish but both give similar issues. maven-publish tries to upload a .pom with a similar failure.
I am able to upload the RPM fine manually using curl, but I would rather do it using Gradle plugins and standards.

Gradle Nexus and FlatDir deployment without java-, ear- or war-plugin

I have a multi-project gradle (version 2.1!!) build consisting of non-java projects.
I would like to deploy the generated artifacts (.tar.gz files) to a Nexus and also to a directory.
Currently I define the repositories in the root build.gradle in the repositories block and also again for each sub-project in a repositories block inside the subprojects in the root build.gradle file.
I apply the base plugin to the root project and the maven-publish plugin to all subprojects that have artifacts to be deployed.
I tried to follow the instructions here:
https://docs.gradle.org/2.1/userguide/publishing_maven.html
https://docs.gradle.org/2.1/dsl/org.gradle.api.publish.maven.MavenPublication.html
https://discuss.gradle.org/t/how-to-have-multiple-uploadarchives/19381/3
How can I make uploadArchives dependent on another task?
and a few more...
but nothing worked. :-(
Here's what I do:
...
# apply the maven-publish plugin only to sub-projects that produce artifacts that should be uploaded.
apply plugin: 'maven-publish'
publishing {
publications {
tarFiles (MavenPublication) {
artifact compressTar
}
}
repositories {
add rootProject.repositories.fsShare
add rootProject.repositories.nexusDeploy
}
}
...
The compressTar is my custom Tar task that creates the artifacts that I want to upload.
When I execute ./gradlew publishTarFilesPublicationToNexusDeployRepository I get the following error:
Execution failed for task ':mySubProject:publishTarFilesPublicationToNexusDeployRepository'.
> Failed to publish publication 'tarFiles' to repository 'nexusDeploy'
> Failed to retrieve remote metadata myRootProject:mySubProject:0.0.0.0-SNAPSHOT/maven-metadata.xml: Could not transfer metadata myRootProject:mySubProject:0.0.0.0-SNAPSHOT/maven-metadata.xml from/to remote (https://myProject.nexus.url:443/nexus3/repository/builds/): Could not get resource 'myRootProject/mySubProject/0.0.0.0-SNAPSHOT/maven-metadata.xml'
When I execute uploadArchives, the task succeeds, but nothing is uploaded anywhere and from the output it looks like the uploadArchives task is only executed for sub-projects that didn't get the maven-plugin applied.
What is the right way to do this? Which plugins should I apply when/where?
Apparently there were two un-related "problems at work" here.
Problem 1): I was not able to publish to Nexus and got a Failed to retrieve remote metadata-error:
Answer 1): I was trying to publish a "SNAPSHOT" to a repository that was configured not to accept "SNAPSHOT" build. Renaming the build version from 1.2.3.4-SNAPSHOT to anything else (e.g. 1.2.3.4-SNAPSHOT-dev or more reasonable 1.2.3.build4`) worked fine.
Problem 2) Publishing to 'flatDir' repository didn't work. The maven-publish plugin didn't create the publish task for it.
Answer 2) To use maven-publish to publish to a directory, flatDir apparently is not recognized as repository the maven-publish plugin can publish to. Defining the 'directory' repository as follows worked fine:
maven {
name "fsShare"
url "/share/pkg"
}

How to specify module name when publishing to Artifactory from Jenkins

I'm using the gradle artifactory publish plugin documented here: http://www.jfrog.com/confluence/display/RTF/Gradle+1.6+Publishing+Artifactory+Plugin
I'm using the standard config exactly as laid out in the documentation.
When I run the gradle publishArtifactory task from the command line I get output like this. I.e. It deploys to my correct module name.
Deploying artifact: http://<my server>/artifactory/libs-snapshot-local/<my actual module name>/web/0.1-SNAPSHOT/web-0.1-SNAPSHOT.war
When I configure Jenkins to run the gradle publishArtifactory task using the same gradle build file I get output like this. I.e. It uses the Jenkins build for the module name.
Deploying artifact: http://artifactory01.bcinfra.net:8081/artifactory/libs-snapshot-local/<the name of the jenkins build>/web/0.1-SNAPSHOT/web-0.1-SNAPSHOT.war
Any ideas on how to prevent the artifactory plugin from using the Jenkins build name for the module name?
The module name used for uploading is derived from the gradle project name. The default value for a gradle project name is taken from the project folder name. I suspect that on your jenkins job you check out your code into a folder named like your build job. That's why per default this folder name is used as project name.
The cleanest solution is to explicitly set your project name in gradle.
Therefore you need a settings.gradle file in your project root folder that contains the project name:
rootProject.name = "web"
You can also let Gradle single-handedly do the publishing to Artifactory, without the need for the Artifactory plugin in Jenkins.
This way, you can set the names of the artifacts using artifactId "your artifact name" without changing the project's name as suggested by Rene Groeschke.
Here's my publish.gradle that demonstrates this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1"
}
}
// Because this is a helper script that's sourced in from a build.gradle, we can't use the ID of external plugins
// We either use the full class name of the plugin without quotes or an init script: http://www.gradle.org/docs/current/userguide/init_scripts.html
apply plugin: org.jfrog.gradle.plugin.artifactory.ArtifactoryPublicationsPlugin
// Pack the sources into a jar
task sourceJar(type: Jar) {
from sourceSets.main.allSource; classifier = "sources"
}
// Pack the Javadoc into a jar
task javadocJar(type: Jar) {
from javadoc.outputs.files; classifier = "javadoc"
}
apply plugin: "maven-publish"
publishing {
publications {
mavenJava(MavenPublication){
from components.java
// Set the base name of the artifacts
artifactId "your artifact name"
artifact jar
artifact sourceJar
artifact javadocJar
}
}
}
artifactory {
contextUrl = "http://localhost:8081/artifactory"
publish {
// Publish these artifacts
defaults{ publications ("mavenJava") }
repository {
repoKey = "libs-release-local"
// Provide credentials like this:
//-Partifactory.publish.password=yourPassword
//-Partifactory.publish.username=yourUsername
}
}
resolve {
repository {
repoKey = "libs-release"
}
}
}
You can use this script in your build.gradle via apply from: "path/to/publish.gradle" and call it like this:
./gradlew artifactoryPublish -Partifactory.publish.username="yourUsername" -Partifactory.publish.password="yourPassword"

Gradle script to copy maven artifact from local folder to another folder

In my project i want to copy certain artifact (war file) from maven repo to local folder in order to deploy. I tried using configurations object but i couldn't give specific groupid, artifact id, and version in that way
repositories {
mavenCentral() // or some other repo
}
configurations {
deploy
}
dependencies {
deploy "someGroup:someArtifact:someVersion"
}
task copyDeploy(type: Copy) {
from configurations.deploy
into "deploy"
}
You can find all of this and more in the Gradle User Guide (e.g. under "Working with dependencies") and the many samples in the full Gradle distribution.

Resources