1111 samples-revision :
1212 default : 11.0.0
1313 description : khiops-samples repo revision
14- image-tag :
15- default : latest
16- description : Development Docker Image Tag
1714 pypi-target :
1815 type : choice
1916 default : None # no publishing to any Package Index by default
3027 build :
3128 runs-on : ubuntu-22.04
3229 permissions :
33- checks : write
3430 contents : read
35- id-token : write
36- packages : read
3731 steps :
3832 - name : Checkout sources
3933 uses : actions/checkout@v4
@@ -53,30 +47,63 @@ jobs:
5347 pip install build
5448
5549 # Build the source package (sdist) only
56- python3 -m build --sdist
50+ python -m build --sdist
5751 - name : Upload the package as artifact
5852 uses : actions/upload-artifact@v4
5953 with :
6054 name : pip-package
6155 path : ./dist/khiops*.tar.gz
56+ # Test Pip package on brand new environments
6257 test :
6358 needs : build
64- runs-on : ubuntu-22.04
6559 strategy :
6660 fail-fast : false
6761 matrix :
68- container : [ubuntu22.04, rocky9, debian13]
69- container :
70- # 'latest' default image tag cannot be set as an environment variable,
71- # because the `env` context is only accessible at the step level;
72- # hence, it is hard-coded
73- image : |-
74- ghcr.io/khiopsml/khiops-python/khiopspydev-${{ matrix.container }}:${{ inputs.image-tag || 'latest' }}
62+ env :
63+ # Test without virtualenv only on platforms that support it out of the
64+ # box (i.e. where passing `--break-system-packages` to Pip is not
65+ # required)
66+ - {os: ubuntu-24.04, json-image: '{"image": null}', use-virtualenv: true}
67+ - {os: ubuntu-24.04, json-image: '{"image": null}', use-virtualenv: false}
68+ - {os: ubuntu-22.04, json-image: '{"image": "debian:trixie"}', use-virtualenv: true}
69+ - {os: ubuntu-22.04, json-image: '{"image": "rockylinux/rockylinux:10"}', use-virtualenv: true}
70+ - {os: ubuntu-22.04, json-image: '{"image": "rockylinux/rockylinux:10"}', use-virtualenv: false}
71+ - {os: windows-2025, json-image: '{"image": null}', use-virtualenv: true}
72+ - {os: windows-2025, json-image: '{"image": null}', use-virtualenv: false}
73+ - {os: macos-15, json-image: '{"image": null}', use-virtualenv: true}
74+ runs-on : ${{ matrix.env.os }}
75+ container : ${{ fromJSON(matrix.env.json-image) }}
7576 steps :
77+ - name : Make sure Python is installed on Linux (might not be in containers)
78+ if : fromJSON(matrix.env.json-image).image != null
79+ shell : sh
80+ run : |
81+ if command -v apt-get; then
82+ apt-get update -y
83+ apt-get install -y python3 python3-pip python3-venv
84+ elif command -v dnf; then
85+ dnf install -y python3 python3-pip
86+ # Install findutils on Rocky Linux when xargs cannot be found
87+ if ! command -v xargs; then
88+ dnf install -y findutils
89+ fi
90+ fi
7691 - name : Set parameters as env
92+ shell : bash
7793 run : |
7894 SAMPLES_REVISION=${{ inputs.samples-revision || env.DEFAULT_SAMPLES_REVISION }}
7995 echo "SAMPLES_REVISION=$SAMPLES_REVISION" >> "$GITHUB_ENV"
96+ if [[ $RUNNER_OS == 'Windows' ]]; then
97+ VENV_ACTIVATE_SCRIPT="khiops-venv/Scripts/activate"
98+ else
99+ VENV_ACTIVATE_SCRIPT="khiops-venv/bin/activate"
100+ fi
101+ echo "VENV_ACTIVATE_SCRIPT=$VENV_ACTIVATE_SCRIPT" >> "$GITHUB_ENV"
102+ # Setup Python (be portable wrt. python vs python3 in runners and
103+ # containers; either python3 or python is present as per the Python
104+ # installation step in the Docker container contexts)
105+ PYTHON=$(basename $(command -v python3 || command -v python))
106+ echo "PYTHON=$PYTHON" >> "$GITHUB_ENV"
80107 - name : Checkout sources # Checkout the sources to be able to extract the dependencies list
81108 uses : actions/checkout@v4
82109 with :
@@ -97,30 +124,37 @@ jobs:
97124 - name : Install the package
98125 shell : bash
99126 run : |
100- # Allow Pip to write to its cache
101- mkdir -p /github/home/.cache/pip
102- chown -R $(whoami) /github/home/.cache/pip
127+ # Allow Pip to write to its cache (only applies to Docker containers)
128+ if [[ -n "${{ fromJSON(matrix.env.json-image).image }}" ]]; then
129+ mkdir -p /github/home/.cache/pip
130+ chown -R $(whoami) /github/home/.cache/pip
131+ fi
103132
104133 # Install the Khiops Python library
105134
106- # A virtual env is mandatory under debian
107- if [[ "${{ matrix.container }}" == "debian13 " ]]; then
108- python -m venv khiops-debian -venv
109- source khiops-debian-venv/bin/activate
135+ # Use a virtualenv if required
136+ if [[ "${{ matrix.env.use-virtualenv }}" == "true " ]]; then
137+ $PYTHON -m venv khiops-venv
138+ source "$VENV_ACTIVATE_SCRIPT"
110139 fi
111- pip install --upgrade pip
140+ $PYTHON -m pip install --upgrade pip
112141 # Add homogeneous TOML support (Python >= 3.12 has standard tomllib)
113- pip install tomli
142+ $PYTHON -c "import tomllib" 2>/dev/null || $PYTHON -m pip install tomli
114143 # First, install all dependencies except khiops-core and khiops-drivers-*
115- python scripts/extract_dependencies_from_pyproject_toml.py -f "pyproject.toml" --exclude-khiops-family > requires-no-khiops.txt
116- pip install `cat requires-no-khiops.txt`
144+ $PYTHON scripts/extract_dependencies_from_pyproject_toml.py -f "pyproject.toml" --exclude-khiops-family > requires-no-khiops.txt
145+ [ ! -s requires-no-khiops.txt ] || xargs $PYTHON -m pip install < requires-no-khiops.txt
146+ # On Windows, the `impi-rt` MPI dependency must be installed
147+ # separately, from PyPI, because it is not present on TestPyPI
148+ if [[ $RUNNER_OS == 'Windows' ]]; then
149+ $PYTHON -m pip install impi-rt
150+ fi
117151 # khiops-core and khiops-drivers-* must always be installed from TestPyPI in order to avoid distorting usage statistics
118- python scripts/extract_dependencies_from_pyproject_toml.py -f "pyproject.toml" --khiops-family-only > requires-khiops.txt
119- pip install --index-url https://test.pypi.org/simple `cat requires-khiops.txt`
152+ $PYTHON scripts/extract_dependencies_from_pyproject_toml.py -f "pyproject.toml" --khiops-family-only > requires-khiops.txt
153+ [ ! -s requires-khiops.txt ] || xargs $PYTHON -m pip install --index-url https://test.pypi.org/simple < requires-khiops.txt
120154 rm -f requires-khiops.txt requires-no-khiops.txt
121155 # Lastly, install khiops-python
122- pip install $(ls khiops*.tar.gz)
123- if [[ "${{ matrix.container }}" == "debian13 " ]]; then
156+ $PYTHON -m pip install khiops*.tar.gz
157+ if [[ "${{ matrix.env.use-virtualenv }}" == "true " ]]; then
124158 deactivate
125159 fi
126160 - name : Run tests
@@ -140,12 +174,13 @@ jobs:
140174 # modules are currently not initializing the shell anyway
141175 if [ -n "$MODULESHOME" ]; then module unload mpi; fi
142176
143- # A virtual env is mandatory under debian
144- if [[ "${{ matrix.container }}" == "debian13 " ]]; then
145- source khiops-debian-venv/bin/activate
177+ # Use a virtualenv if required
178+ if [[ "${{ matrix.env.use-virtualenv }}" == "true " ]]; then
179+ source "$VENV_ACTIVATE_SCRIPT"
146180 fi
147- if [[ $RUNNER_OS != 'Windows' ]]; then
148- # Set rights to OpenMPI-specific folder
181+ if [[ -n "${{ fromJSON(matrix.env.json-image).image }}" ]]; then
182+ # Set rights to OpenMPI-specific folder (only applies to Docker
183+ # containers)
149184 mkdir -p /github/home/.pmix/components
150185 chown -R $(whoami) /github/home/.pmix/components
151186 fi
@@ -163,7 +198,7 @@ jobs:
163198 # The MPI command is not always named mpiexec, but can be orterun etc
164199 # (as given by khiops_env)
165200 kh-status | grep "MPI command" | grep -vwq "<empty>"
166- if [[ "${{ matrix.container }}" == "debian13 " ]]; then
201+ if [[ "${{ matrix.env.use-virtualenv }}" == "true " ]]; then
167202 deactivate
168203 fi
169204 - name : Test package / Git tag version coherence
@@ -172,19 +207,18 @@ jobs:
172207 run : |
173208 # Don't exit on first error: print relevant error message
174209 set +e
175- # A virtual env is mandatory under Debian 13
176- if [[ "${{ matrix.container }}" == "debian13" ]]; then
177- python -m venv khiops-debian-venv
178- source khiops-debian-venv/bin/activate
210+ # Use a virtualenv if required
211+ if [[ "${{ matrix.env.use-virtualenv }}" == "true" ]]; then
212+ source "$VENV_ACTIVATE_SCRIPT"
179213 fi
180214 # Convert pre-release version specification in the Git tag to the Pip
181215 # format and check that it matches the Pip package version
182- PACKAGE_VERSION=$(pip show khiops | awk 'BEGIN {FS = ": "} $1 ~ /^Version$/ {print $2}')
183- if [[ "${{ matrix.container }}" == "debian13 " ]]; then
216+ PACKAGE_VERSION=$($PYTHON -m pip show khiops | awk 'BEGIN {FS = ": "} $1 ~ /^Version$/ {print $2}')
217+ if [[ "${{ matrix.env.use-virtualenv }}" == "true " ]]; then
184218 deactivate
185219 fi
186- echo ${{ github.ref_name }} | tr -d '-' | rev | sed -E 's/\.([^0-9].*)/\1/' | rev | \
187- grep -wq $PACKAGE_VERSION
220+ echo " ${{ github.ref_name }}" | tr -d '-' | rev | sed -E 's/\.([^0-9].*)/\1/' | rev | \
221+ grep -wq " $PACKAGE_VERSION"
188222 if [[ $? -ne 0 ]]
189223 then
190224 echo "::error::Python package version $PACKAGE_VERSION does not match Git tag ${{ github.ref_name }}"
0 commit comments