Github Action

[Github Action] 기본 개념

운덩하는 개발자 2022. 10. 30.
반응형

이전에 EC2를 빌려 각종 Docker, Nginx, Apache tomcat, Spring boot 프로젝트 서버 띄우기, 설치하고 삭제하는 등을 반복하여, 이번 프로젝트 서버의 기본 환경을 조성하였다. 단순히 쉬워보여서 금방 할 줄 알았지만  정말 많은 시간이 걸렸고 많은 오류와 많은 시행착오를 겪었다. 그러한 부분을 기록으로 남겨 나의것으로 만들었어야 했는데 아쉬움이 남는다.

 

 그래서 이번에는 CICD관련 작업들을 하며 나의 생각들과 실수들을 정리하며 할까한다.

GitHub Actions이란

GitHub Actions를 사용하면 이제 세계적 수준의 CI/CD로 모든 소프트웨어 워크플로를 쉽게 자동화할 수 있습니다. GitHub에서 바로 코드를 빌드, 테스트 및 배포하세요. 코드 검토, 분기 관리 및 문제 분류가 원하는 방식으로 작동하도록 합니다. -- by 공식문서  https://github.com/features/actions

 

 쉽게 말해서 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼이다.

Repository에 대한 모든 pull request를 빌드 및 테스트하는 Workflow를 생성하거나 병합된 pull request를 프로덕션에 배포할 수 있다.

 

 GitHub Actions는 단순한 DevOps를 넘어 Repository에서 다른 이벤트가 발생할 때 Workflow를 실행할 수 있도록 한다.

예를 들어, 누군가가 저장소에 새로운 이슈를 생성할 때마다 적절한 레이블을 자동으로 추가하는 Workflow를 실행할 수 있다.

 

 Runs-on으로 workflow를 실행하기 위한 Ubuntu Linux, Windows, macOS가상 머신을 제공하거나 자체 데이터 센터 또는 클라우드 인프라에서 자체 호스팅 러너를 호스팅할 수 있다.

    - > 여기서 나는 잘못 이해를 했던것이  Actions로 CI/CD를 하기위해서는 현재 EC2 OS와 Actions에서 제공하는 가상머신과 운영체제롤 동일시 해줘서 구성해야만 한다고 생각하였다. 

요금과 제한

public 저장소의 경우 무료로 사용 가능하며 private 저장소는 월마다 제공되는 무료 사용량 초과 시에 요금이 부과된다. 무료 계정을 기준으로 500MB의 스토리지와 월마다 2,000분의 실행시간이 제공된다.

구성요소

 pull request가 열리거나 이슈가 생성되는 것과 같은 이벤트가 repository에서 발생할 때 트리거되도록 GitHub workflow를 구성할 수 있다. workflow에는 순차적으로 또는 병렬로 실행할 수 있는 하나 이상의 job이 포함되어 있다. 각 job은 자체 가상 머신 runner 내부 또는 컨테이너 내부에서 실행되며, 사용자가 정의한 스크립트를 실행하거나 job을 실행하는 하나 이상의 단계(워크플로를 단순화할 수 있는 재사용 가능한 확장)가 있다.

 

Workflow, Event, Job, Step, Action, Runner로 구성

 

1. Workflows

  • 가장 최상위 개념 
  •  Workflow는 하나 이상의 Job으로 구성
  •  Event에 의해 트리거될 수 있는 자동화된 프로세스
  •  YAML로 작성
  •  Github Repository의 .github/workflows 폴더 아래에 저장
  •  Repository에는 여러 Workflow를 가질 수 있으며 각 Workflow는 서로 다른 작업 수행 가능.

2. Events

  • Workflow 실행을 트리거하는 특정 활동이나 규칙
  • 커밋의 push, pull request가 생성되었을 때뿐만 아니라 저장소 dispatch event를 통해 Github 외부에서 발생하는 활동으로도 이벤트를 발생시킬 수도 있다.
# push나 pull request가 발생할 때 워크 플로우 실행
on: [push, pull_request]

또한 schedule에 POSIX cron 문법으로 스케쥴 이벤트를 발생시킬 수도 있다.

on:
  schedule:
    - cron: '*/15 * * * *'

다양한 이벤트에 대한 정보는 여기에서 확인 가능하다.

 

3. Jobs

  • 여러 Step으로 구성
  • 가상환경의 인스턴스에서 실행
  • 다른 Job에 의존 관계 가능, 독립적 병렬 실행 또한 가능

4. Steps

  • Task들의 집합으로 커맨드를 날리거나 쉘 스크립트 실행하는 것 처럼 Action을 실행 가능

5. Actions

  • Workflow의 가장 작은 블럭, Job을 만들기 위해 Step들을 연결할 수 있다
  • 재사용이 가능한 컴포턴트로서 반복적인 코드의 양을 줄이기 가능
  • Git Repository를 가져오거나 클라우드 공급자에게 인증을 설정할 수 있다
  • 개인적으로 만든 Action을 작성 가능, Github Marketplace에 있는 공용 Action 사용 가능

