diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6d2be3d..f5ae0e7 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -38,6 +38,7 @@ jobs: uses: awvwgk/setup-fortran@v1 - name: Install build frontend + # language=sh run: python -m pip install --upgrade pip build - name: Retrieve 6S source archives @@ -51,6 +52,7 @@ jobs: # from the sdist. In all other jobs, the wheel is built directly from the source directory. # This way, we confirm that wheels can be successfully built from the sdist. - name: Build wheel${{ matrix.sdist && ' and sdist' || '' }} + # language=sh run: python -I -m build ${{ !matrix.sdist && '--wheel' || '' }} env: SIXS_ARCHIVE_DIR: 6s-archives @@ -84,6 +86,7 @@ jobs: python-version: "3.11" - name: Configure wheel platform compatibility tags + # language=sh run: | python -m pip install --upgrade wheel python -m wheel tags --remove --python-tag=py3 --abi-tag=none ./dist/*.whl @@ -102,7 +105,7 @@ jobs: fail-fast: false matrix: os: [ "windows-latest", "ubuntu-latest", "macos-latest" ] - python-version: [ "3.9", "3.10", "3.11" ] + python-version: [ "3.9", "3.10", "3.11", "3.12" ] steps: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 @@ -119,6 +122,7 @@ jobs: # --only-binary - use a wheel (not sdist) # --no-deps - only install named distribution (do not try to find other dependencies) - name: Install candidate wheel without dependencies + # language=sh run: python -m pip install --no-index --only-binary ':all:' --no-deps --find-links=dist 6s-bin # Install remaining dependency from PyPI, including those for the 'wrapper' extra. @@ -126,11 +130,13 @@ jobs: # status if `...` is not found in the output. - name: Install candidate wheel's dependencies from PyPI if: ${{ !contains(matrix.os, 'windows') }} + # language=sh run: | python -m pip install --find-links=dist '6s-bin[wrapper]' | tee /dev/tty | grep 'Requirement already satisfied: 6s-bin' > /dev/null - name: Install candidate wheel's dependencies from PyPI (Windows) if: ${{ contains(matrix.os, 'windows') }} + # language=sh run: | $output = python -m pip install --find-links=dist '6s-bin[wrapper]' | Out-String Write-Host $output @@ -141,7 +147,7 @@ jobs: sparse-checkout: test - name: Run pytest + # language=sh run: | python -m pip install pytest pytest - diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fff0496..5108f0a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -2,13 +2,20 @@ name: Release run-name: Release from ${{ github.ref }} -on: [ workflow_dispatch ] +on: + push: + tags: + # Only trigger on release tags (including "dev" and "release candidates"). + - v[0-9]+.[0-9]+.[0-9]+ + - v[0-9]+.[0-9]+.[0-9]+dev[0-9]+ + - v[0-9]+.[0-9]+.[0-9]+rc[0-9]+ jobs: build: uses: ./.github/workflows/build.yaml + # Publish the release to TestPyPI (https://test.pypi.org). test-publish: needs: build # if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') @@ -22,6 +29,27 @@ jobs: name: dist-release path: dist + # Verify that the version tag on all distribution files matches the pushed tag. + - name: Check version consistency + # language=sh + run: | + tag_prefix="refs/tags/v" + pushed_ref="${{ github.ref }}" + expected_version="${pushed_ref#${tag_prefix}}" + + echo "::notice:: expected version is ${expected_version} for ref ${pushed_ref}" + + for dist_file in ./dist/*; do + dist_version=$(echo ${dist_file%.tar.gz} | cut -d'-' -f2) + + echo "::debug:: found version ${dist_version} for file '${dist_file}'" + + if [ "${expected_version}" != "${dist_version}" ]; then + echo "::error:: expected ${expected_version}, got ${dist_version} in distribution file '${dist_file}'" + exit 1 + fi + done + # # Allow the same distribution version to be test-published multiple times. # # Useful for prototyping the release process. # - name: Rename wheels with build number @@ -32,7 +60,9 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ + print-hash: true + # Verify that the release just published to TestPyPI can be installed successfully with pip. test-install: needs: test-publish runs-on: ${{ matrix.os }} @@ -41,39 +71,50 @@ jobs: fail-fast: false matrix: os: [ "windows-latest", "ubuntu-latest", "macos-latest" ] - python-version: [ "3.9", "3.10", "3.11" ] + python-version: [ "3.9", "3.10", "3.11", "3.12" ] steps: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + # Install ONLY the released distribution from TestPyPI. Allow prereleases. - name: Install distribution from TestPyPI + # language=sh run: pip install --pre --no-deps -i https://test.pypi.org/simple/ 6s-bin + # Install all remaining dependencies from PyPI. + # Verify that pip does not attempt to re-install the distribution from the previous step. - name: Install dependencies from PyPI if: ${{ !contains(matrix.os, 'windows') }} + # language=sh run: | python -m pip install '6s-bin[wrapper]' packaging | tee /dev/tty | grep 'Requirement already satisfied: 6s-bin' > /dev/null + # Windows version of the previous step. - name: Install dependencies from PyPI (Windows) if: ${{ contains(matrix.os, 'windows') }} + # language=sh run: | $output = python -m pip install '6s-bin[wrapper]' packaging | Out-String Write-Host $output exit [int]$($output -notmatch 'Requirement already satisfied: 6s-bin') - name: Verify that installed distribution version matches tag - # TODO find fix for double-quotes being stripped when the below command is run in PowerShell. - if: ${{ !contains(matrix.os, 'windows') }} - run: > - python -c 'import packaging.version; - import sixs_bin; - installed_version = packaging.version.parse(sixs_bin.__version__); - expected_version = packaging.version.parse("${{ github.ref }}".split("/")[-1].removeprefix("v")); - print(f"{installed_version=} {expected_version=}"); + shell: python + # language=python + run: | + import packaging.version + import sixs_bin + + installed_version = packaging.version.parse(sixs_bin.__version__) + expected_version = packaging.version.parse("${{ github.ref }}".split("/")[-1].removeprefix("v")) + + print(f"::notice::{installed_version=} {expected_version=}") + assert installed_version.release == expected_version.release - ' + # Quick final self-check. - name: Run wrapper test + # language=sh run: python -m sixs_bin --test-wrapper diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index cabd2c9..1bc0906 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,6 +1,9 @@ name: Tests -on: [ push ] +on: + push: + branches: [ develop ] + workflow_dispatch: jobs: download_archives: @@ -21,7 +24,7 @@ jobs: fail-fast: false matrix: os: [ "windows-latest", "ubuntu-latest", "macos-latest" ] - python-version: [ "3.9", "3.10", "3.11" ] + python-version: [ "3.9", "3.10", "3.11", "3.12" ] steps: - uses: actions/checkout@v3 @@ -40,6 +43,7 @@ jobs: uses: awvwgk/setup-fortran@v1 - name: Install package and test dependencies + # language=sh run: | python -m pip install --upgrade pip python -m pip install '.[wrapper]' pytest @@ -47,4 +51,5 @@ jobs: SIXS_ARCHIVE_DIR: 6s-archives - name: Run pytest + # language=sh run: python -m pytest -vv diff --git a/.github/workflows/web_artifact.yaml b/.github/workflows/web_artifact.yaml index 5f3e4c0..1161f84 100644 --- a/.github/workflows/web_artifact.yaml +++ b/.github/workflows/web_artifact.yaml @@ -24,6 +24,7 @@ jobs: url: ${{ fromJSON(inputs.urls) }} steps: - name: Download file + # language=sh run: curl --create-dirs --output-dir artifacts -O ${{ matrix.url }} - uses: actions/upload-artifact@v3 diff --git a/pyproject.toml b/pyproject.toml index 0c92c94..3b1a380 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "6s-bin" -version = "0.10.1" +version = "0.11.0" description = "Compiled binaries for the 6S Radiative Transfer Model exposed as package resources." license = "Apache-2.0" authors = ["Brian Schubert "] diff --git a/src/sixs_bin/_cli.py b/src/sixs_bin/_cli.py index 406880b..7f7a6d8 100644 --- a/src/sixs_bin/_cli.py +++ b/src/sixs_bin/_cli.py @@ -16,7 +16,6 @@ # limitations under the License. import argparse -import os import pathlib import subprocess import sys