perf(ci): run selected tests once before service builds
This commit is contained in:
Vendored
+32
-1
@@ -108,6 +108,9 @@ pipeline {
|
|||||||
}
|
}
|
||||||
env.RESOLVED_JOB_PREFIX = jobPrefix
|
env.RESOLVED_JOB_PREFIX = jobPrefix
|
||||||
env.DATABASE_CHANGE_DETECTED = 'false'
|
env.DATABASE_CHANGE_DETECTED = 'false'
|
||||||
|
if (env.RESOLVED_ENVIRONMENT == 'production' && params.SKIP_TESTS) {
|
||||||
|
error('生产环境禁止跳过测试')
|
||||||
|
}
|
||||||
|
|
||||||
List selected = []
|
List selected = []
|
||||||
if (params.BUILD_MODE == 'ALL') {
|
if (params.BUILD_MODE == 'ALL') {
|
||||||
@@ -177,6 +180,33 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stage('统一 Maven 测试门禁') {
|
||||||
|
when {
|
||||||
|
expression { env.NO_SERVICE_CHANGE != 'true' && !params.SKIP_TESTS }
|
||||||
|
}
|
||||||
|
agent { label 'java-builder' }
|
||||||
|
tools { maven 'maven-3.8.8' }
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
String selectedModules = env.SELECTED_SERVICES.split(',')
|
||||||
|
.collect { it.trim() }
|
||||||
|
.findAll { it }
|
||||||
|
.join(',')
|
||||||
|
echo "统一测试本次选中的服务及其公共依赖: ${selectedModules}"
|
||||||
|
sh """
|
||||||
|
test \"\$(git rev-parse HEAD)\" = \"${env.SOURCE_COMMIT}\"
|
||||||
|
mvn --settings deploy/maven/settings-ci.xml --batch-mode --errors -pl ${selectedModules} -am test
|
||||||
|
"""
|
||||||
|
echo "统一测试门禁通过: ${env.SOURCE_COMMIT};下游单服务任务不再重复执行测试"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
junit allowEmptyResults: true, testResults: '**/target/surefire-reports/TEST-*.xml'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('并行调度独立服务 Job') {
|
stage('并行调度独立服务 Job') {
|
||||||
when { expression { env.NO_SERVICE_CHANGE != 'true' } }
|
when { expression { env.NO_SERVICE_CHANGE != 'true' } }
|
||||||
steps {
|
steps {
|
||||||
@@ -196,7 +226,8 @@ pipeline {
|
|||||||
string(name: 'IMAGE_TAG', value: env.IMAGE_TAG),
|
string(name: 'IMAGE_TAG', value: env.IMAGE_TAG),
|
||||||
string(name: 'ENVIRONMENT', value: env.RESOLVED_ENVIRONMENT),
|
string(name: 'ENVIRONMENT', value: env.RESOLVED_ENVIRONMENT),
|
||||||
booleanParam(name: 'DEPLOY', value: params.DEPLOY),
|
booleanParam(name: 'DEPLOY', value: params.DEPLOY),
|
||||||
booleanParam(name: 'SKIP_TESTS', value: params.SKIP_TESTS),
|
// 总控已完成统一测试,或用户已明确选择跳过;下游仅负责编译、打包和部署。
|
||||||
|
booleanParam(name: 'SKIP_TESTS', value: true),
|
||||||
string(name: 'IMAGE_REPOSITORY', value: env.RESOLVED_IMAGE_REPOSITORY),
|
string(name: 'IMAGE_REPOSITORY', value: env.RESOLVED_IMAGE_REPOSITORY),
|
||||||
string(name: 'DOCKER_BASE_IMAGE', value: params.DOCKER_BASE_IMAGE),
|
string(name: 'DOCKER_BASE_IMAGE', value: params.DOCKER_BASE_IMAGE),
|
||||||
string(name: 'EVENT_BRIDGE_REGION', value: params.EVENT_BRIDGE_REGION)
|
string(name: 'EVENT_BRIDGE_REGION', value: params.EVENT_BRIDGE_REGION)
|
||||||
|
|||||||
+6
-3
@@ -114,12 +114,15 @@ pipeline {
|
|||||||
stage('Maven 测试与打包') {
|
stage('Maven 测试与打包') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
if (params.ENVIRONMENT == 'production' && params.SKIP_TESTS) {
|
boolean coordinatorPinnedCommit = params.SOURCE_COMMIT?.trim() as boolean
|
||||||
error('生产环境禁止跳过测试')
|
if (params.ENVIRONMENT == 'production' && params.SKIP_TESTS && !coordinatorPinnedCommit) {
|
||||||
|
error('生产环境手工构建禁止跳过测试;总控流水线可在统一测试通过后执行快速打包')
|
||||||
}
|
}
|
||||||
boolean skipTestExecution = params.ENVIRONMENT == 'test' || params.SKIP_TESTS
|
boolean skipTestExecution = params.ENVIRONMENT == 'test' || params.SKIP_TESTS
|
||||||
String testOption = skipTestExecution ? '-DskipTests' : ''
|
String testOption = skipTestExecution ? '-DskipTests' : ''
|
||||||
if (params.ENVIRONMENT == 'test') {
|
if (params.SKIP_TESTS && coordinatorPinnedCommit) {
|
||||||
|
echo "总控已处理提交 ${env.RESOLVED_SOURCE_COMMIT} 的测试门禁,本单服务仅编译测试源码并打包"
|
||||||
|
} else if (params.ENVIRONMENT == 'test') {
|
||||||
echo '测试环境快速部署:编译主代码和测试代码,但不重复执行单元测试;完整测试由提交门禁和预发布执行'
|
echo '测试环境快速部署:编译主代码和测试代码,但不重复执行单元测试;完整测试由提交门禁和预发布执行'
|
||||||
}
|
}
|
||||||
sh "mvn --settings ${env.MAVEN_SETTINGS} --batch-mode --errors -pl ${env.RESOLVED_SERVICE} -am clean package ${testOption}"
|
sh "mvn --settings ${env.MAVEN_SETTINGS} --batch-mode --errors -pl ${env.RESOLVED_SERVICE} -am clean package ${testOption}"
|
||||||
|
|||||||
@@ -13,6 +13,17 @@ test('coordinator releases its builder while waiting for downstream jobs', () =>
|
|||||||
assert.doesNotMatch(pipeline, /cleanWs\(/)
|
assert.doesNotMatch(pipeline, /cleanWs\(/)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('coordinator runs selected tests once before parallel service packaging', () => {
|
||||||
|
const gateIndex = pipeline.indexOf("stage('统一 Maven 测试门禁')")
|
||||||
|
const dispatchIndex = pipeline.indexOf("stage('并行调度独立服务 Job')")
|
||||||
|
|
||||||
|
assert.ok(gateIndex >= 0, 'unified test gate must exist')
|
||||||
|
assert.ok(dispatchIndex > gateIndex, 'unified tests must finish before downstream dispatch')
|
||||||
|
assert.match(pipeline, /-pl \$\{selectedModules\} -am test/)
|
||||||
|
assert.match(pipeline, /booleanParam\(name: 'SKIP_TESTS', value: true\)/)
|
||||||
|
assert.doesNotMatch(pipeline, /TESTED_COMMIT/)
|
||||||
|
})
|
||||||
|
|
||||||
test('AUTO detects database migrations without expanding them to all services', () => {
|
test('AUTO detects database migrations without expanding them to all services', () => {
|
||||||
assert.match(pipeline, /def databaseMigrationPaths = \['deploy\/sql\/'\]/)
|
assert.match(pipeline, /def databaseMigrationPaths = \['deploy\/sql\/'\]/)
|
||||||
assert.match(pipeline, /!databaseMigration && commonPaths\.any/)
|
assert.match(pipeline, /!databaseMigration && commonPaths\.any/)
|
||||||
|
|||||||
@@ -30,8 +30,9 @@ test('coordinator jobs present their own deployment environment as the default c
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('production deployments cannot skip tests', () => {
|
test('production deployments cannot skip tests', () => {
|
||||||
assert.match(pipeline, /params\.ENVIRONMENT == 'production' && params\.SKIP_TESTS/)
|
assert.match(coordinatorPipeline, /env\.RESOLVED_ENVIRONMENT == 'production' && params\.SKIP_TESTS/)
|
||||||
assert.match(pipeline, /error\('生产环境禁止跳过测试'\)/)
|
assert.match(coordinatorPipeline, /error\('生产环境禁止跳过测试'\)/)
|
||||||
|
assert.match(pipeline, /生产环境手工构建禁止跳过测试/)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Java builds use the shared builder pool and serialize incremental target deployments', () => {
|
test('Java builds use the shared builder pool and serialize incremental target deployments', () => {
|
||||||
@@ -51,6 +52,12 @@ test('Java builds use the shared builder pool and serialize incremental target d
|
|||||||
assert.match(directDeployScript, /--pull never/)
|
assert.match(directDeployScript, /--pull never/)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('production only accepts skipped downstream tests for a coordinator-pinned commit', () => {
|
||||||
|
assert.match(pipeline, /boolean coordinatorPinnedCommit = params\.SOURCE_COMMIT\?\.trim\(\) as boolean/)
|
||||||
|
assert.match(pipeline, /params\.ENVIRONMENT == 'production' && params\.SKIP_TESTS && !coordinatorPinnedCommit/)
|
||||||
|
assert.match(pipeline, /生产环境手工构建禁止跳过测试/)
|
||||||
|
})
|
||||||
|
|
||||||
test('development and test deployment locks are acquired before target executors', () => {
|
test('development and test deployment locks are acquired before target executors', () => {
|
||||||
const directDeployStage = pipeline.slice(
|
const directDeployStage = pipeline.slice(
|
||||||
pipeline.indexOf("stage('部署开发或测试环境')"),
|
pipeline.indexOf("stage('部署开发或测试环境')"),
|
||||||
|
|||||||
Reference in New Issue
Block a user