How to upload file to artifactory generic repository with gradle? - gradle

I build app distribution with gradle, which a tar file contains everything needed. I created a generic repository in artifactory. I want to upload the tarball to the generic repository.
By looking up this documentation
http://www.jfrog.com/confluence/display/RTF/Gradle+Artifactory+Plugin
I didn't find a way to do so.
I am a new gradle and artifactory user, can anyone give me guide.
task uploadDistroTar(type: org._10ne.gradle.rest.RestTask) {
httpMethod = 'PUT'
uri = 'http://x.x.x.x:8081/artifactory/repo/foo.tar'
username = 'admin'
password = 'passwd'
requestContentType = groovyx.net.http.ContentType.BINARY
requestBody = new File("build/distributions/foo.tar").bytes
}

The easiest way will be to use the Gradle REST plugin. Just use the PUT request to upload the file to the repository you want.

More modern solution is to use Artifactory Java Client:
Artifactory artifactory = ArtifactoryClientBuilder.create()
.setUrl("ArtifactoryUrl")
.setUsername("username")
.setPassword("password")
.build();
java.io.File file = new java.io.File("fileToUpload.txt");
File result = artifactory.repository("RepoName").upload("path/to/newName.txt", file).doUpload();

Finally I find the solution by read the plugin's source code,
just set:
preemptiveAuth = true

Related

Gradle Version Catalog (Published): How to dynamically set up repository

I'm not that experienced with Gradle and are currently running into problems when trying to use the new version catalog feature.
Goal:
Using a Gradle 7.4.2 version catalog, managed in a standalone GIT repository and published to private JFrog artifactory, in a second project.
Every project member's artifactory credentials are already available in $HOME/.gradle/gradle.properties (auto-generated by JFrog) and are supposed to be re-used.
Issue:
according to the current Gradle documentation, a published version catalog is supposed to be defined in settings.gradle(.kts) within any project that wants to use the catalog;
inserting that piece of code results in an error because Gradle has no repository definition available for artifact look-up
therefore, adding a repository definition:
// my settings.gradle.kts
rootProject.name = "catalog-consumer"
dependencyResolutionManagement {
val catalogVersion = "0.1.0"
val artifactoryUri = "..."
val catalogGAV = "..."
repositories{
maven {
url = uri("$artifactoryUri")
credentials {
// TODO: how to access user's local gradle.properties for credentials?
username = "$artifactory_user" // key as generated by JFrog
password = "$artifactory_password" // key as generated by JFrog
}
}
}
versionCatalogs {
create("libs") {
from("$catalogGAV")
}
}
}
now, facing the problem that the user's gradle.properties does not seem to be loaded, yet - but hardcoding credentials is not viable :)
Question:
Is the only option to manually check for and load the user's gradle.properties file?
Originally, when reading the documentation, I assumed that the settings file would probably try to look up existing repository definitions from the project's build.gradle.kts, but that wasn't the case either. If I understand it correctly, the settings file is evaluated before everything else, isn't it?
Manually loading the user's config just seems odd to me, therefore, I wanted to ask whether or not I'm missing a mechanism or lifecycle hook that would take care of this. Also possible that I use the version catalog feature incorrectly :D
Any hints very much appreciated!
See the docs here: https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:handling_credentials
Named repository credentials
If you named the repository and add credentials(PasswordCredentials::class)...
// ./settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven {
name = "mySecureRepository"
credentials(PasswordCredentials::class)
// url = uri(<<some repository url>>)
}
}
}
then Gradle will automatically fetch the username/pass from the first found definition:
Using a command line argument
./gradlew build -PmySecureRepositoryUsername=my-username
environment variables prefixed with ORG_GRADLE_PROJECT_ (this is useful for CI/CD)
ORG_GRADLE_PROJECT_mySecureRepositoryUsername=my-username
ORG_GRADLE_PROJECT_mySecureRepositoryPassword=my-password
$GRADLE_USER_HOME/gradle.properties
mySecureRepositoryUsername=my-username
mySecureRepositoryPassword=my-password
gradle.properties in the project root - obviously don't put credentials in your project!
gradle.properties in the Gradle installation directory
Manual providers
If you need to manually set the property names, then you can define your own providers.
// ./settings.gradle.kts
val artifactoryUser = providers.gradleProperty("artifactory_user")
val artifactoryPassword = providers.gradleProperty("artifactory_password")
dependencyResolutionManagement {
repositories {
maven {
name = "mySecureRepository"
credentials {
username = artifactoryUser.get()
password = artifactoryPassword.get()
}
// url = uri(<<some repository url>>)
}
}
}
Again, then Gradle will fetch these properties from either
$GRADLE_USER_HOME/gradle.properties
artifactory_user=my-username
artifactory_password=my-password
or environment variables
ORG_GRADLE_PROJECT_artifactory_user=myUsername
ORG_GRADLE_PROJECT_artifactory_password=my-password

