본문 바로가기
Study/지속적인 통합

[지속적인 통합] 2장. 지속적인 통합 도입하기

by Nahwasa 2023. 3. 8.

지속적인 통합 스터디 메인 페이지

* 주의 : 책(폴M 듀발 저 - 지속적인 통합) 내용 중 기억하고 싶은 내용 및 제 생각을 적은 글 입니다. 책이 나온지 오래되어 설명에 나온 기술스택이 현재 사용되지 않는게 많아 기술스택보다는 이론이나 책의 조언들 위주로 작성할 것 같고, 기술스택은 제가 알고있는대로 수정해서 작성합니다. 따라서 책에서 말하고자 하는 바와 다를 수 있습니다.

* 별도로 표기되어 있지 않다면 이미지 출처는 '지속적인 통합 (폴M 듀발 저)' 책 입니다.

 

 

CHAPTER 2. 지속적인 통합 도입하기

  • 좋은 소프트웨어를 개발하려면 기본적인 실천 방법을 일관되게 수행하는 게 중요하다
    • 소프트웨어 개발에서 가장 심각한 문제 중 하나는 설익은 '가정'
      • 메소드의 매개변수들이 항상 정상적으로 넘어올 거라 가정한다면 그 메소드는 실패할 것이다.
    • 개발 시 가정을 한다면, 시간을 낭비하고 위험을 키우게 된다.
    • CI는 변경 사항이 적용될 때마다 다시 빌드함으로써 가정을 줄이는데 도움이 된다.

 

  • 모든 문제를 해결해줄 '은 탄환'은 없다.
    • 개발할 때는 변경 계획을 수립하고, 지속적으로 그 결과를 관찰하며, 결과에 따라 점진적으로 진로를 수정해야 한다.
    • CI는 소프트웨어를 변경할 능력을 개발자인 우리에게 부여하는 전술들을 한데 모은 것이다.

 

  • CI와 같은 실천 방법을 써서 개발하는 사람이라면, 소스 변경 시마다 시작되는 일관성있고 반복가능한 빌드 프로세스에게서 힘을 얻을 수 있다.

 

 

지속적인 통합과 함께 하는 하루 일과

 

 

업계 용어

  • 자동화된
    • '무인' 프로세스
  • 빌드
    • 소프트웨어를 생성하고 테스트하고 검사하며 배포하기 위해 수행하는 행위의 집합
  • 지속적인
    • CI의 문맥에서 봤을 때 '빈번하다'라는 뜻에 가까움.
  • 지속적인 통합
    • 팀 구성원들이 자기가 한 일을 자주 통합하는 소프트웨어 개발 실천 방법
    • 각자 하루에 적어도 한 번은 통합하며 결과적으로 하루에 여러 번 통합
    • 각 통합은 자동화된 빌드와 테스트, 검증으로 통합 오류를 신속하게 탐지하고 피드백
  • 개발 환경
    • 개발하는 환경. IDE, 빌드 스크립트, 도구, 외부 라이브러리, 서버, 설정 파일 등
  • 검사
    • 내부적인 품질 특성을 파악하기 위한 소스 코드 등
  • 통합
    • 별도의 소스 코드 산출물을 하나로 합쳐 전체적으로 잘 작동하는지 확인하는 행위
  • 통합 빌드
    • 소프트웨어 컴포넌트(프로그램과 파일들)를 하나의 소프트웨어 시스템으로 합치는 행위
    • 책에서는 별도의 독립된 통합 빌드 컴퓨터에서 수행하는 경우에만 통합 빌드라 분류
  • 개인 (시스템) 빌드
    • 개인이 VCS에 커밋하기 전 로컬 컴퓨터에서 빌드를 수행
  • 품질
    • 유지보수성, 확장성, 보안, 성능, 가독성 등
  • 릴리즈 빌드
    • 유저에게 출시할 목적으로 소프트웨어를 준비
    • 릴리즈 빌드에는 인수 테스트가 포함되어야 하며, 더 방대한 성능 및 부하 테스트가 포함될 수도 있음
  • 위험
    • 문제가 발생할 잠재성
    • 현실화된 위험 = '문제'
  • 테스트
    • 소프트웨어가 설계된 대로 작동하는지 검증하는 일반적인 프로세스
    • 단위 테스트, 컴포넌트 테스트, 시스템 테스트 등

 

 

