본문 바로가기
Android/CI, CD

안드로이드 CI/CD (1) - 개념

by 태크민 2024. 1. 6.

CI / CD? 멍미

일단 용어 설명부터 해보자면 이렇다

CI : Continuous Integration (지속적 통합)
CD : Continuous Deployment (지속적 배포)

함축적이어서 이해가 잘 안되었다면, 아래 내용을 보면 도움이 될 것이다.

개발 > 빌드 > 테스트 > 배포 과정을 자동화하는 것

"개발 > 빌드 > 테스트" 를 자동화하는 것을 "CI",
"배포" 를 자동화 하는 것을 "CD" 로 보면 된다.

 

꼭 필요한건가?

서론에서도 언급했지만 CI / CD 는 없어도 된다.
CI / CD 가 없으면 그냥 개발자가 수동으로 하면 된다.

구축했더라도 기능 개발이 급하거나, 개인 혹은 소규모 프로젝트에서는
CI / CD 의 검증 및 배포 시간을 기다려야 하기 때문에 귀찮게 느껴질 수 있다.

그리고 Android 의 경우 gradle 명령어를 매번 호출하면서
gradle 환경에서만 발생하는 오류를 경험하고 이를 대비하는 코드를 작성하기도 한다.

이런저런 불편함이 있지만 CI / CD 는 아래의 상황에서 진가를 발휘한다.

 

1. 프로젝트를 담당하는 인원이 많을수록
인원이 많아질수록 코드 변경 정도와 충돌이 심해지고,
검증 또한 그만큼 깊이있게 이루어져야하기 때문에,
각자 작업한 코드가 프로젝트에 정상적으로 반영되는지가 더욱 중요해진다.

2. 프로젝트 규모가 크고 복잡할수록
프로젝트 규모가 클수록 내가 수정한 내용이 다양한 영역에 영향을 끼칠 수 있다.
그리고 프로젝트가 복잡할수록 다양한 환경을 고려할 확률이 높아지고
이에 따라 배포 시 필요한 작업이 많아질 수 있다.

어디서 요긴하게 쓸까?
필요성은 알았는데 그럼 어디서 이 요긴한 시스템을 활용할까?
인원이 많으면서 규모가 제법 있고 복잡한 프로젝트를 운영하는 곳
이 곳은 어디일까?

바로 회사(실무)이다.

실제 채용 공고를 보면 우대사항에 아래의 문구들을 많이 볼 수 있다.
(경력직은 거의 100% 적혀있다.)

  • CI/CD 경험이 있는 분
  • 빌드/테스트/배포 자동화 경험이 있는 분

자신이 CI / CD 에 대한 경험이나 필요성을 느낀 개발자라면
면접관 분들에게 긍정적인 기운을 보여줄 수 있을 것이라 생각한다.

 

1. CI

안드로이드 프로젝트를 여러명이서 협업한다는 가정하에 CI / CD 이야기를 진행해보겠다.

우리는 한 프로젝트를 여러 사람들과 같이하기 위해

  1. 주로 Git, SVN 등과 같은 버전관리 툴을 활용하기 시작하고
  2. 특정 브랜치에 우리가 작업했던 모든 내용을 합치게 된다
    (위에 언급한 특정 브랜치를 앞으로 master 브랜치로 지칭하겠다)

지극히 평범한 버전관리 툴의 예

그렇게 각자의 작업들이 합쳐졌고, 이제 앱의 배포를 해야한다.
master 브랜치 는 우리가 작업했던 모든 내용이 합쳐진 브랜치이므로
앱을 배포할 때 master 브랜치에서 앱을 추출해 배포해야한다.

그런데 갑자기 누군가가 물어본다.

master 브랜치 에서 추출한 앱.. 문제 없죠?

물어본 사람이 의심이 많다고 생각하고 기분이 나쁠 수 있지만,
문제는 당연히 없어야하는 게 맞다. (당연히 YES 여야 한다)

하지만 안타깝게도 정답은 NO 가 나올때도 있다…
언제 NO 가 될 수 있는지는 아래의 케이스를 통해 확인해보자.

 

1. 합치면서 변질될 수 있는 코드

자신이 당장 작업했을 때는 문제 없었더라도
여러명의 작업을 하나에 반영하면서 다양한 변수가 많이 생긴다.
아래는 다양한 변수의 예이다.

