현대 오토에버 SW 스쿨 - 클라우드/버전관리_Jenkins
[Jenkins] - 프로젝트와 jenkins 연결
yongyongMom
2024. 11. 11. 17:49
SMALL
1. 프로젝트와 Jenkins 연결 - git hub
1) Spring Boot Project 생성
2) git hub 에 repository 만들어서 연결
3) Jenkins Server 에서 Code Checkout ( 코드를 다운로드 받아오는 것)
- 하나는 직접 스크립트를 작성해야 받아올 수 있고 다른 하나는 git 과 연결해서 코드를 받아올 수 있음
- Item 을 Pipeline 으로 생성하고 Script 부분에서 SCM 으로 수정하고 repository 를 설정
- 프로젝트에 Jenkinsfile 을 추가하고 빌드
2. 단위 테스트
class 만 있으면 가능함
1) 테스트 전에 컴파일이나 빌드가 먼저
- 컴파일 :: 운영체제나 VM 이 인식할 수 있는 코드 생성 - 테스트하기 위해서 수행 (java -> class :: 문법 테스트만)
- 빌드 : 실행 가능한 코드를 생성 - 배포하기 전에 수행, 운영체제에 맞는 startup 코드를 추가
- java -> class (유닛테스트) -> binary file (통합테스트)
- 단위 테스트를 수행하기 위한 코드를 추가
public class JenkinsService { public int hap(int n){ int result = 0; for(int i=1; i<=n; i++){ result += i; } return result; } }
- 스크립트 파일에 추가 : 에러가 발생하면 문법 에러 OR 접근 권한에 관련된 에러
- 윈도우즈는 읽기와 쓰기 권한만 부여
- MAC 과 LINUX 는 실행권한이 별도로 주어짐
- 윈도우즈에서 작성할 실행 파일은 MAC 이나 LINUX 에서 가져가서 실행하고자 하면 실행권한 오류 발생
pipeline{ agent any stages{ stage("Permission"){ steps{ sh "chmod +x ./gradlew" } } stage("Compile"){ steps{ sh "./gradlew compileJava" } } } }
2) 단위 테스트
- 단위 테스트를 위한 코드를 작성 : test 디렉터리의 패키지에 클래스를 생성
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class Jenkins1111Test {
//테스트할 메서드를 가진 클래스를 가져오기
private JenkinsService service = new JenkinsService();
@Test
public void testService(){
assertEquals(55, service.hap(10));
}
}
- 테스트 수행 : ./gradlew test
- 스크립트에 스테이지 추가
stage("Unit Test"){
steps{
sh "./gradlew test"
}
}
3) Code Coverage
- 개요
- 코드 전체를 대상으로 테스트를 진행하고 검증이 완료된 부분을 식별하는 작업
- 일정 부분 테스트를 진행하지 않은 경우 빌드를 중단
- build.gradle 파일에 의존성을 설정하고 기본 설정을 추가
- 20% 이상 코드를 테스트하지 않은 경우 빌드 실패
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.5'
id 'io.spring.dependency-management' version '1.1.6'
id 'jacoco'
}
jacocoTestCoverageVerification{
violationRules{
rule{
limit{
minimum = 0.2
}
}
}
- 수행
./gradlew test jacoco TestCoverageVerification
- 보고서 생성 (build/reports 디렉터리에 생성)
./gradlew test jacoco TestReport
- 스테이지에 추가
stage("Code Coverage"){
steps{
sh "./gradlew jacocoTestCoverageVerification"
sh "./gradlew jacocoTestReport"
publishHTML(target: [
reportDir: 'build/reports/jacoco/test/html',
reportFiles: 'index.html',
reportName: 'Jacoco Report'
])
}
- HTML Publisher 플러그인을 설치하고 수행
- 성공 -> 프로젝트 이름 누름 -> HTML 링크가 보임
4) 정적 코드 분석
- 개요
- 컴파일이나 실행과는 관련없는 코드를 작성할 때 서로 간에 암묵적으로 정한 규칙을 확인하는 작업
- Checkstyle 인 Sonarqube 를 많이 이용
- Checkstyle 을 이용한 정적 코드 분석
- build.gradle 파일에 의존성 라이브러리와 기본 환경 코드를 추가
plugins { id 'java' id 'org.springframework.boot' version '3.3.5' id 'io.spring.dependency-management' version '1.1.6' id 'jacoco' id 'checkstyle' } checkstyle { maxWarnings = 0 configFile = file("${rootDir}/config/checkstyle.xml") configProperties = ["suppressionFile":"${rootDir}/config/checkstyle-suppressions.xml"] toolVersion = "8.42" }
- 루트 디렉터리에 config 디렉터리를 생성하고 checkstyle.xml 파일을 만들어서 작성:
https://checkstyle.sourceforge.io/config.html 에서 파일을 다운로드 받아서 참고해서 작성<?xml version="1.0" ?> <!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"> <module name="Checker"> <module name="TreeWalker"> <module name="ConstantName" /> </module> </module>
- 실행 : ./gradlew checkstyleMain
- 스테이지에 추가
stage("Static Code Analysis"){ steps{ sh "./gradlew checkstyleMain" publishHTML(target: [ reportDir: 'build/reports/checkstyle/', reportFiles: 'main.html', reportName: 'Checkstyle Report' ]) } }
- checkstyle 보다 sonarqube 가 더 많이 사용되므로 sonarqube 로 사용을 해보는 것이 좋음
3. 트리거
1) 주기적인 수행
- 스케줄 작성 방법은 Linux 와 Crontab 과 동일
- Build periodically: commit 여부에 상관없이 무조건 빌드를 다시 수행
- Poll SCM : 변경 사항이 있을 때만 빌드를 다시 수행
2) 외부에서 Code Repository 에 이벤트가 발생했을 때 수행
- git hub 에서 token 을 발급
- 레포지토리에 대한 권한과 workflow 에 대한 권한은 반드시 설정
- git hub 의 레포지토리에서 web-hook 을 등록
- payload-url 설정 : http://jenkins URL/github-webhook
- jenkins server 에서 credential 을 생성
- Dash board 메뉴에서 configure credential 을 선택 -> global 부분 클릭해서 생성
- kind 부분을 secret text 로 수정 -> password 부분에 토큰 값을 대입
- jenkins item 에서 구성 부분을 클릭해서 액션을 수정
- GitHub hook trigger for GITScm polling 에 체크
3) 빌드 자동화
- 주기적인 자동화
- 빌드한느데 시간이 오래 걸리는데 push 가 자주 발생하는 경우
- push event 가 발생했을 때 빌드 : 빌드하는데 시간이 짧게 걸리는 경우
4. 이미지 빌드 및 업로드
1) 코드를 수정
- Service 클래스를 수정
import org.springframework.stereotype.Service;
@Service
public class JenkinsService {
public int hap(int n){
int result = 0;
for(int i=1; i<=n; i++){
result += i;
}
return result;
}
}
- Controller 클래스를 추가
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class JenkinsController {
private final JenkinsService jenkinsService;
@RequestMapping("/")
public String index(@RequestParam("data") int data) {
return String.valueOf(jenkinsService.hap(data));
}
}
2) 실행하고 테스트
- http://localhost:8080?data=10
3) gradle 프로젝트 빌드
- 빌드는 실행 가능한 상태로 만들어주는 작업
- 빌드 도구에 따라 빌드하는 명령어는 다름
- gradle 의 경우 : ./gradlew clean build
- maven 의 경우 : ./mvnw clean build
- 빌드 결과는 build 라는 디렉터리에 저장
- 실행할 애플리케이션이 build 디렉터리에 존재
4) 이미지 빌드
- Dockerfile 을 프로젝트 디렉터리에 생성하고 작성
FROM bellsoft/liberica-openjdk-alpine:17
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
- 이미지 빌드
docker build -t 이미지이름 .
5) 빌드 내용을 stage 에 추가
- Gradel Build: Jenkinsfile 에 추가하고 push
stage("Gradle Build"){
steps{
sh "./gradlew clean build"
}
}
- Docker Image Build
stage("Docker Image Build"){
steps{
sh "docker build -t jenkins1111 ."
}
}
- Docker Image Build 단계에서 실패하면 Jenkins 에서 Docker 를 사용할 떄는 Docke pulugin 을 설치해야 함
6) 컨테이너로 생성해서 테스트 진행
- 컨테이너 생성
docker run -d --name 컨테이너이름 -p 외부포트번호:내부포트번호 이미지이름
- 확인
curl http://locahost:외부포트번호?data=정수
7) 도커 허브에 push
- 도커 허브에 레포지토리를 생성
- 도커 허브의 레포지토리에 업로드 할 수 있게 도커 이미지 태그를 변경
docker tage 이미지이름 tpdms0159/jenkins1111:latest
- 도커 푸시
docker push 이미지이름
8) jenkins 에서 도커 허브에 푸시
- credential 추가
- 변수를 추가하는 stage 추가
stage("Set Variables"){
steps{
echo "SetVariables"
script{
DOCKER_HUB_URL = 'registry.hub.docker.com'
DOCKER_HUB_FULL_URL = 'https://' + DOCKER_HUB_URL
DOCKER_HUB_CREDENTIAL_ID = 'docker-hub'
}
}
}
- GIT 과 외부 계정을 이용할 때 토큰 값을 코드에 직접 입력하면 GIT 또는 외부 계정이 잠김
- 직접 입력한 코드를 삭제하더라도 기록이 남아서 계정은 잠김
반응형
LIST