새소식

git

[Github] Github Action 기초 및 Spring Boot CI/CD Workflow 구성하기

  • -

Github Action을 이용한 CI/CD 구축

Github Action

Github Action은 미리 정의된 특정 작업의 수행을 자동화할 수 있게 해주는 기능이다.
빌드/배포 워크플로를 자동화하거나, Pull Request 전 테스트를 자동으로 수행하여 테스트 통과시에만 PR을 open하도록 설정하거나, 특정 시간대에 크롤링 스크립트 등을 반복 수행하도록 하는 등, 여러 작업을 자동화 할 수 있다.

Github Action 구성 요소

Github Action을 구성하는 요소는 아래와 같다.

  • Workflow
    • 가장 최상위에 위치한 개념으로, 모든 명령어의 집합을 말한다.
    • 하나 이상의 Job으로 구성되어 있으며 특정 Event(Push, Pull Request)에 의해서 실행될 수도 있고 특정 시간대에 실행될 수도 있다.
    • .github/workflows 디렉토리에 .yml 형태로 저장된다.
  • Event
    • Workflow를 실행시키는 특정 행동을 의미한다.
    • Push, Pull Request, Commit과 같은 Github 내의 특정 행동이나, Github 외부에서 발생한 이벤트 등이 될 수 있다.
    • Github Action 공식 문서 참고
  • Job
    • 동일한 Runner에서 실행되는 여러 Step의 집합을 말한다.
    • 기본적으로 하나의 Workflow 내의 여러 Job은 독립적으로 실행된다. 독립적으로 실행된다는 말은 병렬로 실행된다는 의미이다.
    • 필요에 따라 의존관계를 설정하여 Job들의 실행 순서를 지정해줄 수 있다. 이 경우, 의존하는 작업이 실패하면 이후의 작업들은 취소된다.
    • 하나의 Job 내에서 각각의 Step은 다양한 Task로 인해 생성된 데이터를 공유할 수 있다.
  • Step
    • Github Action에서 가장 작은 실행 단위로, 명령을 실행할 수 있는 각각의 Task를 의미한다.
    • Stepshell command가 될 수도 있고, 하나의 Action이 될 수도 있다.
  • Action
    • Job을 구성하기 위해 여러 Step을 결합한 독립적인 command를 말한다.
    • Github Action에서 재사용이 가능한 Workflow의 가장 작은 단위이다.
    • 직접 만든 Action을 사용하거나 타인이 작성한 Action을 불러와 사용할 수 있으며, 자신이 작성한 Action을 다른 사람들에게 배포할 수도 있다.
  • Runner
    • Job을 실행시키기 위한 애플리케이션을 말한다.
    • Runner 애플리케이션은 Github에서 호스팅하는 가상 환경 또는 직접 호스팅하는 가상 환경에서 실행 가능하며, Github에서 호스팅하는 가상 인스턴스의 경우, 메모리 및 용량 제한이 존재한다.

참고 : Github Action의 실행 환경
Github Action은 가상기계 위에 도커 컨테이너를 띄워 수행된다. 따라서 가상기계의 실행 환경과 도커 컨테이너로 띄울 실행 환경을 명시해야 한다. 이때, 가상기계의 실행 환경필수로 지정해야 하며, 컨테이너로 띄울 도커 이미지선택사항이다.
컨테이너로 띄울 도커 이미지는 여러개가 주어질 수 있다. 도커 이미지를 여러개 선택하게 되면, 선택한 이미지를 띄운 컨테이너들을 생성하고, 각 컨테이너에서 동일한 작업을 수행하게 된다. 이를 이용하면 서로 다른 운영체제에서 작업을 실행시킬 수 있다.

CI/CD Workflow 구성하기

먼저 Github Repository에서 Actions 탭을 선택하여 Github Action을 구성할 수 있는 페이지로 들어간다.

이후, 상단의 set up a workflow yourself를 클릭하여 Workflow를 구성할 수 있는 페이지로 접근한다. 그러면 Workflow를 작성할 수 있는 에디터가 보이는데, 여기에 구성할 Workflow의 내용을 작성하면 된다.