1.master 브랜치, B 작업 브랜치의 conflict 를 수정 반영할 때

ex
A 개발자가 master 브랜치에 반영시킨 내용이, 
B 개발자가 작업하던 브랜치에는 반영이 안 되어 있어
작업 내용이 겹치게되 충돌된 코드를 수정하고 master 에 반영하면서
B 개발자의 실수로 A 개발자가 작성했던 코드가 삭제되는 경우

 

2.B가 master 브랜치를 pull 한 후, 누락된 작업 내용을 반영할 때

ex
A 개발자가 코드 파일 또는 패키지 정리 작업을 master 브랜치에 반영할 때
B 개발자가 master 최신내용을 작업하던 브랜치에 반영하면서
실수로 자신의 작업을 빼먹거나 추가되어야 할 작업을 놓치는 경우

 

3. merge 하면서 변경사항이 꼬여 관련 코드가 누락되는 경우

ex
1, 2 가 겹쳐 master 브랜치로 합치는 과정에서 일부 코드가 없어지는경우

 

개발자의 실수 혹은 버전 관리 툴을 통해 코드를 합치면서 이런 이슈를 접하게 된다.
특히 Base 부분, 유틸 부분 같이 영향이 큰 코드 작업을 하는 경우 더욱 많이 경험할 확률이 높다.

2. 작업 도중 놓칠 수 있는 코드의 품질

컨벤션 및 코드스타일 규칙을 라이브러리(detekt, ktlint 등)를 활용하여
프로젝트에 적용하고 있다면 작업하면서 스타일 적용을 깜빡할 수 있다.

물론 작업할 때마다 놓치지 않고 확인한다거나,
자동으로 정리해주는 명령어를 활용하면 문제는 없겠지만,
이는 컴파일 오류가 아니기 때문에 놓칠 수 있는 작업이다.

항상 신경쓰라고 하기에는 가혹하지만, 놓친다면 통일성이 깨져 참 그렇다.

코드 컨벤션 강제하기(detekt, ktlint)에 대해 궁금하면 아래 링크르 참조하자.
https://velog.io/@dlwpdlf147/%EC%BD%94%EB%94%A9-%EC%BB%A8%EB%B2%A4%EC%85%98-%EA%B0%95%EC%A0%9C%ED%95%98%EA%B8%B0-feat.-Ktlint-Detekt

 

코딩 컨벤션 강제하기 (feat. Ktlint, Detekt)

Android에서 Ktlint와 DeteKt 사용 및 Git 연동 설정까지

velog.io

코드 합치는 걸 두려워할 필요 없게 만드는 CI

위의 안타까운 사연(?)들을 많이 만나 보았는데
만약 내 코드를 master 브랜치에 통합(!)할 때

  1. 배포할 브랜치에서 프로젝트 빌드가 잘 되는지,
  2. 로직 오류 검증을 위한 테스트 코드를 실행하고 결과를 확인해주는지
  3. 컨벤션 및 코드스타일 규칙을 지켰는지

어떤 시스템이 위 내용들을 자동으로 확인해준다면 어떨까? 
새로운 코드 변경 사항이 반영될때마다 빌드 및 테스트 코드를 실행하고,
개발자가 놓칠 수 있는 내용을 인지하고 바로 수정이 가능해질 것이다.

위에서 말한 어떤 시스템이 바로 CI(지속적 통합) 이다.

 


2. CD

CI 를 통해 우리는 나름의 안정화된 앱을 추출할 수 있었다. 이젠 배포할 차례다.

1. 배포하자

최대한 간단하게 작성해보았으며, 무조건 아래 프로세스가 정답은 아니다.
(개발자가 직접 배포하는 시나리오를 가정하여 설명한다.)

1. 배포
구글 플레이스토어로 들어간다. 
들어가서 관련 앱 파일, 추가적으로 필요한 파일 (ex. 난독해제 파일 등) 을 업로드하고 배포를 한다.

 

2. 공유
관련된 내용을 팀원들에게 공유를 한다. 
경우에 따라 우리는 작업한 내용 전체를 문서화하여 공유해야 할 수도 있고,
그 앱을 언제든지 다운받을 수 있도록 해야 할 수도 있다.

 

