intro : ci/cd의 개념에 대해서 이해하고, ci/cd의 대표적인 github actions 방식에 대해서 알아보자.
하기 글에 대해 참고할수 있는 sample project 입니다.
CI/CD란?
CI/CD는 Continuous Integration
, Continuous Deployment
의 약어로, 지속적인 통합과 지속적인 배포의 의미를 담은 단어이다.
CI/CD를 왜 배워야 할까?
우리가 어떤 웹 서비스(서버)를 AWS EC2에 배포하고, 특정 기능을 개발 중이라고 가정해보자. 이 경우 보통 다음과 같은 과정을 거치게 된다. 먼저, 새로 개발한 기능을 GitHub에 push
한 뒤 EC2에 접속하여 main 브랜치의 최신 코드를 가져오기 위해 git pull
을 실행한다. 이후 build
와 실행 과정을 거쳐 변경된 서비스를 배포하게 된다.
이 과정이 코드 수정이 발생할 때마다 반복적으로 수행된다고 생각해보자. 상당히 번거롭고 비효율적이지 않은가? 이런 비효율적인 과정을 해결하고자 CI/CD라는 개념이 탄생했다.
CI/CD는 코드 변경 사항을 테스트하고, 빌드 및 배포 과정을 자동화하여 개발 생산성을 크게 향상시킨다. 이를 통해 개발자는 반복적인 작업에서 벗어나 본질적인 개발 업무에 집중할 수 있다. 특히, 빠른 배포와 안정성을 유지해야 하는 현대 소프트웨어 개발 환경에서는 필수적인 기술이라 할 수 있다.
CI/CD 흐름을 이해하기 위한 Github Actions 개념
Github Actions는 로직을 실행시킬 수 있는 별도의 컴퓨터라고 생각하면 된다. CI/CD 과정에서 Github Actions는 빌드, 테스트, 배포
에 대한 로직을 실행시키는 역할을 하게 된다.
Github Actions을 통한 CI/CD 전체 흐름
CI/CD의 구성방식은 다양하지만 일반적으로 다음의 흐름을 거친다. 개발자 GitHub애 커밋
> GitHub Actions의 Event Trigger 실행 (commit 감지)
> AWS EC2로 배포
Github Actions 기본 문법 및 사용법 정리
Step1. 프로젝트 생성 및 폴더, 파일 생성
가장 먼저 Intelij에 Empty Project
를 생성한다. 프로젝트명은 다음과 같이 github-actions-study
로 지정하였는데, 본인이 원하는 프로젝트 명으로 설정하여도 무방하다. 프로젝트 루트 경로에 .github
라는 이름의 폴더를 만들고 해당 폴더안에 workflows
라는 폴더를 만들어보자. 그 뒤에 deploy.yml
파일을 생성하자.
폴더 및 파일 생성시 주의 사항
.github
> workflows
의 폴더 이름들은 철자가 틀리면 안된다. 사용자가 원하는 이름으로 변경해서는 안되고 꼭 지정된 이름으로 생성해 주어야 한다. 다만 확장자 .yml
파일의 이름은 사용자가 원하는 이름으로 생성하여도 무방하다.
Step2. deploy.yml 코드 작성하기
deploy.yml
파일에 다음과 같이 코드를 작성해보자.
name: GitHub Actions 실행시켜보기
on:
push:
branches:
- main
jobs:
My-Deploy-job:
runs-on: ubuntu-latest
steps:
- name: Hello World 출력
run: echo "Hello World"
Step3. github에 프로젝트 push 하기
그 뒤에, github에 repository를 생성하고 push 해준다. 그 뒤에 github 페이지의 Actions tab으로 이동해보면 검정색 화면에서 무언가 실행되고 있는것을 확인할 수 있다. 물론 너무빠르게 실행이 되어서 완료가 된 화면만 볼 수도 있다.
지금까지의 과정속의 deploy.yml 파일의 코드 해석하기
deploy.yml
파일의 최상단 name
부분을 보면 GitHub Actions 실행시켜보기
라고 작성하였었다. 이 부분은 Github Actions에서 workflows
의 이름이 된다.
on push ~ main
의 해당하는 코드 부분의 내용은 해석하자면, 브랜치명이 main에 push가 일어난다면, yml파일에 작성한 로직(jobs)을 실행하겠다 라는 뜻이다.
이어서 jobs ~ run
의 해당하는 코드 부분의 내용을 해석해보자.
가장 먼저 jobs
에 대해 짚고 넘어가자. 하나의 workflow는 반드시 1개 이상의 job으로 구성되어야 한다. 만약 여러 개의 job으로 구성된 workflow라면, 이들은 기본적으로 병렬적으로 수행된다. 그러나 현재 코드는 단 하나의 job으로만 이루어져 있어, 실행 시 이 단일 job만 수행된다.
My-Deploy-Job
부분의 내용은 job을 식별할 수 있는 이름이라고 볼 수 있는데, 다음과 같이 Actions tab에서 이름이 지정되어 있는것을 볼 수 있다.
runs-on
부분은 어떤 서버(컴퓨터)에서 Github Actions를 실행시킬 것인지를 작성하게 되는데, 보통 이런 OS는 리눅스의 Ubuntu를 사용하고 최신 버전임을 알리는 latest
키워드가 뒤에 붙게된다.
마지막으로 steps
에 대해 살펴보자. 하나의 job은 여러 개의 step으로 구성될 수 있다. 마치 하나의 workflow에 여러 개의 job이 포함될 수 있는 것처럼, 하나의 job 안에도 여러 개의 step이 존재할 수 있다. 각 step은 특정 작업을 수행하며, 순차적으로 실행된다.
Step4. deploy.yml파일에 step 추가하기
기존에 작성한 deploy.yml
파일의 내용을 어느정도 알아보았다. 우리는 이번에 step 부분에 여러개의 명령어를 한번에 입력해 볼것이다. 코드를 다음과 같이 수정해보자.
name: GitHub Actions 실행시켜보기
on:
push:
branches:
- main
jobs:
My-Deploy-job:
runs-on: ubuntu-latest
steps:
- name: Hello World 출력
run: echo "Hello World"
- name: 여러 명령어 문장 출력하기
run: |
echo "Good"
echo "Morning"
여러 명령어 문장 출력하기
라는 step이 추가되었다. 기존의 step > run
과 다른 점은, 이번에는 명령어가 한 줄이 아닌 여러 개로 구성되어 있다는 것이다. 때로는 여러 개의 명령어를 하나의 step에서 실행하고 싶을 때가 있는데, 이 경우 |
를 사용하여 여러 명령어를 하나의 run 블록 안에 작성할 수 있다. 이를 통해 한 step에서 여러 작업을 순차적으로 처리할 수 있다.
Step5. 수정된 deploy.yml파일 push 하기
정말로 step 안의 여러 명령어가 실행되는지 확인해보자. 이전에 결과를 확인했던 것과 같이 github의 Actions의 tab에 들어가서 확인 할 수 있다. 우리가 예상한것과 같이 여러 명령어(echo Good
, echo Morning
)가 실행이 잘 되었다.
Step6. GitHub Actions 환경변수 사용해보기
Github Actions 자체에는 저장되어 있는 변수가 있다. 대표적으로 아래 테이블에 존재하는 지정된 예약어가 존재하는데 우리는 그것 중 몇개를 deploy.yml
파일에 작성하여 ehco
명령어로 출력해 볼것이다.
변수 | 설명 |
---|---|
GITHUB_REPOSITORY |
리포지토리 이름 (owner/repo ) 형태입니다. |
GITHUB_SHA |
실행 중인 커밋의 SHA 값입니다. |
GITHUB_REF |
실행 중인 브랜치 또는 태그의 참조명입니다. |
GITHUB_EVENT_NAME |
워크플로를 실행시킨 이벤트 이름입니다 (예: push , pull_request ). |
RUNNER_OS |
실행 환경의 운영체제입니다 (Linux , Windows , macOS ). |
코드를 다음과 같이 수정한다.
name: GitHub Actions 실행시켜보기
on:
push:
branches:
- main
jobs:
My-Deploy-job:
runs-on: ubuntu-latest
steps:
- name: Hello World 출력
run: echo "Hello World"
- name: 여러 명령어 문장 출력하기
run: |
echo "Good"
echo "Morning"
- name: Github Actions 자체에 저장되어 있는 변수 사용해 보기
run: |
echo $GITHUB_SHA
echo $GITHUB_REPOSITORY
해당 코드를 수정한 뒤에 git push
를 진행해보자. 아마 다음과 같은 값이 Actions tab에서 출력될 것이다.
참고로 $GITHUB_SHA
값은 우리가 방금 커밋한 commit hashcode 값과 일치한다.
Step7. GitHub Actions Secret 환경변수 사용해보기
이전 단계에서 살펴본 것처럼, GitHub Actions는 자체적으로 제공하는 환경 변수(예: GITHUB_REPOSITORY, GITHUB_SHA 등)가 존재한다. 하지만 이 환경 변수들은 코드 실행과 관련된 정보만 제공되며, DB 비밀번호나 API 키처럼 민감한 값들을 관리하는 용도로는 적합하지 않다. 이를 해결하기 위해 GitHub에서는 Actions Secrets
기능을 제공합니다. Secrets
를 사용하면 민감한 데이터를 안전하게 저장하고 워크플로에서 참조할 수 있다.
아래의 이미지를 참고하여 GitHub
> Setting
> Secrets and variables
> Actions
으로 이동해보자.
그 뒤에 Repository secrets
의 New Repository Secret
버튼을 클릭해보자.
다음과 같이 Name
과 Secret
에 값을 입력하였는데, Name은 아무렇게나 내가 인식할수 있는 값으로 입력하고 Secret에는 민감한 데이터 값을 입력하면된다. 나는 테스트용도의 값들이기에 무작위의 값을 입력하였다. 그 뒤 Add secret
버튼을 클릭하여 저장해주자.
자 이제 다시 deploy.yml
파일로 와서 우리가 Secret 값으로 저장한 API_KEY_PASSWORD
값에 대해서 출력해보자. 아래 코드를 참고해서 수정 후에 git push
하여 어떻게 Actions 에서 출력되는지 확인해보자.
주의사항
secret 값을 사용할때는 secrets
를 앞에 붙이고 .
후에 Name
값을 입력해야한다.
name: GitHub Actions 실행시켜보기
on:
push:
branches:
- main
jobs:
My-Deploy-job:
runs-on: ubuntu-latest
steps:
- name: Hello World 출력
run: echo "Hello World"
- name: 여러 명령어 문장 출력하기
run: |
echo "Good"
echo "Morning"
- name: Github Actions 자체에 저장되어 있는 변수 사용해 보기
run: |
echo $GITHUB_SHA
echo $GITHUB_REPOSITORY
- name: 아무한테나 노출이 되면 안되는 값
run: |
echo ${{ secrets.API_KEY_PASSWORD }}
출력하고자 하였던 API_KEY_PASSWORD
값이 Actions에서 ***
로 출력된다. 민감한 값을 보안을 지키면서 사용 할 수 있음을 알 수 있다.
다음으로
이렇게 하여 기본적인 CI/CD 개념과 GitHub Actions 사용법을 알아보았다. 다음 단계로 Spring Boot
프로젝트에 CI/CD를 적용하는 실습을 진행해보겠다.