Unable to publish the 'Last Verified' status in PACT Broker - gradle

For microservices contract tests, am using PACT with gradle 4.4 and here is my build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'au.com.dius:pact-jvm-provider-gradle_2.12:3.5.22'
}
}
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'eclipse'
apply plugin: "au.com.dius.pact"
pact {
serviceProviders {
// You can define as many as you need, but each must have a unique name
UserService {
// All the provider properties are optional, and have sensible defaults (shown below)
protocol = 'http'
host = 'localhost'
port = 8111
project.version = "2.0.1"
hasPactsFromPactBroker('http://10.100.198.200:8113')
}
}
pact {
publish {
version = "2.0.1"
pactDirectory = 'pacts' // defaults to $buildDir/pacts
pactBrokerUrl = 'http://10.100.198.200:8113'
}
}
}
While am able to publish the pact files in the broker and able to see the dependency graphs, 'Last Verified' shows blank after running the pactVerify method. I saw some documentation around 'pact.verifier.publishResults=true' and tried to pass as gradle parameter, but I got an error message saying:
FAILURE: Build failed with an exception.
What went wrong:
Your project is misconfigured, was expecting a 'pact' configuration in the build, but got a String with value '' instead. Make sure there is no property that is overriding 'pact'.
the gradle command I run is:
./gradlew test pactPublish
./gradlew pactVerify -Ppact.verifier.publishResults=true
Please let me know what am I missing, the pact.verifier.publishResults is not accepted

The first thing is your Gradle config is invalid. There should only be one pact block. You have two. Remove the inner one with the publish block in it (but leave the publish block :-D).
If that does not resolve your issue, have a look at https://github.com/DiUS/pact-jvm/issues/738 and see if any of the changes from the comments helps.

Related

Gradle: Invalid publication 'maven': artifact file does not exist

Java 11 and Gradle 7.2 here. I am trying to build a reusable library that I can (eventually) publish to a Maven repository and pull into other projects. But first I just want to get it publishing to my local m2 repo.
The project directory structure looks like:
mylib/
lib/
src/
build.gradle
Where build.gradle is:
plugins {
id 'java-library'
id 'maven-publish'
id 'io.freefair.lombok' version "6.5.0-rc1"
}
sourceCompatibility = 1.11
targetCompatibility = 1.11
archivesBaseName = 'mylib'
version = '1.0.0-RC1'
group = 'org.example'
repositories {
mavenCentral()
}
dependencies {
// omitted for brevity
)
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
}
publishing {
publications {
maven(MavenPublication) {
artifact("build/libs/${archivesBaseName}-${version}.jar") {
extension 'jar'
}
}
}
}
tasks.named('test') {
useJUnitPlatform()
}
publishToMavenLocal.configure {
mustRunAfter build
}
When I run gradle publishToMavenLocal I get:
% ./gradlew clean build publishToMavenLocal
> Task :lib:publishMavenPublicationToMavenLocal FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':lib:publishMavenPublicationToMavenLocal'.
> Failed to publish publication 'maven' to repository 'mavenLocal'
> Invalid publication 'maven': artifact file does not exist: '/Users/myuser/workspace/mylib/lib/build/libs/mylib-1.0.0-RC1.jar'
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 833ms
6 actionable tasks: 6 executed
So it looks like even though I'm specifying (on the command line) to run clean then build then publishToMavenLocal, and even though I'm even specifying (in build.gradle) that publishToMavenLocal must run after build, it seems what is happening is:
publishToMavenLocal insists on running first (before clean or build)
Since the JAR hasn't been built yet, no JAR file exists at the location specified ("build/libs/${archivesBaseName}-${version}.jar")
The build fails because the artifact doesn't exist
So I think I just need to get build to run before publishToMavenLocal but I'm out of ideas.
You're mixing the plugins DSL (plugins { }) with legacy plugin application (apply plugin). That's not a big deal, but you should go with #sean's answer and use the plugins DSL instead which will solve your issue.
To your problem at hand
Could not get unknown property 'plugin'
That happens because you missed the : in apply plugin
apply plugin: 'maven-publish'
Try placing your plugins in this way. Not sure if that resolves your issue though.
plugins {
id 'java-library'
id 'maven-publish'
}

gradle init script can't apply artifactory plugin

