hyeon.s
개발로그
hyeon.s
전체 방문자
오늘
어제
  • 분류 전체보기 (150)
    • Web 및 인프라 (1)
      • Web (1)
      • Terraform (2)
      • Docker (1)
    • Android (1)
      • 공부 (28)
      • 트러블슈팅 (12)
      • 프로젝트 개발 (10)
      • Compose (2)
      • 우테코 프리코스 (0)
    • Server (5)
      • 공부 (1)
      • Spring (4)
    • 알고리즘 (68)
      • 문제풀이 (C++,Kotlin) (54)
      • 공부 (13)
    • 디자인 (3)
      • UI (3)
    • Language (5)
      • Kotlin (5)
      • JAVA (0)
    • IT 동아리 (8)
      • UMC 3기 (Android) (7)
      • Sopt 32기 (Android) (1)

Github

글쓰기 / 관리자
hELLO · Designed By 정상우.
hyeon.s

개발로그

[Android] Github Actions로 업무 생산성 향상 시키기 feat. APK 자동 추출
Android/프로젝트 개발

[Android] Github Actions로 업무 생산성 향상 시키기 feat. APK 자동 추출

2024. 12. 12. 21:24
728x90

목표

GithubActions CI/CD 파이프라인을 구축해 서버에 APK 업로드를 자동화 하자.

  • 개발 프로세스의 효율성과 생산성을 극대화하기 위함.

문제의식

기존 방법의 문제점

가상화 서버에 안드로이드 어플을 업로드하기 위해서 포털을 이용하여 직접 APK 파일을 업로드 하였다.

하지만 새로운 업데이트가 있을 때 마다 변경된 사항을 Android Studio Build로 APK를 추출하고, 포털에 들어가서 업로드를 진행해야하는 번거로움이 있었다.

Github로 관리하는 코드

어플 프로젝트 코드 및 파일은 Github로 관리하고 있었다.

따라서 이 점을 활용해 GithubActions를 이용하여 APK를 자동으로 추출하고, 추출 뿐만 아니라 서버 업로드까지 자동화하면 어떨까? 라는 생각이 들었다.

GithubActions로 workflow를 작성하면, 수동으로 프로젝트 apk 빌드, 업로드를 하지 않아도 되기 때문에 생산성이 더 향상될 것이라 판단되었다. → 개발에 더욱 집중할 수 있게 된다!

활용 가능한 서버 API를 탐색

관리자 포털에서 apk 업로드가 가능하다는 점에서, 사용 가능한 API가 있을 것이라 생각이 들었다.

관리자 API Docs를 찾아 본 결과 App Upload와 관련된 API를 발견할 수 있었다.

  • file을 upload한 후 response로 오는 uploadFileName을 apps에 목록에 들어가도록 하는 로직이다.

이 API를 호출하여 workflow를 구축하면 자동화를 완성할 수 있을 것이라 생각이 들었다.

Github Actions의 WorkFlow 구축

workflow를 구축하기 전 Github Actions에 대해 알아보자.

Github Actions란?

Github Actions는 CI/CD(지속적인 통합, 배포) 도구로, SW 개발과 배포 과정을 자동화하는 데 사용된다.

Github 플랫폼 내에서 직접 호스팅되며, 사용자가 별도로 서버를 설정할 필요가 없다. YAML 파일을 통해 작업을 정의하고 구성할 수 있어서 설정이 간편하다.

Workflow YAML 파일의 구조

  • Repository 내 Actions에서 볼 수 있는 Android CI 파일이다.
  • 이 파일을 통해서 YAML 파일의 구조 및 의미를 살펴보자.
name: Android CI

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

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: set up JDK 11
      uses: actions/setup-java@v4
      with:
        java-version: '11'
        distribution: 'temurin'
        cache: gradle

    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    - name: Build with Gradle
      run: ./gradlew build

on

on:
  push:
    branches: [ "develop" ]
  pull_request:
    branches: [ "develop" ]
  • develop 브랜치의 push 또는 PR이 발생할 경우 작업을 실행하겠다는 의미이다.

jobs

jobs:
  build:

    runs-on: ubuntu-latest
  • 실행할 작업을 정의하는 곳이다.
  • runs- on은 빌드 작업이 실행 될 환경을 지정한다.
  • ubuntu-latest 는 Ubuntu 최신 버전 환경을 사용함을 의미한다.