Missing checksum files when using Gradle maven-publish and signing plugins

I have a Java project that makes use of Gradle to build and package. My purpose is to create artifacts that are published to Maven Central.
As a first step, I configured my Gradle project as shown in the following example from the documentation:
https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:complete_example
When I run gradle publishToMavenLocal, I get the following files installed in my local repository:
maven-metadata-local.xml
my-library-1.0.2-SNAPSHOT.jar
my-library-1.0.2-SNAPSHOT.jar.asc
my-library-1.0.2-SNAPSHOT-javadoc.jar
my-library-1.0.2-SNAPSHOT-javadoc.jar.asc
my-library-1.0.2-SNAPSHOT.pom
my-library-1.0.2-SNAPSHOT.pom.asc
my-library-1.0.2-SNAPSHOT-sources.jar
my-library-1.0.2-SNAPSHOT-sources.jar.asc
The files are all OK. The only issue I have is that checksum files (md5 and sha1) are not generated. However, checksum files are a requirement to have artifacts deployed on Maven Central via OSS Sonatype.
How can I generate the missing checksum files? It seems the maven-publish or signing plugins do not have an option for this purpose? what is wrong?
The solution I found was to use shadow along with ant.checksum:
tasks.withType(Jar) { task ->
task.doLast {
ant.checksum algorithm: 'md5', file: it.archivePath
ant.checksum algorithm: 'sha1', file: it.archivePath
ant.checksum algorithm: 'sha-256', file: it.archivePath, fileext: '.sha256'
ant.checksum algorithm: 'sha-512', file: it.archivePath, fileext: '.sha512'
}
}
Invoking gradle publishShadowPublicationToMavenLocal will generate the signatures as needed, although won't publish them to ~/.m2.
At first I thought those signatures should have been automatic, so I opened https://github.com/johnrengelman/shadow/issues/718 to discuss.
I thought this was a bug in Gradle and I opened an issue, but as described here this actually mimics mvn install behavior. It sounds like Maven Local works a little different than a Maven Repository.
The proper way to test this locally is to use a file based repository. Since you're only using it to test (and not to actually share things with other projects) I think putting that into the build directory is best. Add the repositories section from below to the publishing block. Then when you ./gradlew publish it will publish to your build directory.
Kotlin
repositories {
maven {
// change URLs to point to your repos, e.g. http://my.org/repo
val releasesRepoUrl = uri(layout.buildDirectory.dir("repos/releases"))
val snapshotsRepoUrl = uri(layout.buildDirectory.dir("repos/snapshots"))
url = if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
}
}
Groovy
repositories {
maven {
// change URLs to point to your repos, e.g. http://my.org/repo
def releasesRepoUrl = layout.buildDirectory.dir('repos/releases')
def snapshotsRepoUrl = layout.buildDirectory.dir('repos/snapshots')
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
}
}
These two samples are actually from the link you shared. It's possible they were added later or you (like me) thought that publishToMavenLocal should behave the same as publish (apart from where the files actually go).

