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