Jenkins Pipeline 문법 정리

Q·2023년 2월 7일
0

Jenkins

목록 보기
4/4

1. Pipeline

  • Pipeline이란 말 그대로 파이프를 이어 붙인것과 같은 형태로 Step by Step 형식의 각 단계를 이어 붙여 실행하는 방식
  • 이를 적용하면, Continuous Delivery & Continuous Deploy 손쉽게 구현할 수 있다.
  • 최신 버전의 jenkins를 설치할 경우 Pipeline이 Plug-In으로 등록되어 있다.
  • 설치되어 있지 않은 Jenkins를 운영 중이라면, Pipeline plugin (https://plugins.jenkins.io/workflow-aggregator)을 설치해야 한다.
  • 보다 상세한 Jenkins 관리를 원한다면 다음 url (https://jenkins.io/doc/book/managing/plugins/)을 참고!

2. Jenkins 파이프라인 정의

Jenkins 파이프라인은 여러 방식으로 구현이 가능하다.

  • Jenkins Webadmin : 일반적인 방식으로 Jenkins 파이프라인을 생성하여 Shell Script를 직접 생성하여 빌드하는 방식
  • Git SCM : Git Repository에 JenkinsFile을 작성하여 빌드하는 방식
  • Blue Ocean : 파이프라인을 시각화하여 손쉽게 구성하여 빌드하는 방식

3. Jenkins 파이프라인 Script 문법 정의

Pipeline

pipeline {
    /* insert Declarative Pipeline here */
}
  • 파이프라인을 정의하기 위해서는 반드시 pipeline을 포함해야 한다.
  • pipeline은 최상위 레벨이 되어야하며, { }으로 정의해야 한다.
  • pipeline은 Section, Directives, Steps 또는 assignment 문으로만 구성되야 한다.

Section

a. agent : agent를 추가할 경우 Jenkins는 해당 agent를 설정한다.
  • any, none, label, node, docker, dockerfile, kubernetes를 파라미터로 포함할 수 있다.

  • agent는 pipeline의 최상위에 포함되어야 하며, agent가 none으로 작성되었을 경우 stage에 포함되어야 한다.

    ex) docker

    agent {
        docker {
            image 'myregistry.com/node'
            label 'my-defined-label'
            registryUrl 'https://myregistry.com/'
            registryCredentialsId 'myPredefinedCredentialsInJenkins'
        }
    }

    ex) dockerfile

    agent {
        dockerfile {
            filename 'Dockerfile.build'
            dir 'build'
            label 'my-defined-label'
            registryUrl 'https://myregistry.com/'
            registryCredentialsId 'myPredefinedCredentialsInJenkins'
        }
    }

    ex) agent가 적용 된 JenkinsFile Sample

    pipeline {
        agent none 
        stages {
            stage('Example Build') {
                agent { docker 'maven:3-alpine' }
                steps {
                    echo 'Hello, Maven'
                    sh 'mvn --version'
                }
            }
            stage('Example Test') {
                agent { docker 'openjdk:8-jre' }
                steps {
                    echo 'Hello, JDK'
                    sh 'java -version'
                }
            }
        }
    }
  • agent none이 pipeline의 최상위에 정의되어 있을 경우 stage는 각각 agent를 포함하여야 한다.

  • 이 JenkinsFile Sample을 통해 새로 작성된 컨테이너의 pipeline을 정의는데 유용히 사용할 수 있다.

b. post : 특정 stage나 pipeline이 시작되기 이전 또는 이후에 실행 될 confition block을 정의한다.
  • always, changed, fixed, regression, aborted, failure, success, unstable, unsuccessful,와 cleanup 등의 상태를 정의할 수 있다.

  • 일반적으로 post는 pipeline의 끝에 배치한다.

    ex) post가 적용 된 JenkinsFile Sample

    pipeline {
        agent any
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
        post { 
            always { 
                echo 'I will always say Hello again!'
            }
        }
    }
c. stages : 하나 이상의 stage에 대한 모음을 정의합니다.
  • pipeline 블록 안에서 한번만 실행 될 수 있습니다.
  • stages 내부에서는 여러 stage를 포함할 수 있습니다.
d. steps : stage 내부에서 실행되는 단계를 정의한다.

ex) stages와 steps가 적용 된 JenkinsFile Sample

