CI/CD 적용 ( GitHub Action )

song yuheon·2023년 9월 19일
0

Github

목록 보기
5/8
post-thumbnail

지속적인 통합(CI)과 지속적인 배포(CD) 란?



개발 환경에서 지속적인 통합(CI)과 지속적인 배포(CD)는 코드의 품질을 유지하면서 빠르고 안정적인 배포를 가능하게 하는 핵심 요소들이다.


지속적인 통합 (CI)

지속적인 통합 (Continuous Integration, CI)은 개발 팀이 자주 코드 변경사항을 중앙 리포지토리에 통합하는 프로세스를 말한다. 이러한 접근 방식의 주요 이점은 다음과 같다.

  • 버그 감소: 자주 코드를 통합함으로써 발생할 수 있는 문제를 조기에 발견하고 해결할 수 있다.
  • 비용 절감: 버그를 조기에 발견함으로써, 문제 해결에 드는 비용을 줄일 수 있다.
  • 시간 절약: 개발자들은 시스템이나 애플리케이션의 더 나은 구조에 집중할 수 있으며, 코드 통합에 드는 시간을 절약할 수 있다.

지속적인 배포 (CD)

지속적인 배포 (Continuous Delivery, CD)는 CI 프로세스를 확장하여, 새로운 변경사항을 사용자에게 빠르고 안정적으로 제공하는 방법을 포함한다. 지속적인 배포의 핵심 요소들은 아래와 같다.

  • 자동화된 테스트: 코드가 통합된 후 자동화된 테스트 스위트를 실행하여 버그 및 회귀를 식별한다.
  • 자동화된 배포: 변경사항이 성공적으로 테스트된 후, 변경사항은 자동으로 스테이징 또는 프로덕션 환경에 배포된다.

CI/CD 파이프라인 구축

CI/CD 파이프라인은 일련의 자동화된 단계로 구성되며, 각 단계는 다음 단계로 진행되기 전에 성공적으로 완료되어야 한다. 아래와 같은 도구들이 파이프라인 구축에 일반적으로 사용된다.

  • 버전 관리 시스템 (VCS): Git, SVN 등이 있다.
  • 통합 서버: Jenkins, Travis CI, CircleCI 등이 있다.
  • 자동화된 테스트 도구: JUnit, Selenium 등이 있다.
  • 배포 도구: AWS CodeDeploy, Docker, Kubernetes 등이 있다.

트러블 슈팅


Q1: GitHub Actions 워크플로우에 테스트 실행 단계는 어떻게 추가하는가?

GitHub Actions 워크플로우에 테스트 실행 단계를 추가하기 위해서는 arguments 옵션에 test 태스크를 추가한다. YAML 파일 내에 arguments: build test라는 지시어를 통해 Gradle 빌드 과정에서 test 태스크가 호출되며 테스트가 실행된다. 아래 예시를 참고한다.

      with:
        arguments: build test

Q2: 빌드 오류 발생 시에도 main 브랜치에 코드 푸시가 가능한 문제를 어떻게 해결하는가?

이 문제는 GitHub의 브랜치 보호 규칙을 사용하여 "Require status checks to pass before merging" 옵션을 활성화함으로써 해결한다. 이와 함께 필요한 상태 검사를 지정하여 빌드 실패 시 병합이 거부되도록 설정한다. 아래 예시를 참고하여 규칙을 설정한다.

Require status checks to pass before merging
  Status checks that are required:
  build

Q3: CI/CD에서 지속적인 개발 방식은 무엇인가?

CI/CD 환경에서 지속적인 개발은 개별 작업 브랜치에서 작업을 완료한 후, 해당 브랜치로 풀 리퀘스트를 생성하여 main 브랜치에 병합하는 방식으로 이루어진다. 이 방법을 통해 코드 변경 사항은 테스트 및 빌드 과정을 거쳐 안정적인 main 브랜치에 병합되며, 코드의 안정성이 유지된다.

Q4: 풀 리퀘스트 시 빌드 대상 브랜치는 어느 것인가?

풀 리퀘스트 시에 빌드 대상은 변경 사항을 담고 있는 작업 브랜치다. 따라서, main 브랜치가 아닌 현재 작업 중인 브랜치에서 테스트와 빌드가 수행된다.


GitHub


스터디 회고


SpringBoot로 개발한 서비스에 GitHub Actions를 적용하려고 했는데, 테스트 중에 "Error: Gradle script '/home/runner/work/GitHubActionTest/GitHubActionTest/gradlew' is not executable."라는 오류를 마주쳤다. 이 문제는 Gradle 스크립트에 실행 권한이 없기 때문에 발생한 것으로 파악했고, GitHub Actions 워크플로우 내에서 chmod +x gradlew 명령을 사용하여 실행 권한을 부여함으로써 문제를 해결할 수 있었다.

그 다음 단계로 테스트를 실행하려고 했는데, 이를 위해 GitHub Actions 워크플로우의 arguments 옵션에 test 태스크를 추가해야 한다는 것을 알게 되었다. 이렇게 하면 Gradle이 프로젝트의 테스트를 자동으로 찾아 실행해 준다. 따라서 YAML 파일에 arguments: build test를 추가하여 test 태스크를 호출할 수 있게 했다.

다만, 푸시 과정에서 몇 번의 오류 메시지를 받게 되었다. 먼저, "푸시가 거부되었다"는 메시지는 pull 작업을 생략하고 바로 push를 시도했기 때문에 발생한 것으로 파악되었다. 이 문제는 원격 저장소의 최신 변경 사항을 로컬 저장소에 먼저 pull하여 동기화한 후 push하는 방식으로 해결할 수 있었다.

또한, "Rule is invalid"라는 메시지도 마주쳤는데, 이는 규칙을 생성할 때 형식을 제대로 따르지 않아 발생한 문제였다. 규칙 설정을 정확하게 검토하고 형식에 맞게 수정함으로써 이 문제 또한 해결할 수 있었다.

이외에도 빌드 오류가 발생하더라도 코드가 main 브랜치에 푸시되는 문제에 직면했다. 이 문제는 GitHub의 브랜치 보호 규칙을 설정하여 "Require status checks to pass before merging" 옵션을 활성화함으로써 해결할 수 있었다. 이 설정을 통해 빌드가 실패하면 병합이 거부되도록 할 수 있었다.

그러나, 브랜치 보호 규칙을 설정한 후에도 빌드 실패에도 불구하고 변경 사항이 main 브랜치에 반영되는 문제가 계속 발생했다. 이유를 찾아보니 main에서 main으로 직접 푸시를 한 탓이었다. 일반적인 CI/CD 환경에서는 main 브랜치에 직접 푸시하지 않고, 별도의 작업 브랜치에서 작업을 완료한 후 풀 리퀘스트를 통해 main 브랜치로 병합하는 방식을 사용해야 한다는 것을 깨달았다.

이렇게 학습한 바로, CI/CD는 main 브랜치와 다른 작업 브랜치들 사이에서 주로 이루어지며, 코드 변경 사항이 작업 브랜치에서 main 브랜치로 풀 리퀘스트를 통해 병합되기 전에 반드시 테스트와 빌드 과정을 거친다는 것이다. 이 방식을 따르면 코드의 안정성을 유지할 수 있다.


profile
backend_Devloper

0개의 댓글