-
CI(Continuous Integration)/CD(Continuous Deployment)란?
- CI/CD는 애플리케이션 개발 단계를 자동화하여 애플리케이션을 보다 짧은 주기로 고객에게 제공하는 방법이다. CI/CD의 기본 개념은 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포이다. CI/CD는 새로운 코드 통합으로 인해 개발 및 운영팀에 발생하는 문제(일명 "인테그레이션 헬(integration hell)")을 해결하기 위한 솔루션이다.
- 특히, CI/CD는 애플리케이션의 통합 및 테스트 단계에서부터 제공 및 배포에 이르는 애플리케이션의 라이프사이클 전체에 걸쳐 지속적인 자동화와 지속적인 모니터링을 제공한다. 이로써 개발자는 코드 작성에만 집중할 수 있게 된다.
CI(Continuous Integration)란?
- 개발자를 위한 자동화 프로세스인 지속적인 통합을 의미한다.
- CI(Continuous Integeration) - wiki
소프트웨어 개발에서 각 소프트웨어 개발자가 작업한 변경점을 프로젝트의 원래 소스 코드에 자주, 빠르게 통합하는 것이다.
개발자들이 저장소에 코드를 제출하려면, 먼저 자신이 코드를 받았던 때부터 현재까지 저장소 코드의 변경 내용을 자신의 코드에 반영되도록 자신의 코드를 업데이트한 후 자신의 코드를 제출해야 한다. 저장소에 변경된 내용이 많을수록, 개발자들이 자신의 작업 내용을 제출하기 전에 해야 할 일이 많아진다. 언젠가는 저장소가 개발자들의 베이스라인과는 너무 많이 달라지게 되는 "통합의 지옥" 이라 불리는 상황에 빠지게 된다. 이 경우, 작업하는 시간보다 작업 내용을 통합하는데 걸리는 시간이 더 걸리게 되어, 최악의 경우 개발자들이 자신들의 변경 내용들을 취소하고 작업들을 완전히 처음부터 다시하는 것이 나을 수도 있다.
지속적인 통합은 초기에 그리고 자주 통합해서 "통합의 지옥"의 함정을 피하는 것을 내포하고 있다. 지속적인 통합은 재작업을 줄여서 비용과 시간을 줄이는데 초점이 맞추어져 있다.- CI를 성공적으로 구현할 경우 애플리케이션에 대한 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 리포지토리에 통합되므로 여러 명의 개발자가 동시에 애플리케이션 개발과 관련된 코드 작업을 할 경우 서로 충돌할 수 있는 문제를 해결할 수 있습니다.
CD(Continuous Deployment)란?
- 지속적인 서비스 제공(Continuous Delivery) 및/또는 지속적인 배포(Continuous Deployment)를 의미한다.
- 소프트웨어가 항상 신뢰 가능한 수준에서 배포될 수 있도록 지속적으로 관리하자는 개념으로, CI의 연장선으로 생각할 수 있다. 배포 이전에 테스트와 빌드는 필수이기 때문에, 사실상 CD가 되려면 항상 CI가 선행되어야 한다고 볼 수 있다.
- 즉, CI 프로세스를 통해 개발중에 지속적으로 빌드와 테스트를 진행하고, 이를 통과한 코드에 대하여 테스트서버와 운영서버에 곧바로 그 내용을 배포하는 것을 의미한다.
참고 : https://www.redhat.com/ko/topics/devops/what-is-ci-cd , 빌드와배포
Jenkins
- 소프트웨어 개발 시 지속적으로 통합 서비스를 제공하는 CI Tool이다.
- 빌드 프로세스를 관리하는 서버
- 정기적인 빌드에서 나아가, 버전 관리 시스템과 연동하여 commit을 감지하면 자동으로 자동화 테스트가 포함된 빌드가 작동되도록 할 수 있다.
- 기능
- 대쉬보드 제공 - 여러가지 배포 작업 상황을 모니터링 할 수 있다.
- 프로파일링(실행된 프로그램의 실행 상태나 커널과의 통신 상태 등에 관해서 해석하는 것) 툴을 이용한 소스 변경에 따른 성능 변화 감시
- 커밋 소스 자동 빌드(Maven, Gradle 방식)
- 자동화 테스트 수행
- 코드 표준 준수 여부의 검사 또는 정적 분석을 통한 코드 품질 검사를 빌드 내부에서 수행
- 빌드/테스트 완료된 파일 배포
Checkstyle
- 코딩컨벤션 검사 도구이다.
- 자바 소스코드의 코딩 규칙에 대한 위반사항을 분석하는 오픈소스 도구이다.
- xml파일을 사용하여 규칙을 작성(코딩 컨벤션의 Checkstyle 사용법 참고)
- 참고
더보기<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<configLocation>checkstyle-rules.xml</configLocation>
<sourceDirectories>
<sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
</sourceDirectories>
<propertyExpansion>config_loc=${basedir}</propertyExpansion>
</configuration>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>8.24</version>
</dependency>
</dependencies>
</plugin>Code Coverage
- 소프트웨어 테스트를 할 때 얼마나 테스트가 충분하지 나타내는 지표 중 하나이다.
- 테스트 케이스가 커버하는 코드의 양을 백분율로 나타낸 값이다.
더보기<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>- 코드 커버리지 기준
- 구문(Statement Coverage) : 코드 한 줄이 한번 이상 실행된다면 충족된다.
더보기int coverage (int n1, int n2) {
int result = 0;
if ((n1 > 0) && (n2 > 0)) {
result = n1 + n2;
}
return result;
}
coverage(2,5)을 호출하면 조건이 만족하므로 result=n1+n2;가 실행되서 모든 Line을 실행하게 된다. 따라서 테스트 coverage(2,5)는 Statement Coverage에 만족한다고 할 수 있다. 그러나 coverage(0,5)는 조건을 만족하지 못하기 때문에 Statement Coverage에 만족한다고 할 수 없다.
- 결정(Decision Coverage) : 전체적인 결과가 참/거짓이면 충족된다.
더보기int coverage (int n1, int n2) {
int result = 0;
if ((n1 > 0) && (n2 > 0)) {
result = n1 + n2;
}
return result;
}
coverage(2,5), coverage(0,5)은 Decision Coverage에 만족한다.
coverage(2,5)은 조건을 만족해 result=n1+n2;가 실행된다(if문의 전체 결과가 참).
하지만 두번 째 coverage(0,5)은 n1>0이라는 조건을 만족하지 않기 때문에 result=n1+n2가 실행되지 않는다(if문의 전체 결과가 거짓).
- 조건(Condition Coverage) : 각 내부 조건이 참/거짓을 가지게 되면 충족한다.
더보기int coverage (int n1, int n2) {
int result = 0;
if ((n1 > 0) && (n2 > 0)) {
result = n1 + n2;
}
return result;
}
coverage(1,0)과coverage(0,1)는 Condition Coverage에 만족한다.
n1>0에서 coverage(1,0)은 True이지만 coverage(0,1)은 False이다. 반대로 n2>0에서 coverage(1,0)은 False이지만 coverage(0,1)은 True이다.
- 참고
정적분석
- 코딩 규칙에 입각하며 버그를 줄여 코드의 품질을 향상시킬 수 있는 자동화된 분석
- 프로그램 코드를 실행하지 않은 상태에서 코드 분석을 통해서 문제가 있는 소스코드를 찾는 컴퓨터 프로그램 디버깅의 방법이다.
더보기<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.1.3</version>
<dependencies>
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs</artifactId>
<version>4.2.0</version>
</dependency>
</dependencies>
</plugin>