3. 히스토리 관리 및 다음버전 대비
난 미래를 대비하는 사람이다 (정말?)
이후 히스토리 관리 차원에서 현재 프로젝트 버전을 tag 처리하고 
안드로이드에서는 동일한 versionCode 를 가진 앱을 업로드할 수 없으므로 
미리 versionCode 를 올려 새로운 배포의 시작을 대비한다.

 

2. 요구사항 대응에 따라 배포 프로세스 변경 및 개선

서비스가 발전하면서 점차 개발 환경이 개선되고,
요구 및 개선사항을 느끼며 프로세스가 변경 및 개선될 수 있다.

있을만한 시나리오 3개를 가져와 보았다.

1. 테스트 환경의 앱도 배포하기
이제 우리에게도 테스트 서버가 생겼고, 앞으로 테스트 환경에서의 앱도 같이 확인하고 싶다.
그래서 테스트 서버를 기반으로 하는 앱을 추출하고 따로 업로드해준다.

각 앱이 바라보는 서버가 다르게 하기

 

2. 이전 버전 앱 확인
타 직군에서 이전 버전에서의 앱을 확인하고 싶어한다. 
그래서 이전에 tag 했던 버전을 찾아 앱을 추출하고 따로 업로드해준다.

 

3. 분할 작업
협의 및 개발 스케일 등으로 인해 6개월 ~ 1년 수준의 장기 작업과 유지보수 작업을 같이 병행할 수 있다.
이런 경우 각 상황에 맞는 앱들을 추출하고 (장기 작업 앱, 유지보수용 앱) 따로 업로드 및 배포해준다.

 

무겁지만 단순 작업들의 모음인 배포 프로세스

여러가지 상황에 따라 배포 작업에 선택사항들은 계속 붙여지고, 배포 작업은 🏋️ 무거워질 것이다.
배포할때마다 이 작업을 계속 해야하고 고려해주어야 하는 환경개수 만큼 n배의 작업이 될 것이다.

이 작업이 개발실력 성장에 보탬이 된다면 그러려니하겠지만,
이 과정들은 어렵지 않으면서 그냥 해주어야하는 단순 작업들이다.

어느새 배포 작업은 성장에 도움이 되지 않으면서 거대해지고 반복적인 기계 작업이 되어버린다.
(이런 작업을 즐기면서 하라고 하기엔… 명분이 없다.)

그러면서 급한 배포 요청이 들어오는 경우 지금 하고있던 개발을 뒤로 제쳐두고 배포를 먼저 해야 한다.
그리고 사람이기 때문에 배포 도중 실수할 수 있고, 그로 인한 시간과 작업이 추가될 수 있다.

그러다 보면 갑자기 이런 생각(🤦‍ 현타) 가 들게 된다.

🤦‍🤦‍🤦‍ 온전한 개발에 집중을 더 하고 싶어요 🤦‍🤦‍🤦‍

이런 저런 사유들로 배포 자체가 개발자에게 스트레스로 다가올 수 있다.

 

개발자의 스트레스를 덜어줄 수 있는 CD

이런 상황에서 소프트웨어를 언제든지 신뢰 가능한 수준으로 배포하고
그 과정을 자동화 하는 이론인 CD (지속적 배포) 는 개발자의 스트레스를 덜어줄 수 있다.

CD 를 통해 배포를 자동화하여 우리는 원활히 배포하고
여러 단순 작업들을 자동화하여 개발자에게 많은 편의를 제공할 수 있다.

Q. 그런데 CD 는 프로덕션 배포를 고려하는 이론 아닌가요?

맞는 말이다. 사실 CD의 원론적 의미 자체는 변경 사항을 고객이 사용 가능한 프로덕션 환경까지 자동으로 릴리스 하는 것을 이야기한다.
하지만 우리는 개발자 및 팀의 편의를 위해 추가적인 작업을 해주고 (2. 이전 버전 앱 확인),다른 환경으로의 자동 릴리스를 고려하는 것(1. 테스트 환경의 앱도 배포하기)도 확인할 수 있었다.
CD 는 프로덕션 환경 뿐만 아니라 다양한 환경에 대한 시나리오도 자동화하여 모두에게 편안함을 줄 수 있다.

 

 

 

 

출처

https://velog.io/@ricky_0_k/Github-Actions-%EC%9C%BC%EB%A1%9C-Android-CICD-%EA%B5%AC%EC%B6%95%ED%95%9C-%EC%8D%B0-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0-1.%EA%B0%9C%EB%85%90