안드로이드에서 깃헙 액션으로 구성하는 CI / CD 에 대해 알아보기

Mendel·2023년 12월 20일
0

git

목록 보기
3/3

우선, 이 내용을 학습하는 이유는 제대로 이번 기회에 깃헙액션에 대해 정리하고자 한다.
마침 medium 글에 흥미를 돋우는 글이 있어서 참고하려 한다. 아래 링크의 글을 번역하는 내용이 주이며, 물론 실제로 해당 블로그에 나온 내용을 적용도 해보았지만 이를 실제 프로젝트에 적용하는 것은 다음 프로젝트를 시작하며 한 번 해보려고 한다.
이 내용에서는 키스토어를 활용해서 릴리즈 apk파일을 생성하는 법은 다루지 않는다. 이는 다음에 다시 알아보면 좋을 것 같다.
https://medium.com/@KaushalVasava/what-is-ci-cd-how-to-build-ci-cd-pipeline-in-android-using-github-actions-60f69805657b

CI / CD 란 무엇인가?

지속적인 통합 및 지속적인 배포 을 의미한다.
쉽게 말해서 소프트웨어 빌딩, 테스트, 배포 등의 작업을 자동화하는 것이다.
CI/CD 를 적용해놓으면, 작업들을 더 작은 부분으로 나누게 되고 워크플로우를 자동화함으로써, 오류를 줄이고 개발 속도를 빠르게 해주며 소프트웨어의 준비 상태를 유지한다.

오늘날 기술환경에서 CI/CD는 애자일을 유지하기 위한 근본적인 요구사항이라고 한다.

CI / CD 는 앱 개발 단계에 자동화를 도입해서 고객들에게 앱을 더 자주 제공할 수 있는 방법이다.
CI / CD 를 통해 개발팀과 운영팀이 새로운 코드를 통합하는 과정에서 겪을 수 있는 문제를 해결하는 방법이 될 수 있다.

이런 연속된 관행들을 CI / CD 파이프라인이라고도 부르며, 이것은 개발팀과 운영팀이 데브옵스 혹은 사이트 안정성 엔지니어링 접근방식을 통해 애자일 방법론으로 협력해서 일하는 것으로써 지원된다.

위 사진을 해석하면 아래와 같이 CI / CD 워크플로우를 정리할 수 있다.
1. 각자 맡은 기능을 작업
2. 원격 저장소에 푸쉬
3. 소스코드 빌드
4. 테스트 돌려보기
5. UAT 환경에 배포
6. 실제 프로덕트 환경에 배포

여기서 UAT 환경이란?
UAT는 사용자 수용 테스트의 약자다. 한마디로 프로덕트 환경에 최종 배포하기 전에 지금까지의 결과물을 일부 유저(혹은 이 프로젝트를 의뢰한 의뢰인)들이 직접 마지막으로 검증하는 테스트 환경이라고 생각하면 된다(즉, 베타환경이라고 생각하면 됨).
보통 UAT와 함께 SIT(시스템 통합 테스트)라는 용어도 함께 나온다. 이는 QA팀에서 하는 시스템 통합 테스트라고 생각하면 될 것 같다. 이는 주로 기술적인 접근방식으로 테스트를 하며, 기술적인 최종 통합 테스트라고 생각하면 될 것 같다.
일반적으로 SIT 이후 UAT를 시행한다.

지속적인 통합

CI를 통과했다는 것은 새로운 코드들이 잘 빌드되고, 기존의 테스트를 통과하고, 안전하게 머지되었다는 것을 의미한다.

이런 CI는 서로 충돌이 날 가능성이 있는 브랜치들이 한번에 너무 많이 있는 개발에서 해결책이 될 수 있다.

(그 외에도 CI에 대한 내용은 많았으나 다 똑같은 말을 반복해서 더이상 적지 않음)

CD(두 가지 의미 모두 지속적인 배포라고 해석됨)

CD 라고 하면 보통 지속적인 delivery 혹은 deployment 라고 한다. 이 두 가지는 모두 CI/CD 파이프라인에서 앞에서 본 CI 단계를 제외한 나머지 단계를 모두 가리킨다. 때로는 두 가지 모두 비슷한 의미로 쓰이지만, 간혹 얼마나 많은 자동화가 이루어지고 있는지를 설명하기 위해 따로따로 사용되기도 한다고 함.

