지속적 통합 및 지속적 배포 이해

CI/CD라는 용어는 익숙하지만, 정확히 무엇을 의미하는지 명확하게 이해하기 어려우신가요?

소프트웨어 개발의 이상적인 목표는 개발자가 작성한 코드가 실제 사용 환경(프로덕션 환경)에서 원활하게 작동하여 사업상의 필요를 충족시키는 것입니다. 사용자(또는 고객)의 만족도를 높이기 위해서는 제품 내에 오류가 없어야 합니다.

일반적으로 소프트웨어 개발자들은 개별 브랜치에서 작업을 진행한 후, 변경 사항을 통합하기 위해 마스터 브랜치에 풀 리퀘스트를 생성합니다. 또한, 새로운 변경으로 인해 예상치 못한 오류가 발생하지 않도록 테스트 코드를 작성하는 것이 일반적입니다. 그러나 많은 개발자들은 특정 기능이 완전히 개발될 때까지 풀 리퀘스트를 생성하지 않는 경향이 있습니다. 이는 다음과 같은 문제로 이어질 수 있습니다.

  • 개발자들은 프로덕션 브랜치에 반영된 최신 변경사항을 자신의 코드베이스에 적용하는 데 많은 시간을 소모하게 됩니다.
  • 이는 결국 병합 충돌을 해결하는 과정으로 이어집니다.
  • 뿐만 아니라, 프로덕션 브랜치에 오류가 발생할 가능성도 있으며, 이는 해당 브랜치를 기반으로 작업하는 다른 개발자들에게 지속적으로 영향을 미칠 수 있습니다.

이와 같은 상황을 경험해 보셨다면, 얼마나 고통스러운지 공감하실 것입니다. 이러한 작업으로 하루를 보내고 싶어하는 개발자는 없을 것입니다.

그렇다면 해결책은 무엇일까요?

지속적인 통합

앞서 언급한 문제점을 해결하기 위해, 엔지니어링 팀에서는 지속적인 통합(Continuous Integration, CI)이라는 방식을 채택할 수 있습니다. 지속적인 통합이란 개발자들이 변경한 코드를 공유 브랜치 또는 저장소에 지속적으로 통합하는 것을 의미합니다. 통합되는 코드는 애플리케이션의 안정성을 확보하기 위해 검증된 테스트를 거쳐야 하며, 테스트를 통과해야만 통합이 가능합니다.

이해를 돕기 위해, 10명의 개발자로 구성된 팀의 실제 상황을 가정해 보겠습니다. 개발자들은 특정 기능 구현을 위해 각자의 로컬 브랜치에서 코드를 작성합니다. 기존처럼 기능이 완성될 때까지 기다렸다가 풀 리퀘스트를 보내는 대신, 개발자들은 작은 변경사항이 있을 때마다 풀 리퀘스트를 보내기로 결정합니다. 예를 들어, 개발자가 사용자가 애플리케이션에서 개별 작업을 관리할 수 있는 기능을 개발하는 과정에서 새로운 모달을 만들었다고 가정해 보겠습니다. 개발자는 작업이 완료될 때까지 기다리는 대신 지속적인 통합 패턴을 따라 이 작은 변경사항을 푸시하고, 코드 병합을 위한 풀 리퀘스트를 생성합니다.

이 새로운 변경 사항은 통합되기 전에 일련의 테스트를 거쳐야 합니다.

소프트웨어 엔지니어링 팀은 Travis CI와 같은 도구를 활용하여 이러한 통합 프로세스와 테스트를 자동화합니다. 이러한 도구를 사용하면 설정 과정에서 지정된 대상 브랜치에 풀 리퀘스트가 제출되는 즉시 테스트가 자동으로 실행됩니다.

테스트 결과가 생성되면, 풀 리퀘스트를 생성한 개발자는 결과를 확인하고 필요한 변경 작업을 수행할 수 있습니다. 이처럼 코드를 최대한 작은 단위로 통합하고, 검증된 테스트를 실행하는 방식은 다음과 같은 이점을 제공합니다.

  • 관련 팀은 빌드 프로세스 또는 테스트 실패의 원인을 신속하게 파악할 수 있습니다. 이를 통해 버그가 프로덕션 환경에 배포될 가능성을 줄일 수 있습니다.
  • 팀이 프로세스를 자동화함으로써 생산성에 집중할 수 있는 시간을 확보할 수 있습니다.

여기서 중요한 점은 팀이 코드를 메인 브랜치에 자주 푸시하도록 장려해야 한다는 것입니다. 팀의 다른 구성원이 자신의 로컬 저장소를 업데이트하기 위해 메인 브랜치에서 코드를 가져오지 않으면, 이러한 노력은 효과가 없습니다.

테스트 유형

