Skip to content
Snippets Groups Projects
Commit ff8b9856 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

feat(release): complete release process refactoring

BREAKING CHANGE: complete refactoring or release process, including variables and jobs redefinition
- no more separate publish job: the entire release process is now performed by the py-release job
- TWINE_XXX variables removed and replaced by PYTHON_REPOSITORY_XXX
- RELEASE_VERSION_PART variable replaced by PYTHON_RELEASE_NEXT

For additional info, see the doc.
parent 319f85c4
No related branches found
No related tags found
No related merge requests found
......@@ -50,6 +50,12 @@ and/or `setup.py` and/or `requirements.txt`), but the build system might also be
## Jobs
### `py-package` job
This job allows building your Python project [distribution packages](https://packaging.python.org/en/latest/glossary/#term-Distribution-Package).
It is bound to the `build` stage, it is **disabled by default** and can be enabled by setting `$PYTHON_PACKAGE_ENABLED` to `true`.
### Lint jobs
#### `py-pylint` job
......@@ -206,7 +212,7 @@ It is bound to the `test` stage, and uses the following variables:
| Name | description | default value |
| ---------------- | ---------------------------------------------------------------------- | ----------------- |
| `BANDIT_ENABLED` | Set to `true` to enable Bandit analysis | _none_ (disabled) |
| `BANDIT_ENABLED` | Set to `true` to enable Bandit analysis | _none_ (disabled) |
| `BANDIT_ARGS` | Additional [Bandit CLI options](https://github.com/PyCQA/bandit#usage) | `--recursive .` |
This job outputs a **textual report** in the console, and in case of failure also exports a JSON report in the `reports/`
......@@ -220,7 +226,7 @@ It is bound to the `test` stage, and uses the following variables:
| Name | description | default value |
| ---------------- | ----------------------------------------------------------------------- | ----------------- |
| `SAFETY_ENABLED` | Set to `true` to enable Safety job | _none_ (disabled) |
| `SAFETY_ENABLED` | Set to `true` to enable Safety job | _none_ (disabled) |
| `SAFETY_ARGS` | Additional [Safety CLI options](https://github.com/pyupio/safety#usage) | `--full-report` |
This job outputs a **textual report** in the console, and in case of failure also exports a JSON report in the `reports/`
......@@ -234,62 +240,92 @@ It is bound to the `test` stage, and uses the following variables:
| Name | description | default value |
| ---------------- | ----------------------------------------------------------------------- | ----------------- |
| `PYTHON_TRIVY_ENABLED` | Set to `true` to enable Trivy job | _none_ (disabled) |
| `PYTHON_TRIVY_ENABLED` | Set to `true` to enable Trivy job | _none_ (disabled) |
| `PYTHON_TRIVY_ARGS` | Additional [Trivy CLI options](https://aquasecurity.github.io/trivy/v0.21.1/getting-started/cli/fs/) | `--vuln-type library` |
This job outputs a **textual report** in the console, and in case of failure also exports a JSON report in the `reports/`
directory _(relative to project root dir)_.
### Package jobs
### `py-release` job
This job is **disabled by default** and allows to perform a complete release of your Python code:
#### `py-package` job
1. increase the Python project version,
2. Git commit changes and create a Git tag with the new version number,
3. build the [Python packages](https://packaging.python.org/),
4. publish the built packages to a PyPI compatible repository ([GitLab packages](https://docs.gitlab.com/ee/user/packages/pypi_repository/) by default).
This job is **disabled by default** and performs a packaging of your Python code.
The Python template supports two packaging systems:
It is bound to the `package-build` stage, applies only on git tags and uses the following variables:
* [Poetry](https://python-poetry.org/): uses Poetry-specific [version](https://python-poetry.org/docs/cli/#version), [build](https://python-poetry.org/docs/cli/#build) and [publish](https://python-poetry.org/docs/cli/#publish) commands.
* [Setuptools](https://setuptools.pypa.io/): uses [Bumpversion](https://github.com/peritus/bumpversion) as version management, [build](https://pypa-build.readthedocs.io/) as package builder and [Twine](https://twine.readthedocs.io/) to publish.
| Name | description | default value |
| --------------- | ---------------------------------------------------- | ------------- |
| `PYTHON_FORCE_PACKAGE` | Set to `true` to force the packaging even if not on tag related event | _none_ (disabled) |
The release job is bound to the `publish` stage, appears only on production and integration branches and uses the following variables:
### Publish jobs
| Name | description | default value |
| ----------------------- | ----------------------------------------------------------------------- | ----------------- |
| `PYTHON_RELEASE_ENABLED`| Set to `true` to enable the release job | _none_ (disabled) |
| `PYTHON_RELEASE_NEXT` | The part of the version to increase (one of: `major`, `minor`, `patch`) | `minor` |
| `PYTHON_SEMREL_RELEASE_DISABLED`| Set to `true` to disable [semantic-release integration](#semantic-release-integration) | _none_ (disabled) |
| `GIT_USERNAME` | Git username for Git push operations (see below) | _none_ |
| :lock: `GIT_PASSWORD` | Git password for Git push operations (see below) | _none_ |
| :lock: `GIT_PRIVATE_KEY`| SSH key for Git push operations (see below) | _none_ |
| `PYTHON_REPOSITORY_URL`| Target PyPI repository to publish packages | _[GitLab project's PyPI packages repository](https://docs.gitlab.com/ee/user/packages/pypi_repository/)_ |
| `PYTHON_REPOSITORY_USERNAME`| Target PyPI repository username credential | `gitlab-ci-token` |
| :lock: `PYTHON_REPOSITORY_PASSWORD`| Target PyPI repository password credential | `$CI_JOB_TOKEN` |
#### `py-release` job
#### Setuptools tip
This job is **disabled by default** and performs an automatic tagging of your Python code.
If you're using a `setup.cfg` declarative file for your project Setuptools configuration, then you will have to write a
`.bumpversion.cfg` file to workaround a bug that prevents Bumpversion from updating the project version in your `setup.cfg` file.
* [Bumpversion](https://github.com/peritus/bumpversion) Python library is used for version management.
* Looks for an existing `.bumpversion.cfg` at the project root. If found, it will be the configuration used by bumpversion. If not, the `$RELEASE_VERSION_PART` variable and `setup.py` will be used instead.
* Creating a Git tag involves an authenticated and authorized Git user.
Example of `.bumpversion.cfg` file:
**Don't use your personal password !!!
Use an [access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with write_repository rights.
If you have a generic account, add it to the project and generate access token from this account.**
```ini
[bumpversion]
# same version as in your setup.cfg
current_version = 0.5.0
It is bound to the `publish` stage, applies only on master branch and uses the following variables:
[bumpversion:file:setup.cfg]
# any additional config here
# see: https://github.com/peritus/bumpversion#file-specific-configuration
```
| Name | description | default value |
| ---------------------- | ----------------------------------------------------------------------- | ----------------- |
| `RELEASE_VERSION_PART` | The part of the version to increase (one of: `major`, `minor`, `patch`) | `minor` |
| `RELEASE_USERNAME` | Username credential for git push | _none_ (disabled) |
| `RELEASE_ACCESS_TOKEN` | Password credential for git push | _none_ |
#### `semantic-release` integration
#### `py-publish` job
If you activate the [`semantic-release-info` job from the `semantic-release` template](https://gitlab.com/to-be-continuous/semantic-release/#semantic-release-info-job), the `py-release` job will rely on the generated next version info.
Thus, a release will be performed only if a next semantic release is present.
This job is **disabled by default** and performs a publication of your Python code.
You should disable the `semantic-release` job (as it's the `py-release` job that will perform the release and so we only need the `semantic-release-info` job) by setting `SEMREL_RELEASE_DISABLED` to `true`.
It is bound to the `publish` stage, applies only on git tags and uses the following variables:
Finally, the semantic-release integration can be disabled with the `PYTHON_SEMREL_RELEASE_DISABLED` variable.
| Name | description | default value |
| ---------------------- | -------------------------------------------------------- | ----------------- |
| `PYTHON_PUBLISH_ENABLED`| Set to `true` to enable the publish job | _none_ (disabled) |
| `TWINE_REPOSITORY_URL` | Where to publish your Python project | GitLab Project's Pypi Packages registry |
| `TWINE_USERNAME` | Username credential to publish to \$TWINE_REPOSITORY_URL | `gitlab-ci-token` |
| `TWINE_PASSWORD` | Password credential to publish to \$TWINE_REPOSITORY_URL | `$CI_JOB_TOKEN` |
####
More info:
#### Git authentication
A Python release involves some Git push operations.
You can either use a SSH key or user/password credentials.
##### Using a SSH key
We recommend you to use a [project deploy key](https://docs.gitlab.com/ee/user/project/deploy_keys/#project-deploy-keys) with write access to your project.
The key should not have a passphrase (see [how to generate a new SSH key pair](https://docs.gitlab.com/ce/ssh/README.html#generating-a-new-ssh-key-pair)).
Specify :lock: `$GIT_PRIVATE_KEY` as secret project variable with the private part of the deploy key.
```PEM
-----BEGIN OPENSSH PRIVATE KEY-----
blablabla
-----END OPENSSH PRIVATE KEY-----
```
The template handles both classic variable and file variable.
##### Using user/password credentials
* [Python Packaging User Guide](https://packaging.python.org/)
* [PyPI packages in the Package Registry](https://docs.gitlab.com/ee/user/packages/pypi_repository/)
Simply specify :lock: `$GIT_USERNAME` and :lock: `$GIT_PASSWORD` as secret project variables.
If you want to automatically create tag and publish your Python package, please have a look [here](#release-python)
Note that the password should be an access token (preferably a [project](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html) or [group](https://docs.gitlab.com/ee/user/group/settings/group_access_tokens.html) access token) with `read_repository` and `write_repository` scopes.
......@@ -150,51 +150,14 @@
}
]
},
{
"id": "package",
"name": "package",
"description": "Packaging of your Python code",
"variables": [
{
"name": "PYTHON_FORCE_PACKAGE",
"description": "Force the packaging even if not on tag related event",
"type": "boolean"
}
]
},
{
"id": "publish",
"name": "Publish",
"description": "Publish your code to a [Twine](https://pypi.org/project/twine/) repository",
"enable_with": "PYTHON_PUBLISH_ENABLED",
"variables": [
{
"name": "TWINE_REPOSITORY_URL",
"type": "url",
"description": "Twine repository url to publish you python project",
"default": "${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/pypi"
},
{
"name": "TWINE_USERNAME",
"description": "Twine repository username credential",
"secret": true,
"default": "gitlab-ci-token"
},
{
"name": "TWINE_PASSWORD",
"description": "Twine repository password credential",
"secret": true,
"default": "$CI_JOB_TOKEN"
}
]
},
{
"id": "release",
"name": "Release",
"description": "Manually trigger a release of your code (uses [bumpversion](https://pypi.org/project/bumpversion/))",
"enable_with": "PYTHON_RELEASE_ENABLED",
"variables": [
{
"name": "RELEASE_VERSION_PART",
"name": "PYTHON_RELEASE_NEXT",
"type": "enum",
"values": [
"",
......@@ -207,16 +170,43 @@
"advanced": true
},
{
"name": "RELEASE_USERNAME",
"description": "Username credential for Git push",
"name": "PYTHON_SEMREL_RELEASE_DISABLED",
"description": "Disable semantic-release integration",
"type": "boolean",
"advanced": true
},
{
"name": "GIT_USERNAME",
"description": "Git username for Git push operations",
"secret": true
},
{
"name": "GIT_PASSWORD",
"description": "Git password for Git push operations",
"secret": true
},
{
"name": "GIT_PRIVATE_KEY",
"description": "SSH key for Git push operations",
"secret": true
},
{
"name": "PYTHON_REPOSITORY_URL",
"type": "url",
"description": "Target PyPI repository to publish packages.\n\n_defaults to [GitLab project's packages repository](https://docs.gitlab.com/ee/user/packages/pypi_repository/)_",
"default": "${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/pypi"
},
{
"name": "PYTHON_REPOSITORY_USERNAME",
"description": "Target PyPI repository username credential",
"secret": true,
"mandatory": true
"default": "gitlab-ci-token"
},
{
"name": "RELEASE_ACCESS_TOKEN",
"description": "Password credential for Git push",
"name": "PYTHON_REPOSITORY_PASSWORD",
"description": "Target PyPI repository password credential",
"secret": true,
"mandatory": true
"default": "$CI_JOB_TOKEN"
}
]
}
......
......@@ -46,13 +46,13 @@ variables:
PYTHON_TRIVY_IMAGE: aquasec/trivy:latest
PYTHON_TRIVY_ARGS: "--vuln-type library"
RELEASE_VERSION_PART: "minor"
PYTHON_RELEASE_NEXT: "minor"
# By default, publish on the Packages registry of the project
# https://docs.gitlab.com/ee/user/packages/pypi_repository/#authenticate-with-a-ci-job-token
TWINE_REPOSITORY_URL: ${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/pypi
TWINE_USERNAME: 'gitlab-ci-token'
TWINE_PASSWORD: $CI_JOB_TOKEN
PYTHON_REPOSITORY_URL: ${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/pypi
PYTHON_REPOSITORY_USERNAME: 'gitlab-ci-token'
PYTHON_REPOSITORY_PASSWORD: $CI_JOB_TOKEN
.python-scripts: &python-scripts |
......@@ -360,65 +360,165 @@ variables:
if ! command -v poetry > /dev/null; then pip install ${PIP_OPTS} poetry; fi
poetry build
;;
setuptools)
*)
# shellcheck disable=SC2086
pip install ${PIP_OPTS} setuptools build
pip install ${PIP_OPTS} build
python -m build
;;
*)
log_error "--- packaging is unsupported with $PYTHON_BUILD_SYSTEM build system: read template doc"
exit 1
;;
esac
}
function _publish() {
case "$PYTHON_BUILD_SYSTEM" in
poetry)
# shellcheck disable=SC2086
if ! command -v poetry > /dev/null; then pip install ${PIP_OPTS} poetry; fi
poetry config repositories.user_defined "$TWINE_REPOSITORY_URL"
poetry publish --username "$TWINE_USERNAME" --password "$TWINE_PASSWORD" --repository user_defined
;;
setuptools)
# shellcheck disable=SC2086
pip install ${PIP_OPTS} twine
twine upload --verbose dist/*.tar.gz
twine upload --verbose dist/*.whl
;;
*)
log_error "--- publish is unsupported with $PYTHON_BUILD_SYSTEM build system: read template doc"
function configure_scm_auth() {
git_base_url=$(echo "$CI_REPOSITORY_URL" | cut -d\@ -f2)
if [[ -n "${GIT_USERNAME}" ]] && [[ -n "${GIT_PASSWORD}" ]]; then
log_info "--- using https protocol with SCM credentials from env (\$GIT_USERNAME and \$GIT_PASSWORD)..."
export git_auth_url="https://${GIT_USERNAME}:${GIT_PASSWORD}@${git_base_url}"
elif [[ -n "${GIT_PRIVATE_KEY}" ]]; then
log_info "--- using ssh protocol with SSH key from env (\$GIT_PRIVATE_KEY)..."
mkdir -m 700 "${HOME}/.ssh"
ssh-keyscan -H "${CI_SERVER_HOST}" >> ~/.ssh/known_hosts
eval "$(ssh-agent -s)"
# Handle file variable
if [[ -f "${GIT_PRIVATE_KEY}" ]]; then
tr -d '\r' < "${GIT_PRIVATE_KEY}" | ssh-add -
else
echo "${GIT_PRIVATE_KEY}" | tr -d '\r' | ssh-add -
fi
export git_auth_url="git@${git_base_url/\//:}"
else
log_error "--- Please specify either \$GIT_USERNAME and \$GIT_PASSWORD or \$GIT_PRIVATE_KEY variables to enable release (see doc)."
exit 1
;;
esac
fi
}
function _release() {
if [[ "${PYTHON_BUILD_SYSTEM}" == "poetry" ]]
# 0: guess packaging system
if [[ -f "pyproject.toml" ]]
then
# that might be PEP 517 if a build-backend is specified
# otherwise it might be only used as configuration file for development tools...
build_backend=$(sed -rn 's/^build-backend *= *"([^"]*)".*/\1/p' pyproject.toml)
if [[ "$build_backend" ]]
then
case "$build_backend" in
poetry.core.masonry.api)
log_info "--- Packaging system auto-detected: Poetry"
pkg_system="poetry"
;;
setuptools.build_meta)
log_info "--- Packaging system auto-detected: Setuptools (PEP 517)"
pkg_system="setuptools"
;;
*)
log_error "--- Unsupported PEP 517 backend \\e[33;1m${build_backend}\\e[0m: abort"
exit 1
;;
esac
fi
fi
if [[ -z "$pkg_system" ]]
then
if [[ -f "setup.py" ]]
then
log_info "--- Packaging system auto-detected: Setuptools (legacy)"
pkg_system="setuptools"
else
log_error "--- Couldn't find any supported packaging system: abort"
exit 1
fi
fi
# 1: retrieve next release info from semantic-release
if [ "$SEMREL_INFO_ON" ] && [ "$PYTHON_SEMREL_RELEASE_DISABLED" != "true" ]
then
if [ -z "$SEMREL_INFO_NEXT_VERSION" ]
then
log_info "[semantic-release] no new version to release: skip"
exit 0
else
py_cur_version="$SEMREL_INFO_LAST_VERSION"
py_next_version="$SEMREL_INFO_NEXT_VERSION"
py_release_part="$SEMREL_INFO_NEXT_VERSION_TYPE"
log_info "[semantic-release] new ($py_release_part) release required \\e[1;94m${py_cur_version}\\e[0m → \\e[1;94m${py_next_version}\\e[0m"
fi
fi
# 2: bumpversion (+ Git commit & tag)
if [[ "$pkg_system" == "poetry" ]]
then
# shellcheck disable=SC2086
if ! command -v poetry > /dev/null; then pip install ${PIP_OPTS} poetry; fi
poetry version "${RELEASE_VERSION_PART}"
if [[ -z "$py_next_version" ]]
then
py_cur_version=$(poetry version --short)
py_next_version="$PYTHON_RELEASE_NEXT"
fi
log_info "[Poetry] change version \\e[1;94m${py_cur_version}\\e[0m → \\e[1;94m${py_next_version}\\e[0m"
poetry version ${TRACE+--verbose} "$py_next_version"
# eval exact next version
py_next_version=$(poetry version --short)
git add pyproject.toml
git commit -m "chore(python-release): $py_cur_version → $py_next_version [ci skip]"
git tag "$py_next_version"
else
# Setuptools / bumpversion
# shellcheck disable=SC2086
pip install ${PIP_OPTS} bumpversion
if [[ -f ".bumpversion.cfg" ]]; then
log_info "--- .bumpversion.cfg file found "
export bumpversion_args="${RELEASE_VERSION_PART} --verbose"
py_commit_message="chore(python-release): {current_version} → {new_version} [ci skip]"
if [[ "$py_next_version" ]]
then
# explicit release version (semantic-release)
log_info "[Setuptools] bumpversion \\e[1;94m${py_cur_version}\\e[0m → \\e[1;94m${py_next_version}\\e[0m"
# create cfg in case it doesn't exist - will be updated by bumpversion
touch .bumpversion.cfg
bumpversion ${TRACE+--verbose} --current-version "$py_cur_version" --commit --message "$py_commit_message" --tag --tag-name "{new_version}" "$py_release_part"
elif [[ -f "setup.py" ]]
then
# retrieve current version from setup.py
py_cur_version=$(python setup.py --version)
py_release_part="$PYTHON_RELEASE_NEXT"
log_info "[Setuptools] bumpversion ($py_release_part) from \\e[1;94m${py_cur_version}\\e[0m"
bumpversion ${TRACE+--verbose} --current-version "$py_cur_version" --commit --message "$py_commit_message" --tag --tag-name "{new_version}" "$py_release_part"
elif [[ -f ".bumpversion.cfg" ]]
then
# current version shall be set in .bumpversion.cfg
py_release_part="$PYTHON_RELEASE_NEXT"
log_info "[bumpversion] increase \\e[1;94m${py_release_part}\\e[0m"
bumpversion ${TRACE+--verbose} --commit --message "$py_commit_message" --tag --tag-name "{new_version}" "$py_release_part"
else
log_info "--- No .bumpversion.cfg file found "
if [[ -f "setup.py" ]]; then
log_info "--- Getting current version of setup.py file "
current_version=$(python setup.py --version)
export bumpversion_args=" --verbose --current-version ${current_version} --tag --tag-name {new_version} --commit ${RELEASE_VERSION_PART} setup.py"
else
log_warn "--- No setup.py file found. Cannot perform release."
fi
log_error "--- setup.py or .bumpversion.cfg file required to retrieve current version: cannot perform release"
exit 1
fi
log_info "--- Release args: ${bumpversion_args}"
fi
# 3: Git commit, tag and push
log_info "--- git push commit and tag..."
git push "$git_auth_url" "$CI_BUILD_REF_NAME"
git push "$git_auth_url" --tags
# 4: build new version distribution
log_info "--- build distribution packages..."
if [[ "$pkg_system" == "poetry" ]]
then
poetry build ${TRACE+--verbose}
else
# shellcheck disable=SC2086
pip install ${PIP_OPTS} build
rm -rf dist
python -m build
fi
bumpversion "${bumpversion_args}"
# 5: publish packages
log_info "--- publish distribution packages..."
if [[ "$pkg_system" == "poetry" ]]
then
poetry config repositories.user_defined "$PYTHON_REPOSITORY_URL"
poetry publish ${TRACE+--verbose} --username "$PYTHON_REPOSITORY_USERNAME" --password "$PYTHON_REPOSITORY_PASSWORD" --repository user_defined
else
# shellcheck disable=SC2086
pip install ${PIP_OPTS} twine
twine upload ${TRACE+--verbose} --username "$PYTHON_REPOSITORY_USERNAME" --password "$PYTHON_REPOSITORY_PASSWORD" --repository-url "$PYTHON_REPOSITORY_URL" dist/*
fi
}
......@@ -473,12 +573,26 @@ variables:
stages:
- build
- test
- package-build
- publish
###############################################################################################
# build stage #
###############################################################################################
# build Python packages as artifacts
py-package:
extends: .python-base
stage: build
script:
- _package
artifacts:
paths:
- $PYTHON_PROJECT_DIR/dist/*
rules:
# exclude merge requests
- if: $CI_MERGE_REQUEST_ID
when: never
- if: '$PYTHON_PACKAGE_ENABLED == "true"'
py-lint:
extends: .python-base
stage: build
......@@ -713,7 +827,6 @@ py-trivy:
fi
trivy fs ${PYTHON_TRIVY_ARGS} --format table --exit-code 0 $PYTHON_PROJECT_DIR
trivy fs ${PYTHON_TRIVY_ARGS} --format json --output reports/trivy-python.json --exit-code 1 $PYTHON_PROJECT_DIR
artifacts:
name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
expire_in: 1 day
......@@ -735,62 +848,30 @@ py-trivy:
when: manual
allow_failure: true
###############################################################################################
# package stage #
###############################################################################################
# (on tag creation): create packages as artifacts
py-package:
extends: .python-base
stage: package-build
script:
- _package
artifacts:
paths:
- $PYTHON_PROJECT_DIR/dist/*.tar.gz
- $PYTHON_PROJECT_DIR/dist/*.whl
rules:
# on tags
- if: '$CI_COMMIT_TAG'
- if: '$PYTHON_FORCE_PACKAGE == "true"'
###############################################################################################
# publish stage #
###############################################################################################
# (on tag creation): performs a release
py-publish:
extends: .python-base
stage: publish
script:
- assert_defined "$TWINE_USERNAME" 'Missing required env $TWINE_USERNAME'
- assert_defined "$TWINE_PASSWORD" 'Missing required env $TWINE_PASSWORD'
- _publish
rules:
# on tags with $PYTHON_PUBLISH_ENABLED set
- if: '$PYTHON_PUBLISH_ENABLED == "true" && $CI_COMMIT_TAG'
# (manual from master branch): triggers a release (tag creation)
py-release:
extends: .python-base
stage: publish
script:
- git config --global user.email '$GITLAB_USER_EMAIL'
- git config --global user.name '$GITLAB_USER_LOGIN'
- git config --global user.email "$GITLAB_USER_EMAIL"
- git config --global user.name "$GITLAB_USER_LOGIN"
- git checkout -B $CI_BUILD_REF_NAME
- configure_scm_auth
- _release
- git_url_base=`echo ${CI_REPOSITORY_URL} | cut -d\@ -f2`
- git push https://${RELEASE_USERNAME}:${RELEASE_ACCESS_TOKEN}@${git_url_base} --tags
- git push https://${RELEASE_USERNAME}:${RELEASE_ACCESS_TOKEN}@${git_url_base} $CI_BUILD_REF_NAME
artifacts:
paths:
- $PYTHON_PROJECT_DIR/dist/*
rules:
# exclude merge requests
- if: $CI_MERGE_REQUEST_ID
when: never
# on production branch(es): manual & non-blocking if $RELEASE_USERNAME is set
- if: '$RELEASE_USERNAME && $CI_COMMIT_REF_NAME =~ $PROD_REF'
when: manual
allow_failure: true
# on integration branch(es): manual & non-blocking if $RELEASE_USERNAME is set
- if: '$RELEASE_USERNAME && $CI_COMMIT_REF_NAME =~ $INTEG_REF'
# exclude if $PYTHON_RELEASE_ENABLED not set
- if: '$PYTHON_RELEASE_ENABLED != "true"'
when: never
# exclude on non-prod, non-integ branches
- if: '$CI_COMMIT_REF_NAME !~ $PROD_REF && $CI_COMMIT_REF_NAME !~ $INTEG_REF'
when: never
# else: manual
- if: '$PYTHON_RELEASE_ENABLED == "true"' # useless but prevents GitLab warning
when: manual
allow_failure: true
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment