diff --git a/.DS_Store b/.DS_Store index 4607662..25cf644 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/docker-swarm/elasticsearch/docker-compose.yml b/docker-swarm/elasticsearch/docker-compose.yml index fa4b5de..b2b94e7 100644 --- a/docker-swarm/elasticsearch/docker-compose.yml +++ b/docker-swarm/elasticsearch/docker-compose.yml @@ -20,16 +20,16 @@ services: constraints: - node.labels.${NAMESPACE}_es==1 kibana: - image: docker.io/bitnami/kibana:8.13.4 + image: docker.elastic.co/kibana/kibana:8.19.10 hostname: ${NAMESPACE}-es-kibana ports: - "${NODE_PORT_KIBANA}:5601" volumes: - - "/mnt/data/volumes/kibana/data:/bitnami/kibana/data" - - "/mnt/data/volumes/kibana/conf:/opt/bitnami/kibana/conf" + - "/mnt/data/volumes/kibana/data:/usr/share/kibana/data" + - "/mnt/data/volumes/kibana/conf/kibana.yml:/usr/share/kibana/config/kibana.yml" environment: - TZ=Asia/Shanghai - - KIBANA_ELASTICSEARCH_URL=${NAMESPACE}-es-elasticsearch + - elasticsearch.hosts=http://${NAMESPACE}-es-elasticsearch:9200 depends_on: - elasticsearch deploy: diff --git a/docker-swarm/nacos-cluser/pipeline {.groovy b/docker-swarm/nacos-cluser/pipeline {.groovy new file mode 100644 index 0000000..2b2549f --- /dev/null +++ b/docker-swarm/nacos-cluser/pipeline {.groovy @@ -0,0 +1,186 @@ +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": "✅ 社区版增量扫描通过" + }' + """ + } + } + } + } + } +} \ No newline at end of file