Publishing non-jar files in gradle - gradle

I am having a set of files (specifically a set of json documents) that I need to publish to my Maven repository.
How do I use publishing and specify the directory in the artifact.
publications {
myPublication(MavenPublication) {
artifact(/path/to/dir>) // directory that contains files to publish
}
}

You can create a task to zip all your documents and then publish the zip.
task jsonZip(type: Zip) {
source file(/path/to/dir)
}
publications {
myPublication(MavenPublication) {
artifact jsonZip.archivePath
}
}

Related

How do I publish file created by zip task in gradle

I'd like to publish the output of my custom zip task to a maven repo. My problem is that when I set the artifact of the publication as the zip task, the file that gets zipped is not what gets published. Instead what gets published is the value given to the "from" argument of my custom zip task. How would I make it so that "jar.zip" is the file that is published?
tasks.register('zipJars', Zip) {
archiveFileName = "jar.zip"
destinationDirectory = layout.buildDirectory.dir("${projectDir.parentFile}/DesktopAndroid/jars/zipped")
from fatJarDev
}
publishing {
publications {
apkBuilding(MavenPublication){
artifact zipJars
}
}
repositories {
maven {
name = 'Local'
url = "file://${rootDir}/Repository"
}
}
}```
Ah - are you referring to the name of the file in the maven repo ? you will need to customise it in publication ;
see https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html
publishing {
publications {
apkBuilding(MavenPublication){
artifact zipJars
artifactId 'zipjars'
}
}
repositories {
maven {
name = 'Local'
url = "file://${rootDir}/Repository"
}
}
}

publish pre-built jars to nexus repo using gradle

I am trying to publish obfuscated jars to nexus repo.
I created a task to obfuscate the code using proguard, then a task that copy the obfuscated jars into build folder.
task proguard (type: proguard.gradle.ProGuardTask) {
println("Performing Obfuscation ..")
configuration 'proguard.conf'
subprojects { porject ->
injars "${projectDir}/build/libs/${porject.name}-${rootProject.version}.jar"
outjars "${projectDir}/build/libs/obfuscated/${porject.name}-${rootProject.version}.jar"
}
libraryjars "/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar"
}
task postProguard (){
doFirst{
println("Deleting Non Obfuscated jars")
subprojects { project ->
delete "${projectDir}/build/libs/${project.name}-${rootProject.version}.jar"
}
println("Copying Obfuscated Jars")
subprojects { project ->
copy {
from "${projectDir}/build/libs/obfuscated/"
into "${projectDir}/build/libs/"
include '*.jar'
}
}
}
}
proguard.finalizedBy postProguard
the issue is when I run ./gradlew publish the project gets re-built and the jars gets changed to non obfuscated again.
I tried to change the publishing task but without results.
publishing {
if(new File("${projectDir}/build/libs/obfuscated").exists()){
publications {
maven(MavenPublication) {
artifact "${projectDir}/build/libs/${project.name}-${rootProject.version}.jar"
pom.withXml {
def dependency = asNode().appendNode('dependencies').appendNode('dependency')
dependency.appendNode("groupId", "${project.name}")
dependency.appendNode("artifactId", "${project.name}")
dependency.appendNode("version", "${rootProject.version}")
}
}
}
}
repositories {
maven {
name = 'maven-snapshots'
url = ***
}
}
}
I added a builtBy attribute to the publication here is a working code
publications {
if(new File("${projectDir}/build/libs/obfuscated").exists()){
maven(MavenPublication) {
artifact ("${projectDir}/build/libs/${project.name}-${rootProject.version}.jar"){
builtBy postProguard
}
}
}
}

Move publishing configuration to one place in gradle

I have a project which has modules, my goal is to configure publishing after each module is built and after all modules are built, so I could create a zip file with all the jars inside and upload it as well. I do it in subprojects section and in outer section.
publishing {
publications {
mavenJava(MavenPublication) {
//my artifacts here
}
}
repositories {
maven {
url "${artifactoryURL}"
credentials {
username = "${artifactoryUsername}"
password = "${artifactoryPassword}"
}
}
}
}
Is there a way to move repositories configuration to one place, so I could avoid duplication of this configuration?
I guess that you're creating your deployables in a top-level (root, parent) project, that does not have any sources.
Is there a way to move repositories configuration to one place, so I could avoid duplication of this configuration?
Sure. Just use subprojects, allprojects or generic configure, depending on your needs:
allprojects {
id 'maven-publish'
publishing {
repositories {
maven {
url "http://maven.repo"
}
}
}
}
This will configure publishing for all the projects (be aware of that you may not want to publish everything).
For a projects with Java source you can configure publishing like usual:
subprojects {
publishing {
publications {
main(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
}
}
}
}
And for root project just configure deployments as in your previous question.

Excluding files and folders during plugin publishing

I want to exclude .svn folders when I publish my plugin to our custom Artifactory repository. I'm assuming the inclusion of .svn folders is the issue based on the error strack trace provided below.
I'm publishing using the following command:
gradlew artifactoryPublish --stacktrace
This is the publishing block in build.gradle:
artifactory {
contextUrl = artifactory_context
publish {
repository {
repoKey = 'plugins-release-local'
username = artifactory_user
password = artifactory_password
maven = true
}
defaults {
publications ('mavenJava')
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
This is the stack trace I get when I attempt to publish, notice the attempt copy of .svn/entries to assets/entries.
...
:copyAssets FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':copyAssets'.
> Could not copy file '/u01/var/build/pluginXYZ/grails-app/assets/.svn/entries' to '/u01/var/build/pluginXYZ/build/resources/main/META-INF/assets/entries'.
* Try:
Run with --info or --debug option to get more log output.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':copyAssets'.
...
Caused by: org.gradle.api.GradleException: Could not copy file '/u01/var/build/pluginXYZ/grails-app/assets/.svn/entries' to '/u01/var/build/pluginXYZ/build/resources/main/META-INF/assets/entries'.
...
Caused by: java.io.FileNotFoundException: /u01/var/build/pluginXYZ/build/resources/main/META-INF/assets/entries (Permission denied)
... 80 more
The permission on entries (both trees) are -r--r--r--.
If I exclude those folders, I should get rid of said permission issue. The first checkout will always publish, but subsequent publishes (say after an update), fail with this error.
Update #2
Here are the three combination I tried without success:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
//first attempt
//exclude("**/.svn/**")
//second attempt
//exclude{ details -> details.file.name.contains(".svn") }
//third attempt
//exclude "**/.svn/**"
}
}
}
The error output when publishing, using all three attempts, is the following:
Caused by: org.gradle.api.internal.MissingMethodException: Could not find method exclude() for arguments [build_3nsvrqvwahy23ir3fxdj970id$_run_closure7_closure13_closure14_closure15#10e9a5fe] on org.gradlpublish.maven.internal.publication.DefaultMavenPublication_Decorated#ca7e37f.
Update #3
I found the following link taking about excluding files.
I then adjusted my gradle.build to this:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java {
exclude "**/.svn/**"
}
}
}
}
Same error.
Update #4
More attempts... same results
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar{
exclude '**/.svn/**'
}
}
}
}
or
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact exclude '**/.svn/**'
}
}
}
Say, you have a file which you want to avoid ONLY while publishing to the repository. If you go with as suggested by #TekiusFanatikus
sourceSets {
main {
java {
exclude '**/.svn/**'
}
}
}
you will be able to achieve it but this will also exclude the file/folder etc. from the artifact that you generate using gradle build.
Instead, I would recommend to use the approach as mentioned here gradle documnetation
You can create a task which have your desired exclusion applied
task apiJar(type: Jar) {
baseName "publishing-api"
from sourceSets.main.output
exclude '**/.svn/**'
}
and then refer the task while publishing.
publishing {
publications {
api(MavenPublication) {
groupId 'org.gradle.sample'
artifactId 'project2-api'
version '2'
artifact apiJar
}
}
}
This way, the jar that gets published will not have .svn folder. The point that I wanted to make here is that it will not touch your artifact that gets created using gradle build. It will still have your .svn folder.
But if you want it to be removed from both the places, then the best option is as suggested above.
I would like to extend on #Neeraj answer. The problem with the custom JAR approach is that it doesn't produce a valid POM -- especially not in the case of multi-module projects -- unlike the from components.java approach which generates a POM correctly.
In order to overcome this, we could declare two publications - one internal used only to generate a POM, and the second is the actual publication we wish to publish (without the excluded files):
task apiJar(type: Jar) {
baseName "publishing-api"
from sourceSets.main.output
exclude '**/.svn/**'
}
publishing {
publications {
def pomString = null
internal(MavenPublication) {
from components.java
pom.withXml {
pomString = asString().toString()
}
}
api(MavenPublication) {
artifact apiJar
pom.withXml {
def builder = asString()
builder.delete(0, builder.length())
builder.append(pomString)
}
}
}
}
generatePomFileForApiPublication.dependsOn(generatePomFileForInternalPublication)
artifactoryPublish {
publications('api')
}
Note that the names of the generatePomFileForXPublication tasks are determined according to the names of the publications.
Old Answer
This is my previous attempt at generating a POM manually, but it is not nearly as complete as the newer answer above.
task apiJar(type: Jar) {
baseName "publishing-api"
from sourceSets.main.output
exclude '**/.svn/**'
}
publishing {
publications {
api(MavenPublication) {
artifact apiJar
pom.withXml {
def dependenciesNode = asNode().appendNode("dependencies")
project.configurations.runtimeClasspath.resolvedConfiguration.firstLevelModuleDependencies.forEach { d ->
def dependencyNode = dependenciesNode.appendNode("dependency")
dependencyNode.appendNode("groupId", d.moduleGroup)
dependencyNode.appendNode("artifactId", d.moduleName)
dependencyNode.appendNode("version", d.moduleVersion)
}
}
}
}
}
artifactoryPublish {
publications('api')
}
I think you can use 'exclude' method with filefilter. Just add it under 'from' in publications block.
I appended the following at the root level in my build.gradle and it seems to work:
sourceSets {
main {
java {
exclude '**/.svn/**'
}
}
}

Gradle: How to upload custom JAR file to Maven repository

I build a jar file without using Gradle Jar task (I need to be using Ant task for that inside my task). How do I configure uploadArchives to be able to install JAR in specified repository.
I have tried to override default artifact with
uploadArchives {
repositories {
mavenDeployer {
// some Maven configuration
}
}
}
artifacts {
archives file: file('bin/result.jar')
}
but I'm getting an error that there may not be 2 artifacts with the same type and classifier, which means this configuration adds rather that overrides configuration.
You are right, artifacts closure can only add artifacts to the given configuration (see ArtifactHandler API).
You have two options:
1) Add an artifact filter as described here (see ch. 45.6.4.1. "Multiple artifacts per project"). If you use this, try declaring your archives configuration like:
artifacts {
archives file: file('bin/result.jar'), name: 'result', type: 'jar'
}
This way, you something like this in your artifact filter:
addFilter('result') {artifact, file ->
artifact.name == 'result'
}
2) Upload it as a separate maven module. If result.jar is the only jar you are uploading this may be a good solution.
configurations {
resultArchives
}
uploadResultArchives {
repositories {
mavenDeployer {
repository(url: "same/url/here")
}
}
}
artifacts{
resultArchives file: file('bin/result.jar')
}
Hope this helps.

Resources