Skip to content

Commit 69bd70f

Browse files
authored
Modernize CI/CD infrastructure and add Python 3.13 support (#80)
This commit represents a major improvement to the project's continuous integration and deployment infrastructure: ## CI/CD Infrastructure Updates - Remove no longer used AppVeyor - for years now - Rename workflow files to use .yml extension consistently - Add concurrency controls to all workflows to cancel redundant builds - Upgrade actions to latest versions (setup-qemu v3, run-on-arch v3) - Add coverage HTML artifact uploads to all test workflows - Fix multi-architecture builds for RISC-V (make libatlas-base-dev optional) ## Python Version Support - Drop Python 3.6 and 3.7 support - Add Python 3.13 and 3.13t (free-threaded) support - Update minimum supported version from 3.6 to 3.8 - Configure PYTHON_GIL=0 for free-threaded builds in CI despite some deps not supporting it yet ## New Packaging/Distribution Testing - Add cx_Freeze compatibility workflow - Add PyInstaller compatibility workflow - Add py2exe compatibility workflow - Add standalone test scripts for verifying packaged distributions - Add demo/example builder scripts for cx_Freeze, py2exe, and PyInstaller ## Security Enhancements - Add new security scanning workflow with pip-audit and bandit - Update SECURITY.md to document automated security scanning - Add .claude to .gitignore ## Code Quality Improvements - Enhance thread safety in ATMOSPHERE_NRLMSISE00 (GIL-less Python compatibility) - Fix coveralls error handling (continue on failure) - Update macOS runner targets (macos-13 → macos-15-intel, macos-latest for ARM) - Remove obsolete platform-specific exclusions ## Documentation - Update README.rst to reflect Python 3.8+ requirement - Update copyright year to 2025 - Remove AppVeyor badge from README - Update developer documentation
1 parent 5e8f2e9 commit 69bd70f

36 files changed

+738
-311
lines changed
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ on:
66
pull_request:
77
branches: [master, release]
88

9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/release' }}
12+
913
jobs:
1014
multi-arch-test:
1115
runs-on: ubuntu-latest
@@ -65,11 +69,11 @@ jobs:
6569
steps:
6670
- uses: actions/checkout@v4
6771
- name: Set up QEMU
68-
uses: docker/setup-qemu-action@v2
72+
uses: docker/setup-qemu-action@v3
6973
with:
7074
platforms: all
7175
- name: Run on ${{ matrix.arch }}
72-
uses: uraimo/run-on-arch-action@v2
76+
uses: uraimo/run-on-arch-action@v3
7377
with:
7478
arch: ${{ matrix.arch }}
7579
distro: ${{ matrix.distro }}
@@ -80,7 +84,9 @@ jobs:
8084
apk add python3 py3-pip py3-scipy py3-matplotlib py3-numpy py3-pandas
8185
elif [[ "${{ matrix.distro }}" == "ubuntu_latest" || "${{ matrix.distro }}" == "ubuntu_rolling" || "${{ matrix.distro }}" == "ubuntu_devel" || "${{ matrix.distro }}" == "ubuntu20.04" || "${{ matrix.distro }}" == "ubuntu22.04" || "${{ matrix.distro }}" == "bookworm" ]]; then
8286
apt-get update
83-
apt-get install -y libatlas-base-dev liblapack-dev gfortran libgmp-dev libmpfr-dev libsuitesparse-dev ccache libmpc-dev python3 python3-pip python3-scipy python3-matplotlib python3-numpy python3-pandas
87+
# Install libatlas-base-dev if available (not available on some architectures like riscv64)
88+
apt-get install -y liblapack-dev gfortran libgmp-dev libmpfr-dev libsuitesparse-dev ccache libmpc-dev python3 python3-pip python3-scipy python3-matplotlib python3-numpy python3-pandas
89+
apt-get install -y libatlas-base-dev || true
8490
fi
8591
run: |
8692
if python3 -c "import subprocess; exit('no such option' not in subprocess.getoutput('pip3 install --break-system-packages'))"; then

.github/workflows/build.yml

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,37 @@ on:
55
branches: [master, release]
66
pull_request:
77
branches: [master, release]
8-
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/release' }}
12+
913
jobs:
1014
build:
1115

1216
runs-on: ${{ matrix.os }}
1317
strategy:
1418
fail-fast: false
1519
matrix:
16-
python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12', 'pypy3.9']
17-
os: [windows-latest, ubuntu-latest, macos-13, macos-latest]
20+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.13t', 'pypy3.9']
21+
os: [windows-latest, ubuntu-latest, macos-15-intel, macos-latest]
1822
architecture: ['x86', 'x64']
1923
exclude:
20-
- os: ubuntu-latest
21-
python-version: 3.7
2224
# Only test pypy on Linux
2325
- os: windows-latest
2426
python-version: pypy3.9
2527
- os: macos-latest
2628
python-version: pypy3.9
27-
- os: macos-13
29+
- os: macos-15-intel
2830
python-version: pypy3.9
2931
# no python builds available on macos 32 bit, arm or x64
3032
- os: macos-latest
3133
architecture: x86
32-
- os: macos-13
34+
- os: macos-15-intel
3335
architecture: x86
3436
# no python builds available on linux 32 bit
3537
- os: ubuntu-latest
3638
architecture: x86
37-
# 3.7 is oldest supported Python on ubuntu 22.04
38-
- os: ubuntu-latest
39-
python-version: 3.6
4039
# scipy dropped 32 bit windows builds
4140
- os: windows-latest
4241
architecture: x86
@@ -56,21 +55,24 @@ jobs:
5655
- os: windows-latest
5756
architecture: x86
5857
python-version: 3.13
58+
- os: windows-latest
59+
architecture: x86
60+
python-version: 3.13t
61+
- os: windows-latest
62+
architecture: x86
63+
python-version: 3.14
64+
# pandas doesn't have wheels for 3.13t on Windows x64
65+
- os: windows-latest
66+
architecture: x64
67+
python-version: 3.13t
5968

6069
# These are arm - old versions of Python are not supported
61-
- os: macos-latest
62-
python-version: 3.6
63-
- os: macos-latest
64-
python-version: 3.7
6570
- os: macos-latest
6671
python-version: 3.8
6772
- os: macos-latest
6873
python-version: 3.9
6974
- os: macos-latest
7075
python-version: 3.10
71-
72-
- os: macos-13
73-
python-version: 3.6 # missing cumulative_trapezoid too old SciPy
7476
steps:
7577
- uses: actions/checkout@v4
7678
- name: Set up Python ${{ matrix.python-version }} ${{ matrix.architecture }}
@@ -118,17 +120,25 @@ jobs:
118120
python -m pip install wheel
119121
pip install -r requirements_test.txt
120122
- name: Add numba
121-
if: ${{ matrix.python-version == '3.6' || matrix.python-version == '3.7' || matrix.python-version == '3.8' || matrix.python-version == '3.9' || matrix.python-version == '3.10' || matrix.python-version == '3.11' || matrix.python-version == '3.12' }}
123+
if: ${{ !contains(fromJSON('["pypy3.9", "3.13t"]'), matrix.python-version) }}
122124
run: |
123125
pip install numba
124126
- name: Test with pytest
125127
run: |
126128
pytest . -v --cov-report html --cov=fluids --cov-report term-missing -m "not online and not thermo"
127-
coveralls
129+
coveralls || true
128130
env:
129131
COVERALLS_REPO_TOKEN: ${{ secrets.coveralls }}
130132
COVERALLS_PARALLEL: true
131133
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
134+
PYTHON_GIL: ${{ matrix.python-version == '3.13t' && '0' || '' }}
135+
136+
- name: Upload coverage HTML report
137+
if: always()
138+
uses: actions/upload-artifact@v4
139+
with:
140+
name: coverage-html-${{ matrix.os }}-${{ matrix.python-version }}-${{ matrix.architecture }}
141+
path: htmlcov/
132142
finish:
133143
needs: build
134144
runs-on: ubuntu-latest
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Check cx_Freeze Compatibility
2+
3+
on:
4+
push:
5+
branches: [release]
6+
pull_request:
7+
branches: [master, release]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/release' }}
12+
13+
jobs:
14+
build:
15+
16+
runs-on: ${{ matrix.os }}
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
python-version: ['3.13']
21+
os: [windows-latest, ubuntu-latest, macos-15-intel, macos-latest]
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
- name: Set up Python ${{ matrix.python-version }} ${{ matrix.architecture }}
26+
uses: actions/setup-python@v5
27+
with:
28+
python-version: ${{ matrix.python-version }}
29+
architecture: ${{ matrix.architecture }}
30+
31+
- name: cache Linux
32+
uses: actions/cache@v4
33+
if: startsWith(runner.os, 'Linux')
34+
with:
35+
path: ~/.cache/pip
36+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements_test.txt') }}
37+
restore-keys: |
38+
${{ runner.os }}-${{ runner.architecture }}-${{ runner.python-version }}pip-
39+
- name: cache MacOS
40+
uses: actions/cache@v4
41+
if: startsWith(runner.os, 'macOS')
42+
with:
43+
path: ~/Library/Caches/pip
44+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements_test.txt') }}
45+
restore-keys: |
46+
${{ runner.os }}-${{ runner.architecture }}-${{ runner.python-version }}pip-
47+
- name: cache Windows
48+
uses: actions/cache@v4
49+
if: startsWith(runner.os, 'Windows')
50+
with:
51+
path: ~\AppData\Local\pip\Cache
52+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements_test.txt') }}
53+
restore-keys: |
54+
${{ runner.os }}-${{ runner.architecture }}-${{ runner.python-version }}pip-
55+
56+
- name: Install Ubuntu dependencies
57+
if: startsWith(runner.os, 'Linux')
58+
run: |
59+
# Taken from scipy
60+
sudo apt-get update
61+
sudo apt-get install -y libopenblas-dev libatlas-base-dev liblapack-dev gfortran libgmp-dev libmpfr-dev libsuitesparse-dev ccache libmpc-dev
62+
63+
- name: Install dependencies
64+
run: |
65+
python -c "import platform; print(platform.platform()); print(platform.architecture())"
66+
python -m pip install --upgrade pip
67+
python -m pip install wheel
68+
pip install -r requirements_test.txt
69+
pip install cx_Freeze
70+
71+
- name: Install fluids
72+
run: |
73+
pip install -e .
74+
75+
- name: Build cx_Freeze executable
76+
shell: bash
77+
run: |
78+
cd dev
79+
python cx_freeze_basic_standalone_check_builder.py build
80+
cd ..
81+
82+
- name: Test build on Linux/macOS
83+
if: runner.os != 'Windows'
84+
run: |
85+
./dev/build/exe.*/basic_standalone_fluids_check
86+
87+
- name: Test build on Windows
88+
if: runner.os == 'Windows'
89+
shell: bash
90+
run: |
91+
./dev/build/exe.*/basic_standalone_fluids_check.exe

.github/workflows/build_multi_numpy_scipy.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ on:
44
branches: [release]
55
pull_request:
66
branches: [master, release]
7-
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/release' }}
11+
812
jobs:
913
build:
1014
runs-on: ubuntu-latest
@@ -13,7 +17,7 @@ jobs:
1317
matrix:
1418
numpy: ['2.0.1'] #['1.16.5', '1.18.5', '1.20.3', '1.22.4', '1.24.4', '1.26.4', '2.0.1']
1519
scipy: ['1.14.0'] #['1.7.3', '1.8.1', '1.9.3', '1.10.1', '1.12.0', '1.14.0']
16-
python-version: ['3.10'] #['3.7', '3.8', '3.9', '3.10']
20+
python-version: ['3.10'] #['3.8', '3.9', '3.10']
1721
os: [ubuntu-latest]
1822
architecture: ['x64']
1923
include:
@@ -98,7 +102,7 @@ jobs:
98102
pip install -r requirements_test.txt
99103
pip install numpy==${{ matrix.numpy }} scipy==${{ matrix.scipy }}
100104
- name: Add numba
101-
if: ${{ matrix.python-version == '3.6' || matrix.python-version == '3.7' || matrix.python-version == '3.8' || matrix.python-version == '3.9' || matrix.python-version == '3.10' || matrix.python-version == '3.11' || matrix.python-version == '3.12' }}
105+
if: ${{ !contains(fromJSON('["pypy3.9"]'), matrix.python-version) }}
102106
run: |
103107
pip install numba
104108
- name: Test with pytest
@@ -109,6 +113,13 @@ jobs:
109113
COVERALLS_REPO_TOKEN: ${{ secrets.coveralls }}
110114
COVERALLS_PARALLEL: true
111115
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
116+
117+
- name: Upload coverage HTML report
118+
if: always()
119+
uses: actions/upload-artifact@v4
120+
with:
121+
name: coverage-html-numpy-${{ matrix.numpy }}-scipy-${{ matrix.scipy }}-py${{ matrix.python-version }}
122+
path: htmlcov/
112123
finish:
113124
needs: build
114125
runs-on: ubuntu-latest

.github/workflows/build_nuitka_library.yml

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,30 @@ on:
55
branches: [release]
66
pull_request:
77
branches: [master, release]
8-
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/release' }}
12+
913
jobs:
1014
build:
1115

1216
runs-on: ${{ matrix.os }}
1317
strategy:
1418
fail-fast: false
1519
matrix:
16-
python-version: ['3.6', '3.12']
17-
os: [windows-latest, ubuntu-latest, macos-13, macos-latest]
20+
python-version: ['3.13']
21+
os: [windows-latest, ubuntu-latest, macos-15-intel, macos-latest]
1822
architecture: ['x86', 'x64']
1923
exclude:
2024
# no python builds available on macos 32 bit, arm or x64
2125
- os: macos-latest
2226
architecture: x86
23-
- os: macos-13
27+
- os: macos-15-intel
2428
architecture: x86
2529
# no python builds available on linux 32 bit
2630
- os: ubuntu-latest
2731
architecture: x86
28-
# 3.7 is oldest supported Python on ubuntu 22.04
29-
- os: ubuntu-latest
30-
python-version: 3.6
3132
# scipy dropped 32 bit windows builds
3233
- os: windows-latest
3334
architecture: x86
@@ -49,19 +50,12 @@ jobs:
4950
python-version: 3.13
5051

5152
# These are arm - old versions of Python are not supported
52-
- os: macos-latest
53-
python-version: 3.6
54-
- os: macos-latest
55-
python-version: 3.7
5653
- os: macos-latest
5754
python-version: 3.8
5855
- os: macos-latest
5956
python-version: 3.9
6057
- os: macos-latest
6158
python-version: 3.10
62-
63-
- os: macos-13
64-
python-version: 3.6 # missing cumulative_trapezoid too old SciPy
6559
steps:
6660
- uses: actions/checkout@v4
6761
- name: Set up Python ${{ matrix.python-version }} ${{ matrix.architecture }}
@@ -110,7 +104,7 @@ jobs:
110104
pip install -r requirements_test.txt
111105
pip install nuitka
112106
- name: Add numba
113-
if: ${{ matrix.python-version == '3.6' || matrix.python-version == '3.7' || matrix.python-version == '3.8' || matrix.python-version == '3.9' || matrix.python-version == '3.10' || matrix.python-version == '3.11' || matrix.python-version == '3.12' }}
107+
if: ${{ !contains(fromJSON('["pypy3.9"]'), matrix.python-version) }}
114108
run: |
115109
pip install numba
116110
- name: Build nuitka library

0 commit comments

Comments
 (0)