I'm trying to offload build logic into a gradle init script, which gets included in a custom gradle wrapper. It seems promising. One of the things I need to do is to apply the artifactory plugin prior to configuring it, while the following code works fine in build.gradle, it fails to find the plugin when the code is shifted into an init script.
build.gradle:
buildscript{
Properties properties = new Properties()
properties.load(new File(gradle.getGradleUserHomeDir(), 'gradle.properties').newDataInputStream())
repositories {
maven {
url properties.artifactory_contextUrl + '/gradle-plugins-virtual'
credentials {
username = properties.artifactory_user
password = properties.artifactory_password
}
}
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.17.2"
}
}
apply plugin: "com.jfrog.artifactory"
and in the init script it's almost the same:
initscript{
Properties properties = new Properties()
properties.load(new File(getGradleUserHomeDir(), 'gradle.properties').newDataInputStream())
repositories {
maven {
url properties.artifactory_contextUrl + '/gradle-plugins-virtual'
credentials {
username = properties.artifactory_user
password = properties.artifactory_password
}
}
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.17.2"
}
}
apply plugin: "com.jfrog.artifactory"
but I get Plugin with id 'com.jfrog.artifactory' not found. with this attempt.
I have also tried making an init plugin, but my plugin skills are not strong, and it also seems to fail.
I tried moving just the apply plugin line to build.gradle from the init script but that also fails, indicating it might be the dependency resolution. How can I debug this further?
I did a build scan and it appears that the plugin jar was found okay.
org.jfrog.buildinfo:build-info-extractor-gradle:4.17.2
commons-io:commons-io:2.7
commons-lang:commons-lang:2.4
commons-logging:commons-logging:1.1.1
1.2
org.apache.ivy:ivy:2.2.0
org.jfrog.buildinfo:build-info-extractor:2.19.2
Any help, comments, suggestions appreciated.
Rant: gradle docs have far too few examples.
For gradle init script, you must use the fully qualified class name of the plugin instead of the id.
Like this:
apply plugin: org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin

Plugin with id 'org.ajoberstar.grgit' not found

