당신이 CI를 사용해야 하는 이유

DeadWhale·2023년 4월 17일
0

CICD

목록 보기
1/3
post-thumbnail

이 글을 적게 된 이유

프로젝트의 설계가 시작된 후 다음으로 진행한 일이 CICD의 구축 과정을 진행했습니다.
이 글에서는 CI를 하면서 어떤 일을 더 할 수 있었고, 왜 했는지에 대해 글을 써보려 합니다.

CI ( Continuous Integration ) | 지속적인 통합

지속적인 통합이라고 불리는 CI는 말 그대로 서로 다른 작업을 하는 개발자들의 코드를
하나로 병합하는 과정을 의미합니다.

서로의 코드가 합쳐지는 매우 당연한 일입니다.
하지만 그 과정에서 일어나는 문제들은 당연한 문제들이 아닙니다.

회사에서 있었던 일로 GitLab 을 이용해 버전 관리를 하던 도중
어떤 개발자가 자체적인 테스트를 하지 않고 빌드 자체가 안되는 코드의 상태로 운영 서버에 병합해 버려
문제를 파악 후 처리 할 때 까지 운영 서버 접속이 30분 가량 불가했던 적이 있습니다.

다행이 실제 운영 기간이 아닌 테스트 기간이였기 때문에 . 큰 문제로 번지진 않았지만.
그 일 이후 매우 빠른 논의를 통해 젠킨스가 도입되는 과정을 보았습니다.

이러한 문제는 CI의 도입을 통해 예방할 수 있었던 일입니다.

CI를 도입하면서 얻을 수 있는 이점은 여러가지 있습니다.
그 중 가장 대표적인 2가지 정도를 소개하자면

  • 배포 위험성의 감소
    - 자동화된 빌드 테스트와 다른 유틸등을 이용해 초기에 감지되는 문제들 모두 차단할 수 있다
  • 높은 품질
    - 개발자는 테스트코드만 짜면 되기 때문에,
    테스트 , 손수 배포같은 번거로운 시간을 아껴 코드 퀄리티를 향상 시킬 수 있다.
    - 또한 정적 분석 , 컨벤션 체크 , 코드 커버리지 측정을 통해 인적자원을 소모하지 않고 향상 시킬 수 있다.

이런 식으로 위험성과 코드 퀄리티를 관리해 CD를 할 때에는 프로젝트는 신뢰하고 배포에만 신경 쓸 수 있습니다.


CI는 어떻게 할까.

CI를 지원하는 툴들은 매우 많습니다.
그 중 인기있는 4가지 정도만 짦게 소개하자면

  • Jenkins:
    - 매우 강력하고 확장 가능한 오픈소스 CI/CD 플랫폼으로, 풍부한 플러그인 생태계가 특징입니다.
    - 대규모 프로젝트에서 가장 많이 사용
  • GitHub Actions:
    - GitHub 저장소와의 완벽한 통합과 간편한 사용법이 강점입니다.
    - 사용법이 매우 편리한 편에 속해 사용성이 좋다
  • CircleCI:
    - 빠른 실행 속도와 클라우드 기반의 병렬화 처리로 높은 효율성을 자랑합니다.
    - 병렬처리와 빠른 속도로 인해 대규모 프로젝트에서 주로 사용
  • Travis CI:
    - 간단한 설정과 편리한 사용자 경험을 제공하는 클라우드 기반 CI/CD 서비스입니다.
    - 오픈 소스 프로젝트에 대해 지원이 매우 좋습니다.
    - githubAction과 연결성이 매우 좋습니다

저희는 여기서 github Action을 활용해 프로젝트의 CICD 구축을 진행했습니다.
젠킨스와 깃허브 액션 둘중 고민했지만.

  • 깃허브 플랫폼과의 통합으로 인한 사용자 경험 향상
  • 설정과 관리의 간편함
  • 편리한 공식 문서 제공

등의 이유들로 인해 GitHub Actions를 선택하여 프로젝트의 CI/CD 구축을 진행하게 되었습니다.

이를 통해 프로젝트의 개발 및 배포 과정을 좀 더 편리하게 구축할 수 있었습니다.

build test

- name: Build with Gradle  
run: ./gradlew build  

gradle을 빌드할 때.

  • 자바 소스 코드를 컴파일 합니다.
  • 프로젝트의 테스트 코드들을 수행합니다.
  • jar,war같은 아티팩트들을 생성합니다.

코드에 예외가 있거나 테스트코드에 실패하는 경우 여기서 모든 문제가 사전에 검증됩니다.
이 때 예외가 발생 시 CI가 안되게 설정할 수 있기 때문에 배포서버까지 이 문제가 전달되지 않습니다.

가장 핵심적인 역할 중 하나입니다. CI의 목적과 가장 부합합니다
이러한 빌드 과정이 없을 경우에는 처음에 설명한 것 처럼 에러 코드가
배포 서버로 올라가 운영이 불가능해집니다.

여기 까지 왔을때 yaml 파일을 한번 보자면

name: CI
  
on:  
	push:  
		branches:  
			- main  
		pull_request:  
			branches:  
				- main  
# 워크플로우 트리거를 설정합니다. 'main' 브랜치에 푸시되거나 풀 리퀘스트가 생성될 때마다 실행됩니다.  
  
jobs:  
	build:  
		runs-on: ubuntu-latest  
# 작업이 실행될 운영 체제를 설정합니다. 여기서는 최신 우분투 버전을 사용합니다.  
  
steps:  
	- uses: actions/checkout@v3  
# 레포지토리의 소스 코드를 체크아웃하는 작업을 설정합니다.  

	- name: Set up JDK 17  
		uses: actions/setup-java@v3  
			with:  
			java-version: '17'  
			distribution: 'temurin'  
  
	- name: Cache Gradle dependencies  
		uses: actions/cache@v3  
		with:  
			path: ~/.gradle/caches  
				key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}  
				restore-keys: |  
						${{ runner.os }}-gradle-  
# Gradle 의존성을 캐시하는 작업을 설정합니다. 이렇게 하면 빌드 시간이 단축됩니다.  
  
	- name: Build with Gradle  
		run: ./gradlew build  
# Gradle을 사용하여 프로젝트를 빌드하는 작업을 설정합니다.

이렇게 설정된 파일을 저장 후 main 브랜치에서 이벤트 발생 시
최신 버전의 우분투 서버에서 해당 프로젝트를 체크아웃 후 버전에 맞는 JDK를 세팅 후
빌드 시간 단축을 위해 캐싱 후 초기의 목적인 빌드를 수행합니다.

이렇게 빌드 후 결과가 정상일 경우 현재 프로젝트는 배포해도 괜찮은 것입니다!

이제 끈났다...!

이제 CD를 구현해 배포만 하면 된다! 라는 마음을 가지고 커밋 후 다른 작업을 하려는 시작하려 할 때.
문득 다른 다른 생각이 들었습니다.


[참조 자료]

[활용 프로젝트]


0개의 댓글