지속적인 통합에는 어떤 가치가 있을까요?

  • 결국 여러 책들이 말하듯 CI 또한 '변경에 대한 자신감'으로 귀결되는 듯.

 

  • 위험을 줄여줌
    • 하루에도 여러번 테스트와 검사를 돌리므로 결함을 보다 조기에 발견하고 수정할 수 있음
    • 마찬가지로 지속적으로 테스트와 검사를 하므로 소프트웨어 건강 상태를 측정할 수 있음
    • 동일한 프로세스와 스크립트로 주기적으로 빌드하고 테스트하므로 외부 라이브러리나 환경 변수가 얼마나 있든간에 '가정'을 줄일 수 있음.
    • CI는 결함이 코드 베이스에 들어올 위험을 줄여줄 안정망을 제공해준다.

 

  • 반복 작업을 줄여줌
    • CI를 자동화할 시 이런 반복적인 프로세스에 들이는 노동력이 줄어듬.
    • 자동화된 매커니즘을 통해 개선을 이뤄내는 것에 대한 저항을 극복할 수 있게 됨

 

  • 언제 어느 때라도 배포할 수 있는 소프트웨어를 생성해냄
    • 고객이나 사용자 같은 '외부인'에게 보이는 CI의 가장 분명한 이점
    • CI가 없는 프로젝트라면 소프트웨어를 전달하기 바로 직전까지 기다려서야 소프트웨어를 통합하고 테스트하게 됨 -> 출시가 늦어지거나, 특정 결함을 고치는게 늦어지거나 아예 고치지 못할 수도 있음.

 

  • 프로젝트 가시성 향상
    • 무언가 결정을 내리는 데 도움이 될 데이터를 제공받을 수 있음.
    • 최근 빌드 상태와 품질 메트릭을 적절하게 제공함으로써 효과적으로 의사결정 할 수 있음
    • 전체적인 프로젝트 품질에 대한 추세를 인지할 수 있음

 

  • 제품에 대해 보다 큰 자신감을 갖게 됨
    • 통합을 자주 하지 않으면 자신이 변경한 코드가 미치는 영향력을 알 수 없어 갑갑하다!
    • CI는 모든 소프트웨어 자산을 한 출처에 모아둘 것을 권장하므로, 그 정확성에 대해서도 훨씬 자신할 수 있게됨.

 

 

지속적인 통합을 왜 도입하지 못할까요?

  • CI 시스템을 유지보수하기 위한 추가적인 과부하
    • CI를 쓰건 안쓰건 통합하고 테스트하고 검사하고 배포해야 할 필요가 있음.
    • 견고한 CI 시스템을 관리하는 편이 사람이 직접 관리하는 것보다 나음.
  • 변경할 게 많음
    • 진행 중인 프로젝트에 도입하려면 변경해야 할게 많다고 느낄 수 있음
    • 점진적으로 접근하는 것이 효과적 -> 먼저 빌드와 테스트를 좀더 낮은 빈도로 실행하게 하고 나서, 사람들이 그 결과에 익숙해지면 주기를 짧게 가져가자.
  • 빌드 실패 횟수가 너무 많음
    • 개인 빌드를 수행하지 않아서 그럼
  • 추가적인 하드웨어 및 소프트웨어 비용
    • 개발 종료 막판에 문제가 생겨 발생하는 값비싼 비용에 비하면 새 발의 피임

 

 

'지속적인' 통합을 도입하려면 어떻게 해야 할까요?

  •  식별하기 (Identify)
    • 자동화해야 할 프로세스 파악 (컴파일, 테스트, 검사, 배포, DB 통합 등)
  • 빌드 (Build)
    • 빌드 스크립트를 만들어 반복 가능하고 일관성 있게 자동화
  • 공유하기 (Share)
    • 만들어둔 빌드 스크립트나 프로그램을 다른 사람도 사용할 수 있도록 공유
  • 지속적으로 돌아가게 만들기 (Make it continuous)
    • CI 서버를 이용해서 변경사항을 적용할 때마다 자동화된 프로세스가 돌아가게 할 것

 

  • 당장 모든 걸 CI 시스템에 쑤셔 넣으려고 하면 일이 꼬일 수 있음.
    • CI 시스템을 조금씩 성장시켜나가는 걸 목표로 삼을 것.

 

  • 도입은 프로젝트 초기에 하는것이 최선
    • 프로젝트 후반에 구축한다면 작은 것 부터 시작해서 시간이 있을 때 좀더 추가해 나갈 것.

 

  • CI는 단순한 기술적 성취를 뜻하는 것이 아니라, 조직과 문화의 성취.

 

 