I'm trying to compile an opensource minecraft mod called VeinMiner.
I use ./gradlew build to compile it.
However it failed and give me this reason:
FAILURE: Build failed with an exception.
* Where:
Build file '/home/xxxx/Desktop/VeinMiner/build.gradle' line: 26
* What went wrong:
A problem occurred evaluating root project 'VeinMiner'.
> Plugin with id 'org.ajoberstar.grgit' not found.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 14.778 secs
I have tried to git clone it again or run it in sudo.
However, neither of these two work.
This build gradle is like this:
(It's too long so I select some part of it)
buildscript {
repositories {
mavenCentral()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
}
}
plugins {
id 'com.matthewprenger.cursegradle' version '1.0.7'
id 'org.ajoberstar.grgit' version '1.3.2'
}
apply plugin: 'forge'
apply plugin: 'maven'
apply plugin: "org.ajoberstar.grgit"
apply plugin: "com.matthewprenger.cursegradle"
ext.git = grgit.open(file('.'))
ext {
configFile = file "build.properties"
revision = git.head().abbreviatedId
depth = git.log().size()
}
I expected to Build Successful. Have anyone met this situation?
The mentioned plugin org.ajoberstar.grgit gets applied twice. The first time it gets applied via the new plugins block, the second time via the old apply plugin: method. Simply remove the line apply plugin: "org.ajoberstar.grgit" and the error should disappear.
To apply plugins via the old apply plugin: method, the plugin package needs to be resolved from an arbitrary repository inside the buildscript block. This works in the same way as resolving project dependencies via the normal repositories and dependencies blocks.
The new plugins block directly resolves plugins from the Gradle plugin portal and applies them in the same step.
I would guess that the way how to apply to plugin was changed to the newer one, but the removal of the old method did not happen. In existing setups the plugin may have been resolved from the local Gradle cache, but on your new setup it could not be found.

Applying Gradle Dependency-Check plugin

I am trying to use the dependency.check from the following link and have been unable to get it to run properly (at all) when following the instructions given.
https://github.com/jeremylong/DependencyCheck/tree/master/dependency-check-gradle
When trying to build with the apply plugin and additional dependency the fails on startup and it throws the following error.
Where:
Build file '/Users/aaron/work/backups/eiss/build.gradle' line: 25
What went wrong:
A problem occurred evaluating root project 'eiss'.
Failed to apply plugin [id 'dependency.check']
Plugin with id 'dependency.check' not found.
I made a little progress when making some changes but was still ultimately unsuccessful.
First, I commented out the apply plugin line.
Next, I switched:
classpath "com.thoughtworks.tools:dependency-check:0.0.7"
over to:
compile "com.thoughtworks.tools:dependency-check:0.0.7"
After these two changes it began recognizing the path and I was able to see it grabbing the items from the repository.
Even with the path correct I am still having issues with the apply plugin line with it throwing the same error whenever I place it into the script or even try to change the '.' in it into a '-' (both are used in the instructions and in different repository examples).
Any help on this issue would be appreciated! Thanks
lastly here is the build.gradle script. I didn't want to just leave this blob right in the center of the post.
defaultTasks 'assemble'
// For third party libs that are widely used, keep versions in one place
ext {
MONGO_JAVA_DRIVER = "org.mongodb:mongo-java-driver:2.12.3"
RABBITMQ_VERSION = "com.rabbitmq:amqp-client:3.4.3"
LOG4J = "log4j:log4j:1.2.16"
// For groovy there are multiple libs, just capture version number and use lib-name-$GROOVY_VERSION
GROOVY_VERSION = "2.3.6"
}
//
// Common settings for all projects
//
subprojects {
defaultTasks 'assemble'
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'codenarc'
apply plugin: 'dependency.check'
targetCompatibility = "1.6"
sourceCompatibility = "1.6"
repositories {
mavenCentral()
}
dependencies {
compile LOG4J
compile "org.codehaus.groovy:groovy:${GROOVY_VERSION}"
compile "org.codehaus.groovy:groovy-json:${GROOVY_VERSION}"
compile "org.codehaus.groovy:groovy-templates:${GROOVY_VERSION}"
compile "com.thoughtworks.tools:dependency-check:0.0.7"
testCompile group: 'junit', name: 'junit', version: '4.+'
testCompile "org.codehaus.groovy:groovy-test:${GROOVY_VERSION}"
testCompile "org.hamcrest:hamcrest-core:1.3"
}
clean.doLast {
// The archive path is configured via the jar tasks. Can't use
// delete jar.archivePath because that will configure the delete with
// the wrong (default) path of build/libs/<component.jar>
jar.archivePath.delete()
jarSources.archivePath.delete()
}
//--------------------------------------------------------------------
// Run and test
//--------------------------------------------------------------------
test {
// Uncomment to see standard output when running tests
testLogging.showStandardStreams = true
// This causes tests to run even when nothing has changed
outputs.upToDateWhen { false }
maxParallelForks = 1
}
task runClass(dependsOn: 'classes', type: JavaExec) {
if (project.hasProperty('classToRun')) {
if (project.hasProperty('arguments')) {
args(arguments.split(','))
}
classpath = sourceSets.main.runtimeClasspath
main=classToRun
}
}
//run this task to create source jars
task jarSources(type:Jar){
destinationDir = new File(projectDir.parent + "/sourcelibs")
from sourceSets.main.allSource
classifier 'sources'
}
}
You added plugin dependency in a wrong place, to the dependencies of your project, not a build script itself, which will use it. Try to add buildscript dependencies, as it's made in the example of plugin installation
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.thoughtworks.tools:dependency-check:0.0.7'
}
}
And then return your apply plugin
apply plugin: 'dependency.check'
Though this is very old post, accepted answer is using legacy plugin application, whereas below could be used while using the plugins DSL: https://plugins.gradle.org/plugin/org.owasp.dependencycheck
plugins {
id "org.owasp.dependencycheck" version "7.3.0"
}
With recent version of gradle it is below steps
add id 'com.diffplug.spotless' version '6.3.0' in plugins section like
plugins {
id 'com.diffplug.spotless' version '6.3.0'
}
And define your task to generate required format reports. Here for e.g. xml and json will be generated along with the html report
dependencyCheck{
formats=['xml','json']
check.dependsOn(dependencyCheckAnalyze)
}
And this can be integrated with Sonar by adding below properties to sonare.properties file (Provide dependency plugin is installed already on the sonar)
sonar.dependencyCheck.xmlReportPath=build/reports/dependency-check-report.xml
sonar.dependencyCheck.jsonReportPath=build/reports/dependency-check-report.json
sonar.dependencyCheck.htmlReportPath=build/reports/dependency-check-report.html

How do I generate maven-metata.xml with maven-publish and the artifactory-gradle-plugin?