pipeline {
    agent any
    stages { 
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

Directives

a. environment : key-value 형태로 파이프라인 내부에서 사용할 환경 변수로 선언할 수 있다.

ex) environment가 적용 된 JenkinsFile Sample

pipeline {
    agent any
    environment { 
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment { 
                AN_ACCESS_KEY = credentials('my-prefined-secret-text') 
            }
            steps {
                sh 'printenv'
            }
        }
    }
}
  • environment 최상위에 정의할 경우 pipeline 모든 단계에 환경 변수가 적용된다.
  • stage 내부에 정의한 환경 변수는 해당 stage에서만 유효하다.
b. options : pipeline의 옵션을 선택적으로 포함 시킬 수 있다.

options는 pipeline에서 한번만 정의 할 수 있다.

  • buildDiscarder

    • 특정 수의 최근 파이프 라인 실행에 대한 아티팩트 및 콘솔 출력을 유지한다.
    • ex) options { buildDiscarder(logRotator(numToKeepStr: '1')) }
  • checkoutToSubdirectory

    • 작업 공간의 서브 디렉토리에서 자동 소스 제어 체크 아웃을 수행한다.
    • ex) options { checkoutToSubdirectory('foo') }
  • disableConcurrentBuilds

    • 파이프 라인의 동시 실행을 허용하지 않는다. 공유 리소스 등에 대한 동시 액세스를 방지하는 데 유용 할 수 있다.
    • ex) options { disableConcurrentBuilds() }
  • disableResume

    • 마스터가 다시 시작되면 파이프 라인을 다시 시작하지 않게 도와준다.
    • ex) options { disableResume() }
  • newContainerPerStage

    • 함께 사용 docker 또는 dockerfile로 지정된 경우 각 스테이지는 동일한 컨테이너 인스턴스에서 실행되는 모든 스테이지가 아니라 동일한 노드의 새 컨테이너 인스턴스에서 실행된다.
  • overrideIndexTriggers

    • 분기 인덱싱 트리거의 기본 처리를 재정의 할 수 있다.
    • 멀티 브랜치 또는 조직 레이블에서 분기 인덱싱 트리거가 비활성화 된 options { overrideIndexTriggers(true) } 경우에 대해서만 활성화된다.
    • 그렇지 않으면 options { overrideIndexTriggers(false) }이 작업에 대해서만 분기 인덱싱 트리거를 비활성화한다.
  • preserveStashes

    • 스테이지를 다시 시작할 때 사용할 수 있도록 완료된 빌드에서 숨김을 유지한다.
    • ex) options { preserveStashes() }
    • 가장 최근에 완료된 빌드 options { preserveStashes(buildCount: 5) }에서 stash를 보존 하거나 가장 최근에 완료된 5 개의 빌드에서 stash를 보존하는 용도로 사용.
  • quietPeriod

    • 파이프 라인에 대한 자동 기간을 초 단위로 설정하여 글로벌 기본값을 대체한다.
    • ex) options { quietPeriod(30) }
  • retry

    • 실패하면 전체 파이프 라인을 지정된 횟수만큼 재 시도한다.
    • ex) options { retry(3) }
  • skipDefaultCheckout

    • agent 지시문에서 기본적으로 소스 제어에서 코드 체크 아웃을 건너 뛴다.
    • ex) options { skipDefaultCheckout() }
  • skipStagesAfterUnstable

    • 빌드 상태가 불안정 해지면 단계를 건너 뛴다.
    • ex) options { skipStagesAfterUnstable() }
  • timeout

    • Jenkins가 파이프 라인을 중단한 후 파이프 라인 실행에 대한 제한 시간을 설정한다.
    • ex) options { timeout(time: 1, unit: 'HOURS') }
  • timestamps

    • 파이프라인 실행에서 생성된 모든 콘솔 출력 앞에 라인이 생성 된 시간을 추가한다.
    • ex) options { timestamps() }
  • parallelsAlwaysFailFast

    • 파이프 라인의 모든 후속 병렬 단계에 대해 failfast를 true로 설정한다.
    • ex) options { parallelsAlwaysFailFast() }

    ex) options가 적용 된 JenkinsFile Sample

    pipeline {
        agent any
        options {
            timeout(time: 1, unit: 'HOURS') 
        }
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
  • 위와 같이 설정할 경우 Jenkins가 파이프라인 실행을 중단 한 후 1시간의 timeout을 설정한다.

c. parameters : 사용자가 제공해야할 변수에 대해 선언할 수 있다.
  • string, text, booleanParam, choice, password 등을 정의할 수 있다.

  • parameters는 pipeline에서 한번만 정의할 수 있다.

    ex) parameters가 적용 된 JenkinsFile Sample

    pipeline {
        agent any
        parameters {
            string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
    
            text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')
    
            booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')
    
            choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')
    
            password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')
        }
        stages {
            stage('Example') {
                steps {
                    echo "Hello ${params.PERSON}"
    
                    echo "Biography: ${params.BIOGRAPHY}"
    
                    echo "Toggle: ${params.TOGGLE}"
    
                    echo "Choice: ${params.CHOICE}"
    
                    echo "Password: ${params.PASSWORD}"
                }
            }
        }
    }
