이 글은 다음을 참조하여 작성되었습니다.
우리는 여태까지 어떻게 하면 더 좋은 코드를 만들어낼 수 있을지에 대해서 고민해왔다.
하지만 궁극적으로 우리가 하고 싶은 것은 사용자에게 우리가 멋드러지게 만든 코드를 결과물로 만들어 보여주는 것이다.
어떻게 하면 사용자에게 우리의 코드를 보여줄 수 있을까?
첫번째로 우리가 만든 코드를 컴파일 한다.
컴파일이란 우리가 만든 프로그래밍 언어를 기계가 이해할 수 있는 기계의 언어로 번역하는 것이다.
우리가 사용한 java, c와 같은 프로그래밍 언어는 기계가 이해할 수 없다. 이렇게 개발자의 편의를 위해 개발자의 언어로 작성한 프로그래밍 언어를 컴파일러가 컴파일 해 기계가 이해할 수 있는 언어로 번역해준다.
다음은 컴파일된 기계의 언어를 사용자에게 보여주기 위해 빌드하여 완성된 상품, 소프트웨어 가공물로 만든다.
java에서는 maven, gradle과 같은 빌드 도구를 이용하면 컴파일과 함께 소스코드 파일을 .jar, .war 와 같은 산출물로 변환하는 빌드도 함께 할 수 있다.
이렇게 만들어진 산출물을 각각의 서버에서 동작하도록 하여 상품을 사용자들에게 공개하는 것이 배포이다. 최종적으로 만들어진 상품을 배포해 사용자에게 사용하게 하는 것이 우리의 목적이자 개발을 하는 이유가 되는 것이다.
프로젝트를 개발하고 배포를 진행할 때 많은 이들이 CI/CD에 대해 언급하곤 한다. 이 때 말하는 CI/CD란 무엇이고 왜 적용해야할까?
사용자에게 우리가 만들어낸 프로젝트를 배포했는데 어떠한 동작이 올바르게 동작하지 않아 문제가 발생했다고 가정해보자.
개발자들에게는 비상이 걸릴 것이다. 급한 프로젝트일수록 더욱 빠르게 문제를 수정해야만 한다. 수정을 했으면 다시 컴파일, 빌드, 배포하는 과정을 통해 수정된 코드가 제대로 동작하는지 테스트하고 검증할 필요가 있다. 이 과정들은 시간도 많이 걸리고 실수하기도 쉽다.
수정된 코드에 문제가 다시 생기면 또 다시 과정을 반복해야한다. 이를 위해서 CI/CD가 생겨났다.
CI는 지속적 통합이라는 뜻으로 개발을 진행하면서도 품질을 관리할 수 있도록 하는 것으로 여러 명이 하나의 코드에 대해서 수정을 진행해도 지속적으로 통합하면서 관리할 수 있음을 의미한다.
CI가 나오기 전까지는 위와 같이 개발을 끝마치고 배포가 되어야만 코드에 오류는 없는지, 올바르게 동작하는지를 검증하며 코드 품질을 관리할 수 있었다.
CI를 적용하게 되면 각자의 개발자가 자신의 구현해야 할 기능을 구현하면 된다. 이후 완성이 되면 main 브랜치와 통합하고 코드가 잘 빌드되는지 보고, 올바르게 동작하는지 테스트하며 코드에 버그가 있다면 해결한다.
하지만 개발자가 직접 코드를 병합하고 빌드, 테스트를 검증하는 것은 시간이 많이 소요될 뿐만 아니라 귀찮고 그 양도 프로젝트의 크기가 커질수록 많아질 수밖에 없다.
이를 자동화하면 개발자가 빌드와 테스트를 직접 하지 않고도 수정한 코드를 브랜치에 병합하기만 하면 자동으로 빌드와 테스트를 검증할 수 있다.
개발자가 단위별로 구현한 부분을 병합할 때마다 자동화된 빌드와 테스트가 트리거되어 실행된다. 결과를 통해 우리는 어떤 부분에서 문제가 있는지 배포 전에 확인할 수 있고, 배포가 완성된 후에야 버그를 수정할 수 있던 기존의 문제를 빠르고 정확하게 해결할 수 있다.
결과적으로 버그를 신속하게 찾아 해결할 수 있을 뿐 아니라, 소프트웨어 품질을 개선하고 새로운 소프트웨어 업데이트를 검증하고 릴리즈하는데에 걸리는 시간을 단축할 수도 있다.
요약하자면 CI의 간단한 순서는 아래와 같다.
개발자가 구현한 코드를 기존 코드와 병합한다.
병합된 코드가 올바르게 동작하고 빌드되는지 검증한다.
테스트 결과 문제가 있다면 수정하고 다시 1로 돌아간다. 문제가 없다면 배포를 진행한다.
이제 지속적 통합을 거친 코드에 대해서 신뢰할 수 있고 바로 배포할 수 있다.
CD는 지속적 배포로 소프트웨어가 항상 신뢰 가능한 수준에서 배포될 수 있도록 관리하자는 개념으로 지속적 제공(Continuous Delivery)로 사용되기도 한다.
지속적 제공은 CI를 통해서 새로운 소스코드의 빌드와 테스트 병합까지 성공적으로 진행되었다면, 빌드와 테스트를 거쳐 github과 같은 저장소에 업로드하는 것을 의미한다.
지속적 배포는 이렇게 성공적으로 병합된 내역을 저장소뿐만 아니라 사용자가 사용할 수 있는 배포환경까지 릴리즈하는 것을 의미한다.
지속적 배포에서는 지속적 통합을 통해 빌드한 소스코드를 테스트 가능한 알파나 베타 버전으로 만든다. 이 버전에서 테스트를 수행해 문제가 발생하면 수정한 뒤 정식 버전으로 배포를 진행한다.
대표적인 CI/CD의 방법으로는 Travis와 Jenkins가 있다.