Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

Continuous integration

소프트웨어 엔지니어링에서 CI는 모든 개발자의 작업 사본을 공유하고, 하루에 여러 번(수시로 혹은 짧은 간격으로) 병합하는 프로세스를 말한다. 1991년 Grady Booch가 CI라는 용어를 처음 제안했으나 당시에는 여러 번 통합하는 것을 권유하지는 않았다. XP(eXtreme programming)에서는 하루에 한번이상 통합할 것을 권하고 있다.

도입 이유

CI는 "통합의 지옥(integration hell)"라는 문제를 방지하는게 주요 목표다. 빈번한 통합이 CI의 목표를 달성하기 위한 주요 수단 중 하나이지만, CI는 빈번한 통합이상을 지향한다.

XP에서 CI는 TDD(Test-driven development)방법을 통해 작성된 테스트를 자동화하기 위해서 사용한다. 우선 개발자는 로컬환경에서 유닛테스트를 실행해서, 통합단계에서 발생 할 수 있는 다른 작업자의 코드를 손상하는 것을 방지한다. 개발자는 필요한 경우 해당 기능을 커밋하기 전에 통합단계에서 문제가 생기지 않도록 비활성화 할 수 있다. 개발자는 통합을 쉽게 하기 위해서 자동으로 유닛테스트를 수행 할 수 있도록 해야하며, 특정 기능에 대해서는 토클 할 수 있도록 코드를 만들어야 할 수도 있다.

이후 정기적으로 혹은 커밋단위로 테스트를 자동으로 실행하고 개발자에게 결고를 보고하는 빌드서버가 도입이 된다. 빌드서버는 XP와는 별개로 실행하고 있는 조직들이 많이 있다. 요즘에는 XP를 채택하지 않고 CI를 채탁하는 경우도 많다.

자동화된 유닛테스트 외에도 CI를 사용하는 조직은 빌드서버를 이용해서 지속적인 품질관리 프로세스를 구현한다. 이러한 프로세스는 유닛테스트외에도 정적및동적테스트, 성능측정 및 프로파일, 소스코드로 부터의 문서추출 등을 통해서 QA 프로세스를 용이하게 한다.

이러한 연속적이고 지속적인 통합과 통합의 자동화는 모든 개발을 완료 한 후 품질 관리를 적용하는 전통적인 관행을 대체함으로써 소프트웨어의 품질을 향상시키고 품질을 유지하는데 소요되는 시간을 줄일 수 있다.

이렇게 CI가 틀을 갖추고나면 CD(Continuous delivery)와 통합이되서, 안전하게 관리된 소프트웨어가 항상 사용자에게 배포할 수 있도록 확장된다.

통합의 지옥과 빈번한 통합

코드 수정이 필요할 경우 개발자는 현재 코드베이스의 사본을(clone) 가져와서 작업을 한다. 사본을 가져와서 작업하는 하는 동안, 다른 개발자들도 사본을 가져와서 작업을 하기 때문에, 코드를 적용하는 시간이 길어질 수록 코드베이스와 사본과의 차이가 점점 늘어난다. 코드베이스와 사본과의 차이에는 코드뿐만 아니라, 새로운 라이브러리 및 종속성이 포함될 수 있으므로 통합하는 시간이 길어질 수록 충돌 및 빌드 실패, 버그가 발생할 위험이 커진다.

개발자들은 자신의 코드를 제출하기 전에, 먼저 지금까지 저장소 코드의 변경내용이 자신의 코드에 반영될 수 있도록 자신의 코드를 다시 업데이트해야 한다. 변경된 내용이 많을 수록, 제출전에 해야 할 일이 많아진다.

결국 언젠가는 코드 저장소가 개발자들의 코드의 너무 달라지는 "통합의 지옥"이라 불리는 상황에 빠지게 된다. 때때로 코드 개발하는 시간보다 통합하는데 더 많은 시간이 걸릴 수 있으며, 자신의 변경 내용을 취소하고 처음부터 다시 코드를 작성하는 것이 나을 수도 있다.

CI를 이용하면 초기에 그리고 자주 통합을 해서 통합의 지옥을 피할 수 있다.

