Skip to content

Commit 3f7e8ae

Browse files
authored
Merge pull request #33 from hydrogeoscience/wheels
Create wheels including compiled Fortran code with Github Actions
2 parents 69de6c6 + a89fb80 commit 3f7e8ae

4 files changed

Lines changed: 111 additions & 63 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: build_and_publish
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- master
7+
- wheels
8+
release:
9+
types: [published]
10+
workflow_dispatch:
11+
12+
concurrency:
13+
group: wheels-${{ github.event_name }}-${{ github.ref_name }}-${{ github.event.pull_request.number }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
build_wheels:
18+
name: build wheels (${{ matrix.os }}, ${{ matrix.build }})
19+
runs-on: ${{ matrix.os }}
20+
env:
21+
CIBW_BUILD: '${{ matrix.build }}-*'
22+
CIBW_SKIP: '*i686 *win32 *s390x *ppc64le *musllinux* *aarch64'
23+
CIBW_BUILD_VERBOSITY: 1
24+
CIBW_TEST_COMMAND: python -c "import pygtide; pygtide.test(); pygtide.update(); pygtide.test()"
25+
MACOSX_DEPLOYMENT_TARGET: 15.0
26+
# Package the DLL dependencies in the wheel for windows
27+
# delvewheel cannot mangle the libraries, stripping does not work.
28+
CIBW_BEFORE_BUILD_WINDOWS: pip install delvewheel
29+
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "delvewheel show {wheel} && delvewheel repair -w {dest_dir} {wheel} --no-mangle-all"
30+
31+
strategy:
32+
# for pushes to master, we only build a subset of wheels
33+
fail-fast: false
34+
matrix:
35+
os: [ubuntu-latest, macos-latest, windows-latest]
36+
build: [cp312, cp313, cp314]
37+
exclude-flag:
38+
- ${{ github.event_name != 'release' }}
39+
exclude:
40+
- build: cp12
41+
exclude-flag: true
42+
- build: cp13
43+
exclude-flag: true
44+
steps:
45+
- uses: actions/checkout@v6
46+
47+
- uses: fortran-lang/setup-fortran@v1
48+
id: setup-fortran
49+
with:
50+
compiler: gcc
51+
52+
- name: Build wheels
53+
uses: pypa/cibuildwheel@v3.3.1
54+
55+
- uses: actions/upload-artifact@v6
56+
with:
57+
name: cibw-wheels-${{ matrix.os }}-${{ matrix.build }}-${{ strategy.job-index }}
58+
path: ./wheelhouse/*.whl
59+
60+
build_sdist:
61+
name: build sdist
62+
runs-on: ubuntu-latest
63+
steps:
64+
- uses: actions/checkout@v6
65+
- name: Set up Python
66+
uses: actions/setup-python@v6
67+
- name: Install build
68+
shell: bash -l {0}
69+
run: >-
70+
python -m
71+
pip install build --user
72+
- name: Build a source tarball
73+
shell: bash -l {0}
74+
run: >-
75+
python -m build
76+
- uses: actions/upload-artifact@v6
77+
with:
78+
name: sdist
79+
path: dist/*.tar.gz
80+
81+
publish:
82+
name: publish release
83+
if: github.event_name == 'release'
84+
needs: [build_sdist, build_wheels]
85+
runs-on: ubuntu-latest
86+
steps:
87+
- uses: actions/download-artifact@v7
88+
with:
89+
path: dist
90+
merge-multiple: true
91+
- uses: pypa/gh-action-pypi-publish@release/v1
92+
with:
93+
user: __token__
94+
password: ${{ secrets.PYPI }}

.github/workflows/pypi.yml

Lines changed: 0 additions & 40 deletions
This file was deleted.

README.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ There are two options:
2424

2525
### Installation options
2626

27-
#### Option 1: Install and compile source distribution from PyPi (Linux, macOS, Windows; Python 3.8–3.14)
27+
#### Option 1: Install and compile source distribution from PyPi (Python 3.8–3.11) or install pre-compiled distribution (Linux, macOS, Windows; Python>=3.12)
2828

2929
```bash
3030
pip install pygtide
3131
```
3232

33-
#### Option 2: Build from source locally (Linux, macOS, Windows; Python 3.8–3.14)
33+
#### Option 2: Build from source locally (Linux, macOS, Windows; Python>=3.8)
3434

3535
**Requirements for building:**
3636
- A Fortran compiler (e.g., `gfortran` via MinGW on Windows; included in Linux/macOS gcc toolchains) `conda install gfortran`
@@ -53,12 +53,6 @@ If Meson or Ninja are missing, pip will attempt to install them automatically. F
5353
pip install meson-python meson ninja
5454
```
5555

56-
#### Option 3: Pre-built wheels (Windows, Python 3.8–3.11)
57-
Download the correct wheel for your Python version from the `windows/` subfolder and install:
58-
```powershell
59-
pip install [wheel_name_depending_on_python_version]
60-
```
61-
6256
### After installation
6357

6458
* Run tests to verify installation:

setup.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,39 @@
22
from pathlib import Path
33
import sys
44

5-
from setuptools import setup, Extension
5+
from setuptools import setup, Distribution
66
from setuptools.command.build import build as _build
77

88

99
class build(_build):
1010
def run(self):
1111
# Detect platform-specific ABI extension
12-
HERE = Path(__file__).resolve().parent
13-
12+
here = Path(__file__).resolve().parent
1413
ext = '.pyd' if sys.platform.startswith('win') else '.so'
15-
etpred_path = HERE / 'pygtide' / f'etpred{ext}'
16-
14+
etpred_path = here / 'pygtide' / f'etpred{ext}'
1715
if etpred_path.exists():
1816
print(f"Use ABI module {etpred_path}")
1917
else:
2018
print(f"Prebuilt ABI module not found: {etpred_path}\n"
2119
"Run build_pygtide_abi.py")
22-
sys.path.insert(0, str(HERE))
20+
sys.path.insert(0, str(here))
2321
import build_pygtide_abi
22+
# Start Meson build
2423
build_pygtide_abi.build()
2524
if not etpred_path.exists():
2625
raise FileNotFoundError(f"No ABI module, error in Meson build")
26+
super().run()
2727

2828

29-
# Define the prebuilt extension
30-
etpred_module = Extension(
31-
name='pygtide.etpred',
32-
sources=[], # No sources; using prebuilt ABI
33-
extra_objects=[str(etpred_path)],
34-
)
35-
36-
super().run()
29+
# tell setuptools to build platform-dependent wheels
30+
class BinaryDistribution(Distribution):
31+
def has_ext_modules(self):
32+
return True
3733

3834

3935
# Metadata pulled from pyproject.toml
40-
setup(cmdclass={'build': build})
36+
setup(
37+
distclass=BinaryDistribution,
38+
cmdclass={'build': build}
39+
)
40+

0 commit comments

Comments
 (0)