Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLD: Wheels! #2197

Merged
merged 1 commit into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 0 additions & 46 deletions .appveyor.yml

This file was deleted.

50 changes: 5 additions & 45 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,56 +12,21 @@ version: 2.1
apt-run: &apt-install
name: Install apt packages
command: |
apt-get -qq update
apt-get install -y \
sudo apt -qq update
sudo apt install -y \
gcc \
g++ \
make

env-run: &env-setup
# Create the basic testing environment
# Mixing conda-forge and defaults in root is a recipe for trouble, so create
# a separate environment.
name: Setup conda environment
command: |
conda config \
--set always_yes yes \
--set changeps1 no \
--set show_channel_urls yes \
--set auto_activate_base false
conda config --add channels conda-forge
conda create -n test-environment python=$PYTHON_VERSION

deps-run: &deps-install
name: Install Python dependencies
command: |
conda install -n test-environment --quiet \
cython \
'matplotlib>3.3' \
numpy \
owslib \
pillow \
pyproj \
pykdtree \
pyshp \
scipy \
setuptools_scm \
shapely \
$EXTRA_PACKAGES \
--file docs/doc-requirements.txt
conda list -n test-environment

cp-run: &cp-install
name: Install Cartopy
command: |
source activate test-environment
pip install -ve .
python -m pip install --upgrade --user pip
python -m pip install --user -ve .[doc,ows,plotting,speedups]

doc-run: &doc-build
name: Build documentation
command: |
source activate test-environment
PYPROJ_GLOBAL_CONTEXT=ON
make -C docs html


Expand All @@ -72,16 +37,11 @@ doc-run: &doc-build
jobs:
docs-python3:
docker:
- image: continuumio/miniconda3:latest
- image: cimg/python:3.11
steps:
- checkout

- run: *apt-install
- run:
<<: *env-setup
environment:
PYTHON_VERSION: 3.11
- run: *deps-install
- run: *cp-install

- run: *doc-build
Expand Down
62 changes: 26 additions & 36 deletions .github/workflows/ci-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,81 +10,71 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.9, '3.10', '3.11']
shapely-dev: [false]
include:
- os: ubuntu-latest
python-version: '3.11'
shapely-dev: true
defaults:
run:
shell: bash -l {0}

steps:
- uses: actions/checkout@v3
- uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: test-environment
fetch-depth: 0

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
channels: conda-forge/label/testing,conda-forge
cache: 'pip'

- name: Minimum packages
# Only run on Linux for now
# Conda's linux packages don't grab the testing label of matplotlib causing failures due to freetype differences
if: matrix.python-version == '3.9' && matrix.os == 'ubuntu-latest'
id: minimum-packages
run: |
echo "PACKAGES=cython=0.29.24 matplotlib-base=3.4 numpy=1.21 owslib=0.24.1 pyproj=3.1 proj=8.0 scipy=1.6.3 shapely=1.7.1" >> $GITHUB_ENV

- name: Latest packages
if: steps.minimum-packages.conclusion == 'skipped' && !matrix.shapely-dev
run: |
echo "PACKAGES=cython fiona matplotlib-base numpy pyproj pykdtree scipy shapely" >> $GITHUB_ENV

- name: Latest packages with Shapely dev
if: steps.minimum-packages.conclusion == 'skipped' && matrix.shapely-dev
run: |
echo "PACKAGES=cython fiona matplotlib-base numpy pyproj pykdtree scipy geos" >> $GITHUB_ENV
pip install cython==0.29.24 matplotlib==3.4.3 numpy==1.21 owslib==0.24.1 pyproj==3.1 scipy==1.6.3 shapely==1.7.1

- name: Coverage packages
id: coverage
# only want the coverage to be run on the latest ubuntu
if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
run: |
echo "PACKAGES=$PACKAGES pytest-cov coveralls" >> $GITHUB_ENV
echo "CYTHON_COVERAGE=1" >> $GITHUB_ENV
echo "EXTRA_TEST_ARGS=--cov=cartopy -ra" >> $GITHUB_ENV

- name: Install dependencies
run: |
PACKAGES="$PACKAGES owslib pep8 pillow pyshp pytest pytest-mpl!=0.16.0"
PACKAGES="$PACKAGES pytest-xdist setuptools_scm"
conda install $PACKAGES
conda info -a
conda list
# Also add doctest here to avoid windows runners which expect a different path separator
echo "EXTRA_TEST_ARGS=--cov=cartopy -ra --doctest-modules" >> $GITHUB_ENV
pip install cython

- name: Install Shapely dev
if: matrix.shapely-dev
run: |
python -m pip install git+https://github.com/shapely/shapely.git@main
# Install Shapely from source on ubuntu
sudo apt-get update
sudo apt-get install -yy libgeos-dev
pip install git+https://github.com/shapely/shapely.git@main

- name: Install Cartopy
id: install
run: |
MPL_CONFIG_DIR=~/.config/matplotlib
mkdir -p $MPL_CONFIG_DIR
echo "backend : agg" > $MPL_CONFIG_DIR/matplotlibrc
pip install --no-deps -e .
pip install -e .[test]
python -c "import cartopy; print('Version ', cartopy.__version__)"

- name: Install extras
# Default is to install just the minimum testing requirements,
# but we want to get as much coverage as possible.
if: steps.minimum-packages.conclusion == 'skipped'
run: |
pip install .[ows,plotting,speedups]

