Gradle - плагин maven-publish: как публиковать только конкретную публикацию в репозитории

У нас есть два разных артефакта, которые будут опубликованы в двух разных репозиториях maven.

  • " ProjectXMergedWar" должен быть опубликован в " MyMavenRepo1" (моментальные снимки)
  • " ProjectXJarRelease" следует опубликовать в MyMavenRepo2 "(выпуск)
  • "ProjectXMergedWar" никогда не должен публиковаться в "MyMavenRepo2" (выпуск)
  • "ProjectXJarRelease" никогда не должен публиковаться в "MyMavenRepo1" (моментальные снимки).

Мы используем плагин maven-publish, где вы настраиваете набор публикаций и репозиториев. Затем плагин создает задачи для всех комбинаций публикаций и репозиториев (см. Список задач внизу). В настоящее время задачи publish и publishRelease делают то, что мы хотим, но есть задачи, которые нам не нужны.

Некоторые решения могут быть:

  • Можем ли мы удалить ненужные задачи **?
  • Можем ли мы настроить maven-publish для генерировать только две задачи публикации (требуемые задачи *)?
  • Можно ли назвать правильные классы напрямую (repo.publish(artifact) или что-то в этом роде)?

Я посмотрел исходный код PublishToMavenRepository. Кажется, что действие, которое я хочу достичь, находится в protected void doPublish.

* Требуемые задачи:

  • publishProjectXMergedWarPublicationToMyMavenRepo1Repository + generatePom
  • publishProjectXJarReleasePublicationToMyMavenRepo2Repository + generatePom

* * Нежелательные задачи:

  • publishProjectXMergedWarPublicationToMyMavenRepo2Repository
  • publishProjectXJarReleasePublicationToMyMavenRepo1Repository

Gradle файл:

apply plugin: 'maven-publish'
publishing {
    publications {
        ProjectXMergedWar(MavenPublication) {
            artifact mergeWar
            artifactId = 'projectx'
        }
        ProjectXJarRelease(MavenPublication) {
            artifact releaseJar
            artifactId = 'projectx'
        }
    }
    repositories {
        maven {
            name 'MyMavenRepo1'
            url 'http://artifactory/url/our-snapshot-local'
            credentials { (...) }
        }
        maven {
            name 'MyMavenRepo2'
            url 'http://artifactory/url/our-release-local'
            credentials { (...) }
        }
    }
}

task publish(dependsOn: [
    'generatePomFileForProjectXMergedWarPublication',
    'publishProjectXMergedWarPublicationToMyMavenRepo1Repository'
], overwrite: true) {
    // We override the normal publish which would have tried to publish all combinations of defined
    // publications and repositories:
    // - publishProjectXMergedWarPublicationToMyMavenRepo1Repository      (we use this in normal snapshot publish)
    // - publishProjectXMergedWarPublicationToMyMavenRepo2Repository      (not to be used)
    // - publishProjectXJarReleasePublicationToMyMavenRepo1Repository     (not to be used)
    // - publishProjectXJarReleasePublicationToMyMavenRepo2Repository     (we use this one in publishRelease)
}
task publishRelease(dependsOn: [
    'generatePomFileForProjectXJarReleasePublication',
    'publishProjectXJarReleasePublicationToMyMavenRepo2Repository'
])

Выход из задач:

$ ./gradlew tasks

(...)

