Jenkins 파이프라인 구문: 초보자를 위한 종합 가이드

이 종합 가이드를 통해 Jenkins 파이프라인 구문의 미스터리를 풀어보세요. 에이전트, 스테이지, 단계, 후속 조치, 환경, 매개변수 및 모범 사례를 포함하여 선언적(Declarative) 및 스크립트(Scripted) 파이프라인의 필수 요소를 배웁니다. 실제 예제와 실행 가능한 조언을 통해 강력한 CI/CD 워크플로우를 효과적으로 구축할 수 있는 역량을 갖추세요.

젠킨스 파이프라인 문법: 초보자를 위한 종합 가이드

젠킨스 파이프라인 문법을 사용하면 빌드, 테스트, 배포 프로세스를 코드와 함께 있는 Jenkinsfile에 정의할 수 있습니다. 이는 파이프라인 변경 사항을 애플리케이션 코드처럼 검토하고, 버전 관리하고, 롤백할 수 있다는 점에서 중요합니다.

젠킨스 파이프라인이 처음이라면 선언형(Declarative) 파이프라인 문법부터 시작하세요. 구조화되어 있고 가독성이 좋으며, Groovy에 대한 깊은 지식 없이도 대부분의 CI/CD 워크플로우를 다룰 수 있습니다.

선언형 vs. 스크립트형 파이프라인

젠킨스는 두 가지 파이프라인 스타일을 지원합니다.

선언형 파이프라인은 엄격한 pipeline { ... } 구조를 사용합니다. 대부분의 팀에 가장 적합한 기본값입니다. 젠킨스가 파일 구조를 검증하고 UI에서 스테이지를 깔끔하게 표시할 수 있기 때문입니다.

스크립트형 파이프라인은 node { ... } 블록 내에서 Groovy를 사용합니다. 더 많은 제어를 제공하지만, 팀이 Groovy에 익숙하지 않으면 유지보수가 어려운 파이프라인을 만들기 쉽습니다.

먼저 선언형을 사용하세요. 선언형으로 깔끔하게 표현할 수 없는 로직이 필요할 때만 스크립트형을 사용하세요.

최소한의 선언형 파이프라인

기본 Jenkinsfile에는 에이전트, 스테이지, 단계가 포함됩니다:

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building the application'
                sh 'mvn clean package'
            }
        }

        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }
    }
}

agent any는 젠킨스가 사용 가능한 모든 에이전트에서 파이프라인을 실행하도록 지시합니다. 각 stage는 젠킨스 UI에 별도로 표시됩니다. steps 블록에는 젠킨스가 실행할 명령어가 포함됩니다.

Windows 에이전트에서는 sh 대신 bat을 사용하세요:

bat 'gradlew.bat test'

agent 지시어

agent 지시어는 파이프라인 또는 스테이지가 실행될 위치를 결정합니다.

사용 가능한 모든 에이전트에서 실행:

agent any

특정 레이블이 있는 에이전트에서 실행:

agent { label 'linux && docker' }

전역 에이전트를 건너뛰고 스테이지별로 선택:

pipeline {
    agent none

    stages {
        stage('Build') {
            agent { label 'linux' }
            steps {
                sh './build.sh'
            }
        }
    }
}

agent none은 빌드는 Linux, 설치 프로그램 테스트는 Windows처럼 서로 다른 스테이지에 다른 환경이 필요할 때 유용합니다.

스테이지와 단계

스테이지를 사용하여 파이프라인을 개발자가 한눈에 이해할 수 있는 작업(체크아웃, 빌드, 테스트, 패키징, 배포)으로 분할하세요.

stages {
    stage('Checkout') {
        steps {
            checkout scm
        }
    }

    stage('Unit Tests') {
        steps {
            sh 'npm test'
        }
    }
}

스테이지 이름을 의미 있게 지정하세요. 명령어 50개가 들어 있는 Run이라는 스테이지는 디버깅하기 어렵습니다. 스테이지가 20개인 파이프라인은 너무 복잡합니다. 실제 워크플로우 체크포인트와 일치하는 스테이지를 목표로 하세요.

환경 변수

여러 스테이지에서 필요한 값에는 environment를 사용하세요:

pipeline {
    agent any

    environment {
        APP_NAME = 'orders-api'
        IMAGE = "registry.example.com/team/orders-api:${env.BUILD_NUMBER}"
    }

    stages {
        stage('Build Image') {
            steps {
                sh 'docker build -t "$IMAGE" .'
            }
        }
    }
}

Groovy 문자열에서는 env.APP_NAME을 통해 변수를 읽을 수 있습니다. 셸 단계에서는 젠킨스가 환경 변수를 내보내므로 $APP_NAME$IMAGE가 셸 내에서 작동합니다.

