Tech

iOS 플랫폼의 Jenkins CI 환경 구축하기

2021. 06. 16

안녕하세요. 화해 개발팀 iOS 플랫폼에서 화해 앱 개발을 하고있는 전규찬입니다. Jenkins CI

 

최근 화해 iOS 플랫폼에서는 Jenkins CI 서버를 자체 구축하는 작업을 진행했는데요. 이전에 사용하던 Travis CI가 있었음에도 왜 Jenkins CI를 자체 구축하게 되었는지와 어떻게 구축하고 활용하고 있는지에 대해 공유해보고자 합니다.

 

 

 


 

 

Travis-CI를 더이상 사용하기 어려웠던 이유

 

iOS 플랫폼에서는 얼마 전까지 Travis-CI를 활용하여 CI를 구축해 사용하고 있었습니다.

 

 

Jenkins CI_구축

 

 

이야기에 앞서서, iOS 플랫폼에서 일하는 방식에 대해 간략히 설명하겠습니다.

 

플랫폼 구성원분들은 플랫폼 업무와 동시에 밴드 업무(크로스펑셔널조직)를 진행하면서 크고 작은 코드변경이 이루어집니다. 모든 코드수정은 Github의 Pull request를 올리도록 약속하고 있으며, Pull request가 올라왔을 경우 build + unittest를 실행합니다. 물론 Pull request의 추가 수정커밋이 발생하면 build + unittest를 실행합니다. 신규 입사 등으로 구성원들이 점차 많아지면서 Pull request의 횟수와 양은 더 많아지고 있는데요. 그만큼 Travis-CI의 사용량도 증가하게 되었습니다. 

 

저희의 Travis-CI 과금 플랜은 다음과 같았습니다.

  • 5 concurrent plan : 249$
  • iOS build credit : 15$ / 25000 credit

 

Travis-CI 과금 정책까지 확인해보니, iOS build에 있어서 매우 불리한 조건이었습니다. 왜냐하면 Travis-CI의 프로젝트 빌드 평균 시간이 개인 macbook으로 돌렸을 때보다도 오래 걸리는데 컴퓨팅 성능을 알 방법도 없었고, 변경할 수 있는 옵션도 없는 상태에서 과금은 빌드 시간을 기반으로 진행되었기 때문입니다.

 

 

Jenkins CI_과금정책

 

 

 

 

Travis-CI 과금 정책을 기반으로 산정한 사용량 계산Jenkins CI_travis사용량

 

 

 

여기서 우리는 의문점이 생깁니다.

 

Q. 프로젝트 평균 빌드 시간을 줄일 수는 없을까?

A. Build + Unit test를 개인 macbook을 이용해 빌드해보면 248.4s의 시간이 소요되는데요. 빌드에 필요한 thirdparty tools에 대해서는 travis-ci의 cache가 이루어져 있기 때문에 github pr branch를 pull하는 시간과 bundle setting하는 시간이 여기에 더 추가될 수 있습니다.

 

 

 

 

빌드 시간 계산

Jenkins CI_딜드시간계산

 

 

 

결과적으로 travis-ci에서 자세히 공개하지 않는 빌드머신의 퍼포먼스가 개인 맥북보다 떨어지고 있으며 빌드 시간으로 측정되는 과금 정책이 매우 아쉽다는 의견에 모두 공감해 이 부분에 대한 해결 방안을 고민하게 되었습니다.

 

 

 

 

 

Jenkins를 통한 CI 환경 구성 아이데이션

 

다양한 해결 방법 중 퍼포먼스가 좋으면서 자유로운 세팅이 가능한 CI server를 자체적으로 구축하는 것을 고려했습니다. 이 경우 편리한 점도 많지만 구축 방법이 무엇보다 중요하기 때문에 iOS 플랫폼은 Jenkins-CI 구축을 전제로 환경 구성에 대한 논의를 본격적으로 시작했습니다.

 

 

Jenkins CI_환경

 

 

 

