[CI/CD] Github Actions를 통한 CI/CD

2025. 4. 16. 16:36기술 창고/CI, CD

728x90
반응형
SMALL

개발을 진행하면서 수정하거나 변경한 내용, 혹은 이때까지 만든 최신 내용을 반영하여 빌드하고 배포하여 다시 실행하는 과정까지 걸리는 시간은 절대 무시못할 시간 소요가 걸리게 됩니다.

이것을 해결하기 위해서 CI/CD를 적용하여 한 번에 효율적으로 테스트, 빌드, 배포까지 모든 처리를 한 번에 할 수 있게끔 하는데 이러한 CI/CD 작업을 일반적으로 대부분 Jenkins라고 하는 외부 툴을 사용하는 것이 일반적이라고 알고있습니다.

 

하지만, 어떤 최근 매체에서 읽기를, 굳이 외부 툴을 사용하는 것이 효율적이라고 볼 순 없다라는 글을 읽었으며 또한 외부 툴에 문제가 발생되었을 경우 이것을 해결하기 위한 시간 소요가 추가적으로 발생되게 됩니다.

따라서 개발을 위해 거의 반드시 사용하게 되는 Github 를 통해 이 CI/CD 작업을 수행할 수 있게 한다면 좀 더 편하고 관리하기에도 수월하지 않을까 하는 생각이 들어 Github Actions를 사용해보기로 하였습니다.

오늘은 이 Github Actions를 활용한 CI/CD 방법을 정리해보겠습니다.

 

 

(1) 배포할 서버에 프로젝트 Git Clone

우선 CI/CD 가 적용되어 배포될 서버에 들어가서 진행하고 있는 프로젝트를 clone 해줍니다.

 

jar 파일을 올릴 서버에 git clone {github repository 주소} 를 입력하여 클론
- username 입력 (예 : JayEsEichi)
- password 입력 (github 계정 토큰값)

 

## 참고사항 ##

지금 이미 CI/CD를 적용하기 이전에 작업한 내용이 남아있다면 우선 그것들을 먼저 commit, push 후 최신화 시켜주시기 바라고, 이후에 나올 yml 파일 작성 내용에 특정 브랜치에 작업을 수행하게끔 하는 부분이 있는데 될 수 있는한 해당 브랜치에도 방금 push 한 최신 내용을 지금 미리 push 해놓으시면 좋습니다.

 

 

(2) Github Actions 작업 경로 및 실행 yml 파일 생성

우선 프로젝트의 내부 최상위 경로에 .github 경로를 만들어주고, workflows 경로를 만든 뒤, Github Actions에서 실행될 yml 파일을 만들어줍니다.

 

 

(3) yml 파일 내용 작성

name: Deploy

on:
  push:
    branches:
      - dev

