반응형

Directives = 지시

 

젠킨스 파이프라인을 구성해보자.

이 젠킨스 파이프라인이 어떻게 구성되어있는지 익혀보자.

 

- 젠킨스는 하나의 파이프라인으로 구성되어 있다.

- 젠킨스 스크립트 작성 방법은 2가지가 있습니다

  • Declarative Pipeline : 보다 쉽게 작성 할 수 있게, 커스텀 되어 있음. Groovy-syntax기반 - Groovy 문법을 잘 몰라도 작성 가능
  • Scripted Pipeline : Groovy기반, Declarative보다 효과적으로 많은 기능을 포함하여 작성 가능. 하지만 작성 난이도가 높음
  • 2가지 문법을 번갈아 사용 가능 - 동시에는 X

1. 파이프라인 선언

 

2. 섹션(Sections)

섹션(Sections)은 파이프라인(Pipeline)에서 하나이상의 Steps이나 지시(Directives)로 이루어져있다.

젠킨스

stages > stage > steps

 

agent : 젠킨스가 특정 실행자를 지정하기 위해 사용함.

우선, agent는 Declarative Pipeline-specific syntax의 일종이다. 

 agent는 Jenkins가 실행자를 할당하도록 지시하는 지시어입니다. 그리고 그것은 또한 전체 pipeline을 위해 workspace를 지정합니다. 실행자(executor)라고하면 젠킨스 파이프라인을 직접 실행시킬 하나의 주체라고 생각하면 됩니다.

 

젠킨스 스크립트 안에 필수 포함 여부 필수
파라미터
  • any : 사용가능한 agent
  • none : global agent는 설정되지 않음. 대신 각 stage에 설정 필요
  • label : 특정 label 명으로 된 environment로 설정
  • node : label과 유사
  • docker : 특정 도커 이미지로 수행
  • dockerfile : 도커 파일 기반으로 수행
위치
  • pipeline top level(필수)
  • stage block(선택)

 

 

post : 특정 스테이지 이전 혹은 이후에 실행될 codition block

젠킨스 스크립트 안에 필수 포함 여부 선택
파라미터
  • always : 실행 끝나고나서 실행되는 step
  • changed : previous run과 다른 status이면 실행되는 step
  • failure : 실패하면 실행되는 step
  • success : 성공하면 실행되는 step
  • unstable : test fail, code violation 등일때 실행되는 step
  • aborted : 강제로 중지됬을 때 실행되는 step
위치
  • pipeline top level(선택)
  • stage block(선택)

 

 

stages : 스테이지의 모음

젠킨스 스크립트 안에 필수 포함 여부 필수
위치
  •  pipeline block에서 단 한번 쓸 수 있다.