d. triggers : 파이프라인을 다시 트리거해야 하는 자동화된 방법을 정의한다.
  • cron, pollSCM, upstream 등 여러 방식으로 트리거를 구성할 수 있다.
    ex) triggers가 적용 된 JenkinsFile Sample
    pipeline {
        agent any
        triggers {
            cron('H */4 * * 1-5')
        }
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
e. tools : 설치 도구를 정의한다.
  • agent none으로 지정된 경우 무시된다.

  • 지원되는 도구는 maven, jdk, gradle이 있다.

    ex) tools가 적용 된 JenkinsFile Sample

    pipeline {
        agent any
        tools {
            maven 'apache-maven-3.0.1' 
        }
        stages {
            stage('Example') {
                steps {
                    sh 'mvn --version'
                }
            }
        }
    }
  • tools 이름은 Jenkins 관리의 Global Tool Configuration에서 사전 정의되어 있어야 한다.

f. input : input 지시문을 stage에 사용하면 input 단계를 사용하여 입력하라는 메시지를 표시할 수 있다.
  • 사용 가능한 옵션으로는 message, id, ok, submitter, submitterParameter, parameters가 있다.

    ex) input이 적용 된 JenkinsFile Sample

    pipeline {
        agent any
        stages {
            stage('Example') {
                input {
                    message "Should we continue?"
                    ok "Yes, we should."
                    submitter "alice,bob"
                    parameters {
                        string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
                    }
                }
                steps {
                    echo "Hello, ${PERSON}, nice to meet you."
                }
            }
        }
    }

4. Jenkins 파이프라인의 실행

  • Jenkins 파이프라인은 순차적 실행과 평행 실행으로 나눌 수 있다.

    ex) 순차적 실행 예제

    pipeline {
        agent none
        stages {
            stage('Non-Sequential Stage') {
                agent {
                    label 'for-non-sequential'
                }
                steps {
                    echo "On Non-Sequential Stage"
                }
            }
            stage('Sequential') {
                agent {
                    label 'for-sequential'
                }
                environment {
                    FOR_SEQUENTIAL = "some-value"
                }
                stages {
                    stage('In Sequential 1') {
                        steps {
                            echo "In Sequential 1"
                        }
                    }
                    stage('In Sequential 2') {
                        steps {
                            echo "In Sequential 2"
                        }
                    }
                    stage('Parallel In Sequential') {
                        parallel {
                            stage('In Parallel 1') {
                                steps {
                                    echo "In Parallel 1"
                                }
                            }
                            stage('In Parallel 2') {
                                steps {
                                    echo "In Parallel 2"
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    ex) 평행 실행 예제

    pipeline {
        agent any
        stages {
            stage('Non-Parallel Stage') {
                steps {
                    echo 'This stage will be executed first.'
                }
            }
            stage('Parallel Stage') {
                when {
                    branch 'master'
                }
                failFast true
                parallel {
                    stage('Branch A') {
                        agent {
                            label "for-branch-a"
                        }
                        steps {
                            echo "On Branch A"
                        }
                    }
                    stage('Branch B') {
                        agent {
                            label "for-branch-b"
                        }
                        steps {
                            echo "On Branch B"
                        }
                    }
                    stage('Branch C') {
                        agent {
                            label "for-branch-c"
                        }
                        stages {
                            stage('Nested 1') {
                                steps {
                                    echo "In stage Nested 1 within Branch C"
                                }
                            }
                            stage('Nested 2') {
                                steps {
                                    echo "In stage Nested 2 within Branch C"
                                }
                            }
                        }
                    }
                }
            }
        }
    }

이와 같은 Jenkins Pipeline Syntax를 적절히 활용하여 작성한다면, 보다 효과적이고 빠르면서도 다양한 검증 형태를 거칠 수 있을 것 이다.

참고

profile
Data Engineer

0개의 댓글