통합 프로세스에 포함될 테스트를 작성할 때 고려할 수 있는 몇 가지 유형은 다음과 같습니다.

  • 통합 테스트(Integration Tests): 소프트웨어의 개별 단위를 결합하여 그룹으로 테스트합니다.
  • 단위 테스트(Unit Tests): 메소드나 함수와 같은 소프트웨어의 개별 단위 또는 구성 요소를 테스트합니다.
  • UI 테스트(UI Tests): 사용자 관점에서 소프트웨어가 제대로 작동하는지 확인합니다.
  • 승인 테스트(Acceptance Tests): 소프트웨어가 비즈니스 요구 사항을 충족하는지 테스트합니다.

이러한 테스트 중 일부는 이미 개발자가 작성한 코드에 포함되어 있을 수 있으므로 모든 테스트를 실행할 필요는 없다는 점을 유의하는 것이 중요합니다.

지속적 통합 도구

프로젝트에서 사용할 수 있는 몇 가지 도구를 소개합니다.

  • Travis CI: 오픈 소스 커뮤니티에서 잘 알려져 있으며, 코드를 신속하게 테스트할 수 있도록 지원합니다.
  • CircleCI: 제어에서 배포까지 파이프라인을 자동화할 수 있는 기능, 유연성 및 제어 기능을 제공합니다.
  • Jenkins: 모든 프로젝트의 빌드, 배포 및 자동화를 지원하는 수백 가지 플러그인을 제공합니다.

Jenkins를 처음 사용하는 경우, Udemy 강좌를 통해 Java 및 .NET 환경에서 CI를 학습하는 것이 좋습니다.

지속적인 배포

개발한 기능이 저장소에 몇 주 또는 몇 달 동안 저장되어 있다가 프로덕션 환경에 배포된다면 어떨까요? 엔지니어링 팀이 작은 변경 사항을 메인 브랜치에 통합하는 데 노력을 기울이는 것과 마찬가지로, 이러한 변경 사항을 가능한 한 빨리 프로덕션 환경에 적용하는 것 또한 중요합니다.

지속적인 배포(Continuous Deployment, CD)의 목표는 개발자가 변경 사항을 메인 브랜치에 통합하는 즉시 사용자에게 해당 변경 사항을 제공하는 것입니다.

지속적 통합과 마찬가지로, 지속적 배포를 사용하는 경우에도 새로 통합된 변경 사항을 확인하기 위해 자동화된 테스트 및 검증 프로세스를 설정합니다. 배포는 이러한 테스트를 통과한 경우에만 진행됩니다.

팀이 지속적인 배포의 이점을 얻으려면 다음 사항을 준비해야 합니다.

  • 자동화된 테스트는 모든 지속적인 엔지니어링 실천의 핵심입니다. 지속적인 배포의 경우, 배포되는 코드가 팀이 최종 사용자에게 제공하고자 하는 기준을 충족해야 합니다. 이상적으로는 새로운 변경 사항이 임계값 미만이면 테스트가 실패하고 통합되지 않아야 합니다. 그렇지 않은 경우에만 통합이 이루어져야 합니다.
  • 자동화된 테스트가 연속적으로 실행됨에도 불구하고 일부 버그가 프로덕션 환경에 유입될 수 있습니다. 이러한 상황을 대비하여 팀은 변경 사항을 되돌릴 수 있는 메커니즘, 즉 배포를 취소할 수 있는 기능을 갖추어야 합니다. 이를 통해 프로덕션 코드를 새로운 변경 사항이 적용되기 전의 상태로 되돌릴 수 있습니다.
  • 프로덕션 환경에 적용된 변경 사항을 추적하려면 모니터링 시스템이 필요합니다. 이 시스템을 통해 팀은 배포된 변경 사항을 사용할 때 사용자가 경험하는 오류를 추적할 수 있습니다.

앞서 언급된 지속적 통합 도구는 지속적인 배포 시스템을 설정하는 기능 또한 제공합니다. 관련 정보를 더 찾아보실 것을 권장합니다.

결론

개발팀의 생산성은 비즈니스 성공에 매우 중요합니다. 생산성을 높이기 위해서는 이를 장려하는 실천 방식을 채택해야 합니다. 지속적인 통합 및 배포가 그 좋은 예입니다.

지속적인 통합을 통해 팀은 매일 가능한 많은 코드를 푸시할 수 있습니다. 이는 사용자에게 새로 추가된 변경 사항을 가능한 한 빨리 배포하는 것을 용이하게 합니다. 이러한 변경 사항을 배포함으로써 사용자로부터 피드백을 얻을 수 있습니다. 궁극적으로, 기업은 수집된 피드백을 바탕으로 혁신할 수 있으며, 이는 모두에게 윈-윈이 됩니다.

CI/CD를 확장하고 최적화하는 방법도 연구해 보십시오.

CI/CD 학습에 관심이 있는 개발자라면 이 유용한 강좌를 확인해 보십시오.

이 기사가 재미있으셨나요? 다른 사람들과 공유해 보는 건 어떨까요?