Skip to content

Fix tag version check #1190

Fix tag version check

Fix tag version check #1190

Workflow file for this run

---
# After building and testing the pip package,
# this workflow publishes it to Github Release by default
# and to Test PyPI (TEST) or PyPI (PROD) if requested
name: Pip Package
env:
DEFAULT_SAMPLES_REVISION: 11.0.0
on:
workflow_dispatch:
inputs:
samples-revision:
default: 11.0.0
description: khiops-samples repo revision
pypi-target:
type: choice
default: None # no publishing to any Package Index by default
options: [None, testpypi, pypi]
description: Publish to Test PyPI or PyPI
pull_request:
paths: [pyproject.toml, LICENSE.md, .github/workflows/pip.yml]
push:
tags: ['*']
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-24.04
permissions:
contents: read
outputs:
package-version: ${{ steps.build.outputs.PACKAGE_VERSION }}
steps:
- name: Checkout sources
uses: actions/checkout@v4
with:
# Get Git tags so that versioneer can function correctly
# See issue https://github.com/actions/checkout/issues/701
fetch-depth: 0
- name: Build Pip package
id: build
run: |
# This is needed so that the Git tag is parsed and the version is
# retrieved
git config --global --add safe.directory $(realpath .)
# Upgrade Pip
pip install --upgrade pip
# Install required Python build dependency
pip install build
# Build the source package (sdist) only
python -m build --sdist
# Get built package version and make it accessible to subsequent jobs
PACKAGE_VERSION=$(python -m build --metadata | jq ".version" | tr -d '"')
echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> "$GITHUB_OUTPUT"
- name: Upload the package as artifact
uses: actions/upload-artifact@v4
with:
name: pip-package
path: ./dist/khiops*.tar.gz
# Test Pip package on brand new environments
test:
needs: build
strategy:
fail-fast: false
matrix:
env:
# Test without virtualenv only on platforms that support it out of the
# box (i.e. where passing `--break-system-packages` to Pip is not
# required)
- {os: ubuntu-24.04, json-image: '{"image": null}', use-virtualenv: true}
- {os: ubuntu-24.04, json-image: '{"image": null}', use-virtualenv: false}
- {os: ubuntu-22.04, json-image: '{"image": "debian:trixie"}', use-virtualenv: true}
- {os: ubuntu-22.04, json-image: '{"image": "rockylinux/rockylinux:10"}', use-virtualenv: true}
- {os: ubuntu-22.04, json-image: '{"image": "rockylinux/rockylinux:10"}', use-virtualenv: false}
- {os: windows-2025, json-image: '{"image": null}', use-virtualenv: true}
- {os: windows-2025, json-image: '{"image": null}', use-virtualenv: false}
- {os: macos-15, json-image: '{"image": null}', use-virtualenv: true}
runs-on: ${{ matrix.env.os }}
container: ${{ fromJSON(matrix.env.json-image) }}
steps:
- name: Make sure Python is installed on Linux (might not be in containers)
if: fromJSON(matrix.env.json-image).image != null
shell: sh
run: |
if command -v apt-get; then
apt-get update -y
apt-get install -y python3 python3-pip python3-venv
elif command -v dnf; then
dnf install -y python3 python3-pip
# Install findutils on Rocky Linux when xargs cannot be found
if ! command -v xargs; then
dnf install -y findutils
fi
fi
- name: Set parameters as env
shell: bash
run: |
SAMPLES_REVISION=${{ inputs.samples-revision || env.DEFAULT_SAMPLES_REVISION }}
echo "SAMPLES_REVISION=$SAMPLES_REVISION" >> "$GITHUB_ENV"
if [[ $RUNNER_OS == 'Windows' ]]; then
VENV_ACTIVATE_SCRIPT="khiops-venv/Scripts/activate"
else
VENV_ACTIVATE_SCRIPT="khiops-venv/bin/activate"
fi
echo "VENV_ACTIVATE_SCRIPT=$VENV_ACTIVATE_SCRIPT" >> "$GITHUB_ENV"
# Setup Python (be portable wrt. python vs python3 in runners and
# containers; either python3 or python is present as per the Python
# installation step in the Docker container contexts)
PYTHON=$(basename $(command -v python3 || command -v python))
echo "PYTHON=$PYTHON" >> "$GITHUB_ENV"
# Checkout the sources to be able to extract the dependencies list
- name: Checkout sources
uses: actions/checkout@v4
with:
# Get Git tags
# See issue https://github.com/actions/checkout/issues/701
fetch-depth: 0
- name: Checkout Khiops samples
uses: actions/checkout@v4
with:
repository: khiopsml/khiops-samples
ref: ${{ env.SAMPLES_REVISION }}
token: ${{ secrets.GITHUB_TOKEN }}
path: khiops-samples
- name: Download package artifact
uses: actions/download-artifact@v4
with:
name: pip-package
- name: Install the package
shell: bash
run: |
# Allow Pip to write to its cache (only applies to Docker containers)
if [[ -n "${{ fromJSON(matrix.env.json-image).image }}" ]]; then
mkdir -p /github/home/.cache/pip
chown -R $(whoami) /github/home/.cache/pip
fi
# Use a virtualenv if required
if [[ "${{ matrix.env.use-virtualenv }}" == "true" ]]; then
$PYTHON -m venv khiops-venv
source "$VENV_ACTIVATE_SCRIPT"
fi
$PYTHON -m pip install --upgrade pip
# Add homogeneous TOML support (Python >= 3.12 has standard tomllib)
$PYTHON -c "import tomllib" 2>/dev/null || $PYTHON -m pip install tomli
# Install all dependencies except khiops-*
$PYTHON scripts/extract_dependencies_from_pyproject_toml.py -f "pyproject.toml" --exclude-khiops-family > requires-no-khiops.txt
[ ! -s requires-no-khiops.txt ] || xargs $PYTHON -m pip install < requires-no-khiops.txt
# On Windows, the `impi-rt` MPI dependency must be installed
# separately, from PyPI, because it is not present on TestPyPI
if [[ $RUNNER_OS == 'Windows' ]]; then
$PYTHON -m pip install impi-rt
fi
# khiops-core and khiops-drivers-* must always be installed from
# TestPyPI in order to avoid distorting usage statistics
$PYTHON scripts/extract_dependencies_from_pyproject_toml.py -f "pyproject.toml" --khiops-family-only > requires-khiops.txt
[ ! -s requires-khiops.txt ] || xargs $PYTHON -m pip install --index-url https://test.pypi.org/simple < requires-khiops.txt
rm -f requires-khiops.txt requires-no-khiops.txt
# Install the khiops package
$PYTHON -m pip install khiops*.tar.gz
# Deactivate virtualenv if used
if [[ "${{ matrix.env.use-virtualenv }}" == "true" ]]; then
deactivate
fi
- name: Run tests
env:
KHIOPS_SAMPLES_DIR: ${{ github.workspace }}/khiops-samples
# Force > 2 CPU cores to launch mpiexec
KHIOPS_PROC_NUMBER: 4
# Oversubscribe for Open MPI 4.x
rmaps_base_oversubscribe: true
OMPI_MCA_rmaps_base_oversubscribe: true
# Oversubscribe for Open MPI >= 5
PRTE_MCA_rmaps_default_mapping_policy: :oversubscribe
shell: bash
run: |-
# Make sure MPI support is not loaded through env modules
# Note: As the Docker container's shell is non-interactive, environment
# modules are currently not initializing the shell anyway
if [ -n "$MODULESHOME" ]; then module unload mpi; fi
# Use a virtualenv if required
if [[ "${{ matrix.env.use-virtualenv }}" == "true" ]]; then
source "$VENV_ACTIVATE_SCRIPT"
fi
if [[ -n "${{ fromJSON(matrix.env.json-image).image }}" ]]; then
# Set rights to OpenMPI-specific folder (only applies to Docker
# containers)
mkdir -p /github/home/.pmix/components
chown -R $(whoami) /github/home/.pmix/components
fi
# Print khiops installation status
kh-status
# Run some simple training tasks
kh-samples core -i train_predictor -e
kh-samples core -i train_coclustering -e
kh-samples sklearn -i khiops_classifier -e
# Test that the line containing "MPI command" does not contain "<empty>"
# (as given by kh-status in the absence of MPI support)
# The MPI command is not always named mpiexec, but can be orterun etc
# (as given by khiops_env)
kh-status | grep "MPI command" | grep -vwq "<empty>"
# Deactivate virtualenv if used
if [[ "${{ matrix.env.use-virtualenv }}" == "true" ]]; then
deactivate
fi
check-package-version:
if: github.ref_type == 'tag'
needs: build
runs-on: ubuntu-24.04
steps:
- name: Test package / Git tag version coherence
env:
PACKAGE_VERSION: ${{ needs.build.outputs.package-version }}
shell: bash
run: |
# Don't exit on first error: print relevant error message
set +e
# Convert pre-release version specification in the Git tag to the Pip
# format and check that it matches the Pip package version
echo "${{ github.ref_name }}" | tr -d '-' | rev | sed -E 's/\.([^0-9].*)/\1/' | rev | \
grep -wq "$PACKAGE_VERSION"
if [[ $? -ne 0 ]]
then
echo "::error::Python package version $PACKAGE_VERSION does not match Git tag ${{ github.ref_name }}"
false
fi
# The implementation of a unique release job with multiple conditional steps
# for each publishing mode is not chosen
# because of the required job environment verified for Trusted Publishing
release-github:
# only publish on tag pushes
if: github.ref_type == 'tag' && github.repository_owner == 'KhiopsML'
needs: [test, check-package-version]
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Download package artifact
uses: actions/download-artifact@v4
with:
name: pip-package
- name: Upload Pip source package to the github release
uses: ncipollo/release-action@v1.15.0
with:
allowUpdates: true
artifacts: khiops*.tar.gz
body: '**For testing purposes only**'
draft: false
makeLatest: false
prerelease: true
updateOnlyUnreleased: true
release-testpypi:
# only publish on testpypi if requested and on tag pushes
if: inputs.pypi-target == 'testpypi' && github.ref_type == 'tag' && github.repository_owner == 'KhiopsML'
needs: [test, check-package-version]
runs-on: ubuntu-24.04
permissions:
# IMPORTANT: OIDC token mandatory for trusted publishing on TestPyPI and PyPI
id-token: write
# required job environment verified for Trusted Publishing
environment:
name: testpypi
steps:
- name: Download package artifact
uses: actions/download-artifact@v4
with:
name: pip-package
path: dist/
- name: Publish Python distribution to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true
repository-url: https://test.pypi.org/legacy/
release-pypi:
# only publish on pypi if requested and on tag pushes
if: inputs.pypi-target == 'pypi' && github.ref_type == 'tag' && github.repository_owner == 'KhiopsML'
needs: [test, check-package-version]
runs-on: ubuntu-24.04
permissions:
# IMPORTANT: OIDC token mandatory for trusted publishing on TestPyPI and PyPI
id-token: write
# required job environment verified for Trusted Publishing
environment:
name: pypi
steps:
- name: Download package artifact
uses: actions/download-artifact@v4
with:
name: pip-package
path: dist/
- name: Publish Python distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true