pipeline {
    agent any
    stages { 
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}​

 

 

steps: stage 내부 block에서 여러번 호출 될 수 있는 block

젠킨스 스크립트 안에 필수 포함 여부 필수
위치
  • 각 stage block에서 여러번

 

 

출처: 젠킨스 공식 홈페이지

 

 

(Directives(파이프라인 configure))

environment : key-value style로 파이프라인 내부에서 사용할 변수로 선언 가능하다.

젠킨스 스크립트 안에 필수 포함 여부 선택
위치
  • pipeline 혹은 stage block 내부

https://www.jenkins.io/doc/pipeline/tour/environment/

 

 

 

 

pipeline {
    agent {
        label '!windows'
    }

    environment {
        DISABLE_AUTH = 'true'
        DB_ENGINE    = 'sqlite'
    }

    stages {
        stage('Build') {
            steps {
                echo "Database engine is ${DB_ENGINE}"
                echo "DISABLE_AUTH is ${DISABLE_AUTH}"
                sh 'printenv'
            }
        }
    }
}

https://www.jenkins.io/doc/pipeline/tour/environment/

 

 

Jenkins 예제

# 예제 3 shell command 이용하기

pipeline {
    agent { docker { image 'maven:3.8.4-openjdk-11-slim' } }
    stages {
        stage('build') {
            steps {
                sh 'mvn --version'
                sh 'echo hello world'
            }
        }
    }


# 출력화면


- shell command 여러개 입력하고 싶을 때

sh """#!/bin/bash +x
	cd ${FULLPATH} ;
	git checkout -b ${BRANCH} ;
	git checkout -b ${BRANCH} ;
"""

 

# 예제 2

pipeline {
    agent any
    stages {
    	stage('SCM') {
        	steps {
            	git 'https://github.com/simple-kss/DirectXTK12.git'
            }
        }
        stage('VS Build') {
        	steps {
            	bat 'msbuild.exe DirectXTK_Desktop_2019_Win10.vcxproj'
            }
        }
        stage('Verification') {
          steps{
            bat 'cppcheck --enable=all --inconclusive --xml --xml-version=2 src 2> cppcheck.xml'
            recordIssues enabledForFailure: true, aggregatingResults: true, tool: cppCheck(pattern: 'cppcheck.xml')
          }
        }
    }
}



만약 검증도 할 시

stage('Verification') {
  steps{
    bat 'cppcheck --enable=all --inconclusive --xml --xml-version=2 src 2> cppcheck.xml'
    recordIssues enabledForFailure: true, aggregatingResults: true, tool: cppCheck(pattern: 'cppcheck.xml')
  }
}


파이프라인을 의미하는게 하나가 있고.
agent라는 의미는 어떤 노드에서 할거냐 라는 의미
any는 활용가능한 노드를 스스로 선택해서 하는 것.
none은 사용하지 않는 것
혹은 레이블을 명시해서 노드를 지정해서 사용할 수 있다

stages안에 stage가 여러 개 있다.
파이프라인을 쓰는 이유는 소스코드를 가져와서 빌드도 하고
테스트와 정적도구로 검증도하고 패키징화해서 각각의 서버에 배포하는 것.

각각의 단계를 지정해 놓는게 stage이다.
steps 안에는 실행명령이 올 수 있음.

첫번쨰 stage는 SCM
맨처음에 이전까지 빌드하기 전
GIT에서 소스코드 가져오기 -> 그게 SCM이다.
SCM 소프트웨어 컨피규레이션 매니지먼트

window 같은 경우는 bat
리눅스 같은 경우는 sh 로 앞에 붙여준 다음 따옴표안에 넣어주면
그것을 실행한다.

Verification 혹은 CppCheck

recordIssues 라는 명령어는
이거는 Warning Next Generation을 제공하는 명령어.
뒤에 tool: cppCheck(pattern: 'cppcheck.xml') 이것이 중요한 문장이다.
WNG에 대한 api문서가 정의되어있는데 C<- 대문자로 해야함
cppcheck.xml값을 바탕으로 cppCheck을 실행을 하고 이 다음의 결과를 젠킨스에 개시를 해준다.

https://www.jenkins.io/doc/pipeline/steps/warnings-ng/
위의 사이트에가보면
publishUssues는 publish issues created by a static analysis scan
recordIssues는 Record compiler warnings and static analysis results.
scanForIssues Scan file or the console log for warnings or issues.
라 되어 있음

(파이프라인의)
이 뒤에 검증 테스트 혹은
동적인 테스트 혹은 '패키징' 하고 어디에 배포하고
'배포'는 직접적인 운영서버가 될 수 있고
C나 C++윈도우 앱같은 경우 특정파일서버나 ftp 서버가 될 수 있습니다.

젠킨스 파이프라인 문법

https://www.jenkins.io/doc/book/pipeline/syntax/

 

script

Declarative: 선언적인

script step은 Scripted Pipeline의 block 형식으로 되어있습니다. 그리고, 이 script step은 선언적인 Pipleline안에서 실행되는데요. 가장 흔한 use-cases를 위해, script step은 Declarative Pipelines에서 불필요해야만 합니다, 하지만, 그것이 유용한 "탈출구"를 제공할 수 있습니다.
복잡하거나 non-trivial(자명하지않은) 사이즈의 script block들은, Shared Libraries 로 옮겨져야 합니다.

예제

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

                script {
                    def browsers = ['chrome', 'firefox']
                    for (int i = 0; i < browsers.size(); ++i) {
                        echo "Testing the ${browsers[i]} browser"
                    }
                }
            }
        }
    }
}

 

