-
Notifications
You must be signed in to change notification settings - Fork 1
/
Jenkinsfile
142 lines (117 loc) · 5.51 KB
/
Jenkinsfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!groovy
@Library('github.com/cloudogu/[email protected]')
import com.cloudogu.ces.cesbuildlib.*
node('docker') {
properties([
// Keep only the last 10 build to preserve space
buildDiscarder(logRotator(numToKeepStr: '10')),
// Don't run concurrent builds for a branch, because they use the same workspace directory
disableConcurrentBuilds(),
parameters([
booleanParam(name: 'deployToNexus', defaultValue: false,
description: 'Deploying to Nexus tages ~10 Min since Nexus 3. That\'s why we skip it be default'),
booleanParam(name: 'deployToK8s', defaultValue: false,
description: 'Deploys to Kubernetes. We deploy to GitHub pages, so skip deploying to k8s by default.')
])
])
String conferenceName = '2021-03-17-javaLand'
pdfBaseName = 'Good-Practices-for-Secure-Kubernetes-AppOps'
String imageBaseName = 'cloudogu/k8s-appops-security-talks'
def introSlidePath = 'docs/slides/00-title.md'
headlessChromeVersion = 'yukinying/chrome-headless-browser:87.0.4280.11'
Git git = new Git(this, 'cesmarvin')
git.committerName = 'cesmarvin'
git.committerEmail = '[email protected]'
catchError {
stage('Checkout') {
checkout scm
git.clean('')
}
String pdfName = createPdfName()
String versionName = "${new Date().format('yyyyMMddHHmm')}-${git.commitHashShort}"
String imageName = "${imageBaseName}:${versionName}"
String packagePath = 'dist'
def image
stage('Build') {
writeVersionNameToIntroSlide(versionName, introSlidePath)
image = docker.build imageName
}
stage('Print PDF & Package WebApp') {
String pdfPath = "${packagePath}/${pdfName}"
printPdfAndPackageWebapp image, pdfName, packagePath
archiveArtifacts pdfPath
// Use a constant name for the PDF for easier URLs, for deploying
sh "mv '${pdfPath}' '${packagePath}/${createPdfName(false)}'"
// Build image again, so PDF is added
image = docker.build imageName
}
stage('Deploy GH Pages') {
if (env.BRANCH_NAME == 'main') {
git.pushGitHubPagesBranch(packagePath, versionName, conferenceName)
} else {
echo "Skipping deploy to GH pages, because not on master branch"
}
}
}
mailIfStatusChanged(git.commitAuthorEmail)
}
String pdfBaseName
String headlessChromeVersion
String createPdfName(boolean includeDate = true) {
String title = pdfBaseName
if (!title) {
title = sh (returnStdout: true, script: "grep -r '<title>' index.html | sed 's/.*<title>\\(.*\\)<.*/\\1/'").trim()
}
String pdfName = '';
if (includeDate) {
pdfName = "${new Date().format('yyyy-MM-dd')}-"
}
pdfName += "${title}.pdf"
return pdfName
}
void writeVersionNameToIntroSlide(String versionName, String introSlidePath) {
String filteredIntro = filterFile(introSlidePath, "<!--VERSION-->", "Version: $versionName")
sh "cp ${filteredIntro} ${introSlidePath}"
sh "mv ${filteredIntro} ${introSlidePath}"
}
void printPdfAndPackageWebapp(def image, String pdfName, String distPath) {
Docker docker = new Docker(this)
image.withRun("-v ${WORKSPACE}:/workspace -w /workspace") { revealContainer ->
// Extract rendered reveal webapp from container for further processing
sh "docker cp ${revealContainer.id}:/reveal '${distPath}'"
def revealIp = docker.findIp(revealContainer)
if (!revealIp || !waitForWebserver("http://${revealIp}:8080")) {
echo "Warning: Couldn't deploy reveal presentation for PDF printing. "
echo "Docker log:"
echo new Sh(this).returnStdOut("docker logs ${revealContainer.id}")
error "PDF creation failed"
}
docker.image(headlessChromeVersion)
// Chromium writes to $HOME/local, so we need an entry in /etc/pwd for the current user
.mountJenkinsUser()
// Try to avoid OOM for larger presentations by setting larger shared memory
.inside("--shm-size=2G") {
// If more flags should ever be neccessary: https://peter.sh/experiments/chromium-command-line-switches
sh "/usr/bin/google-chrome-unstable --headless --no-sandbox --disable-gpu --print-to-pdf='${distPath}/${pdfName}' " +
"http://${revealIp}:8080/?print-pdf"
}
}
}
/**
* Filters a {@code filePath}, replacing an {@code expression} by {@code replace} writing to new file, whose path is returned.
*
* @return path to filtered file
*/
String filterFile(String filePath, String expression, String replace) {
String filteredFilePath = filePath + ".filtered"
// Fail command (and build) if file not present
sh "test -e ${filePath} || (echo Title slide ${filePath} not found && return 1)"
sh "cat ${filePath} | sed 's/${expression}/${replace}/g' > ${filteredFilePath}"
return filteredFilePath
}
boolean waitForWebserver(String url) {
echo "Waiting for website to become ready at ${url}"
// Output to stdout and discard (O- >/dev/null) because we don't want the file we only want to know if it's available
int ret = sh (returnStatus: true, script: "wget O- --retry-connrefused --tries=30 -q --wait=1 ${url} &> /dev/null")
return ret == 0
}