아래와 같이 SpringBoot 애플리케이션의 CI/CD Workflow를 구성한 내용을 작성했다.
Workflow 파일의 각 위치에 설명을 달아뒀다. #은 해당 코드가 의미하는 바를, ###은 해당 Step이 어떤 작업을 하는지에 대한 설명이다.

# Workflow name
name: ComeOn App Dev CI/CD
# Event Trigger
on:
  push:
    branches: [ "dev" ]
# 현재 Workflow를 구성하는 Job들을 정의
jobs:
  # 하나의 Job에 대한 식별자를 설정. test_and_build는 하나의 Job이 된다.
  test_and_build:
    # 실행환경 설정
    runs-on: ubuntu-latest
    # 현재 Job을 구성하는 Step들을 정의
    steps:
    # `-`으로 Step을 구분한다. name은 Step의 식별자를 정의한다.
    - name: Checkout
      # Action을 사용하여 Step을 구성한다.
      uses: actions/checkout@v3
      # Action에 사용될 변수값 지정
      with:
        # repo settings에서 설정한 secrets 값을 사용한다.
        token: ${{ secrets.ACCESS_TOKEN }}
        submodules: true
    ### runner application java 설정
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
    ### gradlew 실행 권한 부여
    - name: Grant execute permisstion for gradlew
      # shell 명령어로 Step의 Task를 지정한다.
      run: chmod +x gradlew
    ### project test
    - name: Test
      run: ./gradlew clean test -Pprofile=test
    ### project build
    - name: Build
      run: ./gradlew bootJar
    ### 도커 buildx 설정
    - name: Setup Docker Buildx
      uses: docker/setup-buildx-action@v2.2.1
    ### 도커 이미지 build & push
    - name: Docker Image build and push
      # 다음과 같이 작성하여 한 Task에서 여러 shell 명령을 수행하게 할 수 있다.
      run: |
        docker login --username=${{ secrets.DOCKERHUB_USERNAME }} --password=${{ secrets.DOCKERHUB_PASSWORD }}
        docker buildx build --platform linux/arm64/v8,linux/amd64 --tag ${{ secrets.DOCKERHUB_USERNAME }}/image-name:latest --push .

  # 하나의 Job에 대한 식별자를 설정. deploy는 하나의 Job이 된다.
  deploy:
    # 현재 Job의 의존관계 설정. test_and_build 식별자를 갖는 Job이 성공해야 현재 Job이 수행된다.
    needs: test_and_build
    runs-on: ubuntu-latest
    steps:
      ### ssh로 배포 서버에 접근하여 도커 이미지 pull & run
      - name: Docker image pull and run
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PRIVATE_KEY }}
          port: ${{ secrets.PORT }}
          script: |
            docker compose down
            docker image rm ${{ secrets.DOCKERHUB_USERNAME }}/image-name
            docker compose up -d --no-recreate

중간중간 ${{ secrets.XXXX }}와 같은 형식으로 작성된 부분이 보이는데, 이는 민감한 정보를 Secrets 변수로 등록하여 사용하는 방법이다. 이를 이용하면 비밀번호나 엑세스 토큰과 같은 민감한 정보들을 다른 사람들에게 노출하지 않고 안전하게 사용할 수 있다.

Secrets 변수를 등록하는 방법은 간단하다.
프로젝트 Repository의 Settings 탭으로 접근하여, 왼쪽 네비게이션의 Secrets and variables -> Actions 버튼을 클릭한다.
페이지가 전환되면 우측의 New repository secret 버튼을 클릭해서 원하는 변수의 이름과 변수 호출시 사용할 값을 입력하고 Add secret 버튼을 눌러 등록하면 된다.
이렇게 등록된 Secrets 변수는 Github Action에서 사용시 ${{ secrets.variable-name }}와 같은 형태로 사용하면 된다.
Secrets 변수는 사용시에는 정확한 값이 사용되지만, Workflow의 로그에서는 변수 이름으로 출력되어 로그에 해당 값을 노출시키지 않는다.

'git' 카테고리의 다른 글

[Git] 깃 서브모듈(Submodule)  (0) 2023.01.07
[Github] Github Action 기초 및 Spring Boot CI/CD Workflow 구성하기

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.