Как мне сгенерировать maven-metata.xml с помощью maven-publish и artifactory-gradle-plugin?

Я написал плагин Gradle в Groovy и использовал Gradle для его сборки. У меня есть сервер локальной сети Artifactory, который я публикую результаты с использованием плагина Gradle Artifactory и плагина maven-publish в Gradle. У меня есть другой скрипт сборки Gradle, который использует этот плагин в качестве зависимости. Я смог заставить все это работать, если я перечислю свою зависимость с определенной версией. Я пытался использовать диапазон версий maven (например, '[1.0,2.0)'), но это не помогло, сказав, что он не может найти maven-metadata.xml. Я проверил Artifactory, и, конечно же, его там нет. Что мне нужно сделать, чтобы произвести его, желательно во время сборки плагина?

Вот файл build.gradle для моего пользовательского плагина gradle:

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

Я искал документацию Gradle, Artifactory и Maven, чтобы понять maven-metadata.xml и узнать, как его создавать и развертывать. Имеет смысл, что это такое, и я, вероятно, мог бы создать его вручную, но я не могу найти ничего, что конкретно объясняет, как автоматически генерировать его в Gradle с помощью плагина maven-publish или artifactory-gradle-plugin. Я не хочу обновлять файл вручную, так как это сведет на нет все усилия по автоматизации, и я не хочу переходить на mvn, так как уже столько вложил в Gradle.

2 ответа

Решение

Мне нужно было добавить идентификатор группы в мою публикацию. Как только я это сделал, Artifactory создал maven-metadata.xml.

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
            groupId = 'com.group'
        }
    }
}

maven-metadata.xml должен быть обработан Artifactory. Какая у вас локальная структура репозитория в Artifactory?

У меня была та же проблема, и оказалось, что репозиторий Artifactory не был репозиторием Maven, это был репозиторий Generic. Мне потребовалась целая вечность, чтобы заметить, потому что я не создавал репо, и я предполагал, что это репо Maven, а развертывание / разрешение в противном случае работало, как ожидалось.
После переключения на репозиторий Maven файлы maven-metadata.xml были созданы при публикации.

Принятый ответ правильный. И я проголосовал за это. Однако есть и этот нюанс.

У меня многомодульный проект, поэтому я буду использовать "все проекты". Если у вас есть монолит / одинарная банка (:().., вы можете использовать другую область, отличную от "allprojects".

Ключевым моментом здесь является то, что вы устанавливаете "группу". (и версия тоже)

allprojects {

apply plugin: 'java-library'
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.artifactory'


repositories {
    jcenter()
}

group = 'com.group'

version = '1.0-SNAPSHOT'

}

Хорошо, теперь build.gradle (который в моем многомодульном проекте не является root-build.gradle) (но значения в корневом build.gradle будут аналогичными)

ниже - все содержимое моего файла build.gradle без полномочий root

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

Как говорится в ссылке, вы получите значения по умолчанию для

// groupId, artifactId и version имеют значения по умолчанию, поэтому не отменяйте произвольно: https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:publications

Вам просто нужно установить эти значения, как показано выше с помощью

group = 'com.group' 
version = '1.0-SNAPSHOT'

код

Пройдя через кофемолку несколько раз с

myCustomPublicationName(MavenPublication)

Я считаю, что чем меньше я настраиваю, тем лучше. и предпочитаю использовать значения по умолчанию... что означает установку значений, которые определяют значения по умолчанию... в build.gradle.., а не устанавливать myCustomPublicationName(MavenPublication)

изменение ценностей внутри

myCustomPublicationName(MavenPublication)

должны быть зарезервированы (ИМХО), когда значения по умолчанию не работают для вас. что обычно занимает очень мало времени.

заметка:

"${name}" в верхней части моего non-root-gradle.build заполняется структурой каталогов моего многомодульного проекта.

Я не знаю, как это работает в немульмодуле, потому что я никогда не пишу монолиты.

Пример settings.gradle в моем коде:

rootProject.name = 'com.me.myproject-rootProjectName'

include ':source:java:mydatalayer'
include ':source:java:mybizlogic'
include ':source:java:mydomain'

Бонусная цитата ниже:

Более того, модульная декомпозиция представляет собой ключевой компонент качества программного обеспечения. Если у вас сильно связанная система, когда вы настраиваете один компонент, вся система ломается. Если вы думаете об API, межмодульные границы ясны, поэтому вы можете поддерживать и улучшать один модуль, не затрагивая другие.

Массовый рефакторинг оказывается трудным. Если вы построили что-то как монолитную систему, а затем обнаружите, что у вас есть повторяющийся код повсюду, и вы хотите правильно его реорганизовать, у вас будет огромная работа. Напротив, если вы написали его как компоненты, но вы неправильно поняли некоторые границы компонентов, вы можете легко их настроить.

- Джошуа Блох, бывший главный архитектор Java в Google. Ссылка на модульную декомпозицию

Другие вопросы по тегам