-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.gitlab-ci.yml
243 lines (204 loc) · 7.23 KB
/
.gitlab-ci.yml
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
---
image: python:3.10
stages:
- check
- build
- test
- deploy
- post_deploy
# Global pipeline rules
workflow:
rules:
#
# Run pipelines on tags
- if: $CI_COMMIT_TAG
#
# Run pipelines on branches
- if: $CI_COMMIT_BRANCH
variables:
# The GitLab Pages URL at which build artifacts can be made available
PAGES_URL: https://utopia-project.gitlab.io/-/utopya
# -- Hidden Jobs --------------------------------------------------------------
# ... to be integrated in other jobs via "extends"
# Add reports
#
# 1) Unit test reports, see:
# https://docs.gitlab.com/ee/ci/unit_test_reports.html
#
# 2) Cobertura coverage report visualization for MRs.
#
# Note that this requires a special syntax with *relative* file paths in
# the XML that do *not* include the test files.
# This becomes a bit tricky for utopya, because there are two packages,
# utopya and utopya_cli, and they may not be regarded as two *sources*,
# otherwise the coverage report gets mixed up.
# To that end, the coverage source needs to be the project directory and
# the pyproject.toml file makes some settings to omit the test files.
#
.reports:
coverage: '/TOTAL.*?(\d+\.?\d*)%\s*/' # https://regex101.com/r/vW26X0/1
artifacts:
when: always
expire_in: 3 months
paths:
- coverage.xml
- report.xml
- tests/_output
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
junit: report.xml
# -- Checks -------------------------------------------------------------------
check:hooks:
stage: check
needs: []
before_script:
- pip install pre-commit
script:
- pre-commit run --all-files --verbose --show-diff-on-failure
# -- Build Stage --------------------------------------------------------------
# ... for building the documentation (and potentially more jobs)
build:docs:
stage: build
allow_failure: true
needs: []
variables:
UTOPYA_DOC_GENERATE_FIGURES: "yes"
#
# Turn TLS verification off, because intersphinx is less robust with TLS
SPHINX_TLS_VERIFY: "no"
before_script:
# Install additional dependencies for generating figures
- apt-get update && apt-get install -y ffmpeg graphviz
#
# Install utopya itself
- pip3 install .[doc]
script:
- cd doc
- make build_and_check
after_script:
# Append the error log such that it's more convenient to read
- echo "-------- Errors emitted during building of documentation --------"
- cat doc/build_errors.log
artifacts:
when: always
name: "doc-$CI_COMMIT_REF_NAME"
expire_in: 2 weeks
expose_as: Documentation Build Results - including error log
paths:
- doc/_build/html
- doc/build_errors.log
environment:
name: review/docs/$CI_COMMIT_REF_NAME
auto_stop_in: 2 months
url: $PAGES_URL/-/jobs/$CI_JOB_ID/artifacts/doc/_build/html/index.html
# -- Test Stage ---------------------------------------------------------------
# ... for testing with different python environments
test:py39:
stage: test
image: python:3.9
extends:
- .reports
needs: []
variables:
UTOPYA_USE_TEST_OUTPUT_DIR: "yes" # have output in tests/_output
before_script:
# Install additional dependencies (needed for optional dependencies)
- apt-get update && apt-get install -y graphviz graphviz-dev
#
# Install utopya itself, also testing if the optional dependencies can be
# pulled in separately
- pip3 install .[opt]
- pip3 install .[dev]
script:
# NOTE It's paramount to ONLY add --cov=./ here: If nothing is added, there
# will not be a report; if anything else is added, there are issues
# with cobertura reporting. This also assumes that information about
# which paths to omit is read from the pyproject.toml file
- python tests/run.py -v
--durations=10
--cov=./
--cov-report term-missing
--cov-report xml:coverage.xml
--junitxml=report.xml
tests/.
test:py310:
extends: test:py39
image: python:3.10
test:py311:
extends: test:py39
image: python:3.11
test:py312:
extends: test:py39
image: python:3.12
test:py313:
extends: test:py39
image: python:3.13
# FIXME Stochastic failure of this job due to some ruamel.yaml issue
retry:
max: 1
when: script_failure
# -- Deploy Stage -------------------------------------------------------------
# Deploy utopya to PyPI
deploy:pypi:
stage: deploy
rules: &pypi_deploy_rules
# Run after pushes to tags in original repo, not forks
- if: $CI_COMMIT_TAG && $CI_PROJECT_PATH == "utopia-project/utopya"
variables:
# Define a regex for matching the tag name, see:
# https://regex101.com/r/AsCCJo/2
# Expects fully-qualified version specifiers, like v1.2.3 or v1.2.3a4
# Does NOT accept tags like:
# 1.2.3 (missing v)
# v1.0 (missing patch version)
VERSION_PATTERN: v([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)([[:lower:]][[:digit:]]+)?
# Need another matching pattern to extract a version string from the
# __version__ line of an __init__.py file (line extracted via grep first)
SED_PATTERN: s/.*\"([0-9]+\.[0-9]+\.[0-9]+[a-z]{0,5}[0-9]*)\".*/\1/g
before_script:
# Test the version pattern itself behaves as expected
- "[[ ! \"foo\" =~ ${VERSION_PATTERN} ]]"
- "[[ ! \"v1.2\" =~ ${VERSION_PATTERN} ]]"
- "[[ ! \"1.2.3\" =~ ${VERSION_PATTERN} ]]"
- "[[ \"v1.2.3\" =~ ${VERSION_PATTERN} ]]"
- "[[ \"v1.23.4a5\" =~ ${VERSION_PATTERN} ]]"
- "[[ \"v1.23.45a67\" =~ ${VERSION_PATTERN} ]]"
# Retrieve the utopya version (without importing, to avoid installation)
- export UTOPYA_VERSION=v$(cat utopya/__init__.py | grep __version__ | sed -E $SED_PATTERN)
- echo "utopya version is ${UTOPYA_VERSION}"
# Now do the actual checks
# ... against the selected tag
- "[[ ${CI_COMMIT_TAG} =~ ${VERSION_PATTERN} ]]"
# ... against the utopya package version number
- "[[ ${UTOPYA_VERSION} =~ ${VERSION_PATTERN} ]]"
# ... and that they are the same
- "[[ ${UTOPYA_VERSION} == ${CI_COMMIT_TAG} ]]"
# Checks successful
# Install dependencies needed for pushing packages
- pip install -U twine
script:
# Create distribution files
- python setup.py sdist bdist_wheel
# Check whether description will render correctly on PyPI
- twine check dist/*
# Upload to the TEST PyPI index (using separate credentials)
- twine upload --repository testpypi -u ${PYPI_TEST_USER} -p ${PYPI_TEST_PASSWORD} dist/*
# If this worked, continue and upload to actual package index
- twine upload -u ${PYPI_USER} -p ${PYPI_PASSWORD} dist/*
# -- Test Deploy Stage --------------------------------------------------------
# ... for testing the deployment to the PyPI (and potentially more jobs)
# Install utopya from the PyPI via pip to test automatic deployment
post_deploy:install_from_pypi:
stage: post_deploy
rules: *pypi_deploy_rules
retry: 2
needs:
- "deploy:pypi"
script:
# Wait some time before starting to allow PyPI to process the push
- sleep 30
# Install the newly deployed utopya version via PyPI. The current version
# number is given by the commit tag without the prefixed 'v'.
- pip install utopya==${CI_COMMIT_TAG#v}