이번엔 이 공부 끝내겠다 시리즈/github actions

CI/CD는 무엇일까 (with. github actions)

by GicoMomg (Lux) 2021. 11. 9.

1. CI/CD는 무엇일까?

1) CI, CD란?

CI/CD는 코드 병합, 테스트, 배포를 자동화하는 걸 이야기한다.

  • CI(Continuous Integration)는 지속적 통합을 의미하며,
  • CD는 지속적인 서비스 제공(Continuous Delivery), 배포(Continuous Deployment)를 의미한다.
  • CI, CD는 각각 개념이 다르지만, 같이 구축되는 경우가 많아 CI/CD라고 묶인다.
  • 구체적인 개념은 아래에서 살펴보자.

(1) CI?

  • CI는 지속적 통합을 뜻하며, 일련의 통합 과정을 자동화하는 걸 의미한다.
  • 그런데 CI는 어떤 경우 때문에 필요한걸까?
A팀에 개발자가 5명 존재한다.
이 팀은 각각, 코드 작업을 완료하여 github에 push한다.
그리고 모인 코드는 병합을 거치게 된다.
그런데 병합 과정에서 동일한 코드를 수정한 경우 충돌이 발생하게 된다.
발생한 충돌을 해결하기 위해 수동으로 작업을 진행한다.

그 다음 배포를 해야하는데,
배포 하기에 앞서 코드에 문제가 없는 지 테스트를 진행한다.
그런데 코드에 치명적인 버그가 발생한다.
이 버그를 해결하기 위해 이 코드와 관련된 팀원이 일을 진행한다.

이처럼 A팀은 코드 푸시 -> 병합 -> 충돌 발생시 해결 -> 기능 테스트 작업을 매번 거친다.
  • A팀은 앞서 언급한 일련의 과정을 매번 수동으로 진행한다.
  • 소규모 팀의 경우, 이 과정을 반복하는 게 어렵지 않겠지만, 팀이 성장함에 따라 과정의 규모는 커진다.
  • 규모가 커질수록 투자하는 시간이 증가하게 되고, 이는 배포에 영향을 주게 된다.
  • 하지만 CI를 이용한다면 이 과정을 자동화시켜 시간을 절약해줄 수 있다.

(2) CD?

  • CD는 지속적 서비스 제공 & 배포 두가지를 의미하는데, 이 둘의 차이는 배포를 자동으로 하는지 여부이다.
  • 배포란 사용자에게 소프트웨어를 전달하는 걸 뜻하며, 지속적 배포는 작업이 마칠 때마다 자동으로 배포한다.
  • CD를 진행하기에 앞서, 코드를 병합하고 테스트하는 CI가 우선되어야 한다.
  • CI/CD는 개발 ~ 배포에 이르는 모든 단계를 자동화하는 걸 의미하며, 이러한 일련의 과정을 CI/CD 파이프라인이라고 부른다.

그렇다면 이러한 CI/CD의 장점은 무엇이 있을까?


(3) CI/CD의 장점

  • 코드에서 발생하는 버그 발견, 코드 테스트가 자동화되므로 배포 간격이 짧아질 수 있다.
  • 각 개인이 코드를 병합할 때마다 자동으로 테스트를 거치므로, 버그 발생 가능성이 낮아진다.
  • 코드 배포 및 체크가 자동화되므로, 최종 코드 확인에 필요한 시간이 단축된다.
  • 매 작업마다 테스트가 진행되므로 버그를 초기에 발견할 수 있으며 이는 버그의 빠른 해결에 도움이 된다.

CI/CD가 무엇인지 알아보았으니 이제 CI/CD의 대표적인 툴인 github actions를 한 번 알아보자



2. github actions 맛보기

1) github action란?

  • github ActionsCI/CD는 물론 여러 소프트웨어 개발 과정을 자동화해주는 서비스이다.
  • 만약 github를 사용하고 있다면, 레파지토리에서 아래 탭을 본 적이 있을 것이다.

  • Actions 탭의 좌측을 보면 workflow 리스트가 존재하며, 우측에 커밋 메시지와 초록불이 보인다.
  • 그런데, workflow는 무엇이며 github actions에서는 어떻게 CI/CD를 사용할 수 있을까?



1) actions의 구성 요소

(1) runner, 가상 컴퓨터

  • runner는 깃헙에서 제공하는 가상 컴퓨터로, mac os, window 등 다양한 운영체제에서 작동될 수 있다.
  • 만약 우리가 깃헙에 코드를 푸시하면, 우리가 작성한 코드(로직)가 runner에서 실행한다.
  • 또한 부가적으로 필요한 정보를 runner에 입력할 수 있다.
  • 우리는 runner에서 코드를 실행시켜, 자동으로 디플로이 하거나 테스트할 수 있다.

(3) job, step의 집합

  • 하나의 workflow에서는 여러 job이 존재할 수 있으며 서로 의존하도록 설정할 수 있다.
  • 빌드 job이 테스트 job 다음에 실행되어야 한다는 의존관계를 설정하면, 빌드 job이 실패하면 테스트 job은 실행되지 않는다.

(4) step, 각각의 task

  • 실행할 각각의 커멘트를 의미한다.
  • 하나의 job에는 여러개의 step이 존재할 수 있다.

(5) action, step 뭉치

  • job에서 재사용 가능한 별도의 step들이다.
  • github action에서 사용할 수 있는 라이브러리라고 생각하면 된다.

(6) workflow, 전체 프로세스

  • workflow는 레파지토리에서 실행되는 자동화된 커맨트 집합이다.
  • 하나 이상의 job으로 구성되어 있다.
  • workflow는 이벤트(push, pull request)에 의해 실행되기도 하지만, 시간에 따라 실행될 수도 있다.
  • workflow 코드는 .github/workflows 에 저장된다. (확장자는 yml)