- name: Testing
id: test
# we need to force bash to use line continuations on Windows
shell: bash
run: |
# Check that the downloader tool at least knows where to get the data from (but don't actually download it)
python tools/cartopy_feature_download.py gshhs physical --dry-run
CARTOPY_GIT_DIR=$PWD
PYPROJ_GLOBAL_CONTEXT=ON pytest -ra -n 4 --doctest-modules \
pytest -ra -n 4 \
--color=yes \
--mpl --mpl-generate-summary=html \
--mpl-results-path="cartopy_test_output-${{ matrix.os }}-${{ matrix.python-version }}" \
Expand Down
117 changes: 90 additions & 27 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,63 +1,126 @@
name: Build and upload to PyPI

concurrency:
group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }}
cancel-in-progress: true

# Only build on published releases
on:
release:
types:
- published

jobs:
build:
name: Build sdist
runs-on: ubuntu-18.04
defaults:
run:
shell: bash -l {0}
build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
outputs:
SDIST_NAME: ${{ steps.sdist.outputs.SDIST_NAME }}

steps:
- uses: actions/checkout@v3
- uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: test-environment
python-version: ${{ matrix.python-version }}
channels: conda-forge/label/testing,conda-forge
# We need the full history to generate the proper version number
fetch-depth: 0

- uses: actions/setup-python@v4
name: Install Python
with:
python-version: '3.11'

- name: Install dependencies
run: python -m pip install build twine

- name: Build sdist
id: sdist
run: |
PACKAGES="cython fiona matplotlib-base numpy pyproj pykdtree scipy"
PACKAGES="$PACKAGES owslib pep8 pillow pyshp pytest"
PACKAGES="$PACKAGES pytest-xdist setuptools_scm shapely"
conda install $PACKAGES
python -m build --sdist
# Get the name of the build sdist file for later use
echo "SDIST_NAME=$(ls -1 dist)" >> $GITHUB_OUTPUT

- name: Create sdist
run: python setup.py build_ext sdist
- name: Check README rendering for PyPI
run: twine check dist/*

- name: Save built packages as artifact
- name: Upload sdist result
uses: actions/upload-artifact@v3
with:
name: packages-${{ runner.os }}-${{ matrix.python-version }}
path: dist/
name: sdist
path: dist/*.tar.gz
if-no-files-found: error
retention-days: 5

generate-wheels-matrix:
name: Generate wheels matrix
runs-on: ubuntu-latest
outputs:
include: ${{ steps.set-matrix.outputs.include }}
steps:
- uses: actions/checkout@v3
- name: Install cibuildwheel
run: pipx install cibuildwheel==f21bb8376a051ffb6cb5604b28ccaef7b90e8ab7 # v2.14.1
- id: set-matrix
run: |
MATRIX=$(
{
cibuildwheel --print-build-identifiers --platform linux \
| jq -nRc '{"only": inputs, "os": "ubuntu-latest"}' \
&& cibuildwheel --print-build-identifiers --platform macos \
| jq -nRc '{"only": inputs, "os": "macos-latest"}' \
&& cibuildwheel --print-build-identifiers --platform windows \
| jq -nRc '{"only": inputs, "os": "windows-2019"}'
} | jq -sc
)
echo "include=$MATRIX" >> $GITHUB_OUTPUT
env:
CIBW_BUILD: "cp39-* cp310-* cp311-*"
# Skip 32 bit windows builds and musllinux due to lack of numpy wheels
CIBW_SKIP: "*-win32 *-musllinux*"
CIBW_ARCHS_MACOS: x86_64 arm64

build_wheels:
name: Build ${{ matrix.os }} ${{ matrix.only }}
needs: [generate-wheels-matrix, build_sdist]
strategy:
matrix:
include: ${{ fromJson(needs.generate-wheels-matrix.outputs.include) }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:

- name: Download sdist
uses: actions/download-artifact@v3
with:
name: sdist
path: dist/

- uses: pypa/cibuildwheel@f21bb8376a051ffb6cb5604b28ccaef7b90e8ab7 # v2.14.1
with:
only: ${{ matrix.only }}
package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }}

- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl

publish:
name: Publish to PyPI
needs: build
# Only publish on releases
if: github.event_name == 'release'
Comment on lines +108 to +109
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this redundant with the entire workflow's on trigger? Should that be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You beat me to this :) I was just going to add a comment here indicating I added this. I agree it is the same as the trigger, but this is an extra safeguard that I think is worth it in this case. For example, when I was testing building wheels on my fork, I removed the "on: release", but this would fail because I don't have credentials. However, then I force-pushed to this branch, and all of a sudden triggered this workflow on the PR. I'm not entirely clear it would have gone through the action but it seems prudent to keep to me just to make sure I don't fat finger something again on accident. In the future, we may want to change the trigger to let us trigger it automatically on certain pushes or on request.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PRs shouldn't have any of the credentials/write permissions necessary.

Also, there's no way this workflow as written should be able to trigger on a PR.

That said, there's no harm in being careful.

needs: [build_wheels, build_sdist]
environment:
name: PyPI
url: https://pypi.org/project/cartopy
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
runs-on: ubuntu-18.04
runs-on: ubuntu-latest

steps:
- name: Download packages
uses: actions/download-artifact@v3

- name: Consolidate packages for upload
run: |
mkdir dist
cp packages-*/* dist/
dopplershift marked this conversation as resolved.
Show resolved Hide resolved
with:
name: artifact
path: dist

- name: Publish Package
uses: pypa/gh-action-pypi-publish@v1.8.8
Loading