Github과 jenkins 간 구축을 위한 전반적인 동작 방식을 정리해보면 아래와 같습니다.

  • github pull request event를 webhook을 통해 jenkins에 전달
  • jenkins 환경에는 iOS build에 필요한 환경구성을 미리 셋업 함으로써 초기 prebuild 시간 최소화
  • fastlane을 통한 CI용 lane 설정
  • 빌드 결과를 github에 통보

Next step

  • 추후 플랫폼 스터디를 통해 slack과의 interaction(slack bot + slash commends)을 통한 jenkins 빌드를 구축할 예정이고, 구축 완료되면 한 번 더 블로그 글을 작성할 계획입니다.

 

 

 

 

 

Jenkins CI 셋팅

 

1. 초기 환경 확인

  • fastlane

우리는 fastlane을 이용해 unittest를 진행할 lane 구축을 진행하였습니다. (이 글에서 fastlane 설치 및 세팅하는 방법에 대해서는 생략합니다) 이 lane이 Jenkins CI에서 실행될 수 있도록 구축하는 것이 1차 목표입니다.
block

Jenkins CI_fastlane

 

 

  • homebrew

homebrew 설치는 https://brew.sh/index_ko 에서 확인해주세요!

 

 

 

 

 

 2. Jenkins 설치

  1. brew를 통해 Jenkins를 설치합니다. 설치 과정에서 얻은 administrator password를 잘 기억합니다. (만약 잊어버렸다면 /var/lib/jenkins/secrets/initialAdminPassword로 이동해서 확인할 수 있습니다.)
    block
    Jenkins CI_설치
    block
    block
    block
  2. Jenkins를 실행합니다.

    Jenkins CI_실행
    block
    block
    block
  3. 실행 후 http://localhost:8080에 접속해서 젠킨스 페이지를 확인합니다.이때 최초 1회 administrator password를 입력하면 되는데 설치 과정에서 얻은 password를 입력합니다.
    block
  4. admin user account를 세팅하면 완료입니다.

 

 

 

 

 

3. Jenkins 환경설정

  1. 새로운 item 생성하기
    block
    block

    Jenkins CI_환경설정
    block
    block
    block

    1) 새로운 item을 선택합니다.
    blockJenkins CI_item
    block
    block
    2) 프로젝트 이름을 작성한 후 Freestyle project로 생성합니다.
    block
    Jenkins CI_itemname
    block
    block
    3) [General 탭] 이어서 나오는 구성화면에서 github과 연결을 진행합니다.
    block
    Jenkins CI_연결

    Github repo url을 작성합니다.
    block
    block
    4) [소스 코드 관리 탭] github의 소스코드를 가져올 수 있도록 권한을 부여합니다.

    • Repository URL : ssh를 이용한 접근 url로 복사하여 기재합니다.
    • Credentials에서 Add를 눌러 새로운 Credential을 생성합니다.
      block
      Jenkins CI_소스코드관리

    blockblock
    block

    5) Credentials 생성 팝업이 뜨면 필요한 내용을 작성합니다.

    Jenkins CI_personal

    block

    block

    6) [소스 코드 관리 탭] 고급을 선택하면 나오는 Refspec에 ‘+refs/pull/:refs/remotes/origin/pr/’를 추가해 PR에 대한 주소를 가져올 수 있도록 설정합니다. 이어서 특정 PR의 branch로 이동해서 빌드하기 위해 Branchs to build의 Branch Specifier에 ‘${sha1}’를 추가합니다.
    block
    Jenkins CI_소스코드관리2

    blockblock
    block

    7) [빌드 유발] 이 부분은 Jenkins plugin의 설치 절차를 마친 후 이어서 아래에 별도로 다루겠습니다.
    block

    8) [빌드 환경] Timeout 시간을 설정합니다.
    block

    Jenkins CI_빌드환경
    block
    block

    9)  [Build] fastlane shell 을 동작시킬 수 있도록 작성합니다.
    block


    block
    block
    block

  2. Jenkins plugin 설치를 통한 Github과 빌드 과정, 결과에 대한 연동 설정
    blockblock

    block
    block
    1) Jenkins 관리 → 플러그인 관리 선택
    block
    block
    block
    2) github pull request builder를 검색하여 설치를 진행합니다.
    block

    block
    block
    3)Jenkins 시스템 설정에 들어가서 Application setup > commit status context를 작성합니다. 여기서 작성하는 이름이 github ci 이름으로 표시됩니다.
    block


    block
    block
    4) webhook을 받고, 빌드 결과를 github에 전달하기 위해 이전에 만들었던 Item (hwahae-ios-ci) > 구성 > [빌드 유발] 부분에서 정보를 작성합니다. admin 또는 organizations 등록을 통해 빌드를 실행시킬 수 있는 사람을 한정해줍니다.
    block
    방법 1.  Admin list에 github의 repo admin username을 작성합니다.
    block

    block
    block

    방법 2. 개발그룹 등록을 통해 birdviewdev그룹에 소속되어있는 github 유저는 모두 가능하도록 설정합니다.
    block

    block
    block
    환경설정 후 github의 project repo에 webhook이 생성되었는지 확인합니다.
    → https://github.com/{githubteam}/{repo}/settings/hooks

 

 

 

 

 

