Gradle多模块项目模板化

前言

Maven 冗余, Gradle 简单轻便 公司原有的 CI/CD 流程,借助 Maven 插件 build Docker Image,改为原生 Docker Runner 原始构建

1、多模块项目

project
 - app
   - src/main/[java|resources] | src/test/[java|resources]   # classpath
   - Dockerfile         # Dockerfile
   - build.gradle       # APP 模块 gradle 配置
 - sdk                  # SDK 模块 可有可无
   - src/main/java
   - build.gradle       # SDK 的 gradle 配置
 - deploy               # delpoy 项目 注意 checkstyle 相关配置在这里面
   - checkstyle/**
   - **.yml
 - build.gradle         # 项目顶级 gradle配置
 - gradle
   - wrapper/**         # gradle 配置信息
   - check.gradle       # pmd & checkstyle
   - repo.gradle        # 仓库定义
# test.gradle 放这儿,就没有高亮了 => 暂时维护在 顶层的 build.gradle 中,单独维护,不要和其他配置混在一起。
 - settings.gradle      # 配置
 - versions-prod.gradle      # 版本定义
 - versions-dev.gradle      # 版本定义
 - .gitignore           # git忽略文件
 - .gitlab-ci.yml       # CI/CD

2、Project 下各个gradle文件

Project/versions.gradle 可以统一版本管理

//start step
def versions = new Expando()
def deps = new Expando()
ext.versions = versions
ext.deps = deps

//set versions
versions.springboot = "2.1.16.RELEASE"
versions.mysql = "8.0.16"
versions.guava = "25.1-jre"
versions.httpclient = "4.5.9"

versions.okhttp3 = "3.8.1"
versions.apm = "1.7.0"

versions.kotlin = "1.4.10"

//set dependencies

// 基础开源包
deps.mysql = "mysql:mysql-connector-java:${versions.mysql}"
deps.guava = "com.google.guava:guava:${versions.guava}"
deps.okhttp3 = "com.squareup.okhttp3:okhttp:${versions.okhttp3}"
deps.apm = "co.elastic.apm:apm-agent-attach:${versions.apm}"

Project/settings.gradle 根配置文件,build 快不快全靠它

//配置插件走国内代理
pluginManagement {
    repositories {
        maven {
            url 'https://maven.aliyun.com/repository/gradle-plugin'
        }
        gradlePluginPortal()
    }
}

rootProject.name = 'project-name'
include ':app'
include ':sdk'    // 没有SDK模块的化不需要这个

Project/build.gradle

buildscript {
    ext {
        kotlinVersion = "1.4.10"
        springBootVersion = '2.1.16.RELEASE'
        springBootGradleVersion = '2.3.3.RELEASE'
    }
}

plugins {
    id "java"
    id "pmd"
    id "checkstyle"
    id "maven-publish"

    id "org.jetbrains.kotlin.jvm" version "$kotlinVersion"
    id "org.jetbrains.kotlin.plugin.spring" version "$kotlinVersion"

    id "org.springframework.boot" version "$springBootVersion"
    id "io.spring.dependency-management" version "1.0.9.RELEASE"

}

apply from: file("versions.gradle")

// 为了一如不同的版本环境下的代码配置
def env = System.getProperty('env') ?: 'dev'
apply from: "${rootDir}/versions-${env}.gradle"



allprojects {

    // 配置 group 
    group "com.XXX.XXX"
    //配置版本
    version = findProperty 'version' ?: '1.0.0-SNAPSHOT'
    
    bootJar {
        enabled = false
    }

    apply plugin: "java"
    apply plugin: "idea"
    apply plugin: "maven-publish"

    apply plugin: "org.jetbrains.kotlin.jvm"
    apply plugin: "kotlin-spring"

    apply plugin: "org.springframework.boot"
    apply plugin: "io.spring.dependency-management"

    apply plugin: 'jacoco'

    //假如 你的 mapper.xml 或者 grovvy 写在 src/main/java ,打包需要处理到 需要加入的resources,需要手动处理
    // 当然如果 你的 mapper.xml 直接在 src/main/resources 里面 不需要处理,可以直接删除
    processResources {
        from('src/main/java') {
            include '**/*.xml'
            include '**/*.groovy'
        }
    }

}

// apply from: file("gradle/repo.gradle")
// apply from: file("gradle/check.gradle")
// apply from: file("gradle/maven-publish.gradle")
apply from: 'https://${DownloadPath}/gradle/check-style.gradle'
apply from: 'https://${DownloadPath}/gradle/maven-repo.gradle'
apply from: 'https://${DownloadPath}/gradle/maven-publish.gradle'


subprojects {

    configurations {
        provided
    }
    sourceSets.main.compileClasspath += configurations.provided
    sourceSets.test.compileClasspath += configurations.provided
    sourceSets.test.runtimeClasspath += configurations.provided

    tasks.withType(JavaCompile) {
        options.encoding = 'UTF-8'
    }

    task sourceJar(type: Jar) {
        from sourceSets.main.allJava
        classifier "sources"
    }

    task javadocJar(type: Jar, dependsOn: javadoc) {
        from javadoc.destinationDir
    }
    dependencies {
        implementation "com.google.guava:guava:$versions.guava"

        compileOnly 'org.projectlombok:lombok:1.18.4'
        annotationProcessor 'org.projectlombok:lombok:1.18.4'

        testCompileOnly 'org.projectlombok:lombok:1.18.4'
        testAnnotationProcessor 'org.projectlombok:lombok:1.18.4'

        testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
        testImplementation "org.mockito:mockito-core:2.23.4"
        testImplementation 'junit:junit:4.13'
        // h2
        testImplementation "com.h2database:h2:1.4.200"
        // redis memery
        testImplementation "com.github.kstyrc:embedded-redis:0.6"
    }

    // jacoco report
    jacocoTestReport {
        reports {
            xml.enabled false
            html.enabled true
        }
    }

    check.dependsOn jacocoTestReport

    
}

