Commit 38ecc2ba authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

refactor: reuse $PYTHON_BUILD_SYSTEM for packaging and release

parent 1a58dd19
Loading
Loading
Loading
Loading
+52 −135
Original line number Diff line number Diff line
@@ -251,15 +251,7 @@ variables:
    case "${PYTHON_BUILD_SYSTEM:-auto}" in
    auto)
      ;;
    poetry*)
      log_info "--- Build system explictly declared: ${PYTHON_BUILD_SYSTEM}"
      return
      ;;
    setuptools*)
      log_info "--- Build system explictly declared: ${PYTHON_BUILD_SYSTEM}"
      return
      ;;
    pipenv*)
    poetry*|setuptools*|pipenv*)
      log_info "--- Build system explictly declared: ${PYTHON_BUILD_SYSTEM}"
      return
      ;;
@@ -320,6 +312,14 @@ variables:
    fi
  }

  function maybe_install_poetry() {
    if [[ "$PYTHON_BUILD_SYSTEM" == poetry* ]] && ! command -v poetry > /dev/null
    then
      # shellcheck disable=SC2086
      pip install ${PIP_OPTS} "$PYTHON_BUILD_SYSTEM"
    fi
  }

  # install requirements
  function install_requirements() {
    case "$PYTHON_BUILD_SYSTEM" in
@@ -327,8 +327,7 @@ variables:
      if  [[ ! -f "poetry.lock" ]]; then
        log_warn "Using Poetry but \\e[33;1mpoetry.lock\\e[0m file not found: you shall commit it with your project files"
      fi
      # shellcheck disable=SC2086
      pip install ${PIP_OPTS} "$PYTHON_BUILD_SYSTEM"
      maybe_install_poetry
      poetry install ${PYTHON_EXTRA_DEPS:+--extras "$PYTHON_EXTRA_DEPS"}
      ;;
    setuptools*)
@@ -368,10 +367,9 @@ variables:
  }

  function _run() {
    if [[ "${PYTHON_BUILD_SYSTEM}" =~ poetry.* ]]
    if [[ "$PYTHON_BUILD_SYSTEM" == poetry* ]]
    then
      # shellcheck disable=SC2086
      if ! command -v poetry > /dev/null; then pip install ${PIP_OPTS} poetry; fi
      maybe_install_poetry
      poetry run "$@"
    else
      "$@"
@@ -387,19 +385,16 @@ variables:
    _run pip ${PIP_OPTS} "$@"
  }

  function _package() {
    case "$PYTHON_BUILD_SYSTEM" in
    poetry)
      # shellcheck disable=SC2086
      if ! command -v poetry > /dev/null; then pip install ${PIP_OPTS} poetry; fi
  function py_package() {
    if [[ "$PYTHON_BUILD_SYSTEM" == poetry* ]]
    then
      maybe_install_poetry
      poetry build
      ;;
    *)
    else
      # shellcheck disable=SC2086
      pip install ${PIP_OPTS} build
      python -m build
      ;;
    esac
    fi
  }

  function configure_scm_auth() {
@@ -425,44 +420,7 @@ variables:
    fi
  }

  function _release() {
    # 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

  function py_release() {
    # 1: retrieve next release info from semantic-release
    if [ "$SEMREL_INFO_ON" ] && [ "$PYTHON_SEMREL_RELEASE_DISABLED" != "true" ]
    then
@@ -479,19 +437,19 @@ variables:
    fi

    # 2: bumpversion (+ Git commit & tag)
    if [[ "$pkg_system" == "poetry" ]]
    if [[ "$PYTHON_BUILD_SYSTEM" == poetry* ]]
    then
      # shellcheck disable=SC2086
      if ! command -v poetry > /dev/null; then pip install ${PIP_OPTS} poetry; fi
      maybe_install_poetry
      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"
      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 commit and tag
      git add pyproject.toml
      git commit -m "chore(python-release): $py_cur_version → $py_next_version"
      git tag "$py_next_version"
@@ -503,7 +461,7 @@ variables:
      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"
        log_info "[bumpversion] change version \\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"
@@ -518,7 +476,7 @@ variables:
        # 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"
        log_info "[bumpversion] increase \\e[1;94m${py_release_part}\\e[0m (from current \\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" setup.py
      else
        log_error "--- setup.py or .bumpversion.cfg file required to retrieve current version: cannot perform release"
@@ -532,67 +490,26 @@ variables:
    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

    if [[ -z "$pkg_system" ]]
    then
      if [[ -f "setup.py" ]]
  function py_publish() {
    if [[ "$PYTHON_BUILD_SYSTEM" == poetry* ]]
    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
      maybe_install_poetry
 
    # 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
      log_info "--- build packages (poetry)..."
      poetry build ${TRACE+--verbose}
    else
      # shellcheck disable=SC2086
      pip install ${PIP_OPTS} build
      rm -rf dist
      python -m build
    fi

    # 3: publish built packages
    log_info "--- publish distribution packages..."
    if [[ "$pkg_system" == "poetry" ]]
    then
      log_info "--- publish packages (poetry)..."
      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
      pip install ${PIP_OPTS} build twine
 
      log_info "--- build packages (build)..."
      rm -rf dist
      python -m build

      log_info "--- publish packages (twine)..."
      twine upload ${TRACE+--verbose} --username "$PYTHON_REPOSITORY_USERNAME" --password "$PYTHON_REPOSITORY_PASSWORD" --repository-url "$PYTHON_REPOSITORY_URL" dist/*
    fi
  }
@@ -601,6 +518,14 @@ variables:

  # ENDSCRIPT

###############################################################################################
#                                      stages definition                                      #
###############################################################################################
stages:
  - build
  - test
  - publish

###############################################################################################
#                                      Generic python job                                     #
###############################################################################################
@@ -623,14 +548,6 @@ variables:
    - cd ${PYTHON_PROJECT_DIR}
    - guess_build_system

###############################################################################################
#                                      stages definition                                      #
###############################################################################################
stages:
  - build
  - test
  - publish

###############################################################################################
#                                      build stage                                             #
###############################################################################################
@@ -639,7 +556,7 @@ py-package:
  extends: .python-base
  stage: build
  script:
    - _package
    - py_package
  artifacts:
    paths:
      - $PYTHON_PROJECT_DIR/dist/*
@@ -840,7 +757,7 @@ py-trivy:
    - apt-get update
    - apt-get install trivy
    - |
      if [[ "$PYTHON_BUILD_SYSTEM" =~ poetry.* ]]
      if [[ "$PYTHON_BUILD_SYSTEM" == poetry* ]]
      then
        # When using Poetry, `pip freeze` outputs a requirements.txt with @file URLs for each wheel
        # These @file URLs in requirements.txt are not supported by Trivy
@@ -935,7 +852,7 @@ py-release:
    - git config --global user.name "$GITLAB_USER_LOGIN"
    - git checkout -B $CI_COMMIT_REF_NAME
    - configure_scm_auth
    - _release
    - py_release
  artifacts:
    paths:
      - $PYTHON_PROJECT_DIR/dist/*
@@ -948,12 +865,12 @@ py-release:
      when: manual
      allow_failure: true

# (manual from master branch): triggers a release (tag creation)
# (auto from release tag): publishes the Python package(s) to a PyPi registry
py-publish:
  extends: .python-base
  stage: publish
  script:
    - _publish $CI_COMMIT_TAG
    - py_publish $CI_COMMIT_TAG
  artifacts:
    paths:
      - $PYTHON_PROJECT_DIR/dist/*