조각들

개요

최근에 CI를 주제로 스터디 자료를 준비했었다.

채용 공고를 볼 때 CI/CD를 종종 봤어서 예전부터 관심이 있었다.

쉽게 말해서 CI는 빌드,테스트 자동화, CD는 배포 자동화인데 나는 아직 배포 경험이 없으므로 CI만 공부를 하기로 했다.

 

CI는 협업을 하거나 브랜치를 쪼개서 작업하는 경우에 쓸모가 있다.

 

나는 아직 직접적으로 경험해본 적이 없어서 잘 모르지만 merge conflict에 안 걸렸어도 merge 시 build에 문제가 되는 경우들이 있는 것 같다. 뒤늦게 문제를 찾아내서 해결하려고 들면 이것도 일이고, 매번 빌드를 돌려보는 것도 일이라 이 작업을 자동화시킨 것이 CI다. 

 

CI를 도입하면 merge 전에 빌드 여부를 바로 확인할 수 있어서 좀 더 안정적인 프로젝트 운영이 가능해진다.

 

젠킨스, 깃헙액션 등 여러 툴이 있는데 깃헙 액션이 깃헙에서 공식적으로 지원하는 것이어서 접근성이 좋고

public repo에 한해 무료로 서비스를 제공해주기 때문에 래퍼런스도 쉽게 찾을 수 있어서 좋다.

 

깃헙액션에서 공식 문서를 제공해주는데 양이 많아서 나는 이걸 처음부터 다 읽기보단 다른 사람들이 작성해놓은 CI 코드들을 참고해가면서 당장 내가 필요한 수준에 한정지어서 공부를 했다.

 


내용

아래가 이번에 내가 작성한 CI 코드이다. workflow를 돌리기 위한 기본 세팅에 gitignore로 숨겨놓은 local.properties를 임시로 생성시키는 코드를 작성해주었다.

 

처음엔 깃헙액션에서 제공해주는 템플릿이 있길래 그걸 그대로 가져다 쓰면 되는 줄 알았는데 추가 작성을 해주는 부분이 있었다.

 

name: CI

on:
    push:
        branches: [ develop ]

    pull_request:
        branches: [ develop ]
    
defaults:
    run:
        shell: bash
        working-directory: .

jobs:
    build:
        name: Generate APK
        runs-on: ubuntu-latest
        steps:
            -   name: Checkout
                uses: actions/checkout@v2

            -   name: Gradle cache
                uses: actions/cache@v2
                with:
                    path: |
                        ~/.gradle/caches
                        ~/.gradle/wrapper
                    key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
                    restore-keys: |
                        ${{ runner.os }}-gradle-
            -   name: set up JDK 11
                uses: actions/setup-java@v1
                with:
                    java-version: 11
                    
            - name: Touch local properties
              run: touch local.properties
                    
            - name: Access NAVER_CLIENT_ID
              env:
                  NAVER_CLIENT_ID: ${{ secrets.NAVER_CLIENT_ID }}
              run: echo "NAVER_CLIENT_ID = \"$NAVER_CLIENT_ID\"" >> local.properties
        
            - name: Access RUNNECT_BASE_URL
              env:
                  RUNNECT_BASE_URL: ${{ secrets.RUNNECT_BASE_URL }}
              run: echo "RUNNECT_BASE_URL=\"$RUNNECT_BASE_URL\"" >> local.properties

            - name: Access TMAP_BASE_URL
              env:
                  TMAP_BASE_URL: ${{ secrets.TMAP_BASE_URL }}
              run: echo "TMAP_BASE_URL=\"$TMAP_BASE_URL\"" >> local.properties
              
            - name: Access TMAP_API_KEY
              env:
                  TMAP_API_KEY: ${{ secrets.TMAP_API_KEY }}
              run: echo "TMAP_API_KEY=\"$TMAP_API_KEY\"" >> local.properties

            -   name: Change gradlew permissions
                run: chmod +x ./gradlew

            -   name: Build 
                run: ./gradlew assembleDebug --stacktrace

 

작성한 코드대로 build가 성공적으로 마쳐지면 아래처럼 success 체크가 뜬다.

 

지금보면 이 정도는 정말 간단한 작업인데 secret 변수 추가하는 과정에서 시행착오가 있었다.

 

변수라길래 environment secrets이나 environment variables 쪽에 추가가 되어야 하는 줄 알았는데 repository secrets에 내가 사용할 비밀 값들을 추가해줘야 yaml 파일을 만들 때 해당 값들을 불러와서 사용할 수 있다.

 

여기서 시간을 많이 썼고 한 가지 문제가 더 있었다.

 

처음 해보는 거라 어떤 문제가 생길지 몰라 내 개인 레포에 포크 떠서 연습을 좀 해봤는데 내가 실수로 포크를 뜬 레포에 repository secrets 추가를 안 해줬다. 그래서 빌드 에러가 떴다.

 

나는 local.properties 활용을 위한 세팅을 다 해줬다고 착각을 했어서 처음엔 우리 프로젝트에는 현재 deprecated된 plugin을 사용하는 등 warning 경고가 뜨는 것들이 꽤 있는데 "혹시 이거 때문에 문제가 되는 건가?" 싶었다. 그래서 warning 뜬 거 하나씩 다 해결해보고 다시 run 돌려보느라 정말 힘을 많이 뺐다.

 

"warning이 떠도 안드로이드 스튜디오에서는 잘만 돌아가는데 왜 깃헙액션에서만 이럴까?" 머리가 아팠지만 다행히 문제를 찾아내어 해결할 수 있었다.

 

여전히 내가 모르는 영역이 있을 수 있지만 현재까지 내가 내린 결론은 안드로이드 스튜디오에서 잘 돌아가는데 깃헙액션에서 문제가 생겼다면 깃헙액션에 문제가 있다는 것이다.

 


느낀점

해보고싶었던 걸 해봐서 좋았다. 

그런데 지금까지는 빌드 자동화만 해본 것이고, 테스트 자동화까지 해보고 싶은데 지금 우리 프로젝트 코드가 굉장히 정리가 안 돼있어서 리팩토링을 한다음에야 테스트 자동화를 해볼 수 있을 것 같다.

 

또 아직 배포 경험이 없는데 지금 하고 있는 프로젝트를 릴리즈하고나면 CD까지 해볼 계획이다.

'Android > 공부' 카테고리의 다른 글

retrofit의 비동기 처리  (0) 2024.04.29
Flow  (2) 2024.03.14
Repository의 효용에 대한 고찰  (0) 2023.03.16
[공부] MVVM, ViewModel, LiveData, DataBinding, Fragment  (1) 2023.01.21
[공부] sopt 31기 안드로이드 세미나 과제  (0) 2022.12.05