I've written a Gradle plugin in groovy and used Gradle to build it. I've got a local network Artifactory server that I publish the results to using the Gradle Artifactory plugin and the maven-publish plugin in Gradle. I have another Gradle build script that relies on this plugin as a dependency. I've been able to get this all working if I list my dependency with a specific version. I've tried to use a maven version range (ex. '[1.0,2.0)'), but this fails saying it can't find maven-metadata.xml. I checked Artifactory, and sure enough, it isn't there. What do I need to do to produce it, preferably during the build of the plugin?
Here is the build.gradle file for my custom gradle plugin:
buildscript {
repositories {
maven {
url "${artifactory_contextUrl}/plugins-release"
credentials {
username = "${artifactory_user}"
password = "${artifactory_password}"
}
}
}
dependencies {
classpath group: 'org.apache.directory.studio', name: 'org.apache.commons.io', version: '2.4'
classpath group: 'org.jfrog.buildinfo', name: 'build-info-extractor-gradle', version: '2.0.9'
}
}
plugins {
id 'com.jfrog.artifactory' version '3.0.1'
}
apply plugin: 'groovy'
apply plugin: 'maven-publish'
artifactory {
contextUrl = "${artifactory_contextUrl}"
publish {
repository {
repoKey = 'plugins-snapshot-local'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
defaults {
publications ('mavenJava')
}
}
resolve {
repository {
repoKey = 'libs-release'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
dependencies {
compile gradleApi()
compile localGroovy()
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
I've searched the Gradle, Artifactory, and Maven documentation to understand maven-metadata.xml and how to generate and deploy. It makes sense what it is, and I could probably build one manually, but I can't find anything that explains specifically how to automatically generate it in Gradle with either the maven-publish plugin or the artifactory-gradle-plugin. I don't want to have to manually update the file since that would defeat the automation effort, and I don't want to switch to mvn since I've already invested so much in Gradle.
A groupId had to be added to the publications section. Once implemented, a maven-metadata.xml file was published to the artifact repository.
publishing {
publications {
mavenJava(MavenPublication) {
groupId = 'com.group'
}
}
}
I had the same problem and it turned out that the Artifactory repository was not a Maven repo, it was a Generic repo. It took me forever to notice because I didn't create the repo and I assumed it was a Maven repo, and deploying/resolving otherwise was working as expected.
After switching to a Maven repo, the maven-metadata.xml's were generated upon publishing.
maven-metadata.xml should be handled by Artifactory.
What is your local repository layout in Artifactory?
The accepted answer is correct. And I upvoted it. However, there is also this caveat.
I have a multi module project, so I will use "allprojects". If you have a monolith/single-jar ( :( ).. you can use use a different scope than "allprojects".
They key here is that you set the "group". (and version as well)
allprojects {
apply plugin: 'java-library'
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.artifactory'
repositories {
jcenter()
}
group = 'com.group'
version = '1.0-SNAPSHOT'
}
Ok, now build.gradle (which in my multi-module project is not the root-build.gradle) (but values in a root build.gradle would be similar)
below is the entire contents of my non-root build.gradle file
// the "name" variable inside the publications/myPublicationName block is getting overwritten. so create a variable here to capture the name (as the artifactid)
def artifactIdForPublicationBlockHolder = "${name}"
dependencies {
testImplementation group: 'junit', name: 'junit', version: junitVersion
}
println("hey.here.read.me")
println("group=${group}")
println("version=${version}")
println("artifactId=${name}")
publishing {
publications {
myCustomPublicationName(MavenPublication) {
// groupId, artifactId and version have defaults, so do not arbitrarily override : https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:publications
//your value below could be slightly different, look for *.jar after you do ./gradlew. build (note, this path value (of "./") is relative to the non-root-build.gradle path, not the overall root-build.gradle
"./build/libs/${artifactIdForPublicationBlockHolder}-${version}.jar"
}
}
}
As the link says, you'll get defaults for
// groupId, artifactId and version have defaults, so do not arbitrarily override : https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:publications
You just have to set these values, like I show above with the
group = 'com.group'
version = '1.0-SNAPSHOT'
code
After going thru the grinder a few times with the
myCustomPublicationName(MavenPublication)
I find the least amount of stuff I custom-set, the better. and prefer to piggy back on the defaults...which means setting the values which drive the defaults... in the build.gradle .. and not to set the myCustomPublicationName(MavenPublication)
altering the values inside
myCustomPublicationName(MavenPublication)
should be reserved (IMHO) to when the defaults don't work for you. which usually is a very small minority of time.
note:
"${name}" at the top of my non-root-gradle.build is getting populated by the directory structure of my multi-module project.
i don't know how it works in a non multi-module since i never write monoliths.
settings.gradle example in my code:
rootProject.name = 'com.me.myproject-rootProjectName'
include ':source:java:mydatalayer'
include ':source:java:mybizlogic'
include ':source:java:mydomain'
Bonus Quote below:
Moreover, modular decomposition represents a key component of software
quality. If you have a tightly coupled system, when you tweak one
component, the whole system breaks. If you thought in terms of APIs,
the intermodular boundaries are clear, so you can maintain and improve
one module without affecting the others.
Massive refactorings prove difficult. If you built something as a
monolithic system and then find you had repeated code all over the
place, and you want to refactor it properly, you'll have a massive
job. In contrast, if you wrote it as components, but you got some of
the component boundaries a little wrong, you can tweak them easily.
-- Joshua Bloch, former Chief Java Architect at Google. Modular Decomposition Link

Resources