Как опубликовать модули, которые фактически изменены в Gradle, а не все (не изменены) для настройки CI?

Я настраиваю модель CI для одного проекта. В этом проекте примерно 500 модулей. Мы просто обновляем рабочее пространство каждый раз с помощью нашего инструмента CI и собираем модули, которые фактически меняются. Мы используем gradle для сборки всех модулей, мое требование состоит в том, чтобы публиковать только те модули, которые были изменены в текущей сборке, в хранилище моментальных снимков Nexus. Я знаю, что существует непростая задача опубликовать артефакты, но требуется только публикация в измененных модулях.

Ниже приведен пример.

A
B
C
D
E
F

Если есть изменения в B и F, то я хочу публиковать только модули B и F в нексусе, а если изменения в A и F, то публиковать только модули A и F.

Что-то похожее

 class IncrementalReverseTask extends DefaultTask {
      @InputDirectory
      def File inputDir

      @OutputDirectory
      def File outputDir

      @TaskAction
      void execute(IncrementalTaskInputs inputs) {
          if (!inputs.incremental)
              project.delete(outputDir.listFiles())

          inputs.outOfDate { change ->
              def targetFile = project.file("$outputDir/${change.file.name}")
              targetFile.text = change.file.text.reverse()
          }

          inputs.removed { change ->
              def targetFile = project.file("$outputDir/${change.file.name}")
              if (targetFile.exists()) {
                  targetFile.delete()
              }
          }
      }
  }

Я пробовал ниже и получаю эту проблему

publishing {
    publications {
        maven(MavenPublication) {
            groupId 'com.example'
            artifactId 'core'
            version '1.0-SNAPSHOT'
            from components.java

    }
    }
    repositories {
    maven {
        credentials {
            username "abcde"
            password "***********"
            }
            url "https://nexus.test.com/content/repositories/snapshots"
            }
            }
    }

task incrementalPublishToMavenRepository(type: IncrementalPublishToMavenRepository) {
  inputDir = file('.')
  publication = project.tasks.getByPath(":${project.name}:publishMavenPublicationToMavenRepository").publication
}

class IncrementalPublishToMavenRepository extends org.gradle.api.publish.maven.tasks.PublishToMavenRepository {
    @InputDirectory
    def File inputDir

    @OutputDirectory
    File generatedFileDir = project.file("${project.buildDir}/libs")

    @TaskAction
    void perform(IncrementalTaskInputs inputs) {
        println 'hello this should be executed ones'
    }
}

и получить ниже ошибки

gradle jar incrementalPublishToMavenRepository

Configuration on demand is an incubating feature.
:core:compileJava UP-TO-DATE
:core:processResources NO-SOURCE
:core:classes UP-TO-DATE
:core:jar UP-TO-DATE
:app:compileJava UP-TO-DATE
:app:processResources UP-TO-DATE
:app:classes UP-TO-DATE
:app:jar UP-TO-DATE
:app:generatePomFileForMavenPublication
:app:incrementalPublishToMavenRepository FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:incrementalPublishToMavenRepository'.
> The 'repository' property is required

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

3 ответа

Я нашел другой способ сделать это с плагином Maven-Publish

apply plugin: 'maven-publish'

publishing {
    publications {
        maven(MavenPublication) {
            groupId 'com.example'
            artifactId 'core'
            version '1.0-SNAPSHOT'
            from components.java
        }
    }
}

publishing {
    repositories {
        maven {
        credentials {
            username "abcedf"
            password "***********"
            }
            // change to point to your repo, e.g. http://my.org/repo
            url "https://repo.test.com/content/repositories/snapshots"
        }
    }
}


task incrementalPublishToMavenRepository(type: IncrementalPublishToMavenRepository) {
  inputDir = file('src')
  publication = project.tasks.getByPath(":${project.name}:publishMavenPublicationToMavenRepository").publication
  repository = project.tasks.getByPath(":${project.name}:publishMavenPublicationToMavenRepository").repository
}

class IncrementalPublishToMavenRepository extends org.gradle.api.publish.maven.tasks.PublishToMavenRepository {
    @InputDirectory
    def File inputDir

    @OutputDirectory
    File generatedFileDir = project.file("${project.buildDir}/libs")

    @TaskAction
    void perform(IncrementalTaskInputs inputs) {
        println 'hello this should be executed ones'
    }
}

Вот вывод

