containerized Jenkins (#179)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/179 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
15
Jenkins/Dockerfile
Normal file
15
Jenkins/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM jenkins/jenkins:lts-jdk21
|
||||
|
||||
USER root
|
||||
|
||||
# Docker CLI installieren
|
||||
RUN apt-get update && apt-get install -y docker.io && usermod -aG docker jenkins
|
||||
|
||||
# grant user jenkins access to /var/run/docker.sock
|
||||
RUN usermod -aG messagebus jenkins
|
||||
|
||||
# install plugins
|
||||
COPY Jenkins.plugins /usr/share/jenkins/ref/plugins.txt
|
||||
RUN jenkins-plugin-cli --plugin-file /usr/share/jenkins/ref/plugins.txt
|
||||
|
||||
USER jenkins
|
8
Jenkins/Jenkins.plugins
Normal file
8
Jenkins/Jenkins.plugins
Normal file
@@ -0,0 +1,8 @@
|
||||
git
|
||||
workflow-aggregator
|
||||
pipeline-github-lib
|
||||
docker-workflow
|
||||
credentials
|
||||
git-client
|
||||
blueocean
|
||||
coverage
|
138
Jenkins/Jenkinsfile
vendored
Normal file
138
Jenkins/Jenkinsfile
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
pipeline {
|
||||
parameters {
|
||||
string(name: 'AGENT_CPUS', defaultValue: '2.5', description: 'CPU limit for the build agent')
|
||||
string(name: 'AGENT_NETWORK', defaultValue: 'host', description: 'Network to be used for build agent')
|
||||
booleanParam(name: 'QUICK_RUN', defaultValue: false, description: 'false: all stages but slow, true: just some stages and fast')
|
||||
}
|
||||
agent {
|
||||
dockerfile {
|
||||
filename 'Jenkins/agent/Dockerfile'
|
||||
args """--user root --network ${params.AGENT_NETWORK}
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock
|
||||
--memory=8g --cpus=${params.AGENT_CPUS}"""
|
||||
}
|
||||
}
|
||||
|
||||
environment {
|
||||
GRADLE_USER_HOME = "${env.WORKSPACE}/.gradle-cache"
|
||||
DOCKER_HOST = 'unix:///var/run/docker.sock'
|
||||
HSADMINNG_POSTGRES_ADMIN_USERNAME = 'admin'
|
||||
HSADMINNG_POSTGRES_RESTRICTED_USERNAME = 'restricted'
|
||||
HSADMINNG_MIGRATION_DATA_PATH = 'migration'
|
||||
TESTCONTAINERS_RYUK_DISABLED = true
|
||||
TESTCONTAINERS_LOG_LEVEL = "DEBUG"
|
||||
}
|
||||
|
||||
triggers {
|
||||
pollSCM('H/1 * * * *')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Detect Docker Environment') {
|
||||
steps {
|
||||
sh '''#!/bin/bash +x
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
if docker info --format '{{.SecurityOptions}}' 2>/dev/null | grep -q 'rootless'; then
|
||||
echo "🟡 Docker daemon is running in ROOTLESS mode"
|
||||
else
|
||||
echo "🟢 Docker daemon is running in ROOTFUL mode"
|
||||
fi
|
||||
else
|
||||
echo "❌ Docker CLI not found"
|
||||
fi'''
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
|
||||
stage('Compile') {
|
||||
steps {
|
||||
sh './gradlew clean processSpring compileJava compileTestJava --no-daemon --console=plain'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Tests') {
|
||||
parallel {
|
||||
stage('Other Tests') {
|
||||
stages {
|
||||
stage('Unit-Tests') {
|
||||
steps {
|
||||
sh './gradlew unitTest --no-daemon --console=plain'
|
||||
}
|
||||
}
|
||||
stage('Migration-Tests') {
|
||||
steps {
|
||||
sh './gradlew migrationTest --no-daemon --console=plain'
|
||||
}
|
||||
}
|
||||
stage('Scenario-Tests') {
|
||||
steps {
|
||||
sh './gradlew scenarioTest --no-daemon --console=plain'
|
||||
}
|
||||
}
|
||||
stage('General-Tests') {
|
||||
when {
|
||||
expression { !params.QUICK_RUN }
|
||||
}
|
||||
steps {
|
||||
sh './gradlew generalIntegrationTest --no-daemon --console=plain'
|
||||
}
|
||||
}
|
||||
stage('Booking+Hosting-Tests') {
|
||||
when {
|
||||
expression { !params.QUICK_RUN}
|
||||
}
|
||||
steps {
|
||||
sh './gradlew bookingIntegrationTest hostingIntegrationTest --no-daemon --console=plain'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// in parallel because these tests take about as much time as all others combined
|
||||
stage('Office-Tests') {
|
||||
when {
|
||||
expression { !params.QUICK_RUN }
|
||||
}
|
||||
steps {
|
||||
sh './gradlew officeIntegrationTest --no-daemon --console=plain --fail-fast'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
stage ('Checks') {
|
||||
steps {
|
||||
sh './gradlew check -x pitest -x test -x dependencyCheckAnalyze --no-daemon'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
// archive test results
|
||||
junit testResults: 'build/test-results/*/*.xml', allowEmptyResults: true, checksName: '', skipPublishingChecks: true
|
||||
|
||||
// archive the JaCoCo coverage report
|
||||
// recordCoverage tools: [jacoco(pattern: 'build/reports/jacoco/test/jacocoTestReport.xml')]
|
||||
sh 'find build -name jacocoTestReport.xml'
|
||||
archiveArtifacts artifacts: 'build/reports/jacoco/**/jacocoTestReport.xml', allowEmptyArchive: true
|
||||
|
||||
// archive scenario-test reports in HTML format
|
||||
sh './gradlew convertMarkdownToHtml'
|
||||
archiveArtifacts artifacts:
|
||||
'build/doc/scenarios/*.html, ' +
|
||||
'build/reports/dependency-license/dependencies-without-allowed-license.json',
|
||||
allowEmptyArchive: true
|
||||
|
||||
// cleanup workspace
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
54
Jenkins/Makefile
Normal file
54
Jenkins/Makefile
Normal file
@@ -0,0 +1,54 @@
|
||||
DOCKER := docker
|
||||
SOCKET := /var/run/docker.sock
|
||||
VOLUME := jenkins_home
|
||||
|
||||
.PHONY: build run bash init-pw unprotected protected start stop rm purge
|
||||
|
||||
# building the Jenkins image
|
||||
build:
|
||||
$(DOCKER) build -t jenkins-docker .
|
||||
|
||||
# initially running the Jenkins container
|
||||
run:
|
||||
$(DOCKER) run --detach \
|
||||
--dns 8.8.8.8 \
|
||||
--network bridge \
|
||||
--publish 8080:8080 --publish 50000:50000 \
|
||||
--volume $(SOCKET):/var/run/docker.sock \
|
||||
--volume $(VOLUME):/var/jenkins_home \
|
||||
--restart unless-stopped \
|
||||
--name jenkins jenkins-docker
|
||||
|
||||
# (re-) starts the Jenkins container
|
||||
start:
|
||||
$(DOCKER) start jenkins
|
||||
|
||||
# opens a bash within the Jenkins container
|
||||
bash:
|
||||
$(DOCKER) exec -it jenkins bash
|
||||
|
||||
# prints the inital password of a newly setup Jenkins
|
||||
init-pw:
|
||||
$(DOCKER) exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
|
||||
|
||||
# disables security for the Jenkins, allows login without credentials
|
||||
unprotected:
|
||||
docker exec -it jenkins sed -i 's|<useSecurity>true</useSecurity>|<useSecurity>false</useSecurity>|' /var/jenkins_home/config.xml
|
||||
docker exec -it jenkins grep useSecurity /var/jenkins_home/config.xml
|
||||
|
||||
# enables security for the Jenkins, requires login with credentials
|
||||
protected:
|
||||
docker exec -it jenkins sed -i 's|<useSecurity>true</useSecurity>|<useSecurity>true</useSecurity>|' /var/jenkins_home/config.xml
|
||||
docker exec -it jenkins grep useSecurity /var/jenkins_home/config.xml
|
||||
|
||||
# stops the Jenkins container
|
||||
stop:
|
||||
$(DOCKER) stop jenkins
|
||||
|
||||
# removes the Jenkins container
|
||||
rm: stop
|
||||
$(DOCKER) rm jenkins
|
||||
|
||||
# purges the Jenkins volume (finally deletes the configuration)
|
||||
purge: rm
|
||||
$(DOCKER) volume rm $(VOLUME)
|
9
Jenkins/agent/Dockerfile
Normal file
9
Jenkins/agent/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
||||
FROM eclipse-temurin:21-jdk
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
postgresql-client \
|
||||
bind9-utils \
|
||||
docker.io \
|
||||
pandoc && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
Reference in New Issue
Block a user