Continuous Delivery

이 용어는 할 수 있다는 것을 의미한다. 어떤 것을? 운영팀이 라이브 프로덕션 환경에 테스트가 모두 되어 레포지토리에 통합된 종합코드를 배포할 수 있음을.
이를 통해 비즈니스 팀과 개발팀 간의 가시성과 소통의 부족 문제를 해결할 수 있다고 한다.
즉, Continuous Delivery는 새 코드를 배포하는데 최소한의 노력이 들도록 하는 것이다.

즉, CI는 빌드, 단위 테스트, 통합 테스트를 자동화하는것이였다면, 이를 통해 나온 검증된 코드를 Continuous Delivery는 레포지토리에 자동으로 릴리즈하는 것을 의미한다. 즉, CI가 이미 개발 파이프라인에 있다는 전제가 깔려있는 것이다.

다시 한번 정리하면, Cotinuous Delivery는 프로덕트 환경에 배포 준비가 항상 되어있는 코드베이스(레포지토리 상에 존재하는)를 갖는것이 목적이다.
이를 통해 운영팀은 앱을 배포하는 것을 빠르고 쉽게 할 수 있다.

Continuous Deployment

이 용어가 실제로 지속적 배포의 본질적인 주인이라고 할 수 있다. 바로 개발자의 변경사항이 반영된 준비된 레포지토리의 코드들을 유저가 사용할 프로덕트 환경에 자동으로 릴리즈하는 것을 말한다.

이를 통해, 운영팀에서 수동적으로 일을 해서 앱 배포가 늦춰지는 문제를 해결할 수 있다.
이는 위에서 배운 Continuous Delivery를 기반으로 하며, 개발 파이프라인의 다음 단계를 자동화하는 것이다.
Continuous Delivery는 레포지토리에 자동으로 릴리즈하는 것이고, Continuos Deployment는 앱을 프로덕션에 자동으로 릴리즈하는 것이다.

Continuous Deployment는 잘 설계된 테스트 자동화에 크게 의존한다.

이런 연결된 모든 CI / CD 과정에 의해서 앱에 대한 변경의 배포를 한번에 몰아서 하기보다 부분적으로 하기가 더 쉬워지고, 위험성도 줄어들게 된다. 이러한 점 때문에 CI / CD 를 애자일의 핵심적 요소라고 부르나보다.

하지만, 이 또한 많은 초기 투자 비용이 든다. 다양한 테스트 및 릴리즈 단계를 수용하기 위한 자동화된 테스트를 작성해야 한다는 것이다.

지금까지 읽은 글에 대한 필자 생각,
이 글 내용을 보면 Continuous Delivery와 CI가 크게 다를게 없어 보인다. 이건 좀 더 다른 글도 찾아봐야할듯 싶다.

본격적으로 GitHubActions를 활용해서 안드로이드에 CI-CD 파이프라인을 구축하기

  1. 파일 구조를 프로젝트 모드로 변경한다.
  2. 새 디렉토리(.github/workflows)를 app모듈과 동등한 위치에 만들어라.
  3. workflows 디렉토리 안에 AndroidBuild.yml이라는 파일을 만들어라. 그리고 다음과 같은 코드를 복붙해라. 이 의미는 아래에서 계속 살펴볼 것임.
# This is a basic workflow to help you get started with Actions
name: Android Build

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "master" branch
  pull_request:
    branches: ["master"]
  push:
    branches: ["master"]

# 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
      - name: Checkout
        uses: actions/checkout@v4.1.1

      - name: Setup Java JDK
        uses: actions/setup-java@v4.0.0
        with:
          java-version: '17'
          distribution: 'adopt'

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

      # Runs a single command using the runners shell
      - name: Build with Gradle
        run: ./gradlew build

      - name: Upload a Build Artifact
        uses: actions/upload-artifact@v3.1.3
        with:
          name: AndroidCICD.apk
          path: app/build/outputs/apk/debug/app-debug.apk

GitHub Actions란?