Gradle or Groovy - how to convert URL to file?

In Gradle I have a file stored on the Internet that I would like to access. But I can't figure out how to convert a URL to a File in Gradle. I need the url to be converted to a file so I can pass it to tasks as a file. Here is what I have so far:
allprojects {
afterEvaluate { project ->
String file = new URL('http://techslides.com/demos/samples/sample.json').file
}
}
this is definetly not what i want. The file variable ends up being: demos/samples/sample.json so it looks like it's just taking the path from the url itself.
I need the actual sample.json to be stored in a File object. I would also prefer if possible to not have to write the file to local storage where it is accessible to other people as its a secure file.
The simplest way to do this:
def fileLocation = 'file://techslides.com/demos/samples/sample.json'
def fileURL = new URL(fileLocation)
def remoteFile = new File(fileURL.toURI())
See: File(URI uri)
Replace fileLocation with valid value for your task.
As of May 4, 2018, Gradle 4.8 RC1 or later, if you are facing this problem using checkstyle, you can use
checkstyle {
toolVersion = "8.13"
config project.resources.text.fromUri("${someUrl}/checkstyle.xml")
}
See https://github.com/gradle/gradle/issues/2663

Cloning a git repo in a task by providing authentication

I want to clone a private repository in my system. I am able to clone a public repo using:
def myrepo = org.ajoberstar.grgit.Grgit.clone(dir:'', uri:'')
but in case of a private repo, I need to provide credentials to clone. I have gone through this link, but the properties given here like Force, Hardcoded are not available in my gradle. So, I am not able to make use of the properties given here.
The following properties are available for me:
org.ajoberstar.grgit.auth.AuthConfig.FORCE_OPTION
org.ajoberstar.grgit.auth.AuthConfig.USERNAME_OPTION
org.ajoberstar.grgit.auth.AuthConfig.PASSWORD_OPTION
and if I give any value to these, I get error Cannot assign value to final fields
Can anybody help with the authentication part?
I am using dependency org.ajoberstar:grgit:1.3.0.
The link you provided clearly states that system properties need to be used to pass appropriate settings.
So you need to run gradle passing all the properties via command line. Assume this is build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.ajoberstar:grgit:1.3.0'
}
}
task cloneRepo << {
org.ajoberstar.grgit.Grgit.clone(dir: '', uri: '<link to private repo>')
}
Run it with:
gradle cloneRepo -Dorg.ajoberstar.grgit.auth.username=your_username -Dorg.ajoberstar.grgit.auth.password=your_pass -Dorg.ajoberstar.grgit.auth.force=sshagent

How to retrieve the version,artifactId,package of the artifact built on Hudson

After building the artifact i am executing a script as a Post Build Action to deploy the artifact. So im trying to read the location where it is built.The environment Variables available in Hudson is not givng me enough information about the artifactId, Version, PackageType of the artifact.
So can anyone help me out on how to get the values for these....
Thanks in Advance
All artifacts built by Maven contain META-INF entries that hold this information. Read them as JarFile:
JarFile jf = new JarFile(path/to/artifact);
JarEntry propsEntry = jf.getJarEntry("META-INF/maven/pom.properties");
Properties props = new Properties();
props.load(jf.getInputStream(propsEntry));
// retrieve the values:
String groupId = props.get("groupId");
String artifactId = props.get("artifactId");
String version = props.get("version");
I might have misunderstood your question completely, but is there a reason not to pick up the artifact via the filesystem and the WORKSPACE environment variable, ${WORKSPACE}/target/...
You can use http://${BUILD_URL}/job/${JOBNAME}/${BUILDNUMBER}/api/xml?xpath=//artifact/fileName/text() and set that to an environment variable. This only works if you have 1 artifact, if you have more, then you'll need to do some additional parsing.

Resources