Programming/Github

Android + CI/CD 적용하기 - CI편 (feat.Github Actions)

YK Choi 2022. 3. 9. 02:33

CI/CD는 Continuous IntegrationContinuous Deploy(or Delivery) 의 줄임말로, 지속적인 통합과 배포를 의미한다.

 

CI란

  • CI (Continuous Integration)
    • 개발 + 빌드 + 테스트를 자동화 하는것 (안정화 된 앱 추출)
    • 무엇을 하는것인가?
      • 배포할 브랜치에서 빌드가 잘 되는지
      • 로직 오류 검증을 위한 테스트 코드를 실행하고 결과를 확인
      • 컨벤션 및 코드 스타일 규칙을 지켰는지

 

CD란

  • CD (Continuous Deployment)
    • 배포를 자동화 하는것
    • 대표적인 프로세스는 무엇이 있는가? (Android에서)
      • 구글 플레이스토어에 들어가 관련 앱 파일을 업로드
      • 관련된 내용을 팀원들에게 공유
      • 히스토리 관리 및 다음 버전 대비

최근 내가 꾸준하게 관리하고 배포하는 프로젝트에서 CI/CD를 적용한다면, 반복되는 작업을 진행하면서 발생하는 실수와 시간낭비를 줄일 수 있어서 예전부터 꼭 해보려고 생각했던 기능이다!

 


Github Actions를 선택한 이유

CI/CD를 도와주는 Tool은 여러가지가 있다. Jenkins, CircleCI, Github Actions 등이 있는데 무료이면서 가장 쉽고 세팅이 적은 Github Actions를 선택했다. Github 레포에서 바로 접근할 수도 있어서 접근성도 높았다.

 

 

시작하기

Github Actions에 들어가면 Android CI 가 바로 뜨지는 않는다. 'browse all category' 버튼을 눌러 더 찾거나 아니면 아래 사진처럼 검색을 하면 나온다.

 

 

 

 

그러면 레포의 ./github/workflows 폴더에 android.yml (야믈이라고 읽는다고 한다) 폴더가 생긴다. 여기에 어떤 로직을 짜느냐에 따라 특정 브랜치에 Push or PR을 했을 때 수행하는 Work Flow를 만들 수 있다.

 

깃허브에서 원격 서버(Ubuntu)를 제공해주고, 그 공간에서 내가 올린 소스코드로 빌드 등을 해주는 원리이다.

(public 레포에서는 무료이고, private 레포는 매월 2천 시간까지만 무료이고 이후부터는 유료라고 한다. 기업에서는 private 레포일테니 기업에서 쓰려면 돈을 내는 구조가 되는것 같다.)

 


보안 파일 관리

원격에서 앱을 빌드하려면 한가지 문제가 있었다. 그것은 바로 내가 gitignore로 보이지 않도록 명시한 보안파일들이다. 이것들이 없으면 빌드 에러가 발생할 것이다. 이를 위해 Github에서 제공하는 Secret 기능도 사용하였다.

 

위 사진과 같이 Github사이트에서 Settings -> Secrets -> Actions 에 들어가면 'New Repository secret' 이 우측상단에 보인다. 이걸 클릭해서 파일명과 파일 내용을 작성했다. 나는 우선 파이어베이스를 위한 google-services.json 파일을 GOOGLE_SERVICES_JSON_DEBUG라는 시크릿키 이름으로 추가하였는데, 이것을 가지고 위에서 작성한 yml파일에서 참조하였다. 

    - name: Create google-services
      run: echo '${{ secrets.GOOGLE_SERVICES_JSON_DEBUG }}' > ./app/google-services.json

yml파일에서 이렇게 작성하면 내가 Secrets에서 작성했던 문자열을 읽어와서 ./app폴더에 google-services.json 이라는 파일명으로 만드는 것인것 같다.

 

 

Build Variant/Flavor 신경써야하는 이유

이렇게 한 뒤, yml에서 ./gradlew build 를 실행하도록 하면 빌드가 될것이라 생각했다.

하지만...결과는!

 

google-servies.json을 읽지 못해서 발생한 것이 원인이다. 이유가 뭘지 생각해보니, 나는 이 앱에서 Debug용과 Release용 앱을 따로 관리하면서, 다른 서버를 바라보게 하고 다른 google-services.json파일을 갖게 했었다.

 

