186 lines
6.5 KiB
Groovy
186 lines
6.5 KiB
Groovy
pipeline {
|
|
agent any
|
|
|
|
environment {
|
|
GITEA_TOKEN = credentials('gitea')
|
|
JAVA_HOME = tool 'java17'
|
|
GRADLE_USER_HOME = "${WORKSPACE}/.gradle"
|
|
}
|
|
|
|
options {
|
|
timestamps()
|
|
disableConcurrentBuilds()
|
|
}
|
|
|
|
stages {
|
|
|
|
/* ---------------------------------------------------
|
|
* 1. Checkout PR
|
|
* --------------------------------------------------- */
|
|
stage('Checkout PR') {
|
|
steps {
|
|
script {
|
|
checkout([
|
|
$class: 'GitSCM',
|
|
branches: [[name: env.SOURCE_BRANCH]],
|
|
userRemoteConfigs: [[
|
|
url: "https://git.sino-assist.com/${REPO_OWNER}/${REPO_NAME}.git",
|
|
credentialsId: 'gitlab'
|
|
]]
|
|
])
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------
|
|
* 2. 计算变更文件
|
|
* --------------------------------------------------- */
|
|
stage('计算增量变更') {
|
|
steps {
|
|
script {
|
|
sh """
|
|
git fetch origin ${TARGET_BRANCH}
|
|
git diff --name-only origin/${TARGET_BRANCH}...HEAD > changed_files.txt
|
|
"""
|
|
|
|
def diff = readFile('changed_files.txt').trim()
|
|
if (!diff) {
|
|
echo "✅ 无代码变更,跳过扫描"
|
|
currentBuild.result = 'SUCCESS'
|
|
return
|
|
}
|
|
|
|
env.CHANGED_FILES = diff
|
|
echo "变更文件:\\n${env.CHANGED_FILES}"
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------
|
|
* 3. 解析 Gradle 增量模块
|
|
* --------------------------------------------------- */
|
|
stage('Gradle 增量编译') {
|
|
tools {
|
|
jdk "java17"
|
|
gradle 'gradle'
|
|
}
|
|
steps {
|
|
script {
|
|
def modules = sh(
|
|
script: '''
|
|
awk -F/ '
|
|
{
|
|
if (NF >= 2) {
|
|
module=":"$1
|
|
for (i=2; i<=NF-1; i++) {
|
|
if ($i == "src") break
|
|
module=module":"$i
|
|
}
|
|
print module
|
|
}
|
|
}' changed_files.txt | sort -u
|
|
''',
|
|
returnStdout: true
|
|
).trim()
|
|
|
|
if (!modules) {
|
|
modules = ":classes"
|
|
}
|
|
|
|
echo "✅ 受影响模块:\\n${modules}"
|
|
|
|
def tasks = modules
|
|
.split("\\n")
|
|
.collect { "${it}:classes" }
|
|
.join(" ")
|
|
|
|
sh """
|
|
gradle ${tasks} \
|
|
-x test \
|
|
--parallel \
|
|
--build-cache \
|
|
--configure-on-demand
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------
|
|
* 4. SonarQube 社区版【增量扫描】
|
|
* --------------------------------------------------- */
|
|
stage('SonarQube 增量扫描(社区版)') {
|
|
tools {
|
|
jdk "java17"
|
|
gradle 'gradle'
|
|
}
|
|
steps {
|
|
script {
|
|
|
|
// 仅扫描 src/main/java 下的变更 Java 文件
|
|
def sonarIncludes = sh(
|
|
script: '''
|
|
grep -E "src/main/java/.*\\.java$" changed_files.txt \
|
|
| sed 's#^#./#' \
|
|
| tr '\\n' ','
|
|
''',
|
|
returnStdout: true
|
|
).trim()
|
|
|
|
if (!sonarIncludes) {
|
|
echo "✅ 无 Java 代码变更,跳过 Sonar"
|
|
return
|
|
}
|
|
|
|
echo "Sonar 增量扫描文件:\\n${sonarIncludes}"
|
|
|
|
withSonarQubeEnv('sonar-server') {
|
|
sh """
|
|
gradle sonar \
|
|
-Dsonar.projectKey=${REPO_NAME} \
|
|
-Dsonar.inclusions=${sonarIncludes} \
|
|
-Dsonar.sourceEncoding=UTF-8 \
|
|
-Dsonar.gradle.skipCompile=true \
|
|
-Dsonar.exclusions=**/*
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------
|
|
* 5. 质量门禁 + PR 反馈
|
|
* --------------------------------------------------- */
|
|
stage('反馈审查结果') {
|
|
steps {
|
|
script {
|
|
def report = waitForQualityGate()
|
|
|
|
if (report.status != 'OK') {
|
|
sh """
|
|
curl -X POST \
|
|
"https://git.sino-assist.com/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/issues/${PR_ID}/comments" \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"body": "❌ SonarQube 社区版增量扫描未通过\\n\\n📊 报告:${report.dashboardUrl}"
|
|
}'
|
|
"""
|
|
error "❌ 质量门禁失败"
|
|
} else {
|
|
sh """
|
|
curl -X POST \
|
|
"https://git.sino-assist.com/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/statuses/${GIT_COMMIT}" \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"context": "sonarqube-check",
|
|
"state": "success",
|
|
"description": "✅ 社区版增量扫描通过"
|
|
}'
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |