처음 만드는 CI/CD - CI 세팅 편

홍지범·2023년 4월 3일
0
post-thumbnail

지난 INRTO에서 어떻게 CI/CD 파이프라인을 만들지 얘기했었습니다.

그림과 함께 더 자세하게 볼까요?

  1. 개발자가 깃 허브의 feat * 브랜치에서 코드를 push 하고 pr 을 생성한다
  2. 깃 허브의 웹훅이 젠킨스에서 post 요청을 보내 web hook trigger을 작동 시킨다.
    2-2. 젠킨스 웹훅은 설정한 조건에 해당한다면 빌드 파이프 라인을 작동 시킨다.
  3. 설정한 파이프라인을 작동 시킨 후 파이프라인의 결과(빌드 성공, 실패)를 pr의 코멘트로 달아 리뷰하기 전 올바른 코드를 올린지 먼저 체크한다.

지금부터 그림의 과정을 직접 구현해보겠습니다.

젠킨스 Credentials 세팅

가장 먼저 해야할 것은 젠킨스가 깃 허브의 리포지토리에 접근할 수 있도록 하는 것 입니다.
깃 허브에서 발급받은 access token을 젠킨스 환경변수의 credentials에 미리 세팅해둠으로서 제킨스가 해당 리포에 접근할 수 있도록 합니다.
(단순히 clone 하는 작업에 credentials가 필요하진 않지만 이후 빌드 결과를 코멘트로 남기기 위해 세팅하겠습니다.)

깃 허브의 Access Token 발급

깃 허브의 리포에 접근하려면 Access token이 필요합니다.

깃 허브 페이지의 오른쪽 상단 자신의 프로필 클릭 → Settings → Developer settings → Personal access tokens → Tokens(classic) → Generate new token(classic) 선택 후

그림에서 다음을 입력해 줍니다.

  • Note : 토큰 이름
  • Expiration : 만료 기간
  • Select scopes : 접근 권한
    • 리포지토리와 훅의 권한이 필요하므로 아래와 같이 선택해 줍니다.
      • repo 탭 모두
      • admin: repo_hook 탭 모두

설정을 완료 했으면 맨 밑의 Generate Token 버튼을 클릭하면 토큰을 확인할 수 있습니다.

ex. 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
**토큰은 발급했을 때 위와 같은 문자열을 꼭 어딘가에 저장하기 바랍니다. 까먹으면 새로 발급받고 기존 토큰을 사용한 곳 모두 수정해야 합니다.

젠킨스로 돌아가겠습니다.

젠킨스 메인화면 → 젠킨스 관리 → 시스템 설정 → GitHub 탭 → Credentials에 add를 누릅니다.

그림과 같은 입력창을 볼 수 있는데요.
Kind를 Secret text로 설정한다면 다음과 같이 설정하고 바로 Connection을 테스트 해볼 수 있습니다.

  • Secret : 깃 허브에서 발급받은 Access Token
  • ID : 젠킨스에서 사용할 Credential 이름

그림의 빨간 박스와 같이 나왔다면 발급한 토큰으로 연결에 성공한 것입니다.

하지만 이후 연결에서는 깃 허브의 ID 등이 필요하므로 Kind를 Username with password로 설정하고 옵션에 다음과 같이 입력합니다.

  • Username : 깃 허브 아이디
  • Password : 깃 허브에서 발급받은 Access Token
  • ID : 젠킨스에서 사용할 Credential 이름

등록한 Credential은 젠킨스 메인 → Jenkins 관리 → Manage Credentials에서 확인할 수 있습니다.

지금 한 것은 젠킨스 환경변수에 토큰을 등록한 것인데요.
미리 예고하자면 pipeline script를 작성할 때 credentialsI : ~~ 라든가 withCredentials() 등으로 꺼내쓸 수 있습니다.

파이프라인 만들기

이제 젠킨스에서 깃 허브의 리포로 접근은 가능해졌으니 내가 어떤 CI를 만들지 고민하고 Pipeline을 통해 만들어 보겠습니다.

젠킨스 메인 → 새로운 Item을 눌러보면 다양한 옵션들이 많은데 간단히 살펴볼까요?

  • FreeStyle project : 쉬운 사용과 간단한 파이프라인 구축 가능
  • Pipeline : Pipeline script를 활용한 세세한 설정 가능
  • Multibranch Pipeline: 한 프로젝트에서 여러 브랜치를 관리 가능

젠킨스가 처음이라면 혹은 CI/CD 구축이 처음이라면 FreeStyle로 간단하게 배포를 해볼 수 도 있습니다.

하지만 앞선 Intro 발견한 CI/CD는 다음과 같은 문제점이 있었습니다.

  • 모든 push 이벤트에 대해 CI/CD가 작동한다.
  • CI와 CD가 분리되지 않아 CI 직후 (잘못된 코드 포함) 모든 코드가 원격 서버로 배포된다.

깃 허브에 push 하면 원격 서버에 바로 배포 되는건 좋아보이지만 굳이 이 과정을 위해 서버를 하나 더 만들어가면서 젠킨스를 설치했어야 할까요?

이 문제점을 해결하기 위해 젠킨스의 Pipeline을 이용해 아래의 요구사항을 만족해 보겠습니다.

  • CI 와 CD가 분리되어야 한다.
  • 모든 push 이벤트에 대해 빌드가 일어날 필요 없다.
  • pr을 생성한 브랜치를 기준으로 코드의 빌드 테스트가 일어나야 한다.
  • 코드 리뷰 전 빌드 결과를 알 수 있어야 한다.
  • test 코드에 대한 검증이 일어난다(옵션)
  • 컨벤션에 대한 검증이 일어난다(옵션)

요구사항을 만족해 지속적으로 코드를 push 하고 하나의 pr단위가 만들어졌을 때 pr을 생성하면 자동으로 테스트를 합니다.

테스트에 대한 결과를 바탕으로(빌드 성공/실패) 코드 리뷰가 이루어지고 main 혹은 master 브랜치로 병합을 할 수 있습니다.

여기까지가 구축하려는 CI의 단계입니다. 이후 CD는 완성된 코드를 바탕으로 원격 서버에 배포된다면 되겠죠.
처음 소개한 그림과 같이 말이죠.

자 그럼 CI를 만들어 볼까요?
프로젝트의 이름을 입력하고 Pipeline을 선택 후 OK를 누릅니다.

처음 화면은 그림과 같을 겁니다.
우리는 Build Triggers 탭을 볼건데요.

여기서 Generic Webhook Trigger을 이용할 것 입니다.

만약 해당 옵션이 안보인다면 다음과 같이 해주세요.
젠킨스 메인 → Jenkins 관리 → 플러그인 관리 → Available plugins → Generic Webhook Trigger 검색 후 설치

설치가 되었다면 Generic Webhook Trigger을 체크 후 Post content parameters에 추가 버튼을 눌러주세요.

Post content parameters란?

  • 깃 허브 저장소에 웹훅에서 설정한 이벤트가 일어났을 때 젠킨스의 Generic Webhook Trigger(Token으로 구분)로 post 요청을 날립니다.
    이 때 요청의 payload에 다양한 값들이 저장되어 있습니다. 이 값 들의 상태에 따라 트리거를 작동 시킬지 여부를 선택할 수 있습니다.

이렇게 말로만 하면 더 헤깔리니 직접 설정하며 확인 해봅시다.

Post content parameters의 Variable에 그림과 같이 설정해 줍니다.

Post content parameters의 Variable에 그림과 같이 설정해 줍니다.

  • Name of variable : 변수로 쓸 이름
  • Expression : 깃 허브 웹훅이 post 요청한 payload에서 사용할 값 ($. 으로 시작하고 각 구분마다 . 으로 구분)
  • JSONPath 로 설정

그림의 설정은 pull_request의 state를 이 파이프라인에서 PR_OPEN이라는 변수로 사용하겠다는 의미와 같습니다.

그리고 paramter를 두 개 더 추가 후 다음과 같이 설정합니다.

  • REQUEST_BRANCH / $.pull_request.head.ref / JSONPath
  • NUMBER / $.number / JSONPath

