From 1a58dd1908c6a210ff9a285bc2a61b0fdcb1410b Mon Sep 17 00:00:00 2001
From: Pierre Smeyers <pierre.smeyers@gmail.com>
Date: Sat, 22 Apr 2023 18:59:08 +0200
Subject: [PATCH] feat(release): implement 2 steps release

---
 templates/gitlab-ci-python.yml | 67 ++++++++++++++++++++++++++++++++--
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/templates/gitlab-ci-python.yml b/templates/gitlab-ci-python.yml
index c7ee88e..25803e4 100644
--- a/templates/gitlab-ci-python.yml
+++ b/templates/gitlab-ci-python.yml
@@ -63,6 +63,8 @@ variables:
   PROD_REF: '/^(master|main)$/'
   # default integration ref name (pattern)
   INTEG_REF: '/^develop$/'
+  # default release tag name (pattern)
+  RELEASE_REF: '/^v?[0-9]+\.[0-9]+\.[0-9]+$/'
 
   # compileall
   PYTHON_COMPILE_ARGS: "*"
@@ -491,13 +493,13 @@ variables:
       # 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 commit -m "chore(python-release): $py_cur_version → $py_next_version"
       git tag "$py_next_version"
     else
       # Setuptools / bumpversion
       # shellcheck disable=SC2086
       pip install ${PIP_OPTS} bumpversion
-      py_commit_message="chore(python-release): {current_version} → {new_version} [ci skip]"
+      py_commit_message="chore(python-release): {current_version} → {new_version}"
       if [[ "$py_next_version" ]]
       then
         # explicit release version (semantic-release)
@@ -528,11 +530,52 @@ variables:
     log_info "--- git push commit and tag..."
     git push "$git_auth_url" "$CI_COMMIT_REF_NAME"
     git push "$git_auth_url" --tags
+  }
+
+  function _publish() {
+    # 1: 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
 
-    # 4: build new version distribution
+    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
+
+    # 2: build (new version) distribution
     log_info "--- build distribution packages..."
     if [[ "$pkg_system" == "poetry" ]]
     then
+      # shellcheck disable=SC2086
+      if ! command -v poetry > /dev/null; then pip install ${PIP_OPTS} poetry; fi
       poetry build ${TRACE+--verbose}
     else
       # shellcheck disable=SC2086
@@ -541,7 +584,7 @@ variables:
       python -m build
     fi
 
-    # 5: publish packages
+    # 3: publish built packages
     log_info "--- publish distribution packages..."
     if [[ "$pkg_system" == "poetry" ]]
     then
@@ -904,3 +947,19 @@ py-release:
     - if: '$CI_COMMIT_REF_NAME =~ $PROD_REF || $CI_COMMIT_REF_NAME =~ $INTEG_REF'
       when: manual
       allow_failure: true
+
+# (manual from master branch): triggers a release (tag creation)
+py-publish:
+  extends: .python-base
+  stage: publish
+  script:
+    - _publish $CI_COMMIT_TAG
+  artifacts:
+    paths:
+      - $PYTHON_PROJECT_DIR/dist/*
+  rules:
+    # exclude if $PYTHON_RELEASE_ENABLED not set
+    - if: '$PYTHON_RELEASE_ENABLED != "true"'
+      when: never
+    # on tag with release pattern: auto
+    - if: '$CI_COMMIT_TAG =~ $RELEASE_REF'
-- 
GitLab