Skip to content

Update CI to use newer python versions #786

Update CI to use newer python versions

Update CI to use newer python versions #786

Workflow file for this run

name: CI
concurrency:
group: ${{ github.head_ref || github.sha }}
cancel-in-progress: true
on:
pull_request:
workflow_dispatch:
# schedule:
# - cron: "0 1 * * *"
jobs:
build_and_test_linux:
if: ${{ github.event_name == 'workflow_dispatch' }}
strategy:
fail-fast: false
matrix:
include:
- {platform: 'ubuntu-22.04', python_version: '3.10', mgversion: 'latest'}
- {platform: 'ubuntu-24.04', python_version: '3.10', mgversion: 'latest'}
- {platform: 'ubuntu-24.04', python_version: '3.11', mgversion: 'latest'}
- {platform: 'ubuntu-24.04', python_version: '3.12', mgversion: 'latest'}
- {platform: 'ubuntu-24.04', python_version: '3.13', mgversion: 'latest'}
- {platform: 'fedora-41', python_version: '3.13', mgversion: 'latest'}
runs-on: ["self-hosted", "X64"]
steps:
- name: Checkout repository and submodules
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Set Memgraph Version
run: |
if [[ "${{ matrix.mgversion }}" == "latest" ]]; then
mgversion=$(curl -s https://api.github.com/repos/memgraph/memgraph/releases/latest | jq -r .tag_name)
mgversion=${mgversion#v}
else
mgversion="${{ matrix.mgversion }}"
fi
echo "MGVERSION=$mgversion" >> $GITHUB_ENV
- name: Download Memgraph
run: |
if [[ "${{ matrix.platform }}" == "fedora-41" ]]; then
MEMGRAPH_PACKAGE_NAME="memgraph-${{ env.MGVERSION }}_1-1.x86_64.rpm"
LOCAL_PACKAGE_NAME=memgraph.rpm
else
MEMGRAPH_PACKAGE_NAME="memgraph_${{ env.MGVERSION }}-1_amd64.deb"
LOCAL_PACKAGE_NAME=memgraph.deb
fi
curl -L "https://download.memgraph.com/memgraph/v${{ env.MGVERSION }}/${{ matrix.platform }}/${MEMGRAPH_PACKAGE_NAME}" > "${LOCAL_PACKAGE_NAME}"
echo "LOCAL_PACKAGE_NAME=$LOCAL_PACKAGE_NAME" >> $GITHUB_ENV
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Launch Docker Container
run: |
platform="${{ matrix.platform }}"
tag=${platform//-/:}
docker run -d --rm --name testcontainer "$tag" sleep infinity
- name: Set Environment Variables
run: |
break_packages=""
static_ssl=""
if [[ "${{ matrix.platform }}" == "ubuntu-24.04" ]]; then
# this option is specific to ubuntu, not fedora
break_packages="--break-system-packages"
elif [[ "${{ matrix.platform }}" == fedora* ]]; then
# rpm distros do not ship with static lib for openssl
static_ssl="--no-build-isolation --global-option=build_ext --global-option '--static-openssl=False'"
fi
echo "BREAK_PACKAGES=$break_packages" >> $GITHUB_ENV
echo "STATIC_SSL=$static_ssl" >> $GITHUB_ENV
- name: Install system dependencies
run: |
docker cp $LOCAL_PACKAGE_NAME testcontainer:/$LOCAL_PACKAGE_NAME
if [[ "${{ matrix.platform }}" == "fedora-41" ]]; then
docker exec -i testcontainer \
bash -c "dnf install -y python${{ matrix.python_version }} python3-pip python3-setuptools python3-wheel python3-devel cmake g++ openssl-devel nmap-ncat"
docker exec -i testcontainer \
bash -c "pip3 install --upgrade networkx pytest pyopenssl sphinx"
docker exec -i testcontainer \
bash -c "mkdir -p /etc/systemd/system && ln -s /dev/null /etc/systemd/system/memgraph.service" # Prevents Memgraph from starting.
docker exec -i testcontainer \
bash -c "dnf install -y /$LOCAL_PACKAGE_NAME"
else
if [[ "${{ matrix.platform }}" == "ubuntu-22.04" ]]; then
curl_package=libcurl4
else
curl_package=libcurl4t64
fi
docker exec -i testcontainer \
bash -c "apt update && apt install -y software-properties-common && add-apt-repository ppa:deadsnakes/ppa"
docker exec -i testcontainer \
bash -c "apt update && apt install -y libpython${{ matrix.python_version }} python3-pip python3-setuptools $curl_package cmake libssl-dev netcat-traditional"
docker exec -i testcontainer \
bash -c "pip3 install --upgrade networkx pytest pyopenssl sphinx ${{ env.BREAK_PACKAGES }}"
docker exec -i testcontainer \
bash -c "mkdir -p /etc/systemd/system && ln -s /dev/null /etc/systemd/system/memgraph.service" # Prevents Memgraph from starting.
docker exec -i testcontainer \
bash -c "dpkg -i /$LOCAL_PACKAGE_NAME"
fi
rm -v $LOCAL_PACKAGE_NAME
- name: Copy Repo Into Container
run: |
docker cp . testcontainer:/pymgclient
- name: Build source distribution
run: |
docker exec -i testcontainer \
bash -c "cd /pymgclient && python3 setup.py sdist"
- name: Install pymgclient
run: |
docker exec -i testcontainer \
bash -c "python3 -m pip install ${{ env.STATIC_SSL }} ./pymgclient/dist/pymgclient-* ${{ env.BREAK_PACKAGES }}"
- name: Import mgclient to validate installation
run: |
docker exec -i testcontainer \
bash -c "python3 -c 'import mgclient'"
- name: Run tests
run: |
MEMGRAPH_PORT=10000 # what's this for?
docker exec -i testcontainer \
bash -c "cd /pymgclient && python3 -m pytest -v"
- name: Build docs
run: |
docker exec -i testcontainer \
bash -c "cd /pymgclient/docs && make html"
- name: Copy Package
run: |
docker cp testcontainer:/pymgclient/dist .
- name: Save source distribution package
uses: actions/upload-artifact@v4
with:
name: pymgclient
path: dist/${{ matrix.platform }}-${{ matrix.python_version }}
- name: Cleanup
if: always()
run: |
docker stop testcontainer || echo "Container does not exist"
docker wait testcontainer || echo "Container does not exist"
docker rmi ${{ env.MGVERSION }} || echo "Image does not exist"
build_and_test_windows:
name: Build and Test on Windows
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-2022]
python-version: ["3.11"]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: true
- name: Set up MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
install: >
git
mingw-w64-x86_64-gcc
mingw-w64-x86_64-cmake
mingw-w64-x86_64-make
mingw-w64-x86_64-openssl
- name: Add MSYS2 mingw64/bin to PATH
shell: pwsh
run: |
echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Set up Windows Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: x64
- name: Debug Find OpenSSL DLLs
shell: msys2 {0}
run: |
find /mingw64/bin -iname "*ssl*.dll"
find /mingw64/bin -iname "*crypto*.dll"
- name: Add Windows Python to PATH
run: |
echo "${{ env.pythonLocation }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8
- name: Install Python build tools
run: |
python -m pip install --upgrade pip setuptools wheel pyopenssl pytest
- name: Build pymgclient Wheel
shell: msys2 {0}
run: |
export PATH="$(cygpath -u "$pythonLocation"):$PATH"
python setup.py build_ext --static-openssl=False bdist_wheel
env:
pythonLocation: ${{ env.pythonLocation }}
- name: Install built wheel
shell: msys2 {0}
run: |
export PATH="$(cygpath -u "$pythonLocation"):$PATH"
python -m pip install dist/*.whl
env:
pythonLocation: ${{ env.pythonLocation }}
- name: Check mgclient.pyd DLL Dependencies (MSYS2)
run: |
mgclient_path=$(find $pythonLocation -name "mgclient.cp*.pyd" | head -n1)
if [ -z "$mgclient_path" ]; then
echo "mgclient.pyd not found!"
exit 1
fi
echo "Found: $mgclient_path"
objdump -p "$mgclient_path" | grep 'DLL Name'
shell: msys2 {0}
- name: Check that required DLLs are in PATH
shell: msys2 {0}
run: |
export PATH="$(cygpath -u "$pythonLocation"):/mingw64/bin:$PATH"
echo "🔎 Checking for required DLLs in PATH:"
for dll in libssl-3-x64.dll libcrypto-3-x64.dll python311.dll; do
if command -v $dll >/dev/null 2>&1 || find /mingw64/bin -iname $dll; then
echo "✅ Found $dll"
else
echo "❌ Missing $dll"
exit 1
fi
done
# - name: Check that required DLLs are in PATH
# shell: pwsh
# run: |
# $dlls = @(
# "libssl-3-x64.dll",
# "libcrypto-3-x64.dll",
# "python311.dll"
# )
# foreach ($dll in $dlls) {
# $found = $false
# foreach ($dir in $env:Path.Split(";")) {
# if (Test-Path (Join-Path $dir $dll)) {
# Write-Host "✅ Found $dll in $dir"
# $found = $true
# break
# }
# }
# if (-not $found) {
# Write-Host "❌ Missing $dll"
# exit 1
# }
# }
- name: Setup WSL Ubuntu
uses: Vampire/setup-wsl@v5
with:
distribution: Ubuntu-24.04
- name: Set Memgraph Version
shell: bash -l {0}
run: |
mgversion=$(
curl -s https://api.github.com/repos/memgraph/memgraph/releases/latest \
| grep -m1 '"tag_name":' \
| sed -E 's/.*"([^"]+)".*/\1/' \
| sed 's/^v//'
)
echo "MGVERSION=$mgversion" >> $GITHUB_ENV
- name: Install and Run Memgraph in WSL
shell: wsl-bash {0}
run: |
sudo apt update
sudo apt install -y curl
curl -L https://download.memgraph.com/memgraph/v${{ env.MGVERSION }}/ubuntu-24.04/memgraph_${{ env.MGVERSION }}-1_amd64.deb -o memgraph.deb
sudo mkdir -p /etc/systemd/system && sudo ln -s /dev/null /etc/systemd/system/memgraph.service # Prevents Memgraph from starting.
sudo apt install ./memgraph.deb
nohup sudo memgraph --bolt-port 7687 --telemetry-enabled=False &
- name: Wait for Memgraph to Start
run: Start-Sleep -Seconds 10
# - name: Ensure required DLLs are available
# shell: pwsh
# run: |
# $ErrorActionPreference = "Stop"
# # Paths
# $mingwBin = "C:\msys64\mingw64\bin"
# $pythonLib = "$env:pythonLocation\Lib\site-packages"
# # DLLs that mgclient depends on
# $dlls = @(
# "libssl-3-x64.dll",
# "libcrypto-3-x64.dll"
# )
# # Copy DLLs from MSYS2 into Python site-packages if missing
# foreach ($dll in $dlls) {
# $destPath = Join-Path $pythonLib $dll
# if (-Not (Test-Path $destPath)) {
# $srcPath = Join-Path $mingwBin $dll
# if (Test-Path $srcPath) {
# Copy-Item $srcPath -Destination $destPath
# Write-Host "✅ Copied $dll to site-packages."
# } else {
# Write-Host "❌ $dll not found in $mingwBin!"
# exit 1
# }
# } else {
# Write-Host "✅ $dll already present in site-packages."
# }
# }
# # python311.dll should already be available from pythonLocation, no need to move
# - name: Run Tests
# run: |
# $env:Path = "C:\msys64\mingw64\bin;$env:Path"
# python -m pytest -v
# env:
# MEMGRAPH_HOST: localhost
- name: Copy required DLLs from MSYS2 to Python site-packages
shell: msys2 {0}
run: |
set -e
PY_SITE_PACKAGES=$(cygpath -u "$pythonLocation")/Lib/site-packages
for dll in libssl-3-x64.dll libcrypto-3-x64.dll; do
if [ -f /mingw64/bin/$dll ]; then
cp /mingw64/bin/$dll "$PY_SITE_PACKAGES"
echo "✅ Copied $dll to site-packages."
else
echo "❌ $dll not found in /mingw64/bin!"
exit 1
fi
done
env:
pythonLocation: ${{ env.pythonLocation }}
- name: Run Tests
shell: msys2 {0}
run: |
export PATH="$(cygpath -u "$pythonLocation"):/mingw64/bin:$PATH"
python -m pytest -v
env:
pythonLocation: ${{ env.pythonLocation }}
MEMGRAPH_HOST: localhost
- name: Upload Wheel Artifact
uses: actions/upload-artifact@v4
with:
name: pymgclient-win-${{ matrix.os }}-py${{ matrix.python-version }}
path: dist/
# build_and_test_windows:
# # if: ${{ github.event_name == 'workflow_dispatch' }}
# strategy:
# fail-fast: false
# matrix:
# os: [windows-2022, windows-2025]
# arch:
# - { mingw: "64", msys: x86_64, python: "x64" }
# python_version:
# # - '3.7' # this does work, but do we bother with such an old version?
# - '3.10'
# - '3.11'
# - '3.12'
# - '3.13'
# runs-on: ${{ matrix.os }}
# steps:
# - uses: actions/checkout@v4
# with:
# submodules: true
# - name: Setup python
# uses: actions/setup-python@v2.2.2
# with:
# python-version: ${{ matrix.python_version }}
# architecture: ${{ matrix.arch.python }}
# - uses: msys2/setup-msys2@v2
# with:
# msystem: MINGW${{ matrix.arch.mingw }}
# update: true
# release: false
# install: >
# git
# mingw-w64-${{ matrix.arch.msys }}-toolchain
# mingw-w64-${{ matrix.arch.msys }}-cmake
# mingw-w64-${{ matrix.arch.msys }}-openssl
# mingw-w64-${{ matrix.arch.msys }}-python-pip
# mingw-w64-${{ matrix.arch.msys }}-python-pytest
# - name: Add mingw${{ matrix.arch.mingw }} to PATH
# run: |
# # First make sure python would resolve to the windows native python, not mingw one
# echo "C:\msys64\mingw${{ matrix.arch.mingw }}\bin" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
# echo "${{ env.pythonLocation }}" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
# - name: Print OpenSSL version
# shell: msys2 {0}
# run: |
# openssl version -a
# - uses: Vampire/setup-wsl@v5
# with:
# distribution: Ubuntu-24.04
# - name: Set Memgraph Version
# shell: bash -l {0}
# run: |
# mgversion=$(
# curl -s https://api.github.com/repos/memgraph/memgraph/releases/latest \
# | grep -m1 '"tag_name":' \
# | sed -E 's/.*"([^"]+)".*/\1/' \
# | sed 's/^v//'
# )
# echo "MGVERSION=$mgversion" >> $GITHUB_ENV
# - name: Download, install and run Memgraph under WSL
# shell: wsl-bash {0} # root shell
# run: |
# mkdir ~/memgraph
# curl -L https://download.memgraph.com/memgraph/v${{ env.MGVERSION }}/ubuntu-24.04/memgraph_${{ env.MGVERSION }}-1_amd64.deb --output ~/memgraph/memgraph.deb
# dpkg -i ~/memgraph/memgraph.deb
# openssl req -x509 -newkey rsa:4096 -days 3650 -nodes -keyout key.pem -out cert.pem -subj "/C=GB/ST=London/L=London/O=Testing Corp./CN=PymgclientTest"
# nohup /usr/lib/memgraph/memgraph --bolt-port 7687 --bolt-cert-file="cert.pem" --bolt-key-file="key.pem" --data-directory="~/memgraph/data" --storage-properties-on-edges=true --storage-snapshot-interval-sec=0 --storage-wal-enabled=false --storage-recover-on-startup=false --storage-snapshot-on-exit=false --telemetry-enabled=false --log-file='' &
# sleep 1 # Wait for Memgraph a bit.
# - run: python -m pip install -U pip wheel setuptools pytest pyopenssl
# - name: Build pymgclient
# shell: msys2 {0}
# run: |
# python -m pip install setuptools
# python setup.py build_ext --static-openssl=False bdist_wheel
# - name: Install pymgclient
# shell: msys2 {0}
# run: python -m pip install --verbose dist/*.whl
# env:
# VERBOSE: 1
# - name: Run tests
# shell: msys2 {0}
# run: |
# python3 -m pytest -v
# env:
# MEMGRAPH_HOST: "localhost"
# MEMGRAPH_STARTED_WITH_SSL:
# - name: Save wheel package
# uses: actions/upload-artifact@v4
# with:
# name: pymgclient-win${{ matrix.arch.mingw }}-${{ matrix.python_version }}
# path: dist/
build_macos:
if: ${{ github.event_name == 'workflow_dispatch' }}
strategy:
fail-fast: false
matrix:
platform: [macos-15, macos-14]
python_version:
#- '3.9' # this does work, but is old
- '3.10'
- '3.11'
- '3.12'
- '3.13'
# include:
# - {platform: [macOS-15, ARM64, self-hosted], python_version: '3.13'}
# - {platform: [macOS-15, ARM64, self-hosted], python_version: '3.9'}
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Install python and OpenSSL
run: |
brew install python@${{ matrix.python_version }} openssl@1.1
brew link --force --overwrite openssl@1.1
openssl version -a
- name: Manage OpenSSL 3 on ARM machines
if: ${{ contains(matrix.platform, 'ARM64') }}
run: |
brew install openssl@3
brew link --force --overwrite openssl@3
openssl version -a
- name: Make used python version default
run: |
brew unlink python@3 && brew link --force python@${{ matrix.python_version }}
python${{ matrix.python_version }} --version
- name: Install pytest and pyopenssl
run: |
export PIP_BREAK_SYSTEM_PACKAGES=1
python${{ matrix.python_version }} -m pip install pyopenssl pytest setuptools
- name: Build pymgclient
run: python${{ matrix.python_version }} setup.py sdist
- name: Install pymgclient
run: |
export PIP_BREAK_SYSTEM_PACKAGES=1
python${{ matrix.python_version }} -m pip install dist/*
- name: Import mgclient to validate installation
run: python${{ matrix.python_version }} -c "import mgclient"
- name: Save artifact name on x86 machines
if: ${{ !contains(matrix.platform, 'ARM64') }}
run: echo "OS_TYPE=${{ matrix.platform }}" >> $GITHUB_ENV
- name: Save artifact name on ARM64 machines
if: ${{ contains(matrix.platform, 'ARM64') }}
# Convert macOS-11.6-ARM64 to macos-11.6-arm64 to be consistent with full lowercase naming
run: echo OS_TYPE=`echo "${{ matrix.platform[0] }}-${{ matrix.platform[1] }}" | tr "[:upper:]" "[:lower:]"` >> $GITHUB_ENV
- name: Save wheel package
uses: actions/upload-artifact@v4
with:
name: pymgclient-${{ env.OS_TYPE }}-${{ matrix.python_version }}
path: dist/