-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.gitlab-ci.yml
218 lines (201 loc) · 7.89 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
# Used CI pipeline stages (see https://docs.gitlab.com/ee/ci/yaml/#stages)
stages:
- check # runs all linters
- test # runs pytest tests with different Python versions
- docs # builds and deploys documentation to GitLab Pages
- release # deploy release to GitLab/PyPI/Test-PyPI (for pushed release tags only)
# Set some environment variables based on Gitlab-specific variables
# See https://docs.gitlab.com/ee/ci/variables/
variables:
# documentation and package release configuration
# (NOTE: adjust as needed for your project, depending on your environment)
# ----
release_docs_pages: "true" # NOTE: needs CI variable PAGES_TOKEN
release_to_gitlab: "true"
release_to_testpypi: "false" # NOTE: needs CI variable RELEASE_TOKEN_testpypi
release_to_pypi: "false" # NOTE: needs CI variable RELEASE_TOKEN_pypi
release_to_custom: "false" # NOTE: needs CI variable RELEASE_TOKEN_custom
# ----
#
# settings for caching
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
PRE_COMMIT_HOME: "$CI_PROJECT_DIR/.cache/pre-commit"
# Global cache settings for test jobs (each job by default uses own copy of these settings)
# If key files do not change, restore the listed paths from cache (if cached).
# At the end, store those directories in cache.
# See https://docs.gitlab.com/ee/ci/caching/
cache: &global_cache
key:
files:
- poetry.lock
- .pre-commit-config.yaml
prefix: $CI_JOB_NAME
paths:
- .cache
- .venv
policy: pull-push
# Prepare environment with all required tools.
# Defined as hidden job (starting with dot) + YAML anchor (for referencing)
# See https://docs.gitlab.com/ee/ci/yaml/#anchors
.prepare-env-template: &prepare-env
before_script:
# install needed tools
- pip install pipx==1.2.0
- pipx ensurepath
- pipx install poetry
- export PATH="${PATH}:~/.local/bin" # put poetry on PATH
- ln -s ~/.local/bin/poetry /usr/bin/poetry # for poe (PATH is set only locally)
- poetry --version
- poetry config virtualenvs.in-project true
# install deps and activate venv
- poetry install --no-root
- source .venv/bin/activate
# ----
# Run pre-commit, just to make sure the developers did not mess up and forgot it.
# It uses its own cache for its isolated environments (location: PRE_COMMIT_HOME).
run-pre-commit:
image: python:latest
stage: check
<<: *prepare-env
script:
- poetry run poe lint --all-files
- pipx install safety
- safety check -r pyproject.toml
# ----
# test building docs
test-docs-build:
image: python:latest
stage: test
variables:
<<: *prepare-env
script:
- poetry install --with docs
- poetry run poe docs --verbose
# pytest job template (combine with image(s) containing a specific Python version):
#
# NOTE: it is not possible to easily test against a specific operation system,
# using GitLab CI, as this depends on the used runner (which is usually Linux-based).
.run-pytest-template: &run-pytest
stage: test
<<: *prepare-env
script:
- poetry install
- poetry run poe test --cov --junitxml=report.xml
artifacts:
when: always
reports:
junit: report.xml # for Gitlab integration of test results
# Run tests, using different Python versions:
run-pytest-3.8:
image: python:3.8
<<: *run-pytest
run-pytest-3.9:
image: python:3.9
<<: *run-pytest
run-pytest-3.10:
image: python:3.10
<<: *run-pytest
run-pytest-3.11:
image: python:3.11
<<: *run-pytest
# ----
# Update or push documentation for the current branch or a new tagged release
# See https://github.com/jimporter/mike/issues/25
pages:
image: python:latest
stage: docs
rules:
- if: "($release_docs_pages == 'true' || $release_docs_pages == '1') && $CI_PIPELINE_SOURCE != 'merge_request_event'"
variables:
PAGES_BRANCH: gl-pages
HTTPS_REMOTE: https://gitlab-ci-token:${PAGES_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git
<<: *prepare-env
script:
# Preparation: we need to clone the repository in the job and directly access it via git
- poetry install --with docs
- git config user.name $GITLAB_USER_NAME
- git config user.email $GITLAB_USER_EMAIL
- git fetch origin $PAGES_BRANCH && git -b checkout $PAGES_BRANCH origin/$PAGES_BRANCH || git checkout $PAGES_BRANCH || echo "Pages branch not deployed yet."
- git checkout $CI_COMMIT_SHA
# If triggered by a push, check if the branch is enabled for pages
- |
if [[ -n "$CI_COMMIT_BRANCH" ]] && ! [[ "$CI_COMMIT_BRANCH" =~ ^(main|dev)$ ]]; then
echo "INFO: Branch not enabled for pages, skipping docs deployment ('$PAGES_BRANCH' branch unchanged)."
git checkout $PAGES_BRANCH -- public/
exit 0
fi
# Deploy pages for a tag or enabled branch
- |
if [[ -z "$PAGES_TOKEN" ]]; then
echo "ERROR: CI variable PAGES_TOKEN is missing, cannot proceed!"
exit 1
fi
- DOCS_TAG_RAW=${CI_COMMIT_TAG:=$CI_COMMIT_BRANCH} # get tag (or if not present, current branch)
- DOCS_TAG=${DOCS_TAG_RAW//\//_} # eliminate '/' symbols from branch (or tag) name
- echo Deploying docs for "$DOCS_TAG"
- mike deploy --deploy-prefix public -r $HTTPS_REMOTE -p -b $PAGES_BRANCH -u $DOCS_TAG latest
- mike set-default --deploy-prefix public -r $HTTPS_REMOTE -p -b $PAGES_BRANCH latest
- git checkout $PAGES_BRANCH -- public/
artifacts:
paths:
- public/
# ----
# Create a new GitLab release if a tag is pushed (only if release_to_gitlab is true)
# https://docs.gitlab.com/ee/user/project/releases/release_cicd_examples.html
release_gitlab:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
rules:
- if: "$CI_COMMIT_TAG && ($release_to_gitlab == 'true' || $release_to_gitlab == '1')"
script:
- echo "creating GitLab Release for tag '$CI_COMMIT_TAG'"
release:
tag_name: '$CI_COMMIT_TAG'
description: '$CI_COMMIT_TAG'
# Common script to publish to PyPI, Test PyPI or other custom instances
.release-pypi-common: &release-pypi-common
stage: release
image: python:latest
<<: *prepare-env
script:
- | # set up custom repository for poetry, if corresponding variables are set
if [[ -n "$PKGIDX_NAME" ]]; then
[[ -n "$PKGIDX_URL" ]] || (echo "ERROR: PKGIDX_NAME is provided, but PKGIDX_URL is missing!" && exit 1)
poetry config "repositories.$PKGIDX_NAME" "$PKGIDX_URL"
fi
# determine correct CI token variables to use
- PKGIDX_NAME=${PKGIDX_NAME:=pypi}
- TOKVAR=RELEASE_TOKEN_${PKGIDX_NAME}
- echo Will use token from CI variable $TOKVAR for publishing to $PKGIDX_NAME
- | # check that the correct token is actually provided
if [[ -z "${!TOKVAR}" ]] ; then
echo "ERROR: CI variable $TOKVAR is missing, cannot proceed!"
echo "Please provide the token for $PKGIDX_NAME as a masked CI variable called $TOKVAR!"
exit 1
fi
# set up credentials, build package and upload it to the desired package index
- poetry config -- http-basic.pypi "__token__" "${!TOKVAR}"
- poetry build
- poetry publish -r $PKGIDX_NAME $POETRY_PUBLISH_EXTRA_ARGS
# Create a new PyPI release if a tag is pushed (only if release_to_pypi is true)
release_pypi:
rules:
- if: "$CI_COMMIT_TAG && ($release_to_pypi == 'true' || $release_to_pypi == '1')"
<<: *release-pypi-common
# Create a new Test PyPI release if a tag is pushed (only if release_to_testpypi is true)
release_test_pypi:
rules:
- if: "$CI_COMMIT_TAG && ($release_to_testpypi == 'true' || $release_to_testpypi == '1')"
<<: *release-pypi-common
variables:
PKGIDX_NAME: "testpypi"
PKGIDX_URL: "https://test.pypi.org/legacy/"
# Create a new custom release if a tag is pushed (only if release_to_custom is true)
# NOTE: adjust the URL to the API of your custom package index in order to use this job
release_custom_pypi:
rules:
- if: "$CI_COMMIT_TAG && ($release_to_custom == 'true' || $release_to_custom == '1')"
<<: *release-pypi-common
variables:
PKGIDX_NAME: "custom"
PKGIDX_URL: "https://your.custom.package-index.org/legacy/"