Scripted Pipeline

Flow Control

node {
    stage('Example') {
        if (env.BRANCH_NAME == 'master') {
            echo 'I only execute on the master branch'
        } else {
            echo 'I execute elsewhere'
        }
    }
}

 

node {
    stage('Example') {
        try {
            sh 'exit 1'
        }
        catch (exc) {
            echo 'Something failed, I should sound the klaxons!'
            throw
        }
    }
}

 

When

jenkins if문 해당 value가 있다면
아래의 step을 실행해라라는 뜻 같음. (추후 공부 필요)
https://www.jenkins.io/doc/book/pipeline/syntax/

        stage('Build image') {
            when {
                environment name: 'IS_CONNECTED', value: 'true'
            }
            steps {
                buildImages()
            }
        }

 

젠킨스 환경변수

- https://opensource.triology.de/jenkins/pipeline-syntax/globals
- https://jayy-h.tistory.com/m/43
- (옛날버전, 허드슨, Enum GerritTriggerParameters)
https://javadoc.jenkins.io/plugin/gerrit-trigger/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerParameters.html
- https://github.com/jenkinsci/gerrit-trigger-plugin/blob/65135686c9657091dc000af3ee16a1b698742df7/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerParameters.java

1. env관련 환경변수 (env.으로 접근)

env 환경 변수는 다음과 같은 형식 env.VARNAME으로 참조될 수 있다. 대표적인 env의 property는 아래와 같다.

property (환경변수 이름) 설명
env.BUILD_ID 현재 빌드의 ID이며 이는 v1.597 이상에서는 BUILD_NUMBER와 같은 값을 가진다
env.JOB_NAME 현재 빌드중인 프로젝트의 이름으로 foo 또는 foo/bar와 같은 형식이다.
env.BRANCH_NAME multibranch 프로젝트인 경우 사용할 수 있으며, 현재 빌드되고 있는 브랜치명을 알려준다
env.CHANGE_ID multibranch 프로젝트의 change request에 대한 change ID(PR number)를 나타낸다.
env.CHANGE_URL multibranch 프로젝트의 change request에 대한 change URL을 나타낸다.
env.CHANGE_TARGET multibranch 프로젝트의 change request에 대해 merge될 base branch를 나타낸다.
env.CHANGE_BRANCH multibranch 프로젝트의 change request에 대해 현재 HEAD가 가리키고 있는 브랜치 명을 알려준다. 이는 BRANCH_NAME과 같을 수 있다.
env.BUILD_NUMBER 현재 build number를 나타낸다.
env.WORKSPACE 특정 디렉토리에 대한 절대 경로. 이 특정 디렉토리는 빌드를 위해 workspace로써 할당됨.
env.JENKINS_HOME 특정 디렉토리에 대한 절대 경로. 이 특정 디렉토리는 controller file system위에 할당됨 (젠킨스가 데이터를 저장하기 위해)
env.JENKINS_URL http://server:port/jenkins/와 같은 jenkins의 URL을 알려준다.
env.BUILD_URL http://server:port/jenkins/job/foo/15/와 같은 현재 build의 URL을 알려준다.
env.JOB_URL http://server:port/jenkins/job/foo/와 같은 job의 URL을 알려준다

 

2. currentBuild

currentBuild 변수는 RunWrapper 타입입니다. 아마 현재 진행중인 빌드를 참고하는 데 사용됩니다.
이것은, 읽는게 가능한 아래의 property들을 가지고 있습니다. currentBuild. 으로 접근 가능.

