앞선 글은 Github Action을 이용해서 CI를 구축해보았다.
이번 글은 CD를 구축했고 그에 따른 경험을 적을 예정이다.
CD가 뭐야?
CD는 Continous Delivery로 지속적인 배포
를 뜻한다.
즉 이번 글의 목적은 Github Action으로 배포를 자동화를 어떻게 했는지에 대한 글이다.
어플리케이션의 배포 경험이 없어서 정말 많이 헤멨다.
Github Action에 대한 정확한 개념이 없어서 많은 글을 찾아봤고, 참고해서 성공할 수 있었다.
CD를 하기전에 버전관리에 대해서 간략하게 설명하겠다.
우리가 사용하는 어플리케이션은 지속적인 업데이트로 버그를 수정하고, 기능을 추가한다.
이렇듯 어플리케이션의 버전관리는 아주 기본적이라고 할 수 있다.
버전관리의 전략은 다양한 전략이 있지만 통상적으로 쓰이는 전략은 시멘틱 버저닝 전략이 있다.
https://oliveyoung.tech/blog/2021-07-01/Manage-Oliveyoung-Android-App-Version/
시멘틱 버저닝 전략은 MAJOR.Minor.patch와 같이 3개의 숫자로 관리하는 전략이다.
우리가 자주 사용하는 카카오톡도 시멘틱 버저닝 전략처럼 MAJOR.Minor.patch처럼 버전을 나눈다.
버전을 변경하는 기준은 다음과 같다.
- 기존 버전과 호환되지 않는 API가 추가되었고, 그렇다면 MAJOR 버전을 올린다.
- 기존 버전과 호환되면서 새로운 기능을 추가할때 Minor 버전을 올린다.
- 기존 버전과 호환되면서 버그를 수정했다면 Patch 버전을 올린다.
안드로이드 스튜디오에서는 versionCode와 versionName이라는 2가지의 버전 관리 체계가 존재한다.
versionCode는 안드로이드 시스템 내에서 판단하는 정보로 높을수록 최신버전이다.
versionName은 앱의 배포 버전을 나타내는 문자열이다.
기본으로 1.0으로 설정되어 있다.
CD 전략
CD를 구축하기 위해서 개인 레포지에 정~~말 많은 테스트를 해봤다.
죽을뻔했다..
우선 내가 목표한 것은 자동으로 커밋메시지를 통해서 Tag를 추출하고 Release를 생성하는 것이었다.
해당 링크를 통해서 참고했다.
요약하자면 Commit message에서 1.0.0이라는 형식이 있다면 1.0.0을 태그로 추출해서 release를 생성하는것이다.
name: Release Tag
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: 버전 정보 추출
run: echo "##[set-output name=version;]$(echo '${{ github.event.head_commit.message }}' | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')"
id: extract_version_name
- name: Release 생성
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.extract_version_name.outputs.version }}
release_name: ${{ steps.extract_version_name.outputs.version }}
소스 코드를 이렇게 하고 master 브랜치에 0.1.1이라는 커밋을 보내니
release가 생겼다.
너무 신기했다. 하지만 source code만 담겨있을뿐 나의 app이 Assets에 담겨있지 않아서 조금 더 수정해볼려고 했다.
그러기 위해선 Github Aciont에서 앱을 빌드해야 했기에
- name: Upload Release APK
id: upload_release_asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: $
with:
upload_url: $
asset_path: apk/app-release.apk
asset_name: $.apk
asset_content_type: application/zip
기존 yml 파일에서 아래와 같은 코드를 추가햇다.
위와 같은 오류를 만났다..
아마 apk를 생성하는것까진 성공했지만 경로가 잘못된것이라고 판단했다.
app을 release 하는 과정에서 자바 버전이 너무 낮아서 생긴 오류라는것으로 판단했고,
자바의 버전을 17로 바꿔주는 code를 추가했다.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: 17
뭔가 되는듯한 느낌을 받았다.
성공했다..
성공했을때 정말 소리를 질렀다..ㅠㅠㅠ
지금까지의 코드로는 commit 메시지를 통해서 tag를 추출해서 Release를 생성하고 app을 apk로 release까지 하는것을 완성했다.
다음과정으로는 Firebase App distribution을 이용해서 배포를 하는것이다.
우선 배포를 하기 위해선 준비과정이 필요하다.
Firebase를 당연하게 앱과 연결을 해야 한다.
- name: Upload to Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_APP_ID }}
serviceCredentialsFileContent: ${{ secrets.FIREBASE_CREDENTIAL_FILE_CONTENT }}
groups: test
releaseNotesFile: AOS/release_note.txt
file: AOS/app/build/outputs/apk/release/app-release.apk
블로그에서 사용되는 FireBase에 배포를 하는 코드이다.
처음에는 그대로 복사를 했지만
오류를 만날수 있었다.
${{ }}에 들어가는 인자를 직접 넣어줘야하는거구나라고 생각을 했다.
레포지토리에 들어가서 setting을 누르면 다음과 같이 위 코드와 비슷한 secret을 결정하는 곳이 있다.
아마 처음 들어가면 비어있을텐데 New repository secret을 누르고 추가를 하면 된다.
FireBase 배포를 하기위해선 App id와 추가적인 파일이 필요하다.
Firebase의 프로젝트 설정에 들어가면 앱 id를 확인할 수 있다.
모자이크된 부분을 위 secrets에 추가하면 된다.
그러면 저 밑에 CRE~~는 어떻게 해야하나요
정말 간단하다.
우선 해당링크에 들어가야한다.
https://console.cloud.google.com/welcome?hl=ko&project=mindsync-b3ec5
옆에 메뉴탭을 누르고 IAM 및 관리자를 누르고 서비스 계정을 누른다.
만들기를 누른다.
다음과 같이 누르고 완료를 하면
이렇게 뭐가 생긴다.
키 관리를 살포시 눌러본다.
키 추가를 누르면 오른쪽과 같이 키를 만들수 있고, Json 형태로 만들어지고 다운이 된다.
그 다운받은 파일을 열고 전체복사해서 secrets에 추가하면 된다.
이렇게 하면 Firebase 배포가 가능하다.
그리고 앱 서명을 추가한다면 다음과 같은 작업을 해야한다.
Key Store를 직접 관리하는것은 보안상 권장되는 것은 아니기 때문에 매번 release를 할때마다 생성해주고 관리했다.
android keyStore를 생성하는것은 블로그에 자세히 나와있기 때문에 다루지는 않겠다.
주의해야할것은 KEY_STORE_BASE_64이다.
android studio로 생성한 key는 열수 없기 때문에 secret에 추가할 수 없다.
따라서 그 파일을 BASE_64로 변환해서 텍스트 형식으로 넣어줘야한다.
openssl base64 -in testKey -out keystore.txt
다음과 같은 명령어로 생성한 key를 txt파일로 변환해서 전체복사해서 넣어준다.
위에 ALIAS와 PASSWORD, STORE_PASSWORD는 key를 생성할때의 정보이므로 그떄의 정보를 기억해서 그대로 넣어주면 된다.
이제 우리는 keystore를 통해서 앱을 서명하고, Firebase에 배포까지 할 수 있다.
최종적인 코드이다.
name: Release Tag
on:
push:
branches:
- final
pull_request:
branches:
- final
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: 17
- name: 버전 정보 추출
run: echo "##[set-output name=version;]$(echo '${{ github.event.head_commit.message }}' | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')"
id: extract_version_name
- name: Generate Keystore
env:
KEYSTORE_B64: ${{ secrets.KEY_STORE_BASE_64 }}
run: |
echo $KEYSTORE_B64 > keystore_b64.txt
base64 --decode --ignore-garbage keystore_b64.txt > keystore.jks
working-directory: ./AOS/app
- name: Build Release APK
env:
SIGNING_KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
SIGNING_PASSWORD: ${{ secrets.KEY_PASSWORD }}
run: ./gradlew assembleRelease
working-directory: ./AOS
- name: Release 생성
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.extract_version_name.outputs.version }}
release_name: ${{ steps.extract_version_name.outputs.version }}
files: |
AOS/app/build/outputs/apk/release/app-release.apk
- name: Upload to Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_APP_ID }}
serviceCredentialsFileContent: ${{ secrets.FIREBASE_CREDENTIAL_FILE_CONTENT }}
groups: test
releaseNotesFile: AOS/release_note.txt
file: AOS/app/build/outputs/apk/release/app-release.apk
추가된 코드를 뜯어보자면
groups는 배포할 그룹을 의미하고,
releaseNoteFile은 배포할때 첨부할 패치 버전 설명파일이다.
FireBase App Distribution에 추가한것을 알 수 있다.
느낀점
release에 push할때마다 자동으로 release를 생성해주고, Firebase에 지정한 test 그룹에게 배포를 해보았는데,
정말 편리한 작업인것같다.
기존의 테스터에게 배포를 할려면 apk를 안드로이드 스튜디오 내에서 release하고 넣어줘야했다.
속도는 더 느리지만 자동화를 한다는 측면에서 Github action으로 정의만 한다면 개발에만 집중할 수 있기에 편했다.
'Skils > Android' 카테고리의 다른 글
[Android] - CustomView DrawText (0) | 2023.12.10 |
---|---|
[Android] - Navigation Component(2) (1) | 2023.12.06 |
[Android] Github action을 이용한 CI(ktlint) (1) | 2023.11.27 |
[Android] - Jetpack Compose (1) | 2023.10.31 |
[Android] - 다국어 지원, String.xml 이용하기 (1) | 2023.10.19 |