Jenkinsfile - 파라미터를 받는 실질적인 빌드 Job
2021. 3. 14. 02:59ㆍ버전관리 및 빌드/Jenkins
파라미터를 입력값으로 받는 Job 인 경우에는 "General" 섹션에서 다음을 체크하여야 한다.
[v] This project is parameterized
옵션 바로 밑의 "Add Parameters ▼" 를 클릭하면 파라미터를 추가할 수 있는 form fields 가 나오는데
본 기사에서는 파이프라인으로 다룰 것이기 때문에 그냥 넘어가도 된다. (Job 실행 시 나중에 파라미터 사용내역이 이력으로 남음)

스크립트 소스 :
pipeline {
agent any
tools {
maven 'Maven'
jdk 'JDK'
}
parameters {
string(defaultValue: 'dev', name: 'BUILD_TYPE', description: 'name of sub directory, for workspace')
string(defaultValue: 'master', name: 'GIT_BRANCH', description: 'git branch to pull down')
string(defaultValue: 'myServDev.war', name: 'FILE_NAME', description: 'name of .war file, ex: myApp.war')
string(defaultValue: 'Building for Dev application', name: 'DIST_SSH_SVR_TITLE', description: 'title to print on console log, ex: My Dev build')
string(defaultValue: '127.0.0.1', name: 'DIST_SSH_SVR_IP', description: 'specify the ip of ssh server to distribute ".war" file')
string(defaultValue: '/home/dev/test', name: 'DIST_SSH_PUT_LOCATION', description: 'canonical path of the directory to transfer ".war" file')
}
environment {
BUILD_TYPE = "${params.BUILD_TYPE}"
WORKSPACE = "${env.WORKSPACE}/${BUILD_TYPE}"
GIT_BRANCH = "${params.GIT_BRANCH}"
GIT_REMOTE_BRANCH = "refs/remotes/origin/${env.GIT_BRANCH}"
GIT_URL = 'http://localhost/git/myProject'
TARGET_WAR = "${env.WORKSPACE}/target/${params.FILE_NAME}"
DIST_SSH_SVR_TITLE = "${params.DIST_SSH_SVR_TITLE}"
DIST_SSH_SVR_IP = "${params.DIST_SSH_SVR_IP}"
DIST_SSH_PUT_LOCATION = "${params.DIST_SSH_PUT_LOCATION}"
LOCAL_FIRST_CHECK = 'true'
REMOTE_FIRST_CHECK = 'true'
ERROR_MESG = 'variable_not_set'
EMAIL_RECEPIENTS = 'staff@hey-yo.com, staff-2@hey-yo.com'
EMAIL_SENDER = 'notice@myServApps.com'
}
stages {
stage('빌드 대상 플랫폼') {
steps {
echo "${DIST_SSH_SVR_TITLE}"
}
}
stage('.git 검사') {
steps {
script {
ws("${WORKSPACE}") {
if (fileExists('.git')) {
echo 'found .git'
}
else {
git branch: "${GIT_BRANCH}", credentialsId: 'cc_ssh', url: "${GIT_URL}"
env.IS_GIT_INIT = "true"
}
}
}
}
}
stage('깃 변경여부 검사') {
steps {
checkBranchUsed()
getCommitLocal()
getCommitRemote()
compareLocalAndRemote()
}
}
stage('메이븐으로 컴파일') {
steps {
script {
if (GIT_CHANGED == "true") {// THIS IS TRUE
ws("${WORKSPACE}") {
try {
sh 'mvn clean'
sh 'mvn package'
}
catch (err) {
echo "Compile Failed"
error ${err}
}
}
}
}
}
}
stage('war 파일 생성여부 검사') {
steps {
script {
if (GIT_CHANGED == "true") {// THIS IS TRUE
if (fileExists(env.TARGET_WAR)) {
echo 'fileExists -- Yes!'
}
else {
env.ERROR_MESG = "${env.TARGET_WAR} NOT FOUND!"
error "${env.ERROR_MESG}"
}
}
}
}
}
stage('SSH 로 war 배포 단계') {
steps {
script {
if (GIT_CHANGED == "true") {// THIS IS TRUE
// distLocal()
distSSH()
}
}
}
}
}
post {
success {
script {
if (env.GIT_CHANGED == "true") {// THIS IS TRUE
env.SUCCESS_TITLE = 'from Jenkins -- myServ 앱 배포 성공'
env.SUCCESS_MESG = "(기존 ${GIT_BRANCH} 브랜치)\n " + "${CURRENT_LOCAL_COMMIT}\n" + "${GIT_LOCAL_COMMIT_DETAIL}\n\n" + "(가져온 ${GIT_REMOTE_BRANCH} 브랜치)\n " + "${CURRENT_REMOTE_COMMIT}\n" + "${GIT_REMOTE_COMMIT_DETAIL}\n\n" + "배포일시 : ${BUILD_TIMESTAMP}"
mail(subject: env.SUCCESS_TITLE, body: env.SUCCESS_MESG, to: env.EMAIL_RECEPIENTS, from: env.EMAIL_SENDER)
}
}
}
failure {
script {
env.FAILURE_TITLE = 'from Jenkins -- myServ 앱 배포 실패'
env.FAILURE_MESG = "(기존 ${GIT_BRANCH} 브랜치)\n " + "${CURRENT_LOCAL_COMMIT}\n" + "${GIT_LOCAL_COMMIT_DETAIL}\n\n" + "(빌드 시도 ${GIT_REMOTE_BRANCH} 브랜치)\n " + "${CURRENT_REMOTE_COMMIT}\n" + "${GIT_REMOTE_COMMIT_DETAIL}\n\n" + "${WORKSPACE}"
ws("${WORKSPACE}") {
if (bothCommitsAreSame() == "true") {
// 빌드 실패 발생 시 `다음 번 실행을 위해` 작업경로의 Git commit 를 한 단계 앞으로 되돌림
withCredentials([sshUserPrivateKey(credentialsId: 'cc_ssh', keyFileVariable: 'PASSWORD')]) {
sh 'git reset --hard HEAD~1'
}
}
else {
// Merge 하기 전 commit ID 를 알고 있는 경우 그것으로 되돌림
withCredentials([sshUserPrivateKey(credentialsId: 'cc_ssh', keyFileVariable: 'PASSWORD')]) {
sh 'git reset --hard "${CURRENT_LOCAL_COMMIT}"'
}
}
}
mail(subject: env.FAILURE_TITLE, body: env.FAILURE_MESG, to: env.EMAIL_RECEPIENTS, from: env.EMAIL_SENDER)
}
}
}
}
/* SSH 로 파일을 전송한다
(젠킨스 우선 설정)
1) {원격계정 홈}/.ssh/known_hosts 에 젠킨스가 설치된 서버계정의 public key 값을 추가한다
2) {젠킨스 설정}/manage credentials/ 에서 `Username & Password` 항목으로 `접속 계정정보`를 추가한다. 이 때 ID 를 아래 코드와 동일하게 ('distributor_ssh' 로) 기입한다.
3) 이제 아래 코드를 실행해도 된다.
*/
def distSSH() {
def remoteObj = [:]
remoteObj.name = "${DIST_SSH_SVR_TITLE}"
remoteObj.host = "${DIST_SSH_SVR_IP}"
remoteObj.allowAnyHosts = true
withCredentials([usernamePassword(credentialsId: 'distributor_ssh', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
remoteObj.user = USERNAME
remoteObj.password = PASSWORD
sshPut remote: remoteObj, from: TARGET_WAR, into: DIST_SSH_PUT_LOCATION
sshCommand remote: remoteObj, command: DIST_SSH_PUT_LOCATION + '/run.sh stop && ' + DIST_SSH_PUT_LOCATION + '/run.sh start'
}
}
def checkBranchUsed() {
ws("${WORKSPACE}") {
env.BR_USED_B4 = sh (
script: '''
#!/usr/bin/bash
set +x
git branch | grep "*" | cut -d " " -f 2
''',
returnStdout: true
).trim()
if (env.BR_USED_B4 && "${BR_USED_B4}" != "${GIT_BRANCH}") {
echo '----------------------------------------------------'
echo "바로 전에 빌드했던 브랜치(${BR_USED_B4})와 현재 빌드 대상 브랜치(${GIT_BRANCH})가 일치하지 않아 작업디렉토리를 초기화합니다."
echo "${WORKSPACE}"
sh """
set +x
rm -rf ${WORKSPACE}/*
rm -rf ${WORKSPACE}/.git*
rm -rf ${WORKSPACE}/.mvn
"""
echo '----------------------------------------------------'
git branch: "${GIT_BRANCH}", credentialsId: 'cc_ssh', url: "${GIT_URL}"
env.IS_GIT_INIT = "true"
}
}
}
def getCommitLocal() {
script {
// echo 'call getCommitLocal()'
ws("${WORKSPACE}") {
if ("${LOCAL_FIRST_CHECK}" == "true") {
withCredentials([sshUserPrivateKey(credentialsId: 'cc_ssh', keyFileVariable: 'PASSWORD')]) {
sh 'git rev-parse --is-inside-work-tree'
env.CURRENT_LOCAL_COMMIT = sh (
script: 'git rev-parse "${GIT_BRANCH}"',
returnStdout: true
).trim()
env.GIT_LOCAL_COMMIT_DETAIL = sh (
script: 'git show -s --oneline "${GIT_BRANCH}"',
returnStdout: true
).trim()
}
env.LOCAL_FIRST_CHECK = 'false'
}
}
echo '----------------------------------------------------'
echo "${GIT_BRANCH} : " + "${CURRENT_LOCAL_COMMIT}"
echo "${GIT_BRANCH} : " + "${GIT_LOCAL_COMMIT_DETAIL}"
echo '----------------------------------------------------'
}
}
def getCommitRemote() {
script {
if ("${REMOTE_FIRST_CHECK}" == "true") {
ws("${WORKSPACE}") {
git branch: "${GIT_BRANCH}", credentialsId: 'cc_ssh', url: "${GIT_URL}"
withCredentials([sshUserPrivateKey(credentialsId: 'cc_ssh', keyFileVariable: 'PASSWORD')]) {
env.CURRENT_REMOTE_COMMIT = sh (
script: 'git rev-parse "${GIT_REMOTE_BRANCH}"',
returnStdout: true
).trim()
env.GIT_REMOTE_COMMIT_DETAIL = sh (
script: 'git show -s --oneline "${GIT_REMOTE_BRANCH}"',
returnStdout: true
).trim()
}
env.REMOTE_FIRST_CHECK = 'false'
}
}
echo '----------------------------------------------------'
echo "${GIT_REMOTE_BRANCH} : " + "${CURRENT_REMOTE_COMMIT}"
echo "${GIT_REMOTE_BRANCH} : " + "${GIT_REMOTE_COMMIT_DETAIL}"
echo '----------------------------------------------------'
}
}
def compareLocalAndRemote() {
script {
if (bothCommitsAreSame() == "true") {
/* 기존 소스트리의 브랜치가 refs/remotes/origin/브랜치와 같으나
REPO 에서 처음 가져온 소스라면 `빌드를 허용`! */
if ("${env.IS_GIT_INIT}" == "true") {
env.GIT_CHANGED = "true"
echo '워크스페이스에 처음 가져온 소스이므로 빌드 및 배포를 허용함'
}
else {/* 기존 소스트리에서 검사했을 때 로컬과 리모트가 동일한 경우, `빌드 비허용` */
env.GIT_CHANGED = "false"
echo '워크스페이스의 소스와 리모트 간에 Revision 이 동일하므로 빌드 및 배포를 하지 않습니다'
}
}
else {
env.GIT_CHANGED = "true"
}
}
}
def bothCommitsAreSame() {
script {
/*
* CURRENT_LOCAL_COMMIT, CURRENT_REMOTE_COMMIT 값을 모르는 경우,
* 파이프라인 개발자가 소스를 한 번 더 들여다 볼 수 있도록
* true 를 반환해서 빌드가 실행되는 것을 막는다.
*/
if ("${CURRENT_LOCAL_COMMIT}" == "" || "${CURRENT_LOCAL_COMMIT}" == "null") {
echo 'CURRENT_LOCAL_COMMIT 값이 없네요. getCommitLocal() 를 먼저 실행해야 합니다!'
return "true"
}
else if ("${CURRENT_REMOTE_COMMIT}" == "" || "${CURRENT_REMOTE_COMMIT}" == "null") {
echo 'CURRENT_REMOTE_COMMIT 값이 없네요. getCommitRemote() 를 먼저 실행해야 합니다!'
return "true"
}
// 여기서부터 진짜 비교
else if ("${CURRENT_LOCAL_COMMIT}" == "${CURRENT_REMOTE_COMMIT}") {
return "true"
}
else {
return "false"
}
}
}
def buildEmailContent() {
script {
env.NOJOB_TITLE = 'from Jenkins -- No job'
env.NOJOB_MESG = "(기존 ${GIT_BRANCH} 브랜치)\n " + "${CURRENT_LOCAL_COMMIT}\n" + "${GIT_LOCAL_COMMIT_DETAIL}\n\n" + "(${GIT_REMOTE_BRANCH} 브랜치)\n " + "${CURRENT_REMOTE_COMMIT}\n" + "${GIT_REMOTE_COMMIT_DETAIL}\n\n" + "로컬 저장소의 커밋과 원격 저장소의 커밋이 일치하므로 빌드 및 배포를 하지 않음."
}
}
'버전관리 및 빌드 > Jenkins' 카테고리의 다른 글
Jenkinsfile - binding Parameters (0) | 2021.03.14 |
---|---|
Jenkins 서비스 구축 후기 (0) | 2021.03.08 |