소개
Jenkins 는 두 가지 파이프라인 스타일을 지원합니다. Declarative Pipeline 은 구조화된 pipeline { ... } 블록을 사용하는 반면, Scripted Pipeline 은 node, stage 및 단계 호출과 함께 Groovy 코드를 사용합니다. Scripted Pipeline 은 워크플로우에서 더 직접적인 Groovy 제어 흐름이 필요할 때 유용합니다.
이번 실습에서는 scripted-pipeline-demo라는 이름의 파이프라인 작업을 생성하고, 간단한 Scripted Pipeline 을 실행한 다음, if 조건문과 try/finally 정리 블록을 추가하여 업데이트해 보겠습니다.
기본 Scripted Pipeline 작성하기
이 단계에서는 Scripted Pipeline 의 첫 번째 버전을 작성합니다. node 블록은 Jenkins 에게 실행기 (executor) 와 작업 공간 (workspace) 을 할당하도록 요청합니다. 그 내부에서 stage는 워크플로우의 가시적인 부분을 정의하며, sh는 셸 명령을 실행합니다.
/home/labex/project/scripted-pipeline.groovy 파일을 생성합니다:
cat > /home/labex/project/scripted-pipeline.groovy <<'GROOVY'
node {
stage('Prepare') {
echo 'Preparing scripted pipeline'
sh 'pwd'
}
stage('Build') {
echo 'Building with scripted syntax'
sh 'echo Compiling scripted pipeline demo'
}
}
GROOVY
구조를 검토할 수 있도록 줄 번호와 함께 파일을 출력합니다:
nl -ba /home/labex/project/scripted-pipeline.groovy
Prepare 및 Build 단계를 포함하는 node 블록이 보여야 합니다.
스크립트로부터 파이프라인 작업 생성하기
이 단계에서는 Groovy 스크립트를 인라인으로 저장하는 Jenkins 파이프라인 작업을 생성합니다. Jenkins 파이프라인 작업은 /var/jenkins_home/jobs 아래에 XML 형식으로 저장됩니다. Python 을 사용하여 작업 구성을 작성하기 전에 Groovy 스크립트를 XML 이스케이프 처리함으로써 따옴표나 중괄호와 같은 문자가 안전하게 보존되도록 합니다.
파이프라인 작업 구성을 생성합니다:
python3 - <<'PY'
from html import escape
from pathlib import Path
script = Path("/home/labex/project/scripted-pipeline.groovy").read_text()
config = f"""<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
<actions/>
<description>Run a Jenkins scripted Pipeline example.</description>
<keepDependencies>false</keepDependencies>
<properties/>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
<script>{escape(script)}</script>
<sandbox>true</sandbox>
</definition>
<triggers/>
<disabled>false</disabled>
</flow-definition>
"""
Path("/home/labex/project/scripted-pipeline-config.xml").write_text(config)
PY
작업 구성을 Jenkins 에 복사하고 다시 로드합니다:
docker exec jenkins mkdir -p /var/jenkins_home/jobs/scripted-pipeline-demo
docker cp /home/labex/project/scripted-pipeline-config.xml jenkins:/var/jenkins_home/jobs/scripted-pipeline-demo/config.xml
/home/labex/project/reload-jenkins.sh
Jenkins 가 파이프라인 작업을 성공적으로 로드했는지 확인합니다:
curl -fsS http://localhost:8080/job/scripted-pipeline-demo/api/json | grep -o '"name":"scripted-pipeline-demo"'
Scripted Pipeline 실행하기
이 단계에서는 파이프라인 작업을 트리거하고 결과를 확인합니다. Jenkins 는 크럼 (crumb) 을 사용하여 POST 요청을 보호하므로, 첫 번째 명령으로 크럼을 요청하고 일치하는 쿠키 저장소를 재사용합니다.
첫 번째 빌드를 트리거합니다:
CRUMB=$(curl -fsS -c /tmp/jenkins-scripted-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -b /tmp/jenkins-scripted-build.cookies -H "$CRUMB" -X POST http://localhost:8080/job/scripted-pipeline-demo/build
빌드 #1이 완료될 때까지 기다립니다:
until curl -fsS http://localhost:8080/job/scripted-pipeline-demo/1/api/json >/tmp/scripted-build-1.json 2>/dev/null && grep -q '"building":false' /tmp/scripted-build-1.json; do
echo "Waiting for scripted pipeline build #1..."
sleep 3
done
빌드 결과를 확인합니다:
curl -fsS http://localhost:8080/job/scripted-pipeline-demo/1/api/json | grep -o '"result":"SUCCESS"'
성공적인 결과는 Jenkins 가 Scripted Pipeline 구문을 수락하고 셸 단계를 실행했음을 증명합니다.
Groovy 제어 흐름 추가하기
이 단계에서는 Groovy 제어 흐름을 사용하여 Scripted Pipeline 을 업데이트합니다. if 블록은 Test 단계를 실행할지 여부를 결정합니다. try/finally 블록은 단계가 실패하더라도 정리 메시지가 실행되도록 보장합니다.
파이프라인 스크립트를 더 풍부한 버전으로 교체합니다:
cat > /home/labex/project/scripted-pipeline.groovy <<'GROOVY'
node {
def runTests = true
try {
stage('Prepare') {
echo 'Preparing scripted pipeline'
sh 'pwd'
}
stage('Build') {
echo 'Building with scripted syntax'
sh 'echo Compiling scripted pipeline demo'
}
if (runTests) {
stage('Test') {
echo 'Tests enabled by Groovy condition'
sh 'echo Running scripted pipeline tests'
}
}
} finally {
echo 'Pipeline cleanup complete'
}
}
GROOVY
작업 구성을 다시 생성하고 Jenkins 를 다시 로드합니다:
python3 - <<'PY'
from html import escape
from pathlib import Path
script = Path("/home/labex/project/scripted-pipeline.groovy").read_text()
config = f"""<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
<actions/>
<description>Run a Jenkins scripted Pipeline example.</description>
<keepDependencies>false</keepDependencies>
<properties/>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
<script>{escape(script)}</script>
<sandbox>true</sandbox>
</definition>
<triggers/>
<disabled>false</disabled>
</flow-definition>
"""
Path("/home/labex/project/scripted-pipeline-config.xml").write_text(config)
PY
docker cp /home/labex/project/scripted-pipeline-config.xml jenkins:/var/jenkins_home/jobs/scripted-pipeline-demo/config.xml
/home/labex/project/reload-jenkins.sh
업데이트된 작업 구성에 새로운 Test 단계 텍스트가 포함되어 있는지 확인합니다:
docker exec jenkins grep -n 'Tests enabled by Groovy condition' /var/jenkins_home/jobs/scripted-pipeline-demo/config.xml
업데이트된 파이프라인 로그 확인하기
이 단계에서는 업데이트된 Scripted Pipeline 을 실행하고 콘솔 출력을 확인합니다. 로그에는 조건부 Test 단계 메시지와 finally 블록의 정리 메시지가 표시되어야 합니다.
두 번째 빌드를 트리거합니다:
CRUMB=$(curl -fsS -c /tmp/jenkins-scripted-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -b /tmp/jenkins-scripted-build.cookies -H "$CRUMB" -X POST http://localhost:8080/job/scripted-pipeline-demo/build
빌드 #2가 완료될 때까지 기다립니다:
until curl -fsS http://localhost:8080/job/scripted-pipeline-demo/2/api/json >/tmp/scripted-build-2.json 2>/dev/null && grep -q '"building":false' /tmp/scripted-build-2.json; do
echo "Waiting for scripted pipeline build #2..."
sleep 3
done
중요한 콘솔 라인을 출력합니다:
curl -fsS http://localhost:8080/job/scripted-pipeline-demo/2/consoleText | grep -E 'Tests enabled|Running scripted pipeline tests|Pipeline cleanup complete|Finished: SUCCESS'
데스크톱 인터페이스에서 Firefox 를 열고 http://localhost:8080/job/scripted-pipeline-demo/2/console에 접속합니다. 콘솔 페이지에 Test 단계 출력과 정리 메시지가 표시되어야 합니다.

요약
node, stage, echo, sh 단계를 사용하여 Jenkins Scripted Pipeline 을 작성하고, 이를 파이프라인 작업으로 실행한 다음, Groovy if 및 try/finally 제어 흐름을 추가했습니다. Jenkins 빌드 결과와 콘솔 출력을 통해 두 파이프라인 버전을 모두 검증했습니다.