Play 애플리케이션 CI/CD 작업 중 빌드 작업을 컨테이너 상에서 진행되어 빌드가 정상적으로 종료된 것인지를 체크하는 방법을 고안할 필요가 있었다. 구글링+GPT와 씨름한 결과, Jenkins pipeline 내 Script Block을 이용해 조건문 로직을 추가할 수 있었다.
Script Block을 사용하면 Declarative Pipeline 내에서 Scripted Pipeline 블록을 실행할 수 있다. Scripted Pipeline은 Jenkins의 기존 파이프라인 구문으로, Groovy 문법을 활용하여 보다 절차적인 방식으로 복잡한 워크플로우 및 파이프라인 모델링이 가능하다. 아래 코드를 통해 컨테이너 종료 코드를 받아와 조건문을 통해 스테이지를 이어갈지 에러 처리할지를 선택할 수 있었다.
script{
// Build 컨테이너 실행 후 종료 코드 확인
// docker compose --abort-on-container-exit을 사용하면 컨테이너 종료시 종료 코드를 반환한다.
def exitCode = sh script: 'docker compose -f <build-compose-file-name> up --abort-on-container-exit', returnStatus: true
// 종료 코드에 따라 처리
if (exitCode == 0) {
echo 'Build was successful, proceeding to the deploy stage.'
} else {
error 'play-spark build failed. stopping the pipeline...'
}
}
docker compose 실행 옵션
--abort-on-container-exit
은 docker compose 내 서비스 컨테이너 중 하나가 종료하면 다른 서비스 컨테이너를 모두 종료시키고 첫번째로 종료한 컨테이너의 종료 코드를 반환한다.
만약 compose 내 다른 서비스들이 있고 특정 서비스의 종료 코드를 받아오고 싶다면--exit-code-from <service-name>
옵션을 사용하면 된다.
**--exit-code-from
옵션은--abort-on-container-exit
옵션을 내포하고 있으므로<service-name>
서비스컨테이너가 종료되면 마찬가지로 아직 종료되지 않은 다른 컨테이너를 모두 종료시킨다.
Script Block에 대해 찾아보던 중, parallel
directive를 통한 파이프라인 병렬 처리에 대해 알게 되어 Spring 애플리케이션과 Play 애플리케이션의 빌드 과정을 병렬적으로 수행해주었다. 작성한 파이프라인 스크립트는 다음과 같다.
stage('build'){
steps{
script{
sh 'cd /var/jenkins_home/workspace/dev-backend'
parallel springApiBuild: {
// Spring build process
}, playSparkBuild: {
dir('backend/play-spark'){
// ~~
// Build 컨테이너 실행 후 종료 코드 확인
def exitCode = sh script: 'docker compose -f <build-compose-file-name> up --abort-on-container-exit', returnStatus: true
// 종료 코드에 따라 처리
if (exitCode == 0) {
echo 'Build was successful, proceeding to the deploy stage.'
} else {
error 'play-spark build failed. stopping the pipeline...'
}
}
}
}
}
post {
success {
echo 'Successfully build'
}
failure {
error 'Build is failed'
}
}
}
병렬 처리로 인해 빌드 시간을 25초(31.6%) 단축시킬 수 있었다.
Jenkins Pipeline Syntax - script block
젠킨스 파이프라인 정리 - 2. Scripted 문법 소개
Understanding the Differences Between Jenkins Scripted and Declarative Pipeline