From 42d46cdf28bef809561747611f9b9232c15dd221 Mon Sep 17 00:00:00 2001
From: msalib <msalib@alum.mit.edu>
Date: Thu, 30 Dec 2021 23:15:52 -0500
Subject: [PATCH] feat: add cross compiling and switch to prod pypi (#14)

---
 .github/workflows/CI.yml      | 25 ++++++++++++-
 .github/workflows/Release.yml | 70 +++++++++++++++++++++++++++++++++--
 Cargo.toml                    |  2 +-
 README.md                     | 24 ++++++++----
 4 files changed, 108 insertions(+), 13 deletions(-)

diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index b872084..362f9ff 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -24,6 +24,9 @@ jobs:
   # anyway so there's no point to run tests a third time.
   BuildLinux:
     runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        target: [x86_64, i686]
     steps:
     - uses: actions/checkout@v2
 
@@ -42,6 +45,7 @@ jobs:
     - name: maturin build
       uses: messense/maturin-action@v1
       with:
+        target: ${{ matrix.target }}
         manylinux: manylinux2014
         command: build
         args: --release --strip -o dist
@@ -61,6 +65,9 @@ jobs:
 
   BuildWindows:
     runs-on: windows-latest
+    strategy:
+      matrix:
+        target: [x64, x86]
     steps:
     - uses: actions/checkout@v2
 
@@ -70,16 +77,24 @@ jobs:
         toolchain: stable
         override: true
 
+    # on x86, there's a good python installed but it is an x64 beast
+    # so it cannot install our wheel.
+    - uses: actions/setup-python@v2
+      with:
+        python-version: 3.9
+        architecture: ${{ matrix.target }}
+
     - uses: messense/maturin-action@v1
       with:
+        target: ${{ matrix.target }}
         command: build
         args: --release --strip --no-sdist -o dist
 
     - name: install locally built wheel
-      run: pip install --user --find-links=dist geo_rasterize --force-reinstall
+      run: pip3 install --user --find-links dist geo_rasterize --force-reinstall
 
     - name: run doctests
-      run: python -m doctest -v README.md
+      run: python3 -m doctest -v README.md
 
     - name: Upload wheels
       uses: actions/upload-artifact@v2
@@ -104,6 +119,12 @@ jobs:
         command: build
         args: --release --strip --no-sdist -o dist --universal2
 
+    - name: install locally built wheel
+      run: pip install --user --find-links=dist geo_rasterize --force-reinstall
+
+    - name: run doctests
+      run: python -m doctest -v README.md
+
     - name: Upload wheels
       uses: actions/upload-artifact@v2
       with:
diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml
index 4f2c08e..5c84910 100644
--- a/.github/workflows/Release.yml
+++ b/.github/workflows/Release.yml
@@ -48,6 +48,9 @@ jobs:
     runs-on: ubuntu-latest
     if: github.ref == 'refs/heads/main' && github.event_name == 'push'
     needs: [ BumpVersion ]
+    strategy:
+      matrix:
+        target: [x86_64, i686]
     steps:
     - uses: actions/checkout@v2
 
@@ -66,6 +69,7 @@ jobs:
     - name: maturin build
       uses: messense/maturin-action@v1
       with:
+        target: ${{ matrix.target }}
         manylinux: manylinux2014
         command: build
         args: --release --strip -o dist
@@ -87,6 +91,9 @@ jobs:
     runs-on: windows-latest
     if: github.ref == 'refs/heads/main' && github.event_name == 'push'
     needs: [ BumpVersion ]
+    strategy:
+      matrix:
+        target: [x64, x86]
     steps:
     - uses: actions/checkout@v2
 
@@ -96,8 +103,16 @@ jobs:
         toolchain: stable
         override: true
 
+    # on x86, there's a good python installed but it is an x64 beast
+    # so it cannot install our wheel.
+    - uses: actions/setup-python@v2
+      with:
+        python-version: 3.9
+        architecture: ${{ matrix.target }}
+
     - uses: messense/maturin-action@v1
       with:
+        target: ${{ matrix.target }}
         command: build
         args: --release --strip --no-sdist -o dist
 
@@ -132,6 +147,12 @@ jobs:
         command: build
         args: --release --strip --no-sdist -o dist --universal2
 
+    - name: install locally built wheel
+      run: pip install --user --find-links=dist geo_rasterize --force-reinstall
+
+    - name: run doctests
+      run: python -m doctest -v README.md
+
     - name: Upload wheels
       uses: actions/upload-artifact@v2
       with:
@@ -139,11 +160,54 @@ jobs:
         path: dist
         retention-days: 2
 
+  BuildLinuxCross:
+    runs-on: ubuntu-latest
+    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+    strategy:
+      matrix:
+        # there's less point in building these architectures since
+        # `shapely` doesn't have pre-built wheels available for them.
+        target: [aarch64]  # armv7, s390x, ppc64le, ppc64
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-python@v2
+      with:
+        python-version: 3.9
+    - name: Build Wheels
+      uses: messense/maturin-action@v1
+      with:
+        target: ${{ matrix.target }}
+        manylinux: auto
+        args: --release --strip --out dist --no-sdist
+    - uses: uraimo/run-on-arch-action@v2.0.5
+      if: matrix.target != 'ppc64'
+      name: Install built wheel
+      with:
+        arch: ${{ matrix.target }}
+        distro: ubuntu20.04
+        githubToken: ${{ github.token }}
+        # Mount the dist directory as /artifacts in the container
+        dockerRunArgs: |
+          --volume "${PWD}/dist:/artifacts"
+        install: |
+          apt-get update
+          apt-get install -y --no-install-recommends python3 python3-pip
+          pip3 install -U pip
+        run: |
+          ls -lrth /artifacts
+          pip3 install --user --find-links=/artifacts geo_rasterize --force-reinstall
+          python3 -m doctest -v README.md
+    - name: Upload wheels
+      uses: actions/upload-artifact@v2
+      with:
+        name: wheels
+        path: dist
+
   # We've got a new version! `Build` will run and after it finishes we
   # can publish!
   Publish:
     runs-on: ubuntu-latest
-    needs: [ BuildLinux, BuildWindows, BuildMacOS ]
+    needs: [ BuildLinux, BuildWindows, BuildMacOS, BuildLinuxCross ]
     steps:
       - uses: actions/download-artifact@v2
         with:
@@ -151,7 +215,7 @@ jobs:
       - name: Publish to PyPI
         uses: messense/maturin-action@v1
         env:
-          MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
+          MATURIN_PYPI_TOKEN: ${{ secrets.PROD_PYPI_API_TOKEN }}
         with:
           command: upload
-          args: --repository-url=https://test.pypi.org/legacy/ --username=msalib --skip-existing *
+          args: --username=msalib --skip-existing *
diff --git a/Cargo.toml b/Cargo.toml
index b9a601a..4abcf37 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,7 +9,7 @@ name = "geo_rasterize"
 crate-type = ["cdylib"]
 
 [dependencies]
-# we depend on 3.7+ because 3.6 just went EOL
+# we want to depend on 3.7+ because 3.6 just went EOL
 pyo3 = { version = "0.15", features = ["extension-module", "anyhow", "abi3-py37"] }
 geo-rasterize = "0.1.1"
 numpy = "0.15"
diff --git a/README.md b/README.md
index 7b40796..ff096f8 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,8 @@
 
 [pypi-badge]: https://img.shields.io/pypi/pyversions/geo-rasterize
 [pypi-url]: https://pypi.org/project/geo-rasterize/
-[actions-badge]: https://github.com/msalib/py-geo-rasterize/actions/workflows/CI.yml/badge.svg
-[actions-url]: https://github.com/msalib/py-geo-rasterize/actions?query=CI+branch%3Amain
+[actions-badge]: https://github.com/msalib/py-geo-rasterize/actions/workflows/Release.yml/badge.svg
+[actions-url]: https://github.com/msalib/py-geo-rasterize/actions?query=Release+branch%3Amain
 
 `geo-rasterize` is a Python wrapper for a [rust library with the same
 name](https://crates.io/crates/geo-rasterize) that rasterizes
@@ -16,12 +16,22 @@ vector shapes, just like
 [features.rasterize](https://rasterio.readthedocs.io/en/latest/api/rasterio.features.html#rasterio.features.rasterize). The
 difference is that while [rasterio](https://rasterio.readthedocs.io/)
 is built on GDAL, this library has no dependencies -- you can install
-this wheel without having to worry about GDAL (or any other C library
-at all)! Plus `geo-rasterize`'s rasterization algorithm is based on
-GDAL's so it should be a drop in replacement for
-`rasterio.features.rasterize` and it offers a very similar API.
+it without having to worry about GDAL (or any other C library at all)!
+Plus `geo-rasterize`'s rasterization algorithm is based on GDAL's so
+it should be a drop in replacement for `rasterio.features.rasterize`
+and it offers a very similar API.
+
+We publish wheels to PyPI Python 3.7+ for the following platforms:
+
+| Operating System | Architecture                    |
+|------------------|---------------------------------|
+| Linux            | x86-64                          |
+| Linux            | i686                            |
+| Linux            | aarch64                         |
+| Windows          | x86-64                          |
+| Windows          | i686                            |
+| MacOS            | Universal2 (x86-64 and aarch64) |
 
-<!-- add table showing platforms and build statuses -->
 
 ## Examples