jobs:
  Deploy:
    runs-on: ubuntu-latest
    steps:
      - name: CI/CD
        uses: appleboy/ssh-action@v1
        env:
          APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
          APPLICATION_DEV_PROPERTIES: ${{ secrets.APPLICATION_DEV_PROPERTIES }}
          APPLICATION_PROD_PROPERTIES: ${{ secrets.APPLICATION_PROD_PROPERTIES }}
          APPLICATION_YML: ${{ secrets.APPLICATION_YML }}
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USER_NAME }}
          password: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          envs: APPLICATION_PROPERTIES, APPLICATION_DEV_PROPERTIES, APPLICATION_PROD_PROPERTIES, APPLICATION_YML
          script_stop: true
          script: |
            cd /home/onnury/web/Onnury-Mall-BackEnd
            echo "온누리 몰 프로젝트 경로 진입"
            rm -rf src/main/resources/application.properties
            rm -rf src/main/resources/application-dev.properties
            rm -rf src/main/resources/application-prod.properties
            rm -rf src/main/resources/application.yml
            echo "gitignore 처리된 이전 properties, yml 파일 삭제"
            git pull origin dev
            echo "dev 브랜치 pull"
            echo "$APPLICATION_PROPERTIES" > src/main/resources/application.properties
            echo "$APPLICATION_DEV_PROPERTIES" > src/main/resources/application-dev.properties
            echo "$APPLICATION_PROD_PROPERTIES" > src/main/resources/application-prod.properties
            echo "$APPLICATION_YML" > src/main/resources/application.yml
            echo "properties, yml 설정 파일 생성"
            ./gradlew clean build
            echo "jar 빌드"
            sudo fuser -k -n tcp 8091 || true
            echo "기존 8091 포트 실행 중이던 java 프로세스 확인 후 제거"
            nohup java -jar -server -Xmx5g -XX:+UseG1GC -Djava.awt.headless=true -Dspring.profiles.active=dev -Dsvr.nm=DEV -Dfile.encoding=UTF-8 build/libs/*SNAPSHOT.jar 1> /dev/null 2>&1 &
            echo "jar 배포"

이제 생성한 yml 파일에 actions가 동작될 스크립트 내용들을 넣어줍니다.

 

제가 위에서 작성한 예시 코드 내용에 대한 설명은 아래에서 확인할 수 있습니다.

더보기
# yml 파일명 지정
ame: Deploy 

# dev 브랜치에 push가 발생되게 될 경우 jobs action 실행
on:
  push:
    branches:
      - dev 

# 실행될 Action Jobs(여러개의 job 구성 가능)
jobs:
  Deploy: # 실행될 Job
    runs-on: ubuntu-latest # 실행되는 Job이 어떤 운영체제에서 실행될지 지정 (배포 시 운영되는 해당 서버 운영체제)
    steps: # Job에서 실행되는 Step들 (여러개의 step 구성 가능)
      - name: CI/CD # 실행되는 Step 명 (아무 명칭이나 지정 가능)
        uses: appleboy/ssh-action@v1 # 특정 서버에 접속하기 위한 ssh 접속 외부 프로그램 사용 (github marketplace에서 검색해서 마음에 드는 프로그램 선택 후 지정)
        env: # step 실행 환경 설정
          # 프로젝트 내부의 git ignore 처리된 예민한 정보를 담고 있는 properties 파일 내용을 가지고 있는 github secret 변수들
          APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
          APPLICATION_DEV_PROPERTIES: ${{ secrets.APPLICATION_DEV_PROPERTIES }}
          APPLICATION_PROD_PROPERTIES: ${{ secrets.APPLICATION_PROD_PROPERTIES }}
          APPLICATION_YML: ${{ secrets.APPLICATION_YML }}
        with: # 위의 uses에서 호출한 외부 ssh 접속 프로그램 실행 시 필요한 설정 값들 지정 (host, username, password, port)
          host: ${{ secrets.HOST }} # 빌드한 프로젝트가 배포될 서버 ip (github secret 변수로 호출)
          username: ${{ secrets.USER_NAME }} # 배포할 서버의 접속 계정명 (github secret 변수로 호출)
          password: ${{ secrets.PASSWORD }} # 배포할 서버의 접속 비밀번호 (github secret 변수로 호출)
          port: ${{ secrets.PORT }} # 배포할 서버의 접속 포트 번호 (github secret 변수로 호출)
          # 외부 ssh 프로그램을 사용하면서 git ignore 된 위에서 호출한 환경 변수 내용들을 사용하게끔 지정
          envs: APPLICATION_PROPERTIES, APPLICATION_DEV_PROPERTIES, APPLICATION_PROD_PROPERTIES, APPLICATION_YML
          script_stop: true # script가 실행 중 중단될 수 있음을 true로 설정
          # 본격적인 CI/CD 작업 내용 script 작성
          script: | # | 기호를 사용하면 아래처럼 개행 후 여러 개의 script 실행 명령어를 기입 가능
            cd /home/onnury/web/Onnury-Mall-BackEnd # 서버에 git clone 받아 풀어둔 해당 프로젝트 경로로 진입
            echo "온누리 몰 프로젝트 경로 진입" # 프로젝트 경로에 진입했음을 알리는 용도의 텍스트 출력
            rm -rf src/main/resources/application.properties # 기존에 존재했던 프로젝트 내부의 properties 파일 삭제
            rm -rf src/main/resources/application-dev.properties # 기존에 존재했던 프로젝트 내부의 properties 파일 삭제
            rm -rf src/main/resources/application-prod.properties # 기존에 존재했던 프로젝트 내부의 properties 파일 삭제
            rm -rf src/main/resources/application.yml # 기존에 존재했던 프로젝트 내부의 yml 파일 삭제
            echo "gitignore 처리된 이전 properties, yml 파일 삭제" # properties, yml 파일 삭제 알림 텍스트 출력
            git pull origin dev # git clone 프로젝트에서 최신 내용이 반영된 dev 브랜치 내용을 pull 받아오기
            echo "dev 브랜치 pull" # git pull 알림 텍스트 출력
            echo "$APPLICATION_PROPERTIES" > src/main/resources/application.properties # 위에서 github secret에서 호출하여 관리하고 있는 properties 파일 내용을 git clone 프로젝트 내부에 생성
            echo "$APPLICATION_DEV_PROPERTIES" > src/main/resources/application-dev.properties # 위에서 github secret에서 호출하여 관리하고 있는 properties 파일 내용을 git clone 프로젝트 내부에 생성
            echo "$APPLICATION_PROD_PROPERTIES" > src/main/resources/application-prod.properties # 위에서 github secret에서 호출하여 관리하고 있는 properties 파일 내용을 git clone 프로젝트 내부에 생성
            echo "$APPLICATION_YML" > src/main/resources/application.yml # 위에서 github secret에서 호출하여 관리하고 있는 yml 파일 내용을 git clone 프로젝트 내부에 생성
            echo "properties, yml 설정 파일 생성" # 새롭게 properties, yml 파일 생성 알림 텍스트 출력
            ./gradlew clean build # clone 프로젝트 빌드 작업 수행
            echo "jar 빌드" # 빌드 알림 텍스트 출력
            sudo fuser -k -n tcp 8091 || true # 기존에 8091 포트에 실행되고 있는 프로세스가 존재할 경우 제거
            echo "기존 8091 포트 실행 중이던 java 프로세스 확인 후 제거" # 제거 알림 텍스트 출력
            nohup java -jar -server -Xmx5g -XX:+UseG1GC -Djava.awt.headless=true -Dspring.profiles.active=dev -Dsvr.nm=DEV -Dfile.encoding=UTF-8 build/libs/*SNAPSHOT.jar 1> /dev/null 2>&1 & # 빌드한 파일을 실행하여 프로젝트 무중단 실행
            echo "jar 배포" # 빌드한 jar 새롭게 실행 알림 텍스트 호출

 

## 참고사항 ##

- ${{}} 로 작성된 부분들은 Git Repository의 Settings -> Secrets and variables -> Actions 에서 만들어낸 secret 값들을 말합니다.
- 브랜치 push 하기 이전에 CI /CD 처리될 서버에 들어가서 clone 된 프로젝트 내부에 있는 gradlew 의 접근 허용을 먼저 해줍니다. (접근 허용 명령어 : chmod +x ./gradlew)

 

(4) Github Secret 환경 변수들 등록

이제 위에서 작성한 yml 파일에 나오는 ${{}} 기호로 감싸진 github secret 변수들을 설정하러 가보겠습니다.

 

진행 중인 프로젝트의 git repository에 들어가서 Settings > Secrets and variables > Actions 항목에 들어가서 위에서 작성한 yml secret 변수들 명과 동일하게 생성하고 각 변수마다 넣어야될 내용들을 넣어줍니다.

이 Secret 변수들은 한 번 저장되게 되면 아예 확인할 수 없기 때문에 잘 넣어야 합니다.

이제 여기서 만들어낸 secret 변수들이 yml파일에 호출되어 script가 실행되게 되는 것입니다.

 

 

(4) 최종 확인

이제 모든 설정과 생성은 마무리 되었으니 이제 commit 후 작성한 내용대로 특정 브랜치에 push를 날려 정상적으로 CI/CD 가 진행되는지 확인해보겠습니다.

 

작업한 내용들을 commit 후 dev 브랜치에 push를 했더니,

 

해당 repository의 Actions 메뉴에 진행되었던 Github Actions 내용들이 나온 것을 확인할 수 있습니다.

저는 지금 여러번 진행했기 때문에 여러 개의 Actions 내용들이 나오지만 처음 할 경우 하나의 내용만 나올 것입니다.

 

가장 최신 Action 내용에 들어가서 확인해보면 정상적으로 script 내용대로 작업이 진행되고 알림 텍스트 또한 나오는 것을 확인할 수 있습니다.

 

## 참고사항 ##

가령 진행 도중 test에 실패하여 build 가 정상적으로 수행되지 않았다는 에러가 나오면서 action이 정상적으로 실행되지 않거나 타임아웃이 걸릴 경우도 있는데 이것은 프로젝트 내부에 작성한 test 코드들을 확인하여 처리해주면 됩니다.

728x90
반응형
LIST