steps

  steps:
    - uses: actions/checkout@v4
    - name: set up JDK 11
      uses: actions/setup-java@v4
      with:
        java-version: '11'
        distribution: 'temurin'
        cache: gradle

    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    - name: Build with Gradle
      run: ./gradlew build
  • steps 아래에 실행할 작업들을 나열한다.
  • 실행할 작업을 순서대로 정의하면 된다.

CI/CD Workflow 생성하기

문제의식을 바탕으로 자동화를 위한 시나리오는 다음과 같다.

1. main 브랜치의 push, PR 이벤트가 발생할 시에 Actions 실행
2. 우분투 최신환경, Java 버전 17에서 실행
3. debug-apk 추출 
4. artifact에 upload 하여 debug-apk 다운로드
5. download되는 apk file 로그 찍기
6. 2가지 API 활용하여 가상화 서버에 APK 업로드하기 

시나리오 1~2 : 환경 설정

name: Android build APK to Server 

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

jobs:
  build:

    runs-on: ubuntu-latest // 우분투 최신 

    steps:
    - uses: actions/checkout@v4
    - name: set up JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'
        cache: gradle // JAVA 17 실행

    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    - name: Build with Gradle
      run: ./gradlew build
  • on을 활용하여 main 브랜치의 push와 PR이 있을 때 작업을 실행하도록 한다.
  • jobs build 환경은 우분투 최신 환경으로 설정한다.
  • steps 내부에 자바 17 환경에서 실행되도록 설정한다.

시나리오 3-5 : Debug APK 빌드

 - name: Build debug APK
      run: |
          ./gradlew clean
          ./gradlew assembleDebug --stacktrace

    - name: Display APK file location
      run: |
        echo "APK is located at $(pwd)/app/build/outputs/apk/debug/app-debug.apk"
    - name: Upload Debug APK
      uses: actions/upload-artifact@v4
      with:
        name: app-debug.apk
        path: app/build/outputs/apk/debug/app-debug.apk

시나리오 6: HTTP API 통신

Http 통신 API를 YAML에서 어떻게 실행가능 한지 찾아보았다.

Github Actions로 HTTP API 통신

HTTP API 통신을 위해서 curl 명령어를 사용하여 요청을 보내고 응답을 처리할 수 있다.

예시 ) POST apk 파일 업로드 API 사용

  • 이 때 header에는 TOKEN, request에는 MultiPart form-data file이 들어간다.
  1. curl -X 로 HTTP 요청의 메서드를 지정하는 옵션을 사용한다.
  2. curl -X POST $API_URL/upload 로 URL을 지정한다.
  3. curl -H 로 헤더에 추가할 Auth Token을 지정한다.
  4. curl -F 로 request인 MultiPart-form-data file을 넣어준다.
  5. curl -o 로 서버로부터 받은 응답을 지정 파일에 저장한다.
  6. curl -w로 요청 후 출력할 정보를 지정한다. (http 상태코드를 지정하였다.)
- name: Upload APK to Server
      env:
        API_URL: ${{secrets.API_URL}}
        API_LOGIN_TOKEN: ${{secrets.API_LOGIN_TOKEN}}
      run: |
        response=$(curl -X POST "$API_URL/upload" \
        -H "Authorization: OAuth $API_LOGIN_TOKEN" \
        -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
        -o response.txt \
        -w "\n%{http_code}") 

        status_code=$(echo "$response" | tail -n1)
        body=$(cat response.txt)

        echo "Status Code: $status_code"
        echo "Response Body: $body"

         if [ "$status_code" -ge 200 ] && [ "$status_code" -lt 300 ]; then
          echo "POST API request was successful"

       else
          echo "API request failed"
          exit 1
        fi
  • 이렇게 HTTP POST upload API 를 실행하도록 YAML 파일을 작성하였다.
  • 이 때 echo를 활용하여 API 통신의 응답값, Status Code를 화면에 출력하였다.

Secerets 로 민감 정보 가리기

GithubActions에서 사용하는 url, token과 같은 가려야 하는 값들은 secrets로 환경변수처럼 안보이게 할 수 있다.

