Jenkins로 GitHub CI 구축하기

 

Jenkins와 GitHub를 연동해 develop branch에 대한 PR이 open되면 자동으로 빌드 테스트를 진행하도록 Jenkins CI 환경을 설정하는 과정을 자세히 기록하고자 한다. 

 

우선, 사전에 다음의 Jenkins Plugin을 설치해야 한다.

 

Plugin 목록

 

SSH Agent

Docker
Docker Commons Plugin
Docker Pipeline
Docker API Plugin

Generic Webhook Trigger

 

1. GitHub Webhook 설정

CI pipeline을 구축하기 위해서 가장 먼저 해야할 작업은, Jenkins 서버와 연결할 GitHub Repository가 Jenkins 서버에 신호 즉, hook을 보낼 수 있도록 설정해주는 것이다.

 

GitHub Repository > Settings > Webhooks > Add webhook

 

edited_blob

 

Payload URL에는 GitHub와 연동할 Jenkins 서버 주소/github-webhook/을 입력해준다. Content typeapplication/json을 선택한다.

blob

 

Which events would you like to trigger this webhook? 항목에서는 Let me select individual events > Pullrequests 를 선택한다. 기본적으로 선택되어있는 Pushes 항목은 해제했다.

 

이 부분은 Jenkins pipeline 실행 이벤트에 따라 선택해주면 되는데, 나는 merge 브랜치로 사용하던 develop 브랜치에 팀원들의 PR이 open 되면 빌드 테스트가 진행되도록 pipeline을 구성하고자 했기에 Pull requests 옵션을 선택했다. 실제 코드가 merge 되기 전에, merge 환경에서 테스트 pipeline을 실행하고 성공 및 실패 여부에 따라 merge 가능 여부를 판단할 수 있도록 구성하기 위해서였다.

 

edited_edited_blob

 

 

해당 hook이 설정되도록 Active를 선택한 후, Add webhook을 클릭해 설정을 저장한다.

 

etc-image-3

 

2. Github Rulesets 설정

GitHub Repository에 원하는 방식의 Webhook을 설정했다면, branch rule을 만들어줘야 한다.

 

GitHub Repository > Settings > Rules > Rulesets > New ruleset > New branch ruleset

 

blob

 

Ruleset Name을 지정해주고, Ruleset이 해당 Repository에 반영되게 하기 위해 Enforcement statusActive로 설정한다. Target branches > Add target을 클릭해, Include by pattern > develop 을 입력한다. 패턴식에 따라 특정 패턴을 가진 브랜치들에 모두 적용할 수 있는데, 나는 develop 브랜치에만 적용할 것이기 때문에 develop을 입력해줬다.

blob

 

blob
blob
etc-image-8

다음으로는 위에서 입력한 Target branch에 대한 rule을 설정해줘야 한다. Branch rules에서 Restrict deletions, Require status checks to pass, Block force pushes 를 선택하면 된다. 

edited_blob


Require status checks to pass 를 선택하면 additional settings를 구성할 수 있는데, Require branches to be up to date before merging를 선택하고 Add checks > CI를 입력한다. 

 

Require branches to be up to date before merging 옵션은, 병합(Merge) 전에 branch의 최신 코드를 반영해 테스트가 진행되어야 한다는 의미이다. 이 옵션을 선택하면 기준 branch인 develop의 최신 변경 사항을 PR을 생성한 branch에서 반영해 CI를 진행할 수 있다.

 

 

blob

 

etc-image-11

Create를 눌러, Branch Rule을 저장한다.

 

3. GitHub API 서버 등록

다음으로는 Jenkins에서 GitHub API server를 등록해줘야 한다.

 

Jenkins 관리 > System > Github > Github server

 

API URL에는 https://api.github.com을 입력하면 된다. Name은 지정 해도 되고 안해도 된다. 

Credentials이 Jenkins에 등록되지 않았다면 직접 추가를 해 줘야 한다. Credentials 밑의 +Add > Jenkins를 클릭하고 Jenkins를 GitHub와 연동하기 위해 GitHub personal access token을 등록해보자. 

edited_blob

 

이 부분이 중요한데, Kind에서 반드시 Username and Password가 아닌, Secret Text 를 지정해야 한다. 후에 Jenkins pipeline을 구축하는 과정에서 GitHub Repository를 지정할 때에는 Username and Password 타입의 Credentials을 사용하지만, 이 부분에서는 Secret Text 형식의 Credentials을 사용한다.

 

Secret 값에는 GitHub에서 발급받은 personal access token을 넣어주고, ID에는 Jenkins 내에서 사용할 credentials 이름을 입력한다.

 

blob

 

Add를 눌러 Credentials를 등록했다면 해당 Credentials를 선택한 후, 잘 연동되었는지 Test Connection을 시도한다.

edited_blob

 

정상적으로 연결되었다면, 다음과 같이 GitHub 계정명을 볼 수 있다. Save를 클릭해 설정을 저장해주자.

 

etc-image-15

 

4. Jenkins Gradle 등록

GitHub와 연결하는 데 성공했다면, Jenkins에 Build Tool을 등록해줘야 한다. SpringBoot 프로젝트를 기준으로 나는 Gradle로 Build를 진행하고자 했기에, Tool로 프로젝트에서 사용하는 Gradle과 동일한 버전의 Gradle을 등록해줬다.

 

Jenkins 관리 > Tools > Gradle installations > Add Gradle

 

Install automatically를 선택하면 Add Installer > Install from Gradle.org를 클릭하고 GitHub Repository에서 테스트 시 사용할 Gradle 버전을 선택한다. 내 SpringBoot 프로젝트에선 Gradle 8.12.1 버전을 사용 중이었으므로, 해당 버전을 선택해줬다.

blob

 

 

