Ich habe eine Jenkins-Datei an CI, eine Gradle Java-App mit Jenkins, geschrieben. Wenn ich es an Github weitergebe, wird der Jenkins-Pipeline-Job in AWS ausgeführt. Wenn der Test erfolgreich ist, verwende ich ihn wie die Bereitstellung in Tomcat unter AWS.
Declarative Pipeline Wie es ist, Jenkinsfile
node {
....
}
Es wurde geschrieben als, aber wenn Sie sich [Jenkins offizielle Website] ansehen (https://jenkins.io/doc/book/pipeline/syntax/) Dies ist die Scripted Pipelines-Notation. Ab Version 2.5 Migration des Pipeline Plugins
pipeline {
....
}
Eine Notation namens Declarative Pipeline wurde eingeführt, um wie zu schreiben Es war einfacher und leichter zu schreiben, also habe ich es umgeschrieben. Es ist auf jeden Fall ordentlich (vor allem die letzte E-Mail, Bereitstellung), Es ist schön, im Notfall traditionelle Scripted Pipelines mischen zu können.
Jenkins Zum Zeitpunkt der Ersteinrichtung nicht im empfohlenen Plugin enthalten
Jenkinsfile
Führen Sie einen Jenkins-Pipeline-Job mit einem Webhook von Github aus.
Verwenden Sie für Pipeline-Jobs Jenkinsfile von Github.
Der Auftragsablauf ist wie folgt. Bereitstellung nur, wenn die Analyse und das Testen des statischen Codes erfolgreich sind.
Jenkinsfile
pipeline {
agent any
//Definieren Sie Konstanten und Variablen
environment {
reportDir = 'build/reports'
javaDir = 'src/main/java'
resourcesDir = 'src/main/resources'
testReportDir = 'build/test-results/test'
jacocoReportDir = 'build/jacoco'
javadocDir = 'build/docs/javadoc'
libsDir = 'build/libs'
appName = 'SampleApp'
appVersion = '1.0.0'
}
//Definieren Sie eine oder mehrere Stufen im Stufenblock
stages {
stage('Vorbereitungen') {
//Die eigentliche Verarbeitung wird im Schrittblock definiert
steps {
deleteDir()
//Schauen Sie sich das Github-Projekt an, das diesen Job ausgelöst hat
checkout scm
//Jenkinsfile und Build zur Untersuchung der Ursache von Jobfehlern.Gradle zuerst speichern
archiveArtifacts "Jenkinsfile"
archiveArtifacts "build.gradle"
//Sie können auch die traditionelle Skript-Pipelines-Notation mit dem Skriptblock verwenden
script {
//Erteilen Sie die Ausführungsberechtigung, damit Sie sich nicht über die verweigerte Berechtigung ärgern
if(isUnix()) {
sh 'chmod +x gradlew'
}
}
gradlew 'clean'
}
}
stage('kompilieren') {
steps {
gradlew 'classes testClasses'
}
//Der Nachblock kann den Prozess definieren, der nach dem Schrittblock ausgeführt werden soll
post {
//Der Always-Block wird immer ausgeführt, unabhängig davon, ob die Blockverarbeitung der Schritte fehlschlägt oder erfolgreich ist.
always {
//Wenn Sie es ausführen, wenn JavaDoc generiert wird, wird auch eine JavaDoc-Warnung eingefügt.
//Java-Kompilierungswarnungen werden unmittelbar nach dem Kompilieren gesammelt
step([
//Die Klassenspezifikation beim Ausführen des Plug-Ins muss kein vollständig qualifizierter Name sein
$class: 'WarningsPublisher',
//ConsoleParsers, wenn Sie beim Ausführen von Job Warnungen von der Konsole erfassen möchten
// pmd.Geben Sie Parser-Konfigurationen an, wenn Sie aus einer Datei wie XML sammeln.
//Bei Parser-Konfigurationen zusätzlich zum Parser-Namen Muster(Pfad der zu aggregierenden Datei)Muss auch angegeben werden
//Verwenden Sie den in der folgenden Eigenschaftendatei definierten Parsernamen.
// https://github.com/jenkinsci/warnings-plugin/blob/master/src/main/resources/hudson/plugins/warnings/parser/Messages.properties
consoleParsers: [
[parserName: 'Java Compiler (javac)'],
],
canComputeNew: false,
canResolveRelativesPaths: false,
usePreviousBuildAsReference: true
])
}
}
}
stage('Statische Code-Analyse') {
steps {
//Verwenden Sie die Parallelmethode für die Parallelverarbeitung
parallel(
'Statische Code-Analyse' : {
gradlew 'check -x test'
//Sie können das aktuelle Verzeichnis mit der dir-Methode angeben
dir(reportDir) {
step([
$class: 'CheckStylePublisher',
pattern: "checkstyle/*.xml"
])
step([
$class: 'FindBugsPublisher',
pattern: "findbugs/*.xml"
])
step([
$class: 'PmdPublisher',
pattern: "pmd/*.xml"
])
step([
$class: 'DryPublisher',
pattern: "cpd/*.xml"
])
archiveArtifacts "checkstyle/*.xml"
archiveArtifacts "findbugs/*.xml"
archiveArtifacts "pmd/*.xml"
archiveArtifacts "cpd/*.xml"
}
},
'Schrittzahl': {
//Berichterstellung
//Wenn Sie outputFile und outputFormat angeben, wird auch eine Excel-Datei erstellt.
stepcounter outputFile: 'stepcount.xls', outputFormat: 'excel', settings: [
[key:'Java', filePattern: "${javaDir}/**/*.java"],
[key:'SQL', filePattern: "${resourcesDir}/**/*.sql"],
[key:'HTML', filePattern: "${resourcesDir}/**/*.html"],
[key:'JS', filePattern: "${resourcesDir}/**/*.js"],
[key:'CSS', filePattern: "${resourcesDir}/**/*.css"]
]
//Speichern Sie die Excel-Datei vorerst als Liefergegenstand
archiveArtifacts "stepcount.xls"
},
'Task-Scan': {
step([
$class: 'TasksPublisher',
pattern: './**',
//Wird bei der Suche nach Aggregationszielen zwischen Groß- und Kleinschreibung unterschieden?
ignoreCase: true,
//Zu aggregierende Zeichenfolgen können für jede Priorität angegeben werden
//Wenn Sie mehr als eine angeben, geben Sie eine durch Kommas getrennte Zeichenfolge an.
high: 'System.out.System.err',
normal: 'TODO,FIXME,XXX',
])
},
'JavaDoc': {
gradlew 'javadoc -x classes'
step([
$class: 'JavadocArchiver',
//Javadoc-Index.Geben Sie den Pfad des Ordners an, in dem sich HTML befindet
javadocDir: "${javadocDir}",
keepAll: true
])
}
)
}
post {
always {
//Sammeln Sie JavaDoc-Warnungen
step([
$class: 'WarningsPublisher',
consoleParsers: [
[parserName: 'JavaDoc Tool']
],
canComputeNew: false,
canResolveRelativesPaths: false,
usePreviousBuildAsReference: true
])
}
}
}
stage('Prüfung') {
steps {
gradlew 'test jacocoTestReport -x classes -x testClasses'
junit "${testReportDir}/*.xml"
archiveArtifacts "${testReportDir}/*.xml"
//Abdeckungsbericht erstellen (ohne Testklasse)
step([
$class: 'JacocoPublisher',
execPattern: "${jacocoReportDir}/*.exec",
exclusionPattern: '**/*Test.class'
])
}
}
stage('Bereitstellen') {
//Sie können die Bedingungen für die Ausführung der Phase im when-Block angeben
when {
//Nicht bei statischer Code-Analyse und Testfehlern bereitstellen
expression {currentBuild.currentResult == 'SUCCESS'}
}
steps {
gradlew 'jar'
archiveArtifacts "${libsDir}/${appName}-${appVersion}.jar"
gradlew 'war'
archiveArtifacts "${libsDir}/${appName}-${appVersion}.war"
deploy warDir: libsDir, appName: appName, appVersion: appVersion
}
}
}
//Wenn Sie einen Postblock auf derselben Ebene wie den Stufenblock definieren
//Es ist möglich, die Verarbeitung zu definieren, nachdem die gesamte Stufenverarbeitung abgeschlossen ist.
post {
always {
//Löschen Sie abschließend den Inhalt des Arbeitsbereichs
deleteDir()
}
//Senden Sie eine E-Mail an sich selbst, es sei denn, Sie sind hintereinander erfolgreich
//Wenn sich das Ergebnis gegenüber dem letzten Mal ändert
changed {
sendMail("${currentBuild.previousBuild.result} => ${currentBuild.currentResult}")
}
//Wenn es fehlschlägt
failure {
sendMail(currentBuild.currentResult)
}
//Wenn es instabil ist (hauptsächlich wenn der Test fehlschlägt)
unstable {
sendMail(currentBuild.currentResult)
}
}
}
//Führen Sie den Befehl Gradlew aus
def gradlew(command) {
if(isUnix()) {
sh "./gradlew ${command} --stacktrace"
} else {
bat "./gradlew.bat ${command} --stacktrace"
}
}
//Bereitstellen
// args.warDir war Speicherverzeichnis
// args.appName App-Name
// args.appVersion App-Version
def deploy(Map args) {
//Pfad des privaten Schlüssels * Da die Datei auf den Tomcat-Server übertragen wird, muss der private Schlüssel vorab irgendwo auf dem Jenkins-Server gespeichert werden.
def keyDir = '/var/lib/jenkins/.ssh/xxx'
//Tomcat-Serveradresse und Benutzername
def webServerAddress = 'ecX-XX-XXX-X-X.xx-xxxx-x.xxxxxxxx'
def webServerUser = 'hoge-user'
def webServer = "${webServerUser}@${webServerAddress}"
def srcWar = "${args.appName}-${args.appVersion}.war"
def destWar = "${args.appName}.war"
//Übertragen Sie Dateien und platzieren Sie Krieg in Tomcats Webanwendungen
sh "sudo -S scp -i ${keyDir} ./${args.warDir}/${srcWar} ${webServer}:/home/ec2-user"
sh "sudo -S ssh -i ${keyDir} ${webServer} \"sudo cp /home/ec2-user/${srcWar} /usr/share/tomcat8/webapps/${destWar}\""
}
//Mail an Google Mail senden
def sendMail(result) {
mail to: "[email protected]",
subject: "${env.JOB_NAME} #${env.BUILD_NUMBER} [${result}]",
body: "Build URL: ${env.BUILD_URL}.\n\n"
}
build.gradle Jenkins selbst führt nur Gradle-Befehle aus und generiert einen Bericht basierend auf der Ausgabe Die Java-App build.gradle von Gradle muss in der Lage sein, die folgenden Prozesse auszuführen. Erstellen Sie außerdem einen Gradle-Wrapper, damit Sie Gradle nicht mit Jenkins installieren müssen.
Zum Beispiel,
build.gradle
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'pmd'
apply plugin: 'jacoco'
ext {
appVersion = '1.0.0'
appName = 'SampleApp'
javaVersion = 1.8
defaultEncoding = 'UTF-8'
}
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
tasks.withType(AbstractCompile)*.options*.encoding = defaultEncoding
tasks.withType(GroovyCompile)*.groovyOptions*.encoding = defaultEncoding
mainClassName = 'jp.takumon.sapmleapp.App'
repositories {
mavenCentral()
}
dependencies {
//Listen Sie abhängige Bibliotheken auf
compile group: 'junit', name: 'junit', version: '4.12'
}
jar {
baseName = appName
version = appVersion
}
war {
baseName = appName
version = appVersion
}
checkstyle {
//Setzen Sie die nachfolgende Verarbeitung fort, auch wenn sie fehlschlägt
ignoreFailures = true
sourceSets = [sourceSets.main]
toolVersion = '7.6.1'
}
findbugs {
//Setzen Sie die nachfolgende Verarbeitung fort, auch wenn sie fehlschlägt
ignoreFailures = true
sourceSets = [sourceSets.main]
toolVersion = "3.0.1"
}
pmd {
//Setzen Sie die nachfolgende Verarbeitung fort, auch wenn sie fehlschlägt
ignoreFailures = true
sourceSets = [sourceSets.main]
}
tasks.withType(Pmd) {
reports {
xml.enabled = true
}
}
//CPD (Duplicate Code Check Processing) zur Prüfaufgabe hinzugefügt
check.doLast {
File outputDir = new File("$reportsDir/cpd/")
outputDir.mkdirs()
ant.taskdef(
name: 'cpd',
classname: 'net.sourceforge.pmd.cpd.CPDTask',
classpath: configurations.pmd.asPath)
ant.cpd(
minimumTokenCount: '100',
format: 'xml',
encoding: defaultEncoding,
outputFile: new File(outputDir, 'cpd.xml')
) {
fileset(dir: "src/main/java") {
include(name: '**/*.java')
}
}
}
javadoc {
failOnError = false
//Auf deinem Lieblingslevel
options.memberLevel = JavadocMemberLevel.PRIVATE
}
test {
//Setzen Sie die nachfolgende Verarbeitung fort, auch wenn sie fehlschlägt
ignoreFailures = true
reports {
junitXml.enabled = true
}
}
jacoco {
toolVersion = '0.7.5.201505241946'
}
jacocoTestReport {
reports {
xml.enabled = true
}
//Testklasse vom Abdeckungsbericht ausschließen
afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it, exclude: ['**/*Test.class'])
})
}
}
task wrapper (type: Wrapper) {
gradleVersion = '3.4.1'
}
das ist alles.
Recommended Posts