6. Runners

  • Workflow가 트리거 될 때 실행하는 서버
  • 각 Runner는 1번에 1개의 Job 실행 가능
  • Github에서 호스팅해주는 Github-Hosted runner와 직접 호스팅하는 Self-hosted runner로 나뉜다
  • Github-Hosted runner는 Azure의 Standard_DS2_v2로 vCPU 2, 메모리 7GB, 임시 스토리지 14GB입니다.

 

Github Action 생성하는 흐름

  • 1) 코드 작성
  • 2) 코드 작성 후, Workflow 정의
  • 3) 정상 작동하는지 Test

Workflow 정의하기

  • 기본적인 방법 : .github/worfklows 폴더 안에 .yml 파일을 생성
    • yml 파일 예시
      • Master 브랜치에 Push 또는 Pull Request가 올 경우 실행되는 CI란 이름을 갖는 Workflow
        name: CI
      	
        on:
          push:
            branches: [ master ]
          pull_request:
            branches: [ master ]
      	
        jobs:
          build:
            runs-on: ubuntu-latest
      	
            steps:
            - uses: actions/checkout@v2
      	
            - name: Run a one-line script
              run: echo Hello, world!
      	
            - name: Run a multi-line script
              run: |
                echo Add other actions to build,
                echo test, and deploy your project.
      
  • name : Workflow의 이름을 지정
  • on
    • Event에 대해 작성하는 부분
    • 어떤 조건에 Workflow를 Trigger 시킬지
    • push(Branch or Tag), pull_request, schedule을 사용할 수 있음
      • 단, 다른 CI/CD 도구에 있는 즉시 실행 버튼은 없음(추후에 생길 수도?)
    • 단일 Event를 사용할 수도 있고, array로 작성할 수도 있음
    •   on: push
        # 또는
        on: [pull_request, issues]
      
  •   on:
        push:
          branches: [ master ]
        pull_request:
          branches: [ master ]
    
  • jobs
    • Workflow는 다양한 Job으로 구성됨
    • 여러 Job이 있을 경우, Default로 병렬 실행
    • build라는 job을 생성하고, 그 아래에 2개의 step이 존재하는 구조
    • runs-on은 어떤 OS에서 실행될지 지정
    • steps의 uses는 어떤 액션을 사용할지 지정함. 이미 만들어진 액션을 사용할 때 지정
  •   jobs:
            build:
              runs-on: ubuntu-latest
    		
              steps:
              - uses: actions/checkout@v2
              - name: Run a one-line script
                run: echo Hello, world!
    
              - name: Run a multi-line script
                run: |
                  echo Add other actions to build,
                  echo test, and deploy your project.
    

Workflow 관리

민감한 정보 저장

워크 플로우가 비밀번호나 인증서 같은 민감한 정보를 사용한다면 Github에 secret으로 저장하여 환경 변수로 사용 가능하다.

jobs:
  example-job:
    runs-on: unbuntu-latest
    steps:
      - name: Retrieve secret
        # 환경변수로 저장하고
        env:
          super_secret: ${{ secrets.SUPERSECRET }}
        # 저장한 환경변수를 활용한다.
        run: |
          example-command "$super_secret"

의존적인 작업 구성

기본적으로 작업은 병렬적으로 수행된다. 다른 작업이 완전히 끝난 후에 작업을 실행시키고 싶다면 needs 키워드를 통해 작업이 의존성을 갖도록 지정하면 된다.

jobs:
  setup:
    runs-on: ubuntu-latest
    steps:
      - run: ./setup_server.sh
  build:
    needs: setup
    runs-on: ubuntu-latest
    steps:
      - run: ./build_server.sh
  test:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - run: ./test_server.sh

needs 키워드를 통해 build, test 작업이 각각 이전 작업인 setup, build 작업이 끝난 후에 실행되도록 설정

빌드 매트릭스 활용하기

워크 플로우가 다양한 OS, 플랫폼, 언어의 여러 조합에서 테스트를 실행하려는 경우 빌드 매트릭스를 활용하면 된다. 빌드 옵션을 배열로 받는 strategy 키워드를 사용하면 된다.

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        # 다양한 버전의 Node.js를 이용하여 작업을 여러번 실행
        node: [6, 8, 10]
    steps:
      - uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node }}

종속성 캐싱

GIthub의 러너는 각 작업에서 새로운 환경으로 실행되므로 작업들이 종속성을 재사용하는 경우 파일들을 캐싱하여 성능을 높이면 된다. 캐시를 생성하면 해당 저장소의 모든 워크 플로우에서 사용 가능하다.

jobs:
  example-job:
    steps:
      - name: Cache node modules
        uses: actions/cache@v2
        env:
          cache-name: cache-node-modules
        with:
          # `~/.npm` 디렉토리를 캐시해 성능을 높인다
          path: ~/.npm
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-

 

반응형

댓글