5. Jenkins Item 생성

1 ~ 4번 세팅이 끝났다면, 이젠 Jenkins에 CI 테스트를 위한 Item을 만들 수 있다. 새로운 Item+ 를 클릭해 Item을 생성하자.

 

Item 이름으로는 CI를 입력해줬다. 2번에서 GitHub Branch Ruleset 설정 시 checks 항목으로 추가한 이름과 동일하게 작성해줬다. 다음으로는 Item의 type을 정해야하는데, 나는 Freestyle project를 선택했다. Pipeline type은 실제 script를 작성하는 방식으로 정교하게 stage를 관리할 수 있다고 알려져 있지만, 우선 Jenkins에서 사용자에게 제공하는 GUI 기반의 Freestyle project 방식을 사용해보기 위함이었다.

 

후에 CI/CD를 release branch에 구축하는 작업을 진행했는데, 그 부분에서는 Pipeline type의 Item을 생성해 직접 script를 작성했다. 그 부분은 나중에 포스팅 할 예정이다.

etc-image-17

 

6. Jenkins Item Configure

마지막 단계이다. CI 테스트를 어떠한 구성으로 진행할 것인지 설정하는 단계이다. 가장 어려운 부분이기도 하고 다음 과정을 잘 따라해야 오류 없이 CI를 구축할 수 있다.

 

General에서 GitHub project를 선택하고, Project url에 연동하고자 하는 GitHub Repository 주소를 입력한다. 주의해야 할 점은 .git이 붙은 Clone 주소가 아닌, Repository 주소를 입력해야 한다는 점이다.

 

blob

 

 

이후 소스 코드 관리에서 Git을 선택한 후, Repository URLGitHub Repository Clone 주소를 입력한다.

 

이후 GitHub Repository의 프로젝트를 Jenkins가 Clone할 때 사용할 Credentials를 선택해야 한다. 3번에서 언급했던 Secret text type의 Credentials가 아닌, Username with password type의 GitHub credentials를 등록해야 한다. 미리 등록해놓지 않았다면,  Credentials 아래에 +Add > Jenkins를 선택해 3번에서 진행했던 방식과 유사하게 Credentials를 추가한다. 모든 설정이 끝나면 Add 를 클릭해 Credentials를 저장한다.

edited_blob

 

edited_blob

 

Credentials을 연동했다면, Branches to build에서 Branch Specifier에 Branch를 입력한다. 이 때 PR을 받을 Merge용 branch와 PR을 날릴 작업용 branch를 모두 입력해야 한다. 나의 경우엔 Merge branch로 develop을 사용하니 develop을 입력해줬고, feature 및 hotfix 네이밍의 branch들에서 PR을 open하므로 해당 branch들을 추가적으로 입력해줬다.

 

Branch Specifier을 여러 개 설정하고 싶다면 Add Branch를 클릭하면 된다.

blob

 

branch들을 설정해줬다면, PR 시 Jenkins 쪽에서 우리가 원하는 방식의 테스트를 진행할 수 있도록 커스텀 옵션을 추가해줘야 한다. Additional BehavioursAdd 를 클릭해 Merge before build 를 선택하자. Branch to merge to에 PR 받을 branch명을 입력한다. 나는 develop을 입력했다.

 

이 옵션은 Jenkins가 빌드 테스트를 진행할 때, 작업 branch의 내용을 develop branch에 Merge한 환경에서 테스트하도록 설정하는 옵션이다. PR 내용과 develop branch를 Merge 해도 정상적으로 빌드되는 지 테스트하기 위함이다.

etc-image-22

 

blob

 

다음으로 Triggers 항목을 선택해야 한다. 다음과 같이 설정해주자.

 

Trigger Events 밑의 Add를 누르면 Pull Request Opened를 Trigger Event로 등록할 수 있다.

blob

 

 

다음으로 Build Steps에서 Add build step 를 클릭해 Invoke Gradle script 를 선택해준다. Invoke Gradle의 Gradle Version에 4번에서 등록해 둔 Gradle를 선택한다.

blob

 

드디어 마지막 설정이다. 빌드 후 조치에서 빌드 후 조치 추가 를 클릭해 GitHub PR: set PR status 를 선택한다. Use only for builds with specific status 를 선택하여, Run when build status is better or equalSUCCESS를 선택한다.

테스트 성공 시, SUCCESS status를 GitHub에 전달하기 위함이다.

 

Mark unstable build in GitHub as 에는 FAILURE를 선택해준다. 테스트 결과가 UNSTABLE한 경우, FAILURE status를 전달하고자 했다.

 

blob

 

 

CI 설정을 마쳤으니, Save를 클릭해 설정을 저장하면 된다.

 

7. CI 테스트

 

설정한 Item이 정상적으로 동작하는 지 확인해보자.

 

로컬에서 작업한 branch를 원격 저장소로 push 한 후, develop branch에 PR을 올리면 Jenkins에서 이를 감지하고 PR branch 작업 내용에 대해 develop branch와 Merge된 환경에서 빌드 테스트를 진행한다. 만약 테스트에 성공하게 되면 Check passed 메시지와 함께 Merge 버튼이 활성화되어, Merge를 할 수 있게 된다.

 

etc-image-27

 

edited_blob

 

 

 

Jenkins는 참고 자료가 많아 에러 상황들도 쉽게 컨트롤 할 수 있을 것이라고 생각했는데 그게 아니었다. 각자의 환경이 다 다르고 마주하는 에러도 다양하다보니 다른 사람들의 해결법이 내 프로젝트엔 적용되지 않는 문제도 많았다. 그렇기 때문에 내 환경에 맞는 셋팅 과정을 자세하게 이를 기록해야겠다는 생각이 들었고, 이 글이 누군가에겐 도움이 되길 바란다!