property (환경변수 이름) 설명
getBuildCause  
number 빌드 번호 (integer)
result 보통 SUCCESS, UNSTABLE, 혹은 FAILURE (진행중인 빌드에 대해선 null을 반환할 수 있음)
currentResult 보통 SUCCESS, UNSTABLE, 혹은 FAILURE. null이 절대로 될 수 없음.
displayName 보통 #123 하지만, 때론 SCM commit identifier가 설정되기도 함.
fullDisplayName 보통 folder >> folder 2 >> foo #123.
projectName 이 빌드의 프로젝트 이름, 예를 들어 foo.
description 추가적인 정보, (빌드에 대한)
id 보통 number (문자열로 되어있음)
changeSet 뚜렷한 SCM 체크아웃들로부터 오는 changesets의 목록
keepLog 만약 true이면, 이 빌드에 대한 로그 파일이 유지됨, 즉 지워지지 않음.

 

3. param

이 빌드에 정의된 모든 파라미터들을 보여줍니다. 해당 파라미터들은 다양하게 입력된 값들을 가진 read-only map으로써 되어있습니다. 예를 들면 아래와 같이 활용 가능합니다.

if (params.BOOLEAN_PARAM_NAME) {doSomething()}


혹은, 꽤나 중요한 default value를 제공하기 위해선, 아래와 같이 활용할 수 도 있습니다.

if (params.getOrDefault('BOOLEAN_PARAM_NAME', true)) {doSomething()}

 

4. Plugin: Gerrit trigger 및 Gerrit trigger 전용 환경변수 목록

   
GERRIT_CHANGE_NUMBER 게릿 트리거 발생 시, 해당 패치의 change 번호
GERRIT_PATCHSET_NUMBER 게릿 트리거 발생 시, 해당 패치의 patchset 번호
GERRIT_BRANCH 게릿 트리거 발생 시, 브랜치 정보


GERRIT_TRIGGER할 시 환경변수 목록
https://javadoc.jenkins.io/plugin/gerrit-trigger/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerParameters.html

젠킨스 로그/콘솔 출력

pipeline {
   agent any
    stages {
      stage('World') {
        steps {
            echo "Hello, ${PERSON}, nice to meet you."
        }
      }
   }
}


(ref. https://nerd-mix.tistory.com/50)

젠킨스 메모

 


Groovy 문법

출처: https://kotlinworld.com/320 [Kotlin World:티스토리]

그루비 : 자바 가상 머신에서 동작하는 오픈 소스 스크립트 언어. 피보탈사 중심으로 개발됐었지만, 지금은 아파치 소프트웨어 재단에 이관되었다.
사실 그래들을 이용하는데 그루비는 필요없다. 그래들 소프트웨어에는 그루비가 포함되어 있어서, 단지 그래들을 사용하는 용도라면, 그래들만 설치해도 충분하다.
하지만, 그루비 언어를 이용해서 프로그래밍하는 연습하지 않으면 gradle을 숙달하기가 쉽지 않으므로 다운받자.
https://title-developer.tistory.com/9


- 문자열 선언 방법

def kotlinWorldDef = "Kotlin World"
println(kotlinWorldDef.class)



- 여러줄 선언 방법

        def kotlinWorldHello = 
            """
            hello 
            kotlin world
            """
        println(kotlinWorldHello)



- 문자열에 변수 넣기

        def kotlinWorld = "Kotlin World"
        println("Hello ${kotlinWorld}")



- 패턴 비교

        def kotlinWorld = "support@kotlinworld.com"
        def emailPattern = /([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})/

        println(kotlinWorld ==~ emailPattern)
        //결과 true


- 조건문


- Groovy 메서드
자바랑 똑같습니다.
특이사항은, return을 명시적으로 지정하지 않아도, 마지막 줄이 return 값이 됩니다.

반응형