시작하기 전에
도입하게 된 계기
현재 나는 부동산 정보를 게시 웹 서비스를 운영하는 부서에서 근무하고 있다. 과거부터 현재까지 집적된 수없이 많은 부동산 정보를 게시하고 있기 때문에, 부동산 회사나 건물 관리 회사 등으로부터 정보 수정 요청이 다양하게 들어온다. 이러한 정보 수정 요청들은 고객 대응 부서에서 사용하는 사내 툴에 접수되는데, 이 사내 툴 프로젝트를 운영하고 유지 보수하는 것도 당연히 내가 소속된 부서에서 담당하고 있다.
일부 소수 유저만 사용하는 사내 툴이기 때문에, 기능 추가나 소스 코드 변경도 자주 없다. 그렇기 때문에 프로젝트에 Linter Check 나 Unit test, 자동 배포 등은 전혀 도입되어 있지 않았다. 하지만, 장기적인 개발 생산성의 향상을 위해 CI/CD 도입이 필요했고, 우선적으로 CI를 전담하여 도입하게 되었다.
그래서 CI 가 뭐지?
Google 검색창을 열고, CI/CD란 키워드로 검색을 해보면 정말 다양한 결과가 나온다. Jenkins, Docker, Github, 애자일 등등... 그 중에서도 CI 는
Continuous integration
(지속적인 통합)
라는 뜻이라고 한다. 대부분의 소프트웨어 개발은 여러 사람이 모여 팀 단위로 협업을 하기 때문에, 각자 담당 부분을 나누어 소스 코드를 수정하고 개발한다. 또한, 최근 개발 방법론이 Waterfall 에서 Agile Methodology 로 변화하면서, 이러한 소스 코드의 수정은 빈번하고 자주 일어나게 된다. 이렇게 여러 사람의 손을 통해 수정된 소스 코드들을 정기적으로 통합하는 것을 CI 라고 한다.
왜 CI 가 필요하가?
개발 또는 협업을 조금이라도 해본 개발자라면 Git 같은 형상 관리 시스템 (SCM, Source Code Management) 을 사용해 본 경험이 있을 것이다. 그리고 이러한 형상 관리 시스템을 잘 사용한다면, 여러 사람이 수정한 소스 코드를 병합(Merge) 하고, 테스트(Test) 와 배포(Deploy) 도 어렵지 않게 진행할 수 있을 것 이다.
하지만 프로젝트 규모가 커지고 시스템 구조가 복잡해지다 보면, 예상치 못한 곳에서 장애가 발생하게 되고, 이를 수정하기 위해 여러번의 수정을 급하게 하다 보면, 수 없이 많은 Conflict 와 "내 로컬에서는 잘 되는데...?" 와 같은 상황에 마주하게 될 것이다. 이런 상황이 점차 반복되면, 소스 코드의 품질 관리가 제대로 되지 않아 개발 생산성이 현저하게 저하된다.
그리고, 어찌저찌 테스트를 완료해 LIVE 서버에 서비스를 배포하여 운영하게 되더라도 빈번하게 장애가 발생할 수 있다. 이럴 때 프로젝트에 CI를 도입한다면, 새롭게 Commit 된 코드에 대한 품질 관리와 테스트를 손쉽고 간편하게 수행할 수 있다.
CI 의 도입
무엇을 도입할 것인가?
CI 의 지속적인 통합을 실현하기 위해서는 반드시 필요한 기능이 크게 2가지가 있다.
- Code Inspection (소스코드를 분석하여, 개발 표준에 위배되었거나 잘못 작성된 부분을 수정)
- Testing (Unit Test, E2E Test, Integration Test 등등...)
그리고, 이 2가지는 모두 자동으로 검사되고 실행되어야 한다. 각 언어 또는 시스템에 따라 정말 다양한 Tool 이 존재하지만, 최신의 좋은 기능을 가진 Tool 을 무조건 도입하기는 것 보다는 각 프로젝트의 특성에 알맞게 도입하는 것이 중요하다고 생각했다. 그래서 나는 먼저 사내 툴 프로젝트의 tech stack 을 조사했다.
도입할 CI Tools 을 결정
사내 툴은 크게 Laravel Mix 로 구성되어 있었고, 상세 tech stack 은 아래와 같았다.
- Front End
- JavaScript
- Node.js : v8.17.0
- Vue.js : v2.5.17
- Back End
- PHP : v7.2.34
- Composer : v1.7.1
- Laravel : v5.5.42
그 외에 기타 특이한 사항들은 없었지만 각각 언어별 또는 프레임워크 별 버전들이 꽤 오래되었기 때문에, 도입 전 조사를 진행하면서도 의존성 문제 때문에 꽤나 골치아플 것 같다는 생각을 많이 했다. 그렇기 때문에 우선 아래와 같은 순서로 도입을 진행하기로 결정했다.
- Code Inspection 을 위한 언어별 Linter
- 각 언어별 Unit Test
- Github Actions 를 통한 Linter, Unit Test