CI는 다른 개발 실천 방법을 어떻게 보완할까요?

  • 개발자 테스트
    • 소프트웨어가 변경될 때마다 자동화된 테스트가 포함되므로 변경 사항이 적용될 때 마다 자동화된 회귀 테스트 가능.
  • 코딩 표준 준수
    • 코딩 표준 : 프로젝트에 참가한 개발자가 지켜야 할 지침을 모아놓은 것
    • 변경 내역이 있을 때 마다 자동화된 정적 분석 도구를 실행시켜 표준 준수 여부를 보고할 수 있음
  • 리팩토링
    • 리팩토링 : 코드의 외부 행동은 바꾸지 않으면서 내부 구조를 개선하여 소프트웨어 시스템을 바꾸는 과정 (마틴 파울러)
    • 빌드할 때마다 검사 도구를 돌려 잠재적인 문제 영역을 파악함으로써 리팩토링 작업을 보조함
  • 작은 릴리즈
    • 작은 릴리즈 : 테스터와 사용자가 필요할 때마다 동작하는 소프트웨어를 받아 검토할 수 있게 해주는 것
    • 하루에도 여러번 통합이 이루어지고, 언제라도 릴리즈가 가능
  • 공동 소유권
    • 개발자라면 누구라도 소프트웨어 시스템의 어느 부분이라도 손볼 수 있음
    • 따라서 시스템의 특정 영역에 대한 지식을 한 사람만 아는 '지식 저장고' 현상을 방지할 수 있음.

 

 

지속적인 통합과 나

  • 이하 개인과 팀에 효과를 제대로 발휘하는 실천 방법들!

 

  • 코드를 자주 커밋하세요
    • CI의 핵심은 빨리 그리고 자주 통합하는 것
    • 한 번에 여러개의 컴포넌트를 바꾸려 하지 말고 조금씩 바꿀 것
    • 각 작업이 끝날 때마다 커밋할 것

 

  • 깨진 코드를 커밋해선 안 됩니다
    • 동작하지 않는 코드를 커밋하면 안됨

 

  • 빌드가 깨지면 즉시 고치세요
    • 프로젝트의 문화는 깨진 빌드를 고치는걸 최우선 순위로 다뤄야 함.
    • 그래야 팀 구성원 모두가 자신이 하던 일로 돌아갈 수 있음.

 

  • 자동화된 개발자 테스트를 작성하세요

 

  • 테스트와 검사는 모두 통과해야 합니다
    • 자동화된 테스트는 컴파일 만큼이나 중요!
    • 실패하는 테스트를 대충 주석 처리하고 말 수도 있음 -> 적용범위(테스트 커버리지) 도구 사용

 

  • 개인 빌드를 돌리세요
    • 빌드를 깨먹지 않으려면 개발자들이 단위 테스트를 끝내고 나서 자신의 로컬에서 통합 빌드를 모방해봐야 함.

 

  • 깨진 코드는 가져오지 마세요
    • 빌드가 깨졌을 때는 VCS에서 최신 코드를 체크아웃하지 말 것.
    • 때론 개발자가 빌드가 깨졌다는 피드백을 못봤을 수 있음 -> 불빛이나 소리같은 수동적인 피드백이 유용.. 즉, 알림(물리)

 

 

질문

  • 평균적으로 팀의 모든 사람이 적어도 하루에 한 번은 코드를 커밋합니까? 코드를 자주 커밋하기 쉽게 해줄 기법을 쓰고 있습니까?
  • 하루에 하는 통합 빌드 중 몇 퍼센트가 성공합니까? (가장 최근에 돌린 빌드는 통과했습니까?)
  • 팀의 모든 사람이 저장소에 커밋하기 전에 개인 빌드를 돌려서 통합 오류를 줄이고 있습니까?
  • 테스트나 검사 중 하나라도 실패하면 빌드가 실패하도록 스크립트화했습니까?
  • 깨진 통합 빌드를 고치는 일을 우선적으로 하고 있습니까?
  • 빌드가 깨졌을 때 버전 관리 저장소에서 최신 코드를 가져오지 않습니까?
  • 자동화된 프로세스를 빌드와 지속적인 통합 시스템에 추가할 생각을 얼마나 자주 합니까? 지속적으로 하나요? 아니면 주기적으로라도 하나요?

댓글