Publishing tasks
----------------
generatePomFileForProjectXJarReleasePublication - Generates the Maven POM file for publication 'ProjectXJarRelease'.
generatePomFileForProjectXMergedWarPublication - Generates the Maven POM file for publication 'ProjectXMergedWar'.
publishProjectXJarReleasePublicationToMavenLocal - Publishes Maven publication 'ProjectXJarRelease' to the local Maven repository.
publishProjectXJarReleasePublicationToMyMavenRepo1Repository - Publishes Maven publication 'ProjectXJarRelease' to Maven repository 'MyMavenRepo1'.
publishProjectXJarReleasePublicationToMyMavenRepo2Repository - Publishes Maven publication 'ProjectXJarRelease' to Maven repository 'MyMavenRepo2'.
publishProjectXMergedWarPublicationToMavenLocal - Publishes Maven publication 'ProjectXMergedWar' to the local Maven repository.
publishProjectXMergedWarPublicationToMyMavenRepo1Repository - Publishes Maven publication 'ProjectXMergedWar' to Maven repository 'MyMavenRepo1'.
publishProjectXMergedWarPublicationToMyMavenRepo2Repository - Publishes Maven publication 'ProjectXMergedWar' to Maven repository 'MyMavenRepo2'.
publishToMavenLocal - Publishes all Maven publications produced by this project to the local Maven cache.

(...)

Other tasks
-----------
(...)
publish
publishRelease
(...)

Ответы

Ответ 1

Вы можете отключить и скрыть "недопустимые" задачи следующим образом:

apply plugin: 'maven-publish'

publishing {
    repositories {
        maven {
            name 'Dev'
            url 'http://dev/'
            credentials {
                username 'username'
                password 'password'
            }
        }

        maven {
            name 'Prod'
            url 'http://prod/'
            credentials {
                username 'username'
                password 'password'
            }
        }

    }

    publications {
        // This will only be enabled on Dev
        MyDevJar(MavenPublication) {
            artifactId "test"
            version "1.0"
            groupId "org.example"
            artifact file('abc')
            ext.repo = 'Dev'
        }

        // This will only be enabled on prod
        MyJar(MavenPublication) {
            artifactId "test"
            version "1.0"
            groupId "org.example"
            artifact file('abc')
            ext.repo = 'Prod'
        }
    }
}

afterEvaluate {
    tasks.withType(PublishToMavenRepository) { task ->
        if (task.publication.hasProperty('repo') && task.publication.repo != task.repository.name) {
            task.enabled = false
            task.group = null
        }
    }
}

Ответ 2

Я только начал играть с gradle, и другие плагины и решение @knut-saua-mathiesen были действительно интересными, но для меня это не работало.

Внутри "AfterEvaluate" задача. публикация не была настроена на ее исправление, но была инициализирована на "null". Поэтому я попробовал несколько других вещей и придумал это решение:

afterEvaluate {                                                                                   
  tasks.withType(PublishToMavenRepository).all { publishTask ->                                   
    publishTask.onlyIf { task ->                                                                  
      if (task.publication.hasProperty('repo') && task.publication.repo != task.repository.name) {
        task.enabled = false                                                                      
        task.group = null                                                                         
        return false                                                                              
      }                                                                                           
      return true                                                                                 
    }                                                                                             
  }                                                                                               
}   

Ответ 3

Возможно, этого не было, когда задавался вопрос, но документация Gradle описывает, как добиться желаемой условной публикации.

Используя метод tasks.withType() как в принятом ответе, но затем также используя блок onlyIf{}.

"Gradle позволяет пропустить любую задачу на основе условия с помощью Task.onlyIf(org.gradle.api.specs.Spec)."

Поэтому в их примере используются условия для имени репозитория и типа публикации:

tasks.withType(PublishToMavenRepository) {
    onlyIf {
        (repository == publishing.repositories.external &&
            publication == publishing.publications.binary) ||
        (repository == publishing.repositories.internal &&
            publication == publishing.publications.binaryAndSources)
    }
}
tasks.withType(PublishToMavenLocal) {
    onlyIf {
        publication == publishing.publications.binaryAndSources
    }
}

Где они определили publications и repositories следующим образом:

publishing {
    publications {
        binary(MavenPublication) {
            from components.java
        }
        binaryAndSources(MavenPublication) {
            from components.java
            artifact sourcesJar
        }
    }
    repositories {
        // change URLs to point to your repos, e.g. http://my.org/repo
        maven {
            name = 'external'
            url = "$buildDir/repos/external"
        }
        maven {
            name = 'internal'
            url = "$buildDir/repos/internal"
        }
    }
}