CI / CD 파이프라인에서, 깃헙액션은 지루한 작업을 자동화하는 녀석이다. 모든 깃헙 레포지토리에서 사용가능한 플러그인이라고 생각하면 편하다. 즉, 말그대로 깃헙에서 제공하는 기능이다.
깃헙액션은 우리가 지시한 작업을 할 수 있는 플러그인이다.
이 플러그인이 실행할 작업은 yaml파일로 만든다.
그리고 이런 yaml파일은 우리가 어떤 명령들을 시키든 간에 다음과 같은 의미가 된다고 한다.

"안녕하세요 GitHub Actions, X 브랜치에서 PR이 열릴 때마다 자동으로 새 변경 사항을 빌드하고 테스트하세요. 그리고 새로운 변경 사항이 X 브랜치에 병합되거나 푸시될 때마다 해당 변경 사항을 Y 서버에 배포하세요."

깃헙액션의 핵심으로는 다섯가지 개념이 있다고 한다.

  • jobs
  • workflows
  • events
  • actions
  • runners

위에서 우리가 작성한 코드를 이 다섯가지 개념에 빗대어서 확분석해보고 이해해보자.

Job

Job들은 YAML 구성 파일 안에다가 작성해놓은 깃헙액션에게 우리가 명령한 작업들이다.

이런 작업들은 소스코드를 빌드하거나 테스트를 실행하거나 빌드한 코드를 원격 서버에 배포하도록 깃헙액션에게 지시하는 것이다.

# 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
      - name: Checkout
        uses: actions/checkout@v4.1.1

위 파일의 의미는 build라는 이름의 작업 목록을 하나 지정하고, 이 build라는 작업이 실행될 환경을 지정하기 위해 runs-on이라는 속성을 쓰고 우분투 최신버전을 지정해준다.
그리고 steps에는 각 단계의 이름과 그 단계에서 사용할 깃헙액션 기능이 필요하다면 uses와 함께 그 기능의 버전까지 지정해주면 된다.
여기에서는 실행환경에서 이 레포지토리의 코드에 접근하기 위해 체크아웃이라는 단계를 거치고 있다.

workflow

워크플로우라는 개념은 위에서 내내 봤듯이, 하나 이상의 작업들이 연결된 자동화된 프로세스 그 자체를 의미한다. 빌드 및 실행 테스트 작업은 CI라는 워크플로우로 분리해서 생각해서 이를 하나의 워크플로우에 배치할 수 있고, 배포 작업 또한 CD라는 워크플로우로 분리해서 또다른 하나의 워크플로우에 배치할 수 있다.

깃헙액션은 우리의 레포지토리의 특정 디렉토리 안에 넣은 각 YAML구성파일을 하나의 워크플로우로 간주한다.
하지만, 우리는 현재 하나의 구성파일로 합쳐서 CI/CD를 하나의 워크플로우로 작성했다. 이는 나중에 변경하면 될듯싶다.

Event

이벤트는 말그대로 깃헙액션의 작업을 실행하기 위한 트리거 역할의 이벤트를 말한다. 이런 이벤트는 on키워드를 사용해서 지정할 수 있다.
일반적으로 push되었을때, pr이 생겼을때, merge되었을때 등의 이벤트가 있다.
아래 코드에서는 마스터브랜치에 대한 pr과 push의 경우에 해당 워크플로우를 실행하려고 지정한 것이다.

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "master" branch
  pull_request:
    branches: ["master"]
  push:
    branches: ["master"]

헷갈리면 안되는 것은 굳이 어떤 이벤트의 발생이없어도 job을 예약해서 실행할 수도 있다. 예를들어 뭔가 오전 2시에 매일 반복되어야 하는 job을 지정할 수 있다는 것임. 이것에 대한 방법은 자세히 나오지 않는다. 나중에 필요할때 찾아보면 도움될 것 같다.

Actions

액션이라는 것은 yaml 구성파일에서 재사용할 수 있는 명령을 의미한다.
다음과 같은 예시처럼, 우리가 만든 커스텀 actions나 이미 존재하는 걸 활용할 수 있다.

- name: Checkout
  uses: actions/checkout@v4.1.1

Runner

러너는 깃헙액션이 활용하는 원격 컴퓨터다. 러너에서 우리가 지시한 Job들이 실행된다.

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