비밀 정보는 environment에 넣지 마세요. withCredentials와 함께 젠킨스 자격 증명을 사용하세요.

파라미터

파라미터를 사용하면 수동으로 빌드를 시작할 때 값을 선택할 수 있습니다:

pipeline {
    agent any

    parameters {
        string(name: 'BRANCH_NAME', defaultValue: 'main', description: 'Git branch to build')
        booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Run unit tests')
        choice(name: 'DEPLOY_ENV', choices: ['dev', 'staging', 'prod'], description: 'Target environment')
    }

    stages {
        stage('Show Inputs') {
            steps {
                echo "Branch: ${params.BRANCH_NAME}"
                echo "Deploy target: ${params.DEPLOY_ENV}"
            }
        }
    }
}

실행 간에 달라져야 하는 항목에 파라미터를 사용하세요. 프로덕션 변경 사항에 대한 검토를 우회하는 데 사용하지 마세요.

when을 사용한 조건부 스테이지

when 지시어는 스테이지 실행 여부를 제어합니다:

stage('Deploy to Production') {
    when {
        branch 'main'
    }
    steps {
        sh './deploy-prod.sh'
    }
}

표현식을 사용할 수도 있습니다:

stage('Test') {
    when {
        expression { return params.RUN_TESTS }
    }
    steps {
        sh 'npm test'
    }
}

whensteps 내부가 아닌 스테이지에 배치하세요.

사후 작업

post 블록은 스테이지 또는 파이프라인이 완료된 후 실행됩니다. 테스트 보고서 게시, 빌드 증거 보관, 정리 작업에 유용합니다.

pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
    }

    post {
        failure {
            echo 'Pipeline failed'
        }
        always {
            cleanWs()
        }
    }
}

junit은 테스트가 실패해도 테스트 결과를 게시합니다. cleanWs()는 Workspace Cleanup 플러그인에서 제공되므로 사용하기 전에 해당 플러그인을 설치하세요.

옵션

options를 사용하여 파이프라인 동작을 설정하세요:

pipeline {
    agent any

    options {
        timestamps()
        timeout(time: 30, unit: 'MINUTES')
        disableConcurrentBuilds()
        buildDiscarder(logRotator(numToKeepStr: '20'))
    }

    stages {
        stage('Build') {
            steps {
                sh './build.sh'
            }
        }
    }
}

이러한 옵션은 로그를 읽기 쉽게 만들고, 중단된 빌드를 중지하고, 동일한 작업의 중복 실행을 방지하고, 오래된 빌드 기록을 제한합니다.

실용적인 초보자 파이프라인

이 예제는 코드를 체크아웃하고, Java 프로젝트를 빌드하고, 테스트 결과를 게시하고, 패키징된 JAR을 보관합니다:

pipeline {
    agent { label 'linux' }

    options {
        timestamps()
        timeout(time: 30, unit: 'MINUTES')
        disableConcurrentBuilds()
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }

        stage('Publish') {
            steps {
                junit 'target/surefire-reports/*.xml'
                archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
            }
        }
    }
}

이것은 거대한 배포 파이프라인보다 더 나은 출발점입니다. 빌드가 안정화되면 이미지 게시, 보안 스캔 또는 배포 스테이지를 추가하세요.

스크립트형 파이프라인 기초

간단한 스크립트형 파이프라인은 다음과 같습니다:

node('linux') {
    stage('Checkout') {
        checkout scm
    }

    stage('Build') {
        sh 'mvn clean package'
    }
}

선언형 pipeline {} 블록을 스크립트형 파이프라인 내부에 감싸지 마세요. 선언형 script { ... } 블록 내에 작은 스크립트형 섹션을 혼합해야 하는 구체적이고 테스트된 이유가 없다면 두 스타일을 분리하여 유지하세요.

좋은 파이프라인 습관

Jenkinsfile을 소스 제어에 저장하세요. 비밀 정보는 젠킨스 자격 증명에 보관하세요. 스테이지 이름은 수행하는 작업과 일치하도록 지정하세요. post 블록에서 보고서를 게시하여 실패해도 유용한 증거가 남도록 하세요. 빌드가 밤새 중단되지 않도록 타임아웃을 추가하세요.

초보자의 파이프라인 문제는 대부분 숨겨진 가정에서 비롯됩니다. 특정 에이전트에만 도구가 존재하거나, 비밀 정보가 하드코딩되거나, 보고서가 성공 시에만 게시되는 경우 등입니다. 이러한 가정을 파이프라인에 명시적으로 만들면 젠킨스를 훨씬 더 신뢰할 수 있게 됩니다.