[Android] Github-Action CI 빌드 속도 개선하기 feat.Build Cache + 명령어

Lee Yongin·2024년 6월 28일
0

안드로이드

목록 보기
17/23
post-custom-banner

문제상황: 느린 Github-Action 빌드 속도

CI환경 빌드 11분 49초?? 말도안돼 느려요🥵

다운로드 용량 26.7MB 짜리 앱이 빌드는 12분 가량 된다는 게 가장 큰 문제이다.
로컬 빌드는 3분 47초 걸리는데 CI가 3배나 걸리면 CI빌드를 도입한 보람이 없다고 생각했다. 그래서 CI빌드 속도 개선을 시작했다!

현재 코드

아직 빌드를 위한 전처리와 빌드 밖에 없는 기본 상태이다.

name: Android develop CI

on:
  push:
    branches: [ "feature_github_action" ]
  pull_request:
    branches: [ "feature_github_action" ]

jobs:
  build:

    runs-on: ubuntu-latest
    env:
      HMOA_ANDROID_SECRET_TOKEN: ${{secrets.HMOA_ANDROID_SECRET_TOKEN}}
      RELEASE_KEYSTORE: ${{secrets.RELEASE_KEYSTORE}}
    steps:
      - uses: actions/checkout@v4
      - name: set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: gradle

      - name: Grant execute permissions for scripts
        run: |
          chmod +x copy-hmoa-android-secrets.sh
      - name: Generate release.keystore
        run: echo '${{ secrets.RELEASE_KEYSTORE }}' | base64 --d > ./app/release.keystore

      - name: Run copy secrets
        run: ./copy-hmoa-android-secrets.sh

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build

빌드 캐시에 대해

빌드 캐시, 빌드 캐시 키 2가지가 있다.
빌드 캐시는 캐시 키값이 일치해야 사용할 수 있다.
빌드 캐시 키는 의존성이 바뀔 때마다 값이 달라진다. 이 점을 기억하면 이해하기 쉽다.

빌드 캐시 Input

아래 3가지만 사용했다. 나머지 Input에 대해서는 공식 repository를 참고하면 좋다.

key - 캐시 항목의 명시적인 키.
path - 캐시하고 복원할 파일, 디렉터리 및 와일드카드 패턴의 목록. 지원되는 패턴에 대해서는 @actions/glob를 참조해야 함.
restore-keys - 캐시 적중이 발생하지 않았을 때 오래된 캐시를 복원하기 위해 사용하는 접두사 일치 키의 순서가 있는 목록.

path: 명시된 경로의 파일을 캐싱함

path: |
            ~/.gradle/caches
            ~/.gradle/wrapper

key: 키 값이 완전히 일치해야 캐시가 적용됨

실행하는 운영체제와 gradle파일, gradle-wrapper.properties의 내용이 변경될 때마다 고유한 해시 값을 생성하여 캐시 키에 포함시킨다. 캐시 키값을 대조해서, 값이 일치하지 않을 경우 의존성을 다시 설치하고 새로운 캐시를 생성한다.

key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}

restore-key: 키 값이 달라도 유사한 캐시가 적용됨

restore-key를 쓰는 이유는 의존성 변경이 일어났을 때 key값이 달라지고, 캐시가 적용되지 않을 경우를 대비하는 것이다.

아래와 같이 restore-key를 사용하면 같은 운영체제, runner.os-gradle또는 runner.os-로 시작하는 유사한 캐시를 사용하게 된다.

restore-keys: |
            ${{ runner.os }}-gradle-

빌드 캐싱 스텝 추가하기

		...생략(위의 코드와 동일함)...
      - name: Gradle Caching
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build

빌드 캐시 전후 결과 비교하기

실행된 작업 확인하기

빌드 캐시 추가를 하고나서의 첫 yml파일 실행이기 때문에 생성된 캐시 키와 일치하는 키가 없다고 나온다.

생성된 캐시 크기는 885MB이고, path로 지정한 디렉토리에 저장되었을 것이다.

캐시 키 확인하기

설치된 의존성 파일이 캐시된 것을 볼 수 있다.

2배로 시간 단축...!

빌드 캐시를 적용했더니 6분 54초로 줄어들었다. 거의 2배 단축했지만 이게 최선인지는 모르겠다. 🤔

개선점

이제 1.0.0 버전으로 배포했고 앞으로 핵심 서비스가 더 들어올텐데 더 빌드시간을 줄일 필요가 있겠다.
불필요한 의존성을 삭제하고, 빌드 프로파일링을 해보는 등 더 최적화를 거쳐야 한다.

2024.08.19 추가 개선!

6분 54초도 너무 길다고 생각해 방법을 고민한 찰나에 CD가 아니고 그냥 CI라는 점에 가벼운 빌드 명령어를 사용하기로 했다.
./gradlew build에서 ./gradlew assembleDebug로 수정했다.
그 결과 3분 54초로 더 빠르게 수행되었다.

물론 배포브랜치에서는 Debug용이 아닌 Release용 빌드를 해야하겠지만! 우리팀의 CI 도입 이유는 개발과정에서의 test와 build로 지속적인 통합을 하는 거니까 이 정도면 일단 도입 가능한 정도라고 생각한다. (test가 늘어난다면 분명 시간이 더 걸릴테니 개선해야 한다.)
너무 간단한 해결방법...그 효과는 굉장했다.

참고자료

https://github.com/actions/cache?tab=readme-ov-file
https://pozafly.github.io/dev-ops/cache-and-restore-keys-in-github-actions/
https://devjem.tistory.com/76
https://hellorennon.tistory.com/22

profile
⚡개발자할거야 응애 안드로이드 개발자 ⚡p.s.기록만이 살길이다!
post-custom-banner

0개의 댓글