일반적인 CI 적용 방법

프로세스

 CI 프로세스
  1. 개발자가 코드를 수정하면, Code Repository로 수정한 내용을 COMMIT 한다.
  2. Code Repository는 코드의 형상을 관리한다. 가장 널리 사용하는 툴은 Git이다. GitLab, GitHub, BitBucket와 같은 다양한 Git 기반 서비스들이 있다.
  3. Code Repository로 코드가 업데이트되면, CI 툴이 변경내용을 통합한다.
  4. CI 툴은 코드에 대한 빌드, 테스트를 수행하고 그 결과를 레포팅한다.
  5. 레포팅된 내용은 개발자에게 전달되고, 하나의 주기가 완성된다.

코드 저장소의 관리

프로젝트의 소스코드의 형상을 관리 할 수 있는 시스템의 사용을 권장한다. 프로젝트를 빌드하는데 필요한 모든 데이터들은 저장소에 배치해야 한다. XP의 지지자인 마틴 파울러(Martin Fowler)은 브랜치의 사용을 절제해야 한다고 말한다. 여러 버전의 소프트웨어를 동시에 유지관리하는 대신 변경사항이 통합되는 최소한의 브랜치를 유지하는게 바람직하다.

빌드 자동화

단일 명령으로 시스템을 빌드 할 수 있어야 한다. make와 같은 많은 빌드 도구가 수십년 동안 존재 해왔다. 최근에는 CI환경에서 사용 할 수 있는 툴들이 자주 사용되고 있다. 빌드 자동화는 프러덕트환경으로 통합가능한 자동화 환경의 구축이 필요하다. 대부분의 경우 빌드 스크립트는 코드를 컴파일 할 뿐만 아니라 문서, 웹 사이트, 통계 및 배포 패키지(데비안 DEB, Red Hat RPM, Windows MSI 파일)등을 생성한다.

테스트 자동화

코드가 예상한대로 작동하는지 확인하기 위해서 모든 테스트를 실행해야 한다.

데일리 커밋

정기적으로 커밋을 하면, 코드가 충돌하는 경우의 수를 줄일 수 있다. 1주일간 작업한 내용을 한번에 커밋한다면 기능과 기능이 충돌 할 수 있으며, 해결이 어려울 수 있다. 조기에 발견되는 작은 충돌은 팀 구성원들간의 소통을 통해서 쉽게 해결 할 수 있다. 모든 변경 사항을 최소 하루에 한번 커밋하는 것은 CI의 일부로 권장하고 있다.

빠른 빌드 환경의 유지

빌드가 신속하게 완료되어야, 통합시 발생할 수 있는 문제를 빠르게 식별할 수 있다.

프러덕션과 동일한 환경에서의 테스트

테스트환경이 프러덕션 환경과 다를 경우, 테스트 완료된 시스템이 프러덕션 환경에서 오류가 발생 할 수 있다. 프러덕션 환경의 복제본을 구축하는데에는 많은 비용이 들 수 있으므로 고민이 필요하다. 프러덕션 배포환경이 클라우드라면 아키텍처는 그대로 유지하면서 스케일을 최소로(가용성 포기, 성능 최소로)하는 방법등으로 적은 비용으로 구축 할 수 있다.

이렇게 하더라도 통제 할 수 있는 종속이(예: 외부 API, 타사 응용 프로그램, 외부 서비스 등등) 있을 수 있는데, 이 경우 가상의 테스트랩을 만들어야 할 수 있다.

최신 결과물의 빠른 사용

QA와 기획자와 같은 이해 당사자가 쉽게 사용 할 수 있는 빌드를 만들면, 요구사항의 수정/추가와 같은 작업의 양을 줄일 수 있다. 또한 미리 결과물을 테스트함으로써 배포전에 발생 할 수 있는 결함의 양을 줄일 수 있다.

모든 프로그래머는 저장소에서 최신 프로젝트를 가져오는 것으로 하루를 시작해야 한다. 그러면 모두 최신 정보를 얻을 수 있을 것이다.

최신 빌드 결과의 레포팅