결과

 

이제 Travis CI를 돌리지 않아도 자체적으로 구축한 Jenkins CI 환경이 마련되었습니다.

 

 

 

 

 

 

 

One more Thing!
Pull request comments로 distribution 구축하기

 

Jenkins CI 구축 이후 Jenkins job의 자원에 대해 제한 없이 사용할 수 있게 된 iOS 플랫폼은 이를 조금 더 활용할 수 있는 방안을 고민해보았습니다.

 

iOS 플랫폼에서는 크게 2가지 배포를 진행하고 있는데요. 

  • Firebase App Distribution을 통한 test app 배포
  • AppstoreConnect Testflight에 production app 배포

이 두 가지는 대부분 pull request와 연관성이 있습니다. pull request와 함께 배포를 진행하고 테스트가 완료되면 비로소 merge 할 수 있기 때문입니다.

 

플랫폼에서 스터디 해 본 결과 pull request comments를 트리거하여 특정 job을 실행시킬 수 있었습니다. 이 방법을 통해 두 배포를 Jenkins에서 진행할 수 있도록 구축하는 방법을 소개하겠습니다.

 

 

1. 배포를 위한 job을 만들기

    • hwahae-ios : unittest
    • hwahae-ios-distribution : firebase app distribution
    • hwahae-ios-distribution-appstore : appstoreconnect testflight

block
block

block
block
block

 

2. Github pull request의 comment 트리거 세팅하기

앞서 설치하였던 pull request builder plugin의 속성을 세팅합니다.

  1. hwahae-ios-distribution
    block
    block
    block
  2. hwahae-ios-distribution-appstore
    block
    block
    block
    block
  3. trigger를 pull request의 comment에 남긴 후, 결과를 확인해봅니다.
    block

    block
    block
    block
  4. 완료!

 

 

 

 

 

마치며

 

이번 글은 Jenkins-CI의 기본 환경 구축에 대해 정리해 보았습니다.

 

플랫폼에서는 꾸준히 시간을 잡고 CI부터 CD의 방향까지 설계하고 있습니다. 이후, 더 나은 CI/CD 구축이 완료되면, 기술 블로그를 통해 여러분께 공유해 드리도록 하겠습니다.

 

당장 눈앞에 주어진 업무만 하다 보면 정작 이런 환경 개선은 쉽지 않은 경우가 많은데요. 버드뷰에서는 플랫폼 구성원 모두가 끊임없이 더 나은 환경에 대해 고민하고, 또 이를 통해 함께 성장할 수 있다는 점이 무엇보다 의미 있다고 생각합니다. 화해팀 전체 그리고 기술 조직의 문화가 이런 것들을 뒷받침하고 있어 가능할 수 있었습니다. 

 

긴 글 읽어주셔서 감사합니다.

 

 

 

avatar image

전규찬 | iOS Developer

화해 iOS 서비스 개발을 통해 화장품 정보 비대칭을 해결하고 있습니다.

연관 아티클