Excluding files and folders during plugin publishing - gradle

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/**'
}
}
}

Related

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
}
}
}
}

How do I suppress POM and IVY related warnings in Gradle 7?

After upgrading to Gradle 7 I have many warnings like:
Cannot publish Ivy descriptor if ivyDescriptor not set in task ':myProject:artifactoryPublish' and task 'uploadArchives' does not exist.
Cannot publish pom for project ':myProject' since it does not contain the Maven plugin install task and task ':myProject:artifactoryPublish' does not specify a custom pom path.
The artifactoryPublish task works fine.
My Gradle script:
buildscript {
repositories{
maven {
url = '...'
credentials {
username '...'
password '...'
}
metadataSources {
mavenPom()
artifact()
}
}
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.24.12"
}
}
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
suppressAllPomMetadataWarnings()
}
}
}
group = '...'
artifactory {
contextUrl = '...'
publish {
repository {
repoKey = '...'
username = '...'
password = '...'
}
defaults {
publishConfigs('archives')
publishIvy = false
publications("mavenJava")
}
}
}
How do I disable those warnings?
It looks like you mixed between the old Gradle publish-configuration method and the new Gradle publication method.
You applied the maven-publish plugin which allows creating publications. In artifactory.default, you added the "mavenJava" publication as expected.
However, the archives publish-configuration doesn't exist in your build.gradle file. Basically, publish-configurations are created by the legacy maven plugin. The configured mavenJava publication does the same as the archives publish-configuration and therefore all of the JARs are published as expected.
To remove the warning messages you see, remove the publishConfigs('archives') from artifactory.default clause:
artifactory {
publish {
defaults {
publishConfigs('archives') // <-- Remove this line
publishIvy = false
publications("mavenJava")
}
}
}
Read more:
Gradle Artifactory plugin documentation
Example

publish groovy doc with gradle

I have a project with about 50% Java code and 50% Groovy that i try to publish to Sonatype ossrh. Publishing snapshots goes well but the docs jar is missing (both when publishing locally and publishing to Sonatype Nexus). I can create the combined groovy/java docs by defining:
groovydoc {
use = true
groovyClasspath = configurations.compile // http://issues.gradle.org/browse/GRADLE-1391
}
task groovydocJar(type: Jar, dependsOn: groovydoc ) {
classifier 'javadoc' // must use javadoc classifier to be able to deploy to Sonatype
from groovydoc.destinationDir
}
and running ./gradlew groovydocJar produces the intended -javadoc.jar without problems.
My issue is that this docs jar is not included the publish task.
I tried the following
publishing {
publications {
maven(MavenPublication) {
from components.java
artifacts {
archives sourcesJar
archives groovydocJar
}
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
pom {
// omitted for brevity
}
}
}
}
... but e.g. `./gradlew publishToMavenLocal` publishes only the classes jar, the pom, a module and the sources jar.
No sign of a javadoc jar. I thought this was the idea of the artifacts section but maybe something is missing.
How can i tell the publishing task to include publishing of the groovydocs jar?
Gradle version is 6.8.3, jvm version is 1.8 and i depend on `compile 'org.codehaus.groovy:groovy-all:3.0.7'`
The complete build script is available here:
https://github.com/perNyfelt/ProjectDeployer/blob/main/build.gradle
I figured it out:
That artifacts.archives way was not working.
The syntax for adding the groovy doc is like this:
publishing {
publications {
maven(MavenPublication) {
from components.java
artifact(groovydocJar) {
classifier = 'javadoc'
}
// etc...
}
}
}

I want to publish multiple artifacts with different names with gradle and maven-publish

I have a library containing usual classes and those especially for unit tests. So I want to publish two separate artifacts from the same project. My working solution with the maven plugin looks like this:
task jarTest (type: Jar, dependsOn: testClasses) {
from sourceSets.test.output
archiveBaseName.set('foo-test')
description = 'test utilities'
}
artifacts {
archives jarTest
}
uploadArchives {
repositories {
mavenDeployer {
//...
addFilter('foo') {artifact, file ->
artifact.name == 'foo'
}
addFilter('foo-test') {artifact, file ->
artifact.name == 'foo-test'
}
}
}
}
Unfortunately the maven plugin is deprecated and will be removed in Gradle 7. maven-publish is the suggested replacement and I'm looking for a replacement solution.
My current attempt looks like
publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
artifact jarTest
}
}
}
There is the obvious problem that there are two artifacts with the same name.
Setting the name like this does not work:
artifactId = jar.archiveBaseName
this neither:
afterEvaluate {
artifactId = jar.archiveBaseName
}
It's possible to configure the artifact like this
artifact(jar) {
classifier "src"
extension "zip"
}
But there is no property for the name regarding the documentation (https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenArtifact.html).
So I'm looking for sth. like the addFilter from the maven plugin.

Publishing custom artifact built from task in gradle

I am having some issues trying to create a task that build a special file which is then uploaded to artifactory.
Heres a simplified version:
apply plugin: 'maven-publish'
task myTask {
ext.destination = file('myfile')
doLast {
// Here it should build the file
}
}
publishing {
repositories {
maven {
name 'ArtifactoryDevDirectory'
url 'http://artifactory/artifactory/repo-dev'
credentials {
username 'username'
password 'password'
}
}
}
publications {
MyJar(MavenPublication) {
artifactId "test"
version "1.0"
groupId "org.example"
artifact myTask.destination
}
}
}
This works, except that gradle publish does not run myTask. I tried adding
publishMyJarPublicationToArtifactoryDevDirectoryRepository.dependsOn myTask
but i just get:
Could not find property 'publishMyJarPublicationToArtifactoryDevDirectoryRepository' on root project 'test'.
I tried messing about with the artifact, adding a custom artifact and configuration and publishing that instead but that did not work either.
Any help would be greatly appreciated.
afterEvaluate {
publishMyJarPublicationToArtifactoryDevDirectoryRepository.dependsOn myTask
}
Accomplishes what I want.

Resources