빌드가 수행중인지, 중단 됐는지, 누가 코드를 변경했는지, 변경사항이 무엇인지 쉽게 파악할 수 있어야 한다. 커밋로그, API 문서의 관리 정책도 준비돼야 한다.

배포 자동화

대부분의 CI 시스템은 빌드 완료 후 스크립트를 실행 할 수 있는 기능을 제공한다. 사용자는 프러덕션 환경에 애플리케이션을 배포하는 스크립트를 작성 할 수 있다. 이 과정이 완성이 CD(continuous deployment)다. 소프트웨어를 배포했을 때, 결함이 발생 할 수 있으므로 롤백자동화와 같은 추가적인 장치가 필요하다.

비용과 잇점

CI의 이점은 아래와 같다.
  • 코드를 통합 빌드 할 때, 작은 변경사항들이 적용되므로 조기에 버그를 발견할 수 있으며 쉽게추적할 수 있다. 이를 통해 프로젝트 개발 완료까지 시간과 비용을 절약 할 수 있다.
  • 주기적으로 통합되며, 통합과정에서 기능이 테스트되므로 서비스 출시일에 발생할 수 있는 대규모의 혼란을 방지할 수 있다.
  • 단위테스트가 실패하거나 버그가 발생해서 코드를 되돌려야 할 경우, 쉽게 되돌릴 수 있다.
  • 로컬의 변경이 전체 시스템에 미치는 영향에 대한 즉각적인 피드백을 받을 수 있다. 개발팀은 품질의 유지를 CI 프로세스에 위임하고 코드 개발에 집중 할 수 있다.
CI의 단점은 아래와 같다.
  • 자동화된 테스트 환경을 구축하기 위한 새로운 기능의 개발이 필요할 수 있다. 의도적으로 지속적인 노력을 해야한다.
  • 빌드 시스템을 설정하는데 필요한 작업들은 상당히 복잡해질 수 있고, 유연성이 떨어지는 경우가 있다.
  • 규모가 큰 팀의 경우 새로운 코드가 지속적으로 통합 대기열에 추가되므로, 코드의 추적이 어려워질 수 있다. 대기열이 길어지면 대기열을 빌드하면서 많은 사람들이 오랜시간 기다려야 할 수 있다.
  • 하루에 여러 번 커밋 & 빌드하도록 정책을 정할 경우, 부분적인 기능을 가진 코드가 push되면서 통합테스트가 실패 할 수 있다.
  • 프로젝트가 작거나 테스트 할 수 없는 레거시 코드가 포함돼 있는 경우 CI그 반드시 가치가 있는 것은 아니자.

용어

eXtreme Programming

XP는 켄트 백 등이 제안한 소프트웨어 개발 방법이다. 비지니스요구의 변동이 심한 프로젝트에 적합한 개발 방법이다. 애자일 개발 프로세스라고 불리는 개발 방법론의 대표적인 모델로 꼽힌다. 주요 실천 방법은 아래와 같다.
  • Whole Team
  • Planning Game : XP에서 프로젝트는 여러 개의 반복 주기로 개발이 이루어진다. 이번 주기에 어떤 개발을 끝낼 것인지, 다음 주기에 어떤 개발을 수행 할 것인지가 주요 요소다.
  • Customer Test : 반복적인 고객 테스트를 수행, 고객의 요구에 부합하는 소프트웨어를 만든다.
  • Small Releases : 주기적으로 프로토타입을 고객(혹은 의뢰인)에게 보여준다. 이를 통해서 개발방향이 올바른지를 확인 할 수 있다.
  • Simple Design : 코드를 단순화해서 전체 프로젝트의 복잡도를 낮출 것을 강조한다. KISS(Keep it small and simple, Keep it short and simple, Keep it simple, stupid)원리에 바탕을 두고 있다.
  • Test-Driven Development : 테스트도 코딩의 일부다.
  • Pair Programming : 두명 혹은 그 이상의 프로그래머가 함께 코딩한다. 반드시 두명이 함께 코드개발에 참여해야 한다는 규칙은 없다. 다른 한 명은 QA(Quality Assurance)역할에 집중하는 방식으로 진행할 수도 있다.