Skip to content

Commit 74fa5ea

Browse files
31chtumaisch
authored andcommitted
Update README.md
1 parent d42796a commit 74fa5ea

30 files changed

+1495
-696
lines changed

.devcontainer/Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@ FROM mcr.microsoft.com/devcontainers/python:1-3.12-bookworm
66
# && apt-get -y install --no-install-recommends \
77
# <your-package-list-here> \
88
# && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
9+
10+
# Install UV / UVX
11+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
12+
ENV UV_COMPILE_BYTECODE=1
13+
ENV UV_LINK_MODE=copy
14+
15+
# Install project dependencies
16+
RUN --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
17+
--mount=type=bind,source=uv.lock,target=uv.lock \
18+
uv sync --frozen --no-install-project --all-extras

.devcontainer/devcontainer.json

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,18 @@
55
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
66
//"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye"
77
"build": {
8-
// Path is relative to the devcontainer.json file.
9-
"dockerfile": "Dockerfile"
10-
},
11-
8+
// Path is relative to the devcontainer.json file.
9+
"dockerfile": "Dockerfile",
10+
"context": ".."
11+
},
1212
// Features to add to the dev container. More info: https://containers.dev/features.
1313
// "features": {},
14-
1514
// Use 'forwardPorts' to make a list of ports inside the container available locally.
1615
// "forwardPorts": [],
17-
1816
// Use 'postCreateCommand' to run commands after the container is created.
19-
"postCreateCommand": "pipenv install --dev && pipenv run pip install -e ."
20-
17+
"postCreateCommand": "uv pip install -e ."
2118
// Configure tool-specific properties.
2219
// "customizations": {},
23-
2420
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
2521
// "remoteUser": "root"
26-
}
22+
}

.github/workflows/project-build-test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ jobs:
4242
steps:
4343
- name: Checkout code
4444
uses: actions/checkout@v4
45-
- name: Build package
45+
- name: Build Python package
4646
run: ./tools/build-package.sh
47-
- name: Upload python package
47+
- name: Upload Python package
4848
uses: actions/upload-artifact@v4
4949
with:
5050
name: python-package
@@ -77,7 +77,7 @@ jobs:
7777
steps:
7878
- name: Checkout code
7979
uses: actions/checkout@v4
80-
- name: Run pytest
80+
- name: Run tests
8181
run: ./tools/test-package.sh
8282
- name: Upload test results
8383
uses: actions/upload-artifact@v4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
__pycache__
22
.coverage
3+
.mypy_cache
4+
.pytest_cache
5+
.venv
36
*.egg-info
47
_build
58
build

.gitlab-ci.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
default:
3+
image: mcr.microsoft.com/devcontainers/python:1-3.12-bookworm
4+
5+
workflow:
6+
name: '$CI_COMMIT_AUTHOR: $CI_COMMIT_TITLE'
7+
auto_cancel:
8+
on_new_commit: interruptible
9+
on_job_failure: all
10+
rules:
11+
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
12+
variables:
13+
DEPLOY_ENV: "development"
14+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
15+
variables:
16+
DEPLOY_ENV: "staging"
17+
- if: $CI_COMMIT_BRANCH == $CI_COMMIT_TAG
18+
variables:
19+
DEPLOY_ENV: "production"
20+
- when: never
21+
22+
stages:
23+
- build
24+
- test
25+
- deploy
26+
27+
build-python-package:
28+
stage: build
29+
before_script:
30+
- pipx install uv
31+
script:
32+
- tools/build-package.sh
33+
artifacts:
34+
paths:
35+
- 'dist/*.whl'
36+
expire_in: 1 week
37+
38+
build-documentation:
39+
stage: build
40+
before_script:
41+
- pipx install uv
42+
script:
43+
- tools/build-docs.sh
44+
artifacts:
45+
paths:
46+
- build/html/
47+
48+
test-python-package:
49+
stage: test
50+
before_script:
51+
- pipx install uv
52+
script:
53+
- tools/test-package.sh
54+
coverage: '/TOTAL.*\s+(\d+%)$/'
55+
artifacts:
56+
reports:
57+
junit: report.xml
58+
coverage_report:
59+
coverage_format: cobertura
60+
path: coverage.xml
61+
62+
lint-python-package:
63+
stage: test
64+
before_script:
65+
- pipx install uv
66+
script:
67+
- uv run --all-extras flake8 src/python_training_project --format gl-codeclimate --output-file gl-code-quality-report.json
68+
artifacts:
69+
reports:
70+
codequality: gl-code-quality-report.json
71+
72+
additional-mr-checks:
73+
stage: test
74+
script:
75+
- echo "Additional checks for merge requests"
76+
rules:
77+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
78+
79+
deploy-python-package:
80+
stage: deploy
81+
before_script:
82+
- pipx install uv
83+
variables:
84+
UV_PUBLISH_URL: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi
85+
UV_PUBLISH_USERNAME: gitlab-ci-token
86+
UV_PUBLISH_PASSWORD: ${CI_JOB_TOKEN}
87+
88+
script:
89+
- tools/deploy-package.sh
90+
91+
pages:
92+
stage: deploy
93+
script:
94+
- mv build/html/ public/
95+
artifacts:
96+
paths:
97+
- public/
98+
99+
job-for-tags:
100+
stage: deploy
101+
script:
102+
- echo "Tag pipeline"
103+
rules:
104+
- if: $CI_COMMIT_TAG
105+

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)