fix(ci): isolate Docker registry credentials
This commit is contained in:
+12
-7
@@ -139,16 +139,21 @@ pipeline {
|
||||
String contextDir = ".docker-context/${env.RESOLVED_SERVICE}"
|
||||
String jar = serviceJars[env.RESOLVED_SERVICE]
|
||||
String registryHost = env.RESOLVED_IMAGE_REPOSITORY.tokenize('/')[0]
|
||||
String dockerConfigDir = "${pwd(tmp: true)}/docker-auth"
|
||||
sh "mkdir -p '${contextDir}' && cp -f '${jar}' '${contextDir}/app.jar'"
|
||||
sh "docker build -f deploy/docker/Dockerfile --build-arg BASE_IMAGE=${params.DOCKER_BASE_IMAGE} --build-arg JAR_FILE=app.jar -t ${image} '${contextDir}'"
|
||||
|
||||
echo "推送共享镜像: ${image}"
|
||||
withCredentials([usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS, usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD')]) {
|
||||
try {
|
||||
sh 'printf %s "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin "' + registryHost + '"'
|
||||
sh "docker push ${image}"
|
||||
} finally {
|
||||
sh "docker logout ${registryHost} || true"
|
||||
withEnv(["DOCKER_CONFIG=${dockerConfigDir}"]) {
|
||||
sh 'mkdir -p "$DOCKER_CONFIG"'
|
||||
withCredentials([usernamePassword(credentialsId: env.REGISTRY_CREDENTIALS, usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PASSWORD')]) {
|
||||
try {
|
||||
sh 'printf %s "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin "' + registryHost + '"'
|
||||
sh "docker build -f deploy/docker/Dockerfile --build-arg BASE_IMAGE=${params.DOCKER_BASE_IMAGE} --build-arg JAR_FILE=app.jar -t ${image} '${contextDir}'"
|
||||
sh "docker push ${image}"
|
||||
} finally {
|
||||
sh "docker logout ${registryHost} || true"
|
||||
sh 'rm -rf "$DOCKER_CONFIG"'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (params.DEPLOY) {
|
||||
|
||||
@@ -64,6 +64,26 @@ test('development and test deployment locks are acquired before target executors
|
||||
assert.ok(lockIndex < nodeIndex, 'deployment lock must be acquired before target node allocation')
|
||||
})
|
||||
|
||||
test('parallel image publications isolate registry credentials per Jenkins job', () => {
|
||||
const imageStage = pipeline.slice(
|
||||
pipeline.indexOf("stage('构建并发布单服务镜像')"),
|
||||
pipeline.indexOf("stage('部署开发或测试环境')")
|
||||
)
|
||||
const loginIndex = imageStage.indexOf('docker login')
|
||||
const buildIndex = imageStage.indexOf('docker build')
|
||||
const pushIndex = imageStage.indexOf('docker push')
|
||||
const logoutIndex = imageStage.indexOf('docker logout')
|
||||
const cleanupIndex = imageStage.indexOf('rm -rf "$DOCKER_CONFIG"')
|
||||
|
||||
assert.match(imageStage, /String dockerConfigDir = "\$\{pwd\(tmp: true\)\}\/docker-auth"/)
|
||||
assert.match(imageStage, /withEnv\(\["DOCKER_CONFIG=\$\{dockerConfigDir\}"\]\)/)
|
||||
assert.ok(loginIndex >= 0 && loginIndex < buildIndex, 'registry login must happen before image build')
|
||||
assert.ok(buildIndex < pushIndex, 'image build must happen before image push')
|
||||
assert.ok(pushIndex < logoutIndex, 'registry logout must happen after image push')
|
||||
assert.ok(logoutIndex < cleanupIndex, 'temporary Docker credentials must be removed last')
|
||||
assert.doesNotMatch(imageStage, /\/home\/deploy\/\.docker\/config\.json/)
|
||||
})
|
||||
|
||||
test('parallel remote deployments keep env and compose assets isolated by project', () => {
|
||||
assert.match(directDeployScript, /REMOTE_ENV_NAME="\.env\.\$PROJECT_NAME"/)
|
||||
assert.match(directDeployScript, /REMOTE_COMPOSE_NAME="docker-compose\.\$PROJECT_NAME\.yml"/)
|
||||
|
||||
Reference in New Issue
Block a user