Search code examples
gradlemulti-project

Assemble all gradle build artifacts into a single directory


We're moving from Maven to Gradle and are struggling with one thing. We have a multi-project Gradle-project based on the POMs from Maven. Most of it works fine, but we cannot find out a way to collect the WAR-files and ZIP-files which are the result from building the sub-projects. Each sub-project represents a micro service. We have found (also on Stackoverflow) ways to collect all of the jars and third party libs into a directory. However, we are looking for a way to collect the resources and libraries per micro service. In Maven we did something like this:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>Publish/</outputDirectory>
                        <artifactItems>
                            <artifactItem>
                                <groupId>....</groupId>
                                <artifactId>...</artifactId>
                                <version>${project.version}</version>
                                <type>zip</type>
                            </artifactItem>
                            <artifactItem>
                                <groupId>....</groupId>
                                <artifactId>...</artifactId>
                                <version>${project.version}</version>
                                <type>war</type>
                            </artifactItem>

I would like to end up with a directory where I can find:

project1.war
project2.war
project3.zip
etc.

Solution

  • The following solution is hand-rolled but is simple, and offers flexibility if you need to tweak anything.

    Below is a build.gradle in the root directory. For each subproject, it will:

    • Define a copyArtifacts task that copies war and zip files from the subproject's build/libs folder (using appropriate baseName, version, etc) to root/dist.
    • If a war task is found, then configure it so that it runs copyArtifacts afterwards.

    This can be easily changed to look for other task names, match different filenames, etc. (One might want to delete older versions of a given artifact before the copy, and so on.)

    subprojects { Project subProject ->
        task copyArtifacts {
            doLast {
                def baseName = subProject.archivesBaseName
                def version = subProject.version
                def group = subProject.group
                def DIST_DIR = "${rootDir}/dist"
                def SRC_DIR = "${buildDir}/libs"
    
                ant.mkdir(dir: DIST_DIR)
                ant.copy(todir: DIST_DIR) {
                    fileset(dir: SRC_DIR,
                    includes: "${baseName}*${version}*.war,${baseName}*${version}*.zip")
                }
            }
        }
    
        afterEvaluate {
            def warTask = subProject.tasks.find { it.name == 'war' }
            if (warTask) { 
                warTask.finalizedBy(copyArtifacts)
            }
        }
    }