gradle jar incrementalPublishToMavenRepository
Configuration on demand is an incubating feature.
:core:compileJava UP-TO-DATE
:core:processResources NO-SOURCE
:core:classes UP-TO-DATE
:core:jar UP-TO-DATE
:app:compileJava UP-TO-DATE
:app:processResources UP-TO-DATE
:app:classes UP-TO-DATE
:app:jar UP-TO-DATE
:app:generatePomFileForMavenPublication
:app:incrementalPublishToMavenRepository UP-TO-DATE
:core:generatePomFileForMavenPublication
:core:incrementalPublishToMavenRepository UP-TO-DATE

Вот вывод, если я внесу изменение в модуль приложения, оно просто загрузит приложение и скажет UP-TO-DATE для основного модуля

gradle jar incrementalPublishToMavenRepository
Configuration on demand is an incubating feature.
:core:compileJava UP-TO-DATE
:core:processResources NO-SOURCE
:core:classes UP-TO-DATE
:core:jar UP-TO-DATE
:app:compileJava
:app:processResources UP-TO-DATE
:app:classes
:app:jar
:app:generatePomFileForMavenPublication
:app:incrementalPublishToMavenRepository
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/app-1.0-20170609.180436-15.jar
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/app-1.0-20170609.180436-15.jar.sha1
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/app-1.0-20170609.180436-15.jar.md5
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/app-1.0-20170609.180436-15.pom
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/app-1.0-20170609.180436-15.pom.sha1
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/app-1.0-20170609.180436-15.pom.md5
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/maven-metadata.xml
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/maven-metadata.xml.sha1
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/1.0-SNAPSHOT/maven-metadata.xml.md5
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/maven-metadata.xml
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/maven-metadata.xml.sha1
Upload https://repo.test.com/content/repositories/snapshots/com/example/app/maven-metadata.xml.md5
hello this should be executed ones
:core:generatePomFileForMavenPublication
:core:incrementalPublishToMavenRepository UP-TO-DATE

Каждая задача в Gradle имеет свойства входов и выходов, чтобы включить возможности добавочных задач, поэтому эту возможность можно настроить для публикации задач, чтобы публиковать артефакты в хранилище.

Обновление:

Что ж, для реализации полного решения требуются дополнительные усилия, однако вот идея, как вы можете использовать упомянутые возможности:

apply plugin: 'maven-publish'

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
}

class IncrementalPublishToMavenLocal extends org.gradle.api.publish.maven.tasks.PublishToMavenLocal {
    @Input
    int fileCount = 10

    @OutputDirectory
    File generatedFileDir = project.file("${project.buildDir}/libs")

    @TaskAction
    void perform(IncrementalTaskInputs inputs) {
        println 'hello this should be executed ones'
    }
}

task incrementalPublishToMavenLocal(type: IncrementalPublishToMavenLocal) {
  publication = project.tasks.getByPath(":${project.name}:publishMavenJavaPublicationToMavenLocal").publication
}

Теперь вы можете использовать ./gradlew incrementalPublishToMavenLocal выполнить добавочную публикацию. Надеюсь, что это поможет двигаться вперед.

Я попытался пропустить метод uploadArchives ниже, когда он не создает файл JAR

subprojects {
    apply plugin: 'java'
    apply plugin: 'maven'

    repositories {
        mavenCentral()
    }

    uploadArchives {
    repositories {
       mavenDeployer {
             repository(url: "https://repo.test.com/nexus/repos/snapshots") {
             authentication(userName: "abcdef", password: "******")
}
             pom.version = "1.1-SNAPSHOT"
             pom.groupId = "com.test"
       }
    }
}
uploadArchives {
  onlyIf { jar.didWork }
}

}

Ниже вывод, когда я бегу с чистой

:app:clean
:core:clean
:core:compileJava
:core:processResources NO-SOURCE
:core:classes
:core:jar
:app:compileJava
:app:processResources
:app:classes
:app:jar
:app:copyLicense
:app:startScripts
:app:distTar
:app:distZip
:app:uploadArchives
:core:uploadArchives

Ниже приведен вывод при запуске без очистки

:core:compileJava UP-TO-DATE
:core:processResources NO-SOURCE
:core:classes UP-TO-DATE
:core:jar UP-TO-DATE
:app:compileJava UP-TO-DATE
:app:processResources UP-TO-DATE
:app:classes UP-TO-DATE
:app:jar UP-TO-DATE
:app:copyLicense UP-TO-DATE
:app:startScripts UP-TO-DATE
:app:distTar UP-TO-DATE
:app:distZip UP-TO-DATE
:app:uploadArchives SKIPPED
:core:uploadArchives SKIPPED
Другие вопросы по тегам