새로운 기능의 개발 속도에 대한 증가하는 요구를 충족시키기 위해서는 더 빠르게 구현되어야 합니다. 하지만 이는 동전의 한 면일 뿐입니다. 이러한 모든 기능을 프로덕션에 투입해야 합니다. 배포는 종종 수동으로 수행되므로 오류가 발생하기 쉽고 리소스가 정체되며 시간이 오래 걸릴 수 있습니다. 완벽한 솔루션이 제공됩니다 오토메이션 on – 지속적 전달이라고 합니다. 때때로 또한 사이 지속적 전달 그리고 지속적인 배포 그러나 이것은 기사의 핵심에 중요하지 않은 다면적인 논쟁입니다.
지속적인 전달은 아티팩트 유형에 따라 다른 의미를 가질 수 있으며 이를 달성하기 위해 유사하게 다른 도구를 사용할 수 있습니다. Jenkins Pipelines의 장점은 매우 간단하고 모듈식으로 구현된다는 것입니다. 이 기사에서는 몇 줄의 Groovy 코드로 Nexus 리포지토리에 Java 아티팩트를 지속적으로 제공하는 방법을 보여주기 위해 두 가지 실용적인 예제를 사용합니다.
- 첫 번째 예는 오픈 소스 Java 라이브러리는 먼저 Jenkins GitHub 리포지토리에 푸시될 때 빌드되고 테스트된 다음 SonarCloud로 분석되고 Maven Central에 배포됩니다(그림 1 참조).
- 두 번째 예는 엔터프라이즈 컨텍스트에서 제공되며 SCM Manager의 Git 리포지토리로 푸시될 때 Cloudogu EcoSystem을 사용하여 Jenkins에서 Java 웹 애플리케이션을 자동으로 빌드 및 테스트하고 SonarQube에서 분석한 후 최종적으로 프라이빗 Nexus 리포지토리에 배포하는 방법을 보여줍니다(그림 참조). 2).
예제의 인프라는 다르지만 두 경우 모두 Jenkins 관로사용할 코드.
(PlantUML 원본 다이어그램)
Maven Central에 지속적 전달
다음에서는 오픈 소스 Java 라이브러리를 예로 사용하여 Maven Central에 따라 지속적 전달을 구현하는 방법을 보여줍니다. 완성된 지속적 전달 파이프라인(빌드, 단위 및 통합 테스트, 정적 코드 분석 및 배포 포함)은 Jenkins 파이프라인 Groovy DSL(스크립트 구문)의 100줄 미만으로 Jenkins 파일에서 구현할 수 있습니다. 목록 1은 명령 버스 라이브러리의 Jenkinsfile을 기반으로 하는 예제를 보여줍니다. 명확성을 위해 이 기사에서는 다소 축약되었습니다.
@Library('github.com/cloudogu/[email protected]')
import com.cloudogu.ces.cesbuildlib.*
node {
Maven mvn = new MavenWrapper(this)
catchError {
stage('Checkout') {
checkout scm
}
initMaven(mvn)
stage('Build') {
mvn 'clean install -DskipTests'
}
stage('Unit Test') {
mvn 'test'
}
stage('Integration Test') {
mvn 'verify -DskipUnitTests'
}
stage('Static Code Analysis') {
def sonarQube = new SonarCloud(this, [sonarQubeEnv: 'sonarcloud.io-cloudogu'])
sonarQube.analyzeWith(mvn)
if (!sonarQube.waitForQualityGateWebhookToBeCalled()) {
currentBuild.result ='UNSTABLE'
}
}
stage('Deploy') {
if (preconditionsForDeploymentFulfilled()) {
mvn.useDeploymentRepository([id: 'ossrh', url: 'https://oss.sonatype.org/',
credentialsId: 'mavenCentral-acccessToken', type: 'Nexus2'])
mvn.setSignatureCredentials('mavenCentral-secretKey-asc-file', 'mavenCentral-secretKey-Passphrase')
mvn.deployToNexusRepositoryWithStaging()
}
}
}
junit allowEmptyResults: true, testResults: '**/target/surefire-reports/TEST-*.xml, **/target/failsafe-reports/*.xml'
mailIfStatusChanged(new Git(this).commitAuthorEmail)
}
boolean preconditionsForDeploymentFulfilled() {
if (isBuildSuccessful() &&
!isPullRequest() &&
shouldBranchBeDeployed()) {
return true
} else {
echo "Skipping deployment because of branch or build result: currentResult=${currentBuild.currentResult}, " +
"result=${currentBuild.result}, branch=${env.BRANCH_NAME}."
return false
}
}
private boolean shouldBranchBeDeployed() {
return env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'develop'
}
private boolean isBuildSuccessful() {
currentBuild.currentResult == 'SUCCESS' &&
// Build result == SUCCESS seems not to set be during pipeline execution.
(currentBuild.result == null || currentBuild.result == 'SUCCESS')
}
void initMaven(Maven mvn) {
if ("master".equals(env.BRANCH_NAME)) {
echo "Building master branch"
mvn.additionalArgs = "-DperformRelease"
currentBuild.description = mvn.getVersion()
}
}
목록 1
Jenkins 파일에는 5개의 소위 단계가 포함되어 있습니다.
- Checkout – Git 리포지토리에서 코드를 가져옵니다.
- 빌드, 단위 테스트 및 통합 테스트 – Maven을 사용하여 코드를 빌드하고 이에 대한 단위 및 통합 테스트를 실행합니다.
- 정적 코드 분석 – SonarQube(여기서는 퍼블릭 인스턴스 SonarCloud)의 도움으로 정적 코드 분석을 실행하고 정의된 품질 목표에 대해 기록된 메트릭을 확인합니다.
- 배포 – 오류가 발생하지 않은 경우 Nexus Repository(여기서는 Sonatype에서 공개적으로 제공하는 “Maven Central” 인스턴스)에 아티팩트를 배포합니다.
Jenkins 공유 라이브러리 ces-build-lib는 파이프라인에서 사용됩니다. 여기에는 Maven(Nexus 리포지토리 포함), Git 및 SonarQube용 재사용 가능한 빌딩 블록이 포함되어 있습니다. Jenkins 공유 라이브러리를 사용하면 일반 애플리케이션 개발에서 라이브러리를 통합할 때와 동일한 이점을 얻을 수 있습니다. 특히 ces-build-lib는 Maven Central에 배포할 때 서명 및 스테이징을 처리하고 SonarCloud를 통해 풀 요청에 대한 주석을 시작하므로 대부분의 복잡성을 처리합니다.
모든 브랜치(기능 브랜치 및 풀 리퀘스트 포함)는 자동화된 품질 관리를 거치지만 배포는 보다 안정적인 브랜치 마스터 및 개발(Git Flow 기반)로 제한됩니다. 푸시에 의해 배포가 트리거됩니다.
제시된 파이프라인이 Jenkins에서 실행되기 위해서는 Jenkins에 다음이 존재해야 합니다.
- “파이프라인: GitHub Groovy 라이브러리” 플러그인. GitHub에서 즉시 공유 라이브러리를 로드합니다.
- ID가 sonarcloud.io-cloudogu인 구성된 SonarQube 인스턴스와 URL, 인증 토큰 및 SonarCloud에 대해 구성된 조직. Jenkins가 SonarQube에서 비동기식으로 계산한 Quality Gate Status를 알기 위해서는 /sonarqube-webhook/ 아래 Jenkins 인스턴스의 SonarCloud에 webhook을 생성해야 합니다. SonarCloud도 GitHub 문제에 대해 의견을 제시하려면 GitHub용 SonarCloud 애플리케이션이 GitHub 조직에 설치되어 있어야 합니다.
- 비밀 텍스트 자격 증명 mavenCentral-accessToken으로 oss.sonatype.org에 대한 사용자 액세스 토큰(Central Staging Repository에서 Maven Central로 릴리스).
- ASC 파일의 개인 키(비밀 파일 자격 증명 mavenCentral-secretKey-asc-file). 이는 Maven Central의 아티팩트에 서명하는 데 사용됩니다.
- 개인 키의 암호(Secret Text Credential mavenCentral-secretKey 암호). 자세한 내용은 Maven Central 설명서를 참조하십시오.
예제는 이 Jenkins 서버에서 실제로 볼 수 있습니다.
온프레미스 Nexus 리포지토리에 지속적으로 제공
(OkabtUML 원본 다이어그램)
오픈 소스 라이브러리와 동일한 워크플로를 자체 인프라의 엔터프라이즈 환경에서도 사용할 수 있습니다. 그림 2는 GitHub 대신 SCM Manager, Maven Central 대신 자체 Nexus Repository, SonarCloud 대신 SonarQube 등 가능한 도구 선택을 보여줍니다. 다음을 통해 이러한 도구와 더 많은 도구를 얻을 수 있습니다. Cloudogu 생태계 버튼을 누르면 완전히 자동으로 사전 구성되고 싱글 사인온이 제공됩니다.
이 환경에서는 첫 번째 예제와 거의 동일한 Jenkins 파이프라인을 사용할 수 있습니다. 이것은 두 번째 예제 cloudogu/spring-petclinic의 Jenkins 파일에 표시됩니다(목록 2 참조). 이것은 Jenkins 파일을 사용하여 지속적인 제공을 포함하도록 확장된 Java 웹 애플리케이션의 대표적인 예입니다.
@Library('github.com/cloudogu/[email protected]')
import com.cloudogu.ces.cesbuildlib.*
properties([
disableConcurrentBuilds()
])
node {
String cesFqdn = findHostName()
String cesUrl = "https://${cesFqdn}"
Maven mvn = new MavenWrapper(this)
catchError {
stage('Checkout') {
checkout scm
}
stage('Build') {
mvn 'clean package -DskipTests'
}
String jacoco = "org.jacoco:jacoco-maven-plugin:0.8.1"
parallel(
test: {
stage('Unit Test') {
mvn "${jacoco}:prepare-agent test ${jacoco}:report"
}
},
integrationTest: {
stage('Integration Test') {
mvn "${jacoco}:prepare-agent-integration failsafe:integration-test failsafe:verify ${jacoco}:report-integration"
}
}
)
stage('Static Code Analysis') {
def sonarQube = new SonarQube(this, [usernamePassword: 'jenkins-sonar', sonarHostUrl: "${cesUrl}/sonar"])
sonarQube.analyzeWith(mvn)
}
stage('Deploy') {
mvn.useDeploymentRepository([id: cesFqdn, url: "${cesUrl}/nexus", credentialsId: 'jenkins-nexus', type: 'Nexus3'])
mvn.deployToNexusRepository()
}
}
junit allowEmptyResults: true, testResults: '**/target/failsafe-reports/TEST-*.xml,**/target/surefire-reports/TEST-*.xml'
}
목록 2
모든 프로젝트가 다르므로 파이프라인에도 약간의 차이가 있습니다. 첫 번째 예와 비교하여 다음과 같은 관련 차이점이 있습니다.
- 여기서 SonarQube 및 Nexus에 대한 URL은 Jenkins에 상대적입니다(Cloudogu EcoSystem 덕분에 유지 관리가 더 쉽습니다).
- 더 빠른 피드백을 위해 단위 및 통합 테스트가 동시에 실행됩니다.
- Maven Central과 달리 배포 단계에서는 스테이징 리포지토리를 사용하지 않습니다.
일반적으로 이 예제는 조금 더 간단하므로 Jenkins는 파이프라인을 실행하는 데 덜 필요합니다.
- “파이프라인: GitHub Groovy Libraries” 플러그인은 첫 번째 예와 같이,
- 암호 자격 증명이 있는 사용자 이름 jenkins-sonar, SonarQube의 기술 사용자 및
- 암호 자격 증명이 있는 사용자 이름 jenkins-nexus를 Nexus의 기술 사용자에게 전달합니다.
Cloudogu 생태계
Cloudogu 생태계의 장점을 확신하십시오. 사용 이젠 공짜 최신 DevOps 플랫폼.
플랫폼으로
결론
이 문서는 Nexus 리포지토리에 Java 아티팩트를 얼마나 쉽게 지속적으로 전달할 수 있는지 보여줍니다. 원하는 도구는 오픈 소스 및 엔터프라이즈와 같은 다양한 응용 프로그램에서 사용할 수 있습니다. 물론 #DevSecOps 와 같이 Sonatype Lifecycle 또는 부하 테스트를 통한 취약점 분석을 통해 품질 보증을 확장할 수도 있습니다. 특정 도구 선택에 관계없이 Jenkins 파이프라인은 우아하고 명확한 방식으로 지속적인 제공을 가능하게 합니다.