다음과 같이 설정 했다면 이게 무슨 뜻인지 아리송 할테니 깃 허브의 웹훅에서 보낸 post 요청을 맛보기로 볼까요?

아! 웹훅이 POST 요청을 보냈고, 변수로 설정한 pull_request의 state 라는 값도 보이네요.
실제로 내려보면 엄청 많은 값들이 Payload에 들어가 있습니다.

이제 웹훅의 다양한 조건을 활용해 내가 원하는 조건에서 젠킨스를 작동시킬 수 있겠죠?

다시 젠킨스로 돌아오겠습니다.
이제 Generic Webhook Trigger에서 파라미터 설정은 끝났고 쭉 내려가다보면 Token이 있습니다.

Token은 깃 허브의 웹훅이 post 요청을 보낼 endpoint 입니다. 이전 그림 Headers의 Request URL을 보면

[http://젠킨스_주소/generic-webhook-trigger/invoke?token=SLACK_TOKEN]이 보이죠?

젠킨스에서 설정한 Token의 이름일 뿐입니다.
(이름이 SLACK_TOKEN인 이유는 기존의 슬랙 알림을 위한 프로젝트를 가져왔을 뿐입니다.)

토큰을 설정했다면 깃 허브에서 웹훅을 만들어 보겠습니다.

깃 허브 프로젝트 리포 → Settings → Webhooks → Add webhook 클릭

이제 그림과 같은 화면을 볼 수 있습니다.

  • Payload URL : http://{젠킨스_주소}/generic-webhook-trigger/invoke?token={바로 위에서 설정한 토큰 이름}
  • Content type : application/json
  • Secret : 공백
    그 다음이 중요한데요.

이전 그림의 빨간 박스를 보면 Just the push event라는 탭에 체크가 되어 있는것이 보입니다.
Intro에서 push 할 때 마다 발생했던 문제가 바로 이 웹훅 설정에 있었습니다.

그럼 Let me select individual events. 탭을 클릭해볼까요?
클릭하면 많은 옵션들이 보일겁니다. 이 옵션들을 활용해서 다양한 트리거를 작동시킬 수 있겠죠?
이번에 만들 CI는 pr을 생성했을 때 작동시킬 것 이기 때문에

그림과 같이 Pull requests에 클릭을 해주겠습니다. Pushes는 체크를 풀어주세요.

웹훅을 생성 했다면 다시 젠킨스로 돌아오겠습니다.
Generic web hook trigger의 Token도 설정 했으니 조금만 더 내려가볼까요?
Optional filter가 보입니다.
필터로 트리거 작동 조건을 더 상세하게 조정할 수 있습니다.

그림과 같이 설정합니다.

  • Expression : 정규 표현식으로 ?는 변수 =.*{value}로 특정 조건에 해당할 때 트리거를 작동시킬 수 있습니다.
  • Text : Post content parameters에서 선언한 변수명들을 Expression의 ? 순차대로 사용할 수 있습니다.
  • ex. Expression : (?=.open). / Text : $PR_OPEN 이라면 웹훅이 post 요청으로 보낸 payload에 이전에 설정한 pull_request.state 가 open 인 경우에만 트리거가 작동해 파이프라인을 실행합니다.

지금까지 한 내용을 정리해볼까요?

CI/CD 분리를 위해 웹훅과 트리거를 사용해 pr이 생성되었을 때 이 파이프라인이 작동하도록 했습니다.
이로써 개발자가 열심히 코드를 작성 후 pr 단위가 갖춰졌을 때 pr을 생성할 것이고, 젠킨스 파이프라인 스크립트에 맞는 빌드와 테스트가 이루어져 리뷰를 할 수 있는 상태가 될 것입니다.

이제 거의 다 왔습니다. 남은건 파이프라인 스크립트를 통해 빌드와 테스트만 한다면 CI는 완성됩니다.

** 파이프라인 스크립트 편에서 계속...

profile
왜? 다음 어떻게?

0개의 댓글

관련 채용 정보