DevOps

Travis CI 에서 GitHub Action으로 마이그레이션

2022. 5. 26. 18:10
목차
  1. Jenkins
  2. GitHub Action
  3. 프로젝트 환경
  4. 0 단계: 환경 세팅
  5. 1단계: Front-End Back-End 빌드
  6. 3단계: 빌드 스크립트와 빌드 파일 압축
  7. 4단계: 압축 파일을 AWS S3에 업로드 및 Codedeploy로 배포
  8. 전체 파일
  9. 정리 및 회고

이 글은 Travis CI나 GitHub Action에 대해 자세히 설명하지 않습니다.

 

이동욱 님의 '스프링 부트와 AWS로 혼자 구현하는 웹 서비스'라는 책으로 Travis CI를 통해 CI/CD를 구현한 적이 있다. 이 경험을 살려 진행하는 팀 프로젝트에서 Travis CI로 CI 환경을 구축했는데 문제가 발생했다.

대충 큰일 났다는 뜻

Travis CI는 무료인 줄 알았는데 아니었다...

처음 가입할 때 1달러도 빼갔었다.

여하튼 프로젝트는 진행해야 해서 대안을 알아보던 중 Jekins와 GitHub Action 두 가지 선택지가 나왔다.

Jenkins

어디서 들은 말인데, "퇴사할 때 네가 하던 일을 젠킨스한테 시키고 나가"라는 농담을 할 정도로 주기적인 일을 하는 시종이라고 생각하면 된다.

우리의 시종

하지만 진입 장벽이 높다는 단점을 가지고 있다. Jekins에 대해 좀 더 자세히 알고 싶다면 다음 영상을 추천한다.

https://www.youtube.com/watch?v=JPDKLgX5bRg 

GitHub Action

GitHub에서 제공하는 무료 솔루션으로 Travis CI와 비슷하게 CI 환경을 구축할 수 있다고 한다. 즉, 배우기 쉽고 현재 쓰는 구현되어있는 방식과 비슷하다. 따라서 Travis CI를 GitHub Action으로 마이그레이션 했다.

프로젝트 환경

프로젝트는 Front-End로 React, Back-End로 Spring Boot를 사용하였고 둘을 한 번에 Jar로 빌드한 후 배포하는 방식으로 CI/CD를 구축하였다. 

 

내가 원하는 CI/CD 동작은 다음과 같다.

 

1. Front-End 프로젝트를 빌드 후 Spring Boot의 resources/static 폴더로 빌드 파일 이동

2. Spring Boot를 jar 파일로 빌드

3. 빌드된 jar 파일과 빌드 스크립트들(scripts/.)을 묶어서 압축(. zip)

4. 압축 파일을 AWS S3에 업로드

5. S3에 업로드가 완료되면 AWS Codedeploy에 배포 요청

6. S3에 업로드된 압축파일을 AWS EC2에 배포

7. 배포 스크립트 동작

 

위 단계를 하나씩 비교하며 GitHub Action으로 옮겨보겠다.

 

0 단계: 환경 세팅

Travis CI

language: java
jdk:
  - openjdk11

branches:
  only:
    - main

GitHub Action

name: CI/CD
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
jobs:
  CICD:
    name: CI/CD with Gradle
    runs-on: ubuntu-latest
    defaults:
      run:
        shell: bash

    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'temurin'

 

우선 Java 11 버전 설정과 main 브랜치에 푸시할 경우 동작을 하도록 설정한다.

1단계: Front-End Back-End 빌드

Travis CI

이 부분은 Travis CI에서 문제가 있었다. 0단계의 환경 세팅에서 language: java를 설정하면 java가 설치된 runner에서 작업을 진행하는데 이 runner의 node.js와 npm의 버전이 프로젝트의 버전과 맞지 않아 Front-End 빌드에 문제가 생겼다. 원래는 Gradle에서 빌드를 모두 진행하였지만 Travis CI에서는 Front-End 빌드를 따로 진행했다.

before_install:
  - chmod +x gradlew
  - npm cache clean -f
  - curl -s https://deb.nodesource.com/setup_16.x | sudo bash
  - sudo apt-get -y install nodejs
  - npm install -g nvm
  - nvm install 16
  - nvm use 16
  - npm install -g npm@8.5.0
  - node --version
  - npm --version
  
#Travis Ci 서버의 Home
cache:
  directories:
    - '$HOME/.m2/repository'
    - '$HOME/.gradle'

script: "./gradlew clean build"
  

nvm을 이용해 npm 버전을 관리할 수 있는데 이를 활용하여 Front-End를 빌드하였다. 그리고 Gradle을 이용해 Spring Boot를 빌드하였다.

GitHub Action

