Github Actions, Jenkins로 CI/CD를 도전해보자! 1편 (Github Actions 도입하여 CI 테스트)

김진형·2024년 7월 21일
0

CI/CD

목록 보기
1/4
post-thumbnail

1. Why?

과거 프로젝트에서 느꼈던 가장 큰 불편함이 배포 과정이었습니다. 이때의 배포 과정은 다음과 같습니다.

  1. 개발이 완료된 코드가 모인 브랜치 develop에서 Build하여 Jar 파일 생성
  2. Filezilla를 통해 EC2 인스턴스에 Jar 파일을 넘겨줌
  3. EC2 인스턴스에 접속하여 기존 서버 프로세스를 kill
  4. nohup java -jar [jar 이름] & 명령어로 프로세스를 백그라운드에서 띄워줌

특히 API 통신 단계에서 개발 서버의 코드를 업데이트할 때마다 위 과정을 반복했습니다. (너무너무 귀찮았다..)

때문에 이번 프로젝트에 CI/CD를 도입하게 됐고, 처음으로 CI/CD를 하는 것이기에 기록용 + 팀원들의 이해를 돕기 위해 블로그를 작성합니다.
구현 시작부터 끝까지 차근차근 모든 과정을 총 3편에 걸쳐서 적어보려고 합니다.

2. 구조도

2-1. 전체적인 과정

  1. PR을 날리면 디스코드로 알람이 간다.
  2. Github Actions가 CI 테스트(빌드와 테스트 코드를 실행)를 하여 문제가 없는지 확인한다.
  3. 문제가 없는 코드라면 개발자가 직접 리뷰 후 Merge를 한다.
  4. Merge가 된다면 Github Webhook이 발동되어 자동적으로 Jenkins를 담은 EC2에서 Clone, Build를 실행하게 된다.
  5. Build한 Jar 파일을 앱 서버용 EC2에 보내고 자동적으로 서버를 가동한다.

2-2. 의문점

그렇다면 위 과정을 보고 다음과 같은 의문점이 생길 수도 있습니다.(아닐수도)

  1. 왜 Github Actions, Jenkins만 쓰는 것이 아니라 둘 다 쓰는 것인가??
  • Why Github Actions???

    • CI의 목적은 자동 빌드 및 테스트를 진행하여 여러 개발자들이 공유하는 코드의 신뢰성을 높이는 개념이라고 생각합니다.
      이 개념을 프로젝트에 도입시킨다면 기능 개발을 마친 코드를 모두 합치는 develop 브랜치의 신뢰성을 높이는 것이라고 판단했습니다.
    • 그러려면 develop 브랜치에 PR을 날렸을 때 CI 테스트를 하여 문제가 없는지부터 깃허브 홈페이지에서 확인하고, 코드 리뷰 후 Merge해야 한다고 느꼈습니다. 이 과정을 가장 쉽게 할 수 있는 CI 툴이 Github Actions라고 느껴 선택하였습니다.
  • Why Jenkins???

    • 무엇보다 Jenkins는 높은 수준의 사용자 정의 가능성과 유연성을 제공하기 때문입니다. 이후 보여드릴 Jenkins 스크립트를 보시면 아시겠지만 저의 입맛에 맞게 커스텀을 했습니다. 이런 점이 Jenkins를 선택한 주된 이유라고 생각합니다.
    • Jenkins에는 크고 활발한 커뮤니티가 있으며 다양한 사용 사례에 사용할 수 있는 수많은 플러그인이 있습니다.
    • Jenkins는 대규모 프로젝트에 대해 확장성을 높일 수 있습니다.
  1. 왜 도커에 Jenkins를 담아서 사용하는가?

  2. 왜 Jenkins EC2와 앱 서버 EC2를 분리하였는가?

    프리티어로 사용하기 위해 인스턴스의 유형을 t2.micro인 EC2에서 빌드를 진행했습니다. 그런데?! EC2 멈춤 현상이 발생..! 찾아보니 메모리가 1GB라서 메모리 부족으로 멈춤 현상이 발생할 수도 있다고 합니다.
    스왑 메모리를 통해 멈춤 현상은 없앴지만, 하나의 EC2에서 빌드를 진행하고 서버까지 함께 가동한다면 많은 부하가 발생할 것이기 때문에 Jenkins EC2와 앱 서버용 EC2를 분리하였습니다.

3. Github Actions 도입하여 CI 테스트

3-1. Github Actions란?

Github Actions는 Github 에서 제공하는 CI/CD 툴입니다.

build, test, deploy 등 필요한 Workflow 를 등록해두면 Gihtub 의 특정 이벤트 (push, pull request) 가 발생했을 때 해당 Workflow를 수행합니다.

예를 들어 Pull Request를 올리면 자동으로 해당 코드의 테스트와 빌드를 수행하는 등 Workflow를 커스텀할 수 있습니다.

3-2. 프로젝트에 도입

저는 CI 테스트를 위해 Github Actions를 도입했습니다. 과정은 다음과 같습니다.

  1. 하위 브랜치에서 develop 브랜치로 PR을 날린다.
  2. Github Actions에서 하위 브랜치의 코드를 빌드, 테스트를 진행
  3. 하위 브랜치의 코드가 정상적으로 빌드, 테스트가 된다면 알려주고, 실패했다면 실패를 띄어줍니다.

적용 방법은 매우 간단합니다. 아래 사진처럼 .github/workflows/파일명.yml 경로에 내용을 작성하기만 하면 됩니다.

아래 코드는 프로젝트에 직접 도입한 dev_CI.yml 코드입니다.

name: Java CI

on:
  # develop 브랜치로 pull_request를 보냈을 때
  pull_request:
    branches: [ develop ]

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest

    steps:

      # 1) 워크플로우 실행 전 기본적으로 체크아웃 필요
      - uses: actions/checkout@v3

      # 2) JDK 11 버전 설치, 다른 JDK 버전을 사용한다면 수정 필요
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      # 3)권한 부여 >> 리눅스 명령어
      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash

      # 4) .build시작 >> 리눅스 명령어
      - name: Build with Gradle
        run: ./gradlew clean build -x test
        shell: bash

빌드 및 테스트를 진행했을 때 정상이라면 아래 사진처럼 뜹니다.

4. 느낀점 및 다음으로

PR을 올렸을 때 Github Actions라는 툴이 자동으로 빌드, 테스트를 진행해주니 휴먼 에러를 줄일 수 있다고 느꼈습니다.

다음 포스트에서는 Jenkins 설정, CI에 관한 내용을 다루겠습니다.

참고 블로그:
Github Actions CI: 자동 빌드 및 테스트 하기
Gitaction vs Jenkins 개념과 장단점

0개의 댓글