깃헙액션이 이벤트가 발생되면 우리의 코드를 해당 원격 컴퓨터인 러너로 가져와서 실행한다.

우리가 아까 작성한 파일 이해하기

  • name: Android Build 는 해당 워크플로우의 이름이다. 우리의 깃헙 레포지토리에서 actions tab으로 이동할 때, 정의한 각 워크플로우는 그 이름으로 식별된다고 한다.

    보이는 것처럼, master브랜치에 푸쉬했더니 build라는 이름의 job이 실행되고 있다. 아래 사진은 좀 더 상세하게 확대한 것이다.

    모든 작업을 마치고나니, 아래처럼 아티팩트가 생성되어 나왔다.
    이걸 클릭하고 다운받아서 휴대폰에서 실행해보니 앱이 잘 실행된다!!! 이걸 완전히 플레이스토어에 자동 배포하는 법은 좀 더 찾아봐야할듯 싶다.
  • on: 워크플로우의 실행을 트리거할 이벤트를 지정하는 곳.
  • jobs: 워크플로우는 job들의 집합이다.
  • runs-on: 우분투 리눅스, 마이크로소프트의 윈도우, 맥os등의 러너(우리의 워크플로우를 실행할 원격컴퓨터)를 깃헙에서 제공한다.

job들은 steps: 아래에 각각 정의된다.
이것들은 일반적으로 동일한 러너에서 실행된다. name은 그 각 단계의 이름을 의미한다.
각 단계는 실행할 쉘 스크립트일 수 있고 혹은 action일 수 있다. action을 실행할거라면, uses로 스텝을 정의하고 쉘 스크립트를 실행할거라면 run으로 스텝을 정의한다.

깃헙액션에 대해 더 알아보기


Actions탭에서 new workflow를 선택해서 새로운 워크플로우 구성파일을 만들 수 있으며, 우리가 사용할 수 있는 action들도 Marketplace에서 확인할 수 있다. 업로드중..이런식으로 사용할 버전과 사용법을 알려준다.

이제 해당 블로그에 대한 글은 모두 종료되었다.


추가적인 코드 설명

혹시 더 설명이 필요할까 싶어 적어놓았다.

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "master" branch
  pull_request:
    branches: ["master"]
  push:
    branches: ["master"]

on은 workflow가 언제 동작할지 지정할 경우들을 지정하기 위한 것임.
on안에 pull_request와 push가 있다. 즉, pr이나 push가 발생했을때 동작시키라는 의미다. 또한, 각 경우에 대해 적용할 대상 브랜치를 master로 지정했다.

그러면 이제 어떤 일들을 할지 워크플로우를 지정해줘야 한다.

# 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:

이 워크플로우 작업에는 build라는 이름의 job이 있다. 그렇다면 이 job에 대해 무슨환경에서 실행할지, 단계별로 무슨일을 할지를 지정해야 한다.

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

작업이 실행될 환경(runner)으로 우분투의 최신버전을 이용하겠다.

    steps:

steps는 단계별 작업들을 적어주면 된다.

  # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - name: Checkout
        uses: actions/checkout@v4.1.1

일단, 체크아웃을 해라. 여기서 uses는 이용할 깃헙액션 플러그인 이라고 생각하면 된다. 버전까지 지정해준것.

      - name: Setup Java JDK
        uses: actions/setup-java@v4.0.0
        with:
          java-version: '17'
          distribution: 'adopt'

Java JDK를 설정하는 단계임.
with으로 상세 버전을 지정했다.

      - name: Change wrapper permissions
        run: chmod +x ./gradlew
    # Runs a single command using the runners shell
      - name: Build with Gradle
        run: ./gradlew build

runners shell에서 그레이들 빌드를 위한 명령을 한다.

      - name: Upload a Build Artifact
        uses: actions/upload-artifact@v3.1.3
        with:
          name: AndroidCICD.apk
          path: app/build/outputs/apk/debug/app-debug.apk

빌드되어 나온 아티팩트(빌드 결과물)를 업로드해라. with을 이용해서 업로드할 파일이름(우리가 지정하는 것임)과 경로(해당 파일이 존재하는 경로)를 지정하고 있다.

profile
공부하는 학생입니다.

0개의 댓글