본문 바로가기
DevOps/Jenkins

[Jenkins] 윈도우즈 서버에 Pipeline 적용

by 오이가지아빠 2021. 7. 19.

#1. 윈도우즈 서버 Jenkins Pipeline

윈도우즈 서버에 Jenkins pipeline을 적용하기 위해 구글링을 하다보면 생각보다 정보가 많지 않다.

 

거의 모든 예제가 리눅스 중심으로 이루어져 있어서 윈도우즈 환경에 맞는 샘플을 찾기가 쉽지 않은데

 

많은 삽질 끝에 적용한 Jenkins Pipeline을 공유해본다.

 

참고로 이 예제는 ASP.NET 소스를 배포하는게 목적이기 때문에 빌드 과정이 생략되어 있고

 

1. git에서 소스 가져오기

2. 기존 반영했던 버전과 다른점을 찾아서 반영해야 할 파일만 반영(파일 복사 or 파일 삭제)

 

위와 같은 과정으로 단순하게 작성되었다.

 

Maven 빌드과정이 필요하면 이전 포스팅을 참고하자.

2021.03.29 - [DevOps/Jenkins] - Jenkins 설정 – Pipeline Setting

 

#2. JenkinsFile

node {
    def lastDeployCommitId  // 지난번 최종 반영됐던 커밋 ID (lastDeployCommitId 파일에 저장되어 있음)
    def nowDeployCommitId   // 현재 반영할 git HEAD 의 커밋 ID
    def workDir = 'C:\\DEPLOYDIR\\' // 실제 파일이 배포될 경로
    
    // 1. 저장소 소스 가져오기
    stage('Pull Source') {
        // Get some code from a GitHub repository
        // git 저장소에서 소스를 가져온다
        git 'http://GIT URL/repository.git'
    }

    // 2. 기존 반영소스와 비교하여 변경점 찾기
    stage('Compare Diff') {

        // Check file exists
        // 최종 반영됐던 커밋 ID를 보관하는 파일이 있는지 검사한다.
        def existsFile = fileExists 'lastDeployCommitId'
        if( existsFile ) {
            println('Exist Last Commit Id!!')
            lastDeployCommitId = (readFile(file: 'lastDeployCommitId', encoding: 'UTF-8')).trim()
        } else {
            println('Not Exist Last Commit Id!!')
            lastDeployCommitId = powershell(script:'git rev-parse HEAD', returnStdout: true).trim()
        }
        
        nowDeployCommitId = powershell(script:'git rev-parse HEAD', returnStdout: true).trim()
        
        println('lastDeployCommitId='+lastDeployCommitId)
        println('nowDeployCommitId='+nowDeployCommitId)
        
        // Make file to modified file list
        // 수정된 내용을 감지하여 파일로 저장한다.
        bat(script: """
            git diff --name-only --output=modifiedList --diff-filter=AM ${lastDeployCommitId}..${nowDeployCommitId}
        """)
        
        // Make file to deleted file list
        // 삭제된 내용을 감지하여 파일로 저장한다.
        bat(script: """
            git diff --name-only --output=deletedList --diff-filter=D ${lastDeployCommitId}..${nowDeployCommitId}
        """)
    }

    // 3. 반영할 내용을 배포 경로에 반영한다.
    stage('Source Deploy') {
        // Process deleted files
        // 파일을 읽어 삭제된 내용을 반영한다.
        isDeleted = (readFile(file: 'deletedList', encoding: 'UTF-8')).trim()
        if(isDeleted) {
            println("Exist deleted files!!")
            def lines = isDeleted.readLines()
            for(line in lines) {
                line = line.replace('/', '\\')
                println(line)
                bat(script: """
                    del /q "${workDir}${line}"
                """
                )
            }
        } else {
            println("Not exist deleted files!!")
        }
        
        // Process modefied files
        // 파일을 읽어 수정된 내용을 반영한다.
        isModified = (readFile(file: 'modifiedList', encoding: 'UTF-8')).trim()
        if(isModified) {
            println("Exist modified files!!")
            // Make zip file for modified list
            powershell(script: """
                git archive -o modified.zip HEAD \$(cat modifiedList)
            """)
            bat(script: """
                copy .\\modified.zip ${workDir}
            """
            )
            unzip(zipFile: "${workDir}modified.zip", dir: "${workDir}WebSite")
        } else {
            println("Not exist modified files!!")
        }
    }

    // 4. 최종 반영한 커밋 ID를 파일로 저장한다.
    stage('Write Deploy Results') {
        println('Write file for Last Deploy Commit Id!!')
        writeFile(file: 'lastDeployCommitId', text:nowDeployCommitId, encoding: 'UTF-8')
    }
}

 

git diff 명령어를 사용하여 두 버전간(최종 반영버전과 현재 반영할 버전)의 변경점을 파일로 저장한다.

이 때, diff-filter 옵션으로 삭제된 내용과 변경(추가)된 내용을 각각 저장한다.

 

그 후에 실제 배포할 디렉토리에서 삭제된 파일은 del 명령어로 삭제하고 변경 혹은 추가된 내용은 git archive로 묶어서 이동시킨 후, unzip 하여 그대로 덮어쓴다.

 

최종적으로 반영한 커밋 ID를 파일로 저장하여 다음번 배포 시에 참고할 수 있도록 한다.

물론 해당 파일은 별도로 저장해두어야 한다.(git push등으로)

 

반응형

댓글