- name: Grant execute permission for gradlew
  run: chmod +x gradlew

- name: Build with Gradle
  uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
  with:
    arguments: build

GitHub Action의 steps 아래에 다음 코드를 이어서 넣는다.

GitHub Action에서는 Front-End 빌드 관련 이슈가 없었기 때문에 Gradle을 통해 빌드하였다.

3단계: 빌드 스크립트와 빌드 파일 압축

Travis CI

프로젝트 루트에 scripts라는 폴더에 있는 빌드 스크립트들을 jar, appspec.yml(Codedeploy에서 사용)와 함께 압축한다.

before_deploy:
  - mkdir -p before-deploy # zip에 포함시킬 파일들을 담을 디렉토리 생성
  - cp scripts/*.sh before-deploy/
  - cp appspec.yml before-deploy/
  - cp build/libs/*SNAPSHOT.jar before-deploy/
  - cd before-deploy && zip -r before-deploy * # before-deploy로 이동 후 전체 압축
  - cd ../ && mkdir -p deploy # 상위 디렉토리로 이동 후 deploy 디렉토리 생성
  - mv before-deploy/before-deploy.zip deploy/facealbum-springboot-server.zip # deploy로 zip파일 이동

GitHub Action

- name: Before deply
  run: |
    mkdir -p before-deploy
    cp scripts/*.sh before-deploy/
    cp appspec.yml before-deploy/
    cp build/libs/*SNAPSHOT.jar before-deploy/
    cd before-deploy && zip -r before-deploy *
    cd ../ && mkdir -p deploy
    mv before-deploy/before-deploy.zip deploy/facealbum-springboot-server.zip

4단계: 압축 파일을 AWS S3에 업로드 및 Codedeploy로 배포

이 부분은 암호키가 필요하기 때문에 키를 환경변수로 설정하여 사용하였다.

Travis CI

Settings에서 환경변수를 저장하여 사용하였다.

deploy:
  - provider: s3
    access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값
    secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값
    bucket: static-build-bucket # S3 버킷
    region: ap-northeast-2
    skip_cleanup: true
    acl: private # zip 파일 접근을 private으로
    local_dir: deploy # before_deploy에서 생성한 디렉토리
    wait-until-deployed: true
    on:
      all_branches: true

  - provider: codedeploy
    access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값
    secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값
    bucket: static-build-bucket # S3 버킷
    key: facealbum-springboot-server.zip # 빌드 파일을 압축해서 전달
    bundle_type: zip
    application: facealbum-springboot-server # 웹 콘솔에서 등록한 CodeDeploy 어플리케이션
    deployment_group: facealbum-springboot-server-group # 웹 콘솔에서 등록한 CodeDeploy 배포 그룹
    region: ap-northeast-2
    wait-until-deployed: true
    on:
      all_branches: true

GitHub Action

Secrets > Actions에 환경변수를 저장하여 사용하였다.

- name: AWS config
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
          aws-region: ap-northeast-2

      - name: Upload to AWS S3
        run: aws s3 cp deploy/facealbum-springboot-server.zip s3://faceablum-springboot-build

      - name: Codedeploy
        run: aws deploy create-deployment --application-name facealbum-springboot-server --deployment-group-name facealbum-springboot-server-group --s3-location bucket=faceablum-springboot-build,bundleType=zip,key=facealbum-springboot-server.zip

전체 파일

Travis CI

language: java
jdk:
  - openjdk11

branches:
  only:
    - main

#빌드 전 권한 추가
before_install:
  - chmod +x gradlew
  - npm cache clean -f
  - curl -s https://deb.nodesource.com/setup_16.x | sudo bash
  - sudo apt-get -y install nodejs
  - npm install -g nvm
  - nvm install 16
  - nvm use 16
  - npm install -g npm@8.5.0
  - node --version
  - npm --version

#Travis Ci 서버의 Home
cache:
  directories:
    - '$HOME/.m2/repository'
    - '$HOME/.gradle'

script: "./gradlew clean build"

before_deploy:
  - mkdir -p before-deploy # zip에 포함시킬 파일들을 담을 디렉토리 생성
  - cp scripts/*.sh before-deploy/
  - cp appspec.yml before-deploy/
  - cp build/libs/*SNAPSHOT.jar before-deploy/
  - cd before-deploy && zip -r before-deploy * # before-deploy로 이동 후 전체 압축
  - cd ../ && mkdir -p deploy # 상위 디렉토리로 이동 후 deploy 디렉토리 생성
  - mv before-deploy/before-deploy.zip deploy/facealbum-springboot-server.zip # deploy로 zip파일 이동

deploy:
  - provider: s3
    access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값
    secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값
    bucket: static-build-bucket # S3 버킷
    region: ap-northeast-2
    skip_cleanup: true
    acl: private # zip 파일 접근을 private으로
    local_dir: deploy # before_deploy에서 생성한 디렉토리
    wait-until-deployed: true
    on:
      all_branches: true

  - provider: codedeploy
    access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값
    secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값
    bucket: static-build-bucket # S3 버킷
    key: facealbum-springboot-server.zip # 빌드 파일을 압축해서 전달
    bundle_type: zip
    application: facealbum-springboot-server # 웹 콘솔에서 등록한 CodeDeploy 어플리케이션
    deployment_group: facealbum-springboot-server-group # 웹 콘솔에서 등록한 CodeDeploy 배포 그룹
    region: ap-northeast-2
    wait-until-deployed: true
    on:
      all_branches: true

GitHub Action

name: CI/CD
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  CICD:
    name: CI/CD with Gradle
    runs-on: ubuntu-latest
    defaults:
      run:
        shell: bash

    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'temurin'

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
        with:
          arguments: build

      - name: Before deply
        run: |
          mkdir -p before-deploy
          cp scripts/*.sh before-deploy/
          cp appspec.yml before-deploy/
          cp build/libs/*SNAPSHOT.jar before-deploy/
          cd before-deploy && zip -r before-deploy *
          cd ../ && mkdir -p deploy
          mv before-deploy/before-deploy.zip deploy/facealbum-springboot-server.zip

      - name: AWS config
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
          aws-region: ap-northeast-2

      - name: Upload to AWS S3
        run: aws s3 cp deploy/facealbum-springboot-server.zip s3://faceablum-springboot-build

      - name: Codedeploy
        run: aws deploy create-deployment --application-name facealbum-springboot-server --deployment-group-name facealbum-springboot-server-group --s3-location bucket=faceablum-springboot-build,bundleType=zip,key=facealbum-springboot-server.zip

정리 및 회고

개인적으로 GitHub Action이 좀 더 쉬웠다. 그리고 Travis CI의 경우 Front-End 빌드가 되지 않아 하룻밤을 샜다... 근데 GitHub Action에서 한 번에 되니 그 고생을 왜 했나 싶었다. 어찌 되었건 두 가지 CI 툴을 조금 사용(체험?)해보았는데 Travis CI와 GitHub Action 모두 공식 Document는 잘 되어있었지만 그래도 쓰기 편한 건 GitHub Action이었던 것 같다. 

그리고 일반적인 workflow를 GitHub 홈페이지에서 검색을 통해 찾을 수 있어서 도움이 되었다!

GitHub 레포지토리에 Action탭에서 New workflow를 누르면 나오는 페이지

 

GitHub - KKangGoGo/BackEndServer

Contribute to KKangGoGo/BackEndServer development by creating an account on GitHub.

github.com

 

'DevOps' 카테고리의 다른 글

[쿠버네티스 인 액션] - 실습 트러블슈팅  (0) 2022.12.07
  1. Jenkins
  2. GitHub Action
  3. 프로젝트 환경
  4. 0 단계: 환경 세팅
  5. 1단계: Front-End Back-End 빌드
  6. 3단계: 빌드 스크립트와 빌드 파일 압축
  7. 4단계: 압축 파일을 AWS S3에 업로드 및 Codedeploy로 배포
  8. 전체 파일
  9. 정리 및 회고
'DevOps' 카테고리의 다른 글
  • [쿠버네티스 인 액션] - 실습 트러블슈팅
acisliver
acisliver
acisliver
와당탕탕 개발놀이터
acisliver
전체
오늘
어제
  • 분류 전체보기 (65)
    • 회고 (11)
    • Spring (3)
    • 알고리즘 (21)
    • Java (2)
    • DevOps (2)
    • Shell (2)
    • Nginx (1)
    • Database (22)
    • Project (1)

블로그 메뉴

  • 태그
  • 방명록
  • GitHub
  • Notion

공지사항

인기 글

태그

  • 백준
  • 자바
  • FOSSLight
  • 프리코스
  • 코딩테스트
  • 구름톤 트레이닝
  • Shell
  • 풀 테이블 스캔
  • innodb
  • DevOps
  • mysql
  • 이분탐색
  • 카카오
  • 알고리즘
  • 오픈소스
  • 풀스택
  • Spring
  • Java
  • 이진탐색
  • 풀 인덱스 스캔
  • binarySearch
  • dp
  • Leetcode
  • Bash
  • 우아한테크코스
  • FuntionalInterface
  • 프로그래머스
  • 오픈소스 컨트리뷰톤
  • 인덱스
  • spring boot

최근 댓글

최근 글

hELLO · Designed By 정상우.
acisliver
Travis CI 에서 GitHub Action으로 마이그레이션
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.