(7) event, 이벤트

  • workflow는 이벤트 기반의 동작한다.
  • 이벤트는 push, pull request가 있다.
  • 더 자세한 이벤트 종류는 깃헙 공식문서 링크에서 확인할 수 있다.
  • 만약 사용자가 코드를 푸시하는 이벤트를 발생시키며, 이에 해당하는 jobs들이 실행된다.



2) github actions 예시

github에 테스트용 레파지토리를 만든 상태라고 가정하고 진행한다.

(1) workflow 생성 방법

  • 생성한 레파지토리의 action탭으로 가면 아래와 같은 화면이 나온다.
  • set up a workflow yourself를 클릭해보자.


  • 이동해보면, .github/workflowsmain.yml이 자동으로 생성되는 걸 볼 수 있다.
  • 우리는 main.yml라는 워크플로우를 작성할 수 있다.


  • 원래라면 workflow에 코드를 작성해야하지만 예시 코드를 그대로 두고, start commit을 눌러보자.


  • 그리고 actions 탭으로 이동하면 workflow가 실행되는 걸 볼 수 있다.


  • 실행되고 있는 workflow를 클릭해보면, 상세 내역을 볼 수 있는데 어떤 작업을 했는지 확인할 수 있다.

workflow 생성 과정을 보았는데, 이제 직접 코드를 작성해보자!


(2) step 추가해보기

  • 앞서 설명했듯이 workflow는 이벤트 기반의 동작한다.
  • 만약 사용자가 코드를 푸시(이벤트)하면 해당하는 jobs들이 실행된다.
  • 아래 코드는 workflow의 기본적인 예시이다.
  • 라인별로 의미를 알아보자
name: Hello world
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Run pwd # 동작명
      run: rwd # 실제 동작
    - name: Run ls -al
      run: ls -al

  • name은 해당 workflow의 이름을 뜻한다.
name: Hello world  

  • on은 이벤트를 지정하는 곳으로, 쉼표(,)를 이용해 여러 이벤트를 추가할 수 있다.
  • [push]라고 작성하면 push가 발생했을 때 작업을 실행한다는 말이 된다.
name: Hello world
on: [push]       

  • jobs에는 여러 step을 추가하거나 구동 환경을 지정할 수 있다.
jobs:
  build:
    runs-on: ubuntu-latest  # 우분투에서 실행 

  • steps에는 실행할 커멘트를 지정하며, name에는 동작명, run에는 실행할 커멘트를 작성한다.
jobs:
  build:
    runs-on: ubuntu-latest
    steps:              
    - name: Run pwd       # 동작명
      run: pwd            # 실제 동작

  • 앞서 본 코드의 의미를 해석하면 아래와 같다.
name: Hello world     # 1. 이 워크플로우의 이름은 Hello world야
on: [push]            # 2. 만약 push 이벤트가 발생하면 jobs를 실행할거야

jobs:
  build:
    runs-on: ubuntu-latest    # 3. jobs을 실행할 환경은 우분투이고,
    steps:                    # 4. 실행한 커멘트는 steps에 지정할 거야
    - name: Run pwd # 동작명    # 5. Run pwd라는 동작은 pwd를 실행시키는 거야
      run: pwd # 실제 동작
    - name: Run ls -al
      run: ls -al

  • 이제 이 워크플로우를 추가하고 실행해보면 아래와 같은 화면이 나온다.


  • 우리가 지정한 step들이 진행된 걸 확인할 수 있다.


(2) 액션 사용해보기

  • 우리는 uses 키워드를 사용해 다른 사람이 이미 구축한 액션을 사용할 수 있다.
  • 사용가능한 액션의 종류는 마켓 플레이스(빨간색 표시)에서 볼 수 있다.


  • 앞선 예시에 액션을 추가해보자!
name: github-checkout
on: [push]
jobs: 
  build:
    runs-on: ubuntu-latest # 구동 환경

    steps:
    - uses: actions/checkout@v2 # 액션 라이브러리를 실행

  • 해당 워크플로우를 추가하고 결과를 보면, 액션이 실행됐음을 알 수 있다.
  • 액션별 동작은 각 액션 문서에서 확인할 수 있다.


(3) 문맥 사용해보기

  • 러너에서 작동되는 steps을 만들 때, 러너가 구동된 시점의 상태 정보를 알면 여러 처리를 할 수 있다.
  • 문맥(context)은 바로, 러너가 구동된 시점의 상태를 알려주는 환경변수이다.
  • 문맥의 여러 종류는 깃업 문서에서 확인할 수 있다.
  • env 키워드를 사용해 환경변수 속성과 값을 지정할 수 있다.
name: context
on: [push]
jobs: 
  build:
    runs-on: ubuntu-latest # 구동 환경

    steps:
    - name: "context"
      env:                                # 환경변수 관련
        COMMIT_ID: ${{ github.sha }}      # 환경변수 지정(키: 값)
      run: echo "Commit id => $COMMIT_ID" # 환경변수 출력해보기


잠깐! 숨겨야하는 환경변수를 어떻게 설정할까?

  • 먼저 settingssecrets에 외부에 공개하면 안되는 변수를 추가한다.


  • 그 다음 secrets.추가한_속성명을 사용하면 된다.
name: secret-test
on: [push]
jobs: 
  build:
    runs-on: ubuntu-latest # 구동 환경

    steps:
    - name: Print Password
      env:
        MY_PASSWORD: ${{ secrets.PASSWORD }}
      run: echo My Password is $MY_PASSWORD

  • secrets에 추가한 속성은 출력시 암호화된 상태로 출력된다.




반응형

댓글