따라서 $API_URL, $API_LOGIN_TOKEN은 secrets을 활용해 가린 정보이므로 $로 사용하면 된다.

이 외에도 주요 curl 옵션은 다음과 같다.

주요 curl 옵션 설명

옵션 설명
-X, --request 사용할 HTTP 메서드를 지정합니다. (예: GET, POST, PUT, DELETE)
-H, --header 요청에 추가할 HTTP 헤더를 설정합니다.
-d, --data POST 요청 시 전송할 데이터를 설정합니다. 일반적으로 URL 인코딩된 형식으로 데이터를 보냅니다.
-F, --form 멀티파트 폼 데이터 전송을 위해 사용됩니다. 파일 업로드 시 주로 사용됩니다. (예: -F "file=@/path/to/file")
-o, --output 서버로부터 받은 응답을 지정한 파일에 저장합니다. (예: -o filename.txt)
-w, --write-out 요청 후 출력할 정보를 지정합니다. (예: HTTP 상태 코드)
-i, --include 응답의 HTTP 헤더를 포함하여 출력합니다.
-v, --verbose 요청과 응답의 상세한 정보를 출력합니다. 디버깅에 유용합니다.
-L, --location 리디렉션이 발생할 경우 자동으로 따라갑니다.
-k, --insecure SSL 인증서 검증을 생략하고 연결합니다. (보안상 권장되지 않음)
-u, --user 기본 인증을 위한 사용자 이름과 비밀번호를 지정합니다. (예: username:password)
-T, --upload-file 로컬 파일을 서버로 업로드할 때 사용됩니다.
-C, --continue-at 이전 다운로드를 재개하는 데 사용됩니다.

예제

  1. GET 요청:
  2. bashcurl -X GET "http://example.com/api/resource"
  3. POST 요청:
  4. bashcurl -X POST -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' "http://example.com/api/resource"
  5. 파일 업로드:
  6. bashcurl -X POST -F "file=@/path/to/file" "http://example.com/upload"
  7. 응답을 파일로 저장:
  8. bashcurl -o output.txt "http://example.com/api/resource"
  9. 리디렉션 따라가기:
  10. bashcurl -L "http://example.com/redirect"
  11. 상세 정보 출력:
  12. bashcurl -v "http://example.com/api/resource"

이렇게 Github Actions의 YAML 파일을 작성하여 Update를 진행하였다.

그 결과 Main에 Push, PR 이벤트가 발생하였을 때 해당 YAML 파일이 작업을 실행하고 APK빌드, API를 통한 앱 업로드를 진행하여 성공적으로 가상화 서버에 어플이 올라간 것을 볼 수 있었다.

이전에 Android Studio에서 Build → 관리자 포털 로그인 → 관리자 포털 apk 파일 업로드 과정보다 Android Studio에서 Main으로 Push 만으로 3가지의 과정이 자동화되어 생산성이 향상된 것을 몸소 느낄 수 있었다.

GithubActions에 API를 활용하여 자동화할 수 있다면 해당 방법을 적극 추천한다.

728x90
저작자표시 (새창열림)

'Android > 프로젝트 개발' 카테고리의 다른 글

[Android] implemantation을 Version Catalog로 바꿔보자  (0) 2024.12.12
[Android] PDF 뷰어 띄우기 / Activity 내에 PDF 뷰어 넣기 feat. 파일관리  (0) 2024.09.20
[Android/JAVA] Zxing 활용 바코드/QR 스캐너 구현하기  (0) 2024.08.07
[Android] Retrofit에서 XML 데이터 통신 및 파싱 방법 / RecyclerView XML 데이터 받아오기  (0) 2024.02.26
[Android] 인앱 업데이트 구현하기 / 인앱 업데이트 테스트  (1) 2023.11.01
'Android/프로젝트 개발' 카테고리의 다른 글
  • [Android] implemantation을 Version Catalog로 바꿔보자
  • [Android] PDF 뷰어 띄우기 / Activity 내에 PDF 뷰어 넣기 feat. 파일관리
  • [Android/JAVA] Zxing 활용 바코드/QR 스캐너 구현하기
  • [Android] Retrofit에서 XML 데이터 통신 및 파싱 방법 / RecyclerView XML 데이터 받아오기
hyeon.s
hyeon.s
이유있는 코드를 짜자

티스토리툴바