allprojects {
    apply plugin: 'maven-publish'

    publishing {

        task sourceJar(type: Jar) {
            from sourceSets.main.allJava
            classifier "sources"
        }


        publications {
            mavenSnapshots(MavenPublication) {
                groupId project.group
                artifactId project.name
                version project.version
                from components.java
                artifact sourceJar
                ext.repo = 'Dev'
            }

            mavenRelease(MavenPublication) {
                groupId project.group
                artifactId project.name
                version project.version
                from components.java
                artifact sourceJar
                ext.repo = 'Prod'
            }
        }
        repositories {
            maven {
                name 'Dev'
                url "${NEXUS_URL}/repository/maven-snapshots/"
                authentication {
                    header(HttpHeaderAuthentication)
                }
                credentials(HttpHeaderCredentials) {
                    name "Authorization"
                    value "Basic ${NEXUS_CAS_HEADER}"
                }
            }
            maven {
                name 'Prod'
                url "${NEXUS_URL}/repository/maven-releases/"
            }
        }
    }
}

Project/gradle/repo.gradle 指定私有仓库地址以及验证方式

buildscript {
    repositories {
        mavenLocal()
        maven {
            url "${NEXUS_URL}/repository/maven-releases/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven {
            url "${NEXUS_URL}/repository/maven-snapshots/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven {
            url "${NEXUS_URL}/repository/maven-public/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven { url "https://maven.aliyun.com/nexus/content/groups/public/" }
        maven { url "https://repo.spring.io/milestone" }
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
    }

}

allprojects {
    repositories {
        mavenLocal()
        maven {
            url "${NEXUS_URL}/repository/maven-releases/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven {
            url "${NEXUS_URL}/repository/maven-snapshots/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven {
            url "${NEXUS_URL}/repository/maven-public/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven { url "https://maven.aliyun.com/nexus/content/groups/public/" }
        maven { url "https://repo.spring.io/milestone" }
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
    }

}

subprojects {

    repositories {
        mavenLocal()
        maven {
            url "${NEXUS_URL}/repository/maven-releases/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven {
            url "${NEXUS_URL}/repository/maven-snapshots/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven {
            url "${NEXUS_URL}/repository/maven-public/"
            authentication {
                header(HttpHeaderAuthentication)
            }
            credentials(HttpHeaderCredentials) {
                name "Authorization"
                value "Basic ${NEXUS_CAS_HEADER}"
            }
        }
        maven { url "https://maven.aliyun.com/nexus/content/groups/public/" }
        maven { url "https://repo.spring.io/milestone" }
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
    }
}

Project/gradle/check.gradle

subprojects {
    apply plugin: 'checkstyle'
    checkstyle {
        configFile = rootProject.file('deploy/checkstyle/checkstyle.xml')
        showViolations = true
       // ignoreFailures = true

    }

    //可以指定排查
    checkstyleMain {
        exclude "**/*.groovy"
    }

    apply plugin: 'pmd'
    dependencies {
        pmd "com.alibaba.p3c:p3c-pmd:2.0.0"
    }
    pmd {
        consoleOutput = true
        ruleSets = [
                "java-ali-comment",
                "java-ali-concurrent",
                "java-ali-constant",
                "java-ali-exception",
                "java-ali-flowcontrol",
                "java-ali-naming",
                "java-ali-oop",
                "java-ali-orm",
                "java-ali-other",
                "java-ali-set"
        ]
        incrementalAnalysis = false
    }

    pmdMain {
        exclude "**/exclude_package/**"
    }
}
test.mustRunAfter checkstyleMain, checkstyleTest

Project/sdk/build.gradle

apply from: file("$rootDir/versions.gradle")

jar {
    enabled = true
}
bootJar {
    enabled = false
}
dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:2.1.0.RELEASE'
    ......
}

Project/app/build.gradle

apply from: file("$rootDir/versions.gradle")

bootJar {
    enabled = true
}

jar {
    enabled = false
}

dependencies {
    implementation deps.springboot.starter
    implementation deps.springboot.starter_web
    implementation deps.mysql
    implementation deps.myabtis.myabtis
    implementation deps.myabtis.starter
    implementation 'org.springframework.boot:spring-boot-starter-amqp:2.1.2.RELEASE'
    implementation "org.springframework.cloud:spring-cloud-starter-openfeign:2.1.0.RELEASE"
    implementation 'com.zaxxer:HikariCP:3.4.1'
    implementation 'com.baomidou:mybatis-plus:2.2.0'
    implementation 'com.github.pagehelper:pagehelper:5.1.2'
    implementation 'org.mongodb:mongo-java-driver:3.8.0'
    ...... //剩余映射依赖
}

3、 Dockerfile 注意 ADD 文件路径

FROM {HARBOR_HOST}/BaseImage
ADD ./build/libs/app.jar /app.jar
.... 其他配置

4、Project/ 下添加 gradle.properties, 注意在 .gitignore 里面添加上它,不要传递到公开服务器,是你的密码等敏感信息

# Nexus 仓库地址
NEXUS_URL=https://nexus-url
# 指定为你自己的maven的用户配置 settings.xml 里面的你的配置
NEXUS_CAS_HEADER=XXXXXXX
# gradle daemon
org.gradle.daemon=true
# 禁用Gradle 6.x 版本 SHA-256和SHA-512校验和的发布
# https://juejin.im/post/6844904101126553614
systemProp.org.gradle.internal.publish.checksums.insecure=true

5、gitlab-ci 模板化,下次分享~~~~

comments powered by Disqus