Skip to content

Commit fe33ed3

Browse files
committed
Add Jenkins CI
Signed-off-by: Thomas Keller <[email protected]>
1 parent 67328b4 commit fe33ed3

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed

Jenkinsfile

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
pipeline {
2+
agent {
3+
/*docker {
4+
image 'mcr.microsoft.com/devcontainers/python:1-3.12-bookworm'
5+
}*/
6+
dockerfile {
7+
filename '.devcontainer/Dockerfile'
8+
dir '.'
9+
args '--net="jenkins_default"' // required for accessing the Gitea server
10+
}
11+
}
12+
options {
13+
disableConcurrentBuilds()
14+
//skipDefaultCheckout() // default checkout is required for .devcontainer/Dockerfile
15+
//newContainerPerStage()
16+
}
17+
parameters {
18+
booleanParam(
19+
name: 'DEPLOY_PACKAGE',
20+
defaultValue: false,
21+
description: 'Flag indicating if Python package should be deployed'
22+
)
23+
}
24+
stages {
25+
stage('Cleanup') {
26+
steps {
27+
sh 'rm -rf dist build'
28+
}
29+
}
30+
stage('Build documentation') {
31+
steps {
32+
sh './tools/build-docs.sh'
33+
archiveArtifacts(
34+
artifacts: 'build/html/**',
35+
onlyIfSuccessful: true
36+
)
37+
publishHTML([
38+
allowMissing: false,
39+
alwaysLinkToLastBuild: false,
40+
keepAll: false,
41+
reportDir: 'build/html/',
42+
reportFiles: 'index.html',
43+
reportName: 'Documentation',
44+
reportTitles: '',
45+
useWrapperFileDirectly: true
46+
])
47+
}
48+
}
49+
stage('Build Python package') {
50+
steps {
51+
sh './tools/build-package.sh'
52+
archiveArtifacts(
53+
artifacts: 'dist/*.whl',
54+
onlyIfSuccessful: true
55+
)
56+
}
57+
}
58+
stage('Static code analysis') {
59+
steps {
60+
warnError('lint issues found') {
61+
sh './tools/lint-package.sh'
62+
}
63+
recordIssues(
64+
sourceCodeRetention: 'LAST_BUILD',
65+
tools: [
66+
taskScanner(
67+
highTags: 'FIXME',
68+
includePattern: 'src/**/*.py',
69+
lowTags: 'HACK',
70+
normalTags: 'TODO'
71+
),
72+
flake8(pattern: 'build/flake8.txt'),
73+
pyLint(pattern: 'build/pylint.txt'),
74+
myPy(pattern: 'build/mypy.txt'),
75+
pyLint(pattern: 'build/ruff.txt', id: 'ruff', name: 'Ruff')
76+
]
77+
)
78+
}
79+
}
80+
stage('Test Python package') {
81+
steps {
82+
sh './tools/test-package.sh'
83+
junit(
84+
testResults: 'build/test-report.xml'
85+
)
86+
recordCoverage(
87+
tools: [
88+
[parser: 'JUNIT', pattern: 'build/test-report.xml'],
89+
[parser: 'COBERTURA', pattern: 'build/test-coverage.xml']
90+
]
91+
)
92+
}
93+
}
94+
stage('Deploy Python package') {
95+
when {
96+
expression {
97+
params.DEPLOY_PACKAGE == true
98+
}
99+
}
100+
//environment {
101+
// TWINE_REPOSITORY = 'gitea'
102+
//}
103+
//steps {
104+
// sh 'twine upload --config-file .pypirc dist/*'
105+
//}
106+
environment {
107+
UV_PUBLISH_URL = 'http://gitea.lan:3000/api/packages/root/pypi'
108+
CREDENTIALS = credentials('gitea')
109+
UV_PUBLISH_USERNAME = "$CREDENTIALS_USR"
110+
UV_PUBLISH_PASSWORD = "$CREDENTIALS_PSW"
111+
}
112+
steps {
113+
sh './tools/deploy-package.sh'
114+
}
115+
}
116+
}
117+
}

Jenkinsfile.groovy

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
node {
2+
properties([
3+
disableConcurrentBuilds()
4+
])
5+
stage('Checkout SCM') {
6+
checkout scm
7+
}
8+
stage('Agent Setup') {
9+
docker.withRegistry('http://gitea.lan:3000', 'gitea') {
10+
customImage = docker.build(
11+
"root/jenkins-python:latest",
12+
"-f .devcontainer/Dockerfile ./")
13+
customImage.push() // push custom image to the own registry
14+
}
15+
}
16+
customImage.inside('--net="jenkins_default"') { // required for accessing the Gitea server
17+
stage('Cleanup') {
18+
sh 'rm -rf dist build'
19+
}
20+
stage('Build documentation') {
21+
sh './tools/build-docs.sh'
22+
archiveArtifacts(
23+
artifacts: 'build/html/**',
24+
onlyIfSuccessful: true
25+
)
26+
publishHTML([
27+
allowMissing: false,
28+
alwaysLinkToLastBuild: false,
29+
keepAll: false,
30+
reportDir: 'build/html/',
31+
reportFiles: 'index.html',
32+
reportName: 'Documentation',
33+
reportTitles: '',
34+
useWrapperFileDirectly: true
35+
])
36+
}
37+
stage('Build Python package') {
38+
sh './tools/build-package.sh'
39+
archiveArtifacts(
40+
artifacts: 'dist/*.whl',
41+
onlyIfSuccessful: true
42+
)
43+
}
44+
stage('Static code analysis') {
45+
warnError('lint issues found') {
46+
sh './tools/lint-package.sh'
47+
}
48+
recordIssues(
49+
sourceCodeRetention: 'LAST_BUILD',
50+
tools: [
51+
taskScanner(
52+
highTags: 'FIXME',
53+
includePattern: 'src/**/*.py',
54+
lowTags: 'HACK',
55+
normalTags: 'TODO'
56+
),
57+
flake8(pattern: 'build/flake8.txt'),
58+
pyLint(pattern: 'build/pylint.txt'),
59+
myPy(pattern: 'build/mypy.txt'),
60+
pyLint(pattern: 'build/ruff.txt', id: 'ruff', name: 'Ruff')
61+
]
62+
)
63+
}
64+
stage('Test Python package') {
65+
sh './tools/test-package.sh'
66+
junit(
67+
testResults: 'build/test-report.xml'
68+
)
69+
recordCoverage(
70+
tools: [
71+
[parser: 'JUNIT', pattern: 'build/test-report.xml'],
72+
[parser: 'COBERTURA', pattern: 'build/test-coverage.xml']
73+
]
74+
)
75+
}
76+
stage('Deploy Python package') {
77+
//withEnv([
78+
// 'TWINE_REPOSITORY="gitea"'
79+
//]) {
80+
// sh 'twine upload --config-file .pypirc dist/*'
81+
//}
82+
withEnv([
83+
'UV_PUBLISH_URL=http://gitea.lan:3000/api/packages/root/pypi'
84+
]) {
85+
withCredentials([
86+
usernamePassword(
87+
credentialsId: 'gitea',
88+
usernameVariable: 'UV_PUBLISH_USERNAME',
89+
passwordVariable: 'UV_PUBLISH_PASSWORD'
90+
)
91+
]) {
92+
sh './tools/deploy-package.sh'
93+
}
94+
}
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)