Exclude root project dependency from custom configuration


(mvm) #1

Hello everyone!
I’ve been using Gradle for the past year, but this is the first time something has puzzled me hard enough to ask for help in the forums.

Let me start by clarifying that I am building several small tasks that will compose the pipeline of my project. That pipeline will do the usual: build a project, do a release, push to Artifactory, pull the artifact to create a Docker image and deploy that somewhere. The idea is to have Jenkins execute these tasks.
The bit that makes me struggle is pulling the artifact from Artifactory. I found this answer on the forums and thought it was a really neat way to achieve the result.

However, in my scenario I’d be pulling the artifact from a task in the same project that will be pushing it, thus, group and name turn out to be the same. This is causing Gradle to resolve the artifact even if it does not exist in the remote Artifactory repo. Here is what I got so far:

configurations {
    pipeline
}

repositories {
    maven {
        url artifactory_url + '/libs-release'
    }
}

dependencies {
    pipeline group: project.group, name: project.name, version: version, ext: 'jar'
}

task printDeps() {
    doLast {
      configurations.pipeline.resolvedConfiguration.lenientConfiguration.getFiles(Specs.SATISFIES_ALL).each {
            println it
      }
      configurations.pipeline.resolvedConfiguration.resolvedArtifacts.each {
            println it
      }
    } 
}

The output of the printDeps task is the following, even after I clean the project and there is no /build folder:

/home/mvm/git/work/app-name/build/libs/app-name-0.2.0.jar
app-name.jar (project :)

What I would like to achieve is being able to bring the jar from Artifactory and use it to generate a Docker image. If the jar is not found, I don’t want the project to fail building or on configuration stage (that’s why I am using the lenientConfiguration). However, I would like the specific task that stages the files for the Docker image creation to fail if invoked and the jar is not found.
The way it is now, it always “finds” some artifact and packages it into a jar. I want to avoid this happening as it could end up building an image and deploying it with nothing inside.

For the sake of completeness, this is what I am using (probably the onlyIf block can be removed if there is a way to make this work):

task stageApp(type: Copy) {
  onlyIf {
      if (configurations.pipeline.resolvedConfiguration.resolvedArtifacts.isEmpty()) {
          throw new GradleException('Main project artifact not found on Artifactory!')
      }
      return true
  }
  from(configurations.pipeline.resolvedConfiguration.lenientConfiguration.getFiles(Specs.SATISFIES_ALL)) {
      include "*.jar"
      rename { "${project.name}.jar" }
  }
  from(fileTree("${projectDir}/config/${env}").files) {
      include "configuration.yml"
  }
  into("${rootDir}/docker/${project.name}")
}

I would be very grateful for any help or guidance :slight_smile: