CI/CD
CI/CD는 지속적 통합 Continuous Integration과 지속적 배포 Continuous Deploy/Delivery를 의미한다.
지속적 통합(CI)이란?
CI는 개발자들이 코드 변경사항을 자주 공유하고 통합하는 과정이다.
- 빈번한 코드 업데이트 : 개발자들이 작업을 자주 중앙 저장소에 올림.
- 자동화된 검증 : 코드가 올라갈 때 마다 자동으로 빌드와 테스트가 실행됨.
- 빠른 문제 발견 : 통합 과정에서 발생할 수 있는 문제를 조기에 발견하고 해결.
지속적 배포(CD)란?
CD는 검증된 코드를 자동으로 배포하는 과정이며 두 가지 형태로 나뉜다.
- 지속적 전달 Continuous Delivery : 배포 준비가 완료된 코드를 수동으로 배포
- 지속적 배포 Continuous Deploy : 검증된 코드를 자동으로 운영 환경에 배포
CI/CD의 중요성
- 빠른 개발 주기 : 코드 변경부터 배포까지의 과정이 빨라진다.
- 높은 품질 : 자동화된 테스트로 버그를 빨리 발견하고 수정할 수 있다.
- 팀 협업 강화 : 개발자들이 더 자주, 더 작은 단위로 코드를 공유하게 된다.
- 사용자 피드백 반영 : 새로운 기능이나 수정사항을 빠르게 사용자에게 전달할 수 있다.
→ CI/CD는 현대 소프트웨어 개발에서 필수적인 요소로, 개발 과정을 더욱 효율적이고 안정적으로 만들어줌.
Github Actions
Github Actions는 Github에서 제공하는 CI/CD 플랫폼이다.
Actions에는 Workflow, Job, Step 이라는 개념이 있다.
각각 파이프라인에서 하나의 실행 단위라고 볼 수 있다.
WorkFlow
# Actions.yml
name: Spring boot CI/CD with AWS EC2, ECR
# 해당 workflow의 트리거 이벤트를 정의한다. 여기서는 main branch에 push되면 트리거된다.
on:
push:
branches:
- main
...
Workflow는 하나 이상의 작업을 실행할 자동화된 프로세스이다.
Workflow 파일은 YAML으로 작성되고, Github Repository의 .github/workflows 폴더 아래에 저장된다.
따라서 위의 Actions.yml 파일이 하나의 Workflow가 된다.
위에서는 main 브랜치에 push 이벤트가 발생할 때 workflow가 실행되도록 설정되어 있다.
push 뿐만 아니라 다양한 트리거를 설정 할 수 있는데 자세한 사항은 깃헙 홈페이지 참고
Job
# Actions.yml
name: githubActionsTest
on:
push:
branches:
- main
jobs:
build: # job 이름
name: Build # job의 보여지는 이름
runs-on: ubuntu-latest # job 이 실행되는 실행기를 정의한다.
# job 도 하나의 컨테이너에서 실행된다고 생각하면 이해가 쉽다.
...
Job은 Workflow에서 실행되는 하나의 작업 단위이다.
여러 개의 Job을 정의할 수 있고 Job들을 병렬적으로 처리하거나, 순차적으로 처리할 수 있다.
Step
# Actions.yml
name: Spring boot CI/CD with AWS EC2, ECR
on:
push:
branches:
- main
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4 # 미리 정의된 action.
# https://github.com/marketplace?type=actions
# 위 링크에서 여러 action 들을 살펴볼 수 있다.
- name: Set up JDK 17
uses: actions/setup-java@v4
with: # actions 사용에 필요한 인자들을 전달할 수 있다.
# 자세한 사용법은 해당 repository로 가서 확인할 수 있다.
# https://github.com/actions/setup-java
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
run: ./gradlew clean build # shell 에서 명령어를 실행하듯이 명령어를 입력할 수 있다.
...
Step은 하나의 Job 안에서 단계별로 작업을 수행하며 실질적으로 어떤 작업을 할지 직접적으로 명시하는 부분이다.
이 때 uses를 사용해서 미리 정의된 action들을 가져다 사용 할 수 있다.
단순히 run 명령어로 원하는 명령어를 실행시킬 수도 있다.
실제 사용중인 Github Actions 들여다보기
name: Java CI with Gradle
on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Grant execute permission for Gradle Wrapper
run: chmod +x ./gradlew
- name: Build Gradle Project (Skip Tests)
run: ./gradlew build -x test
dependency-submission:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
위 파일은 현재 진행중인 팀 프로젝트 내에서 사용중인 gradle.yml 이다.
이 워크플로는 자바 프로젝트를 Gradle로 빌드하고, 의존성을 캐싱하여 빌드 시간을 단축하며, Dependabot을 이용하여 의존성을 관리하는 것을 자동화한다.
즉, 코드가 변경될 때마다 자동으로 빌드하고 테스트하며, 의존성에 대한 보안 취약점도 알려주는 역할을 한다.
자세히 뜯어보면
name: Java CI with Gradle
on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]
이 워크 플로의 이름은 Java CI with Gradle 이며 develop 브랜치에 Push가 발생하거나 pull request가 생성될 때 실행된다.
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Grant execute permission for Gradle Wrapper
run: chmod +x ./gradlew
- name: Build Gradle Project (Skip Tests)
run: ./gradlew build -x test
dependency-submission:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
Job에는 build 와 dependency-submission이 있다.
build
- runs-on: Ubuntu 환경에서 실행된다.
- permissions: 레포지토리 내용에 대한 읽기 권한만 필요하다.
- steps:
- 코드 체크아웃
- JDK 17 설치
- Gradle 설정 (의존성 캐싱 포함)
- Gradle Wrapper 실행 권한 부여
- Gradle 빌드 (테스트 생략)
dependency-submission
- runs-on: Ubuntu 환경에서 실행된다.
- permissions: 레포지토리 내용에 대한 읽기/쓰기 권한이 필요하다.
- steps:
- 코드 체크아웃
- JDK 17 설치
- 의존성 그래프 생성 및 제출 (Dependabot 연동)
코드 체크아웃 : 깃허브 레포지토리에서 코드를 가져온다.
JDK 설치 : 자바 17 버전 설치.
Gradle 설정 : Gradle을 설정하고 의존성을 캐싱하여 빌드 시간을 단축.
Gradle 빌드 : Gradle을 이용하여 프로젝트를 빌드. 테스트는 생략하여 빌드 시간 단축.
의존성 그래프 생성 및 제출 : 프로젝트의 의존성 관계를 그래프로 생성하여 Dependabot에 제출. Dependabot은 이 정보를 바탕으로 보안 취약점이 있는 의존성을 찾아 알려준다.
저 파일을 루트 디렉토리의 .github/workflows 안에 두고 develop 브랜치에 pull request를 하게 되면
위와 같이 pull request 하단에서 Actions가 실행된다.
테스트를 통과하지 못 하면 어떤 부분에서 오류가 났는지 확인 할 수 있고
테스트를 모두 통과하면 초록색 마크로 변한다!
🔗 더 자세한 내용은 공식 Docs 참조
'Git' 카테고리의 다른 글
Github Actions의 환경 변수 참조 에러 Github Secrets 사용으로 해결하기 (0) | 2024.10.18 |
---|---|
[🐙 Git & Github] 깃 명령어 사용해서 특정 브랜치로 이동하기 (2) | 2024.10.07 |
[💡 트러블 슈팅] Github에서 머지 충돌 일어났을 때 해결하기 Can't automatically merge (0) | 2024.10.02 |
[🐙 Git & Github] 깃헙 이슈 이해하기 + Issue & PR Template 만들기 (1) | 2024.09.26 |
[🐙 Git & Github] 깃 컨벤션으로 커밋 메세지 형식 통일하기 (0) | 2024.09.26 |