따라서 원인은 Debug용 google-services.json을 만들었지만 빌드가 release용으로 되고 있었기 때문이었다. 커멘드 라인에서 Build Variant를 변경할 수 있는 방법을 알아보았고, ./gradlew assembleDebug 명령어로 가능하다는 알게 되었다.

 

같은 이슈로 main브랜치에 Push/PR 이 들어오면 유닛테스트를 거치고 싶었는데, 단순히 ./gradlew test 명령어로는 안되고, ./gradlew testdebugUnitTest 명령어로 가능토록 할 수 있었다.

 

결과 화면:

yml 파일 내용:

name: Android CI

# Every new pull request to develop branch must fire CI check
on:
  push:
    branches: [ develop ]
  pull_request:
    branches: [ develop ]
    
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:

    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - uses: actions/checkout@v2
    
    - name: set up JDK 11
      uses: actions/setup-java@v2
      with:
        java-version: '11'
        distribution: 'temurin'
        cache: gradle

    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
      
    - name: Create google-services
      run: echo '${{ secrets.GOOGLE_SERVICES_JSON_DEBUG }}' > ./app/google-services.json
      
    # Build Debug App
    - name: Build with Gradle
      run: ./gradlew assembleDebug
      
    # Run unit test
    - name: Run unit test
      run: ./gradlew testdebugUnitTest

 

 

참고 자료

https://developer.android.com/studio/test/command-line?hl=ko

 

명령줄에서 테스트  |  Android 개발자  |  Android Developers

명령줄에서 테스트를 실행하는 방법입니다.

developer.android.com

https://keelim.tistory.com/entry/Github-Actions%EC%9C%BC%EB%A1%9C-%EA%B5%AC%EA%B8%80-%ED%94%8C%EB%A0%88%EC%9D%B4%EC%8A%A4%ED%86%A0%EC%96%B4-%EB%B0%B0%ED%8F%AC-with-google-servicesjson

 

[안드로이드] Github Actions으로 구글 플레이스토어 배포 with google-services.json

---이전 글--- 2021.02.17 - [안드로이드] - [안드로이드] Github Actions으로 구글 플레이스토어 배포 [안드로이드] Github Actions으로 구글 플레이스토어 배포 안녕하세요!! 오늘은 간단하게 CI/CD를 구성하여

keelim.tistory.com

https://zkdlu.tistory.com/19

 

넌 못지나간다! Test가 실패했으면 배포도 되면 안되지!

프로젝트를 진행하고 수많은 테스트 코드가 쌓여 프로덕션 코드가 완성되게 됩니다. 그러나 어디까지 테스트는 개발자가 직접 거쳐줘야 하는 단계이고 자동화 되지 않은 절차는 쉽게 잊혀질 수

zkdlu.tistory.com

https://thiagolopessilva.medium.com/running-android-unit-testing-on-github-action-with-a-project-that-contains-firebase-dependency-621603363bc1

 

Running Android unit testing on GitHub action with a project that contains firebase dependency

Hello folks!! These days I’ve faced the problem to run my unit testing on the Github Actions once while the build process was started it…

thiagolopessilva.medium.com

https://github.com/thiagoolsilva/ShoppingList

 

GitHub - thiagoolsilva/ShoppingList: An android application that uses jetpack components and Firebase

An android application that uses jetpack components and Firebase - GitHub - thiagoolsilva/ShoppingList: An android application that uses jetpack components and Firebase

github.com

https://keelim.tistory.com/entry/7777?category=1080005 

 

[안드로이드] Github Actions으로 구글 플레이스토어 배포

---다음 글--- 2021.08.26 - [안드로이드] - [안드로이드] Github Actions으로 구글 플레이스토어 배포 with google-services.json [안드로이드] Github Actions으로 구글 플레이스토어 배포 with google-services..

keelim.tistory.com

https://dealicious-inc.github.io/2021/03/30/android-ci-with-actions.html

 

GitHub Actions로 안드로이드 CI환경 구축하기 (Goodbye Jenkins)

Github Actions로 쾌적한 자동화 빌드 구성하기

dealicious-inc.github.io