diff --git a/.github/scripts/smoke_wheel.py b/.github/scripts/smoke_wheel.py new file mode 100644 index 0000000..2befd5a --- /dev/null +++ b/.github/scripts/smoke_wheel.py @@ -0,0 +1,48 @@ +"""Install one wheel in a fresh environment and exercise its CLI and extension.""" +from pathlib import Path +import os +import subprocess +import sys +import tempfile +import venv + + +SMOKE = """ +import json +from pathlib import Path +import sys + +import nnnotes +from nnnotes import _deck, deckdata + +assert Path(nnnotes.__file__).resolve().is_relative_to(Path(sys.prefix).resolve()) +assert Path(_deck.__file__).resolve().is_relative_to(Path(sys.prefix).resolve()) +info = _deck.info() +data = { + "format": info["dataFormat"], + "master": {name: {"columns": [], "rows": []} for name, _ in deckdata.TABLES}, + "charts": [], +} +stats = json.loads(_deck.chart_stats(json.dumps(data), workers=1, aptitude=False)) +assert stats["format"] == info["format"] +assert stats["charts"] == [] +print(f"nnnotes {nnnotes.__version__}: {info['name']} {info['version']}") +""" + + +def main(directory: str) -> None: + wheel, = Path(directory).resolve().glob("*.whl") + with tempfile.TemporaryDirectory(prefix="nnnotes-wheel-") as directory: + root = Path(directory) + environment = root / "venv" + venv.EnvBuilder(with_pip=True).create(environment) + scripts = environment / ("Scripts" if os.name == "nt" else "bin") + python = scripts / ("python.exe" if os.name == "nt" else "python") + subprocess.run([python, "-I", "-m", "pip", "install", str(wheel)], cwd=root, check=True) + subprocess.run([python, "-I", "-c", SMOKE], cwd=root, check=True) + subprocess.run([scripts / ("nnnotes.exe" if os.name == "nt" else "nnnotes"), "--help"], + cwd=root, check=True) + + +if __name__ == "__main__": + main(sys.argv[1]) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61ab385..280ff7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,12 +6,13 @@ on: pull_request: # the Deck model workflow dispatches CI on the pull request it opens workflow_dispatch: + workflow_call: permissions: contents: read concurrency: - group: ci-${{ github.ref }} + group: ci-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ebb881a..7ba8ba0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,6 +27,10 @@ jobs: exit 1 fi + quality: + needs: check + uses: ./.github/workflows/ci.yml + # one abi3 wheel (CPython 3.11 and later) per platform with the extension module nnnotes._deck, and the sdist wheels: needs: check @@ -50,6 +54,8 @@ jobs: target: ${{ matrix.target }} manylinux: ${{ matrix.manylinux || 'auto' }} args: --release --locked --out dist + - name: Test the installed wheel + run: python .github/scripts/smoke_wheel.py dist - uses: actions/upload-artifact@v7 with: name: wheel-${{ matrix.os }}-${{ matrix.target }} @@ -72,7 +78,7 @@ jobs: if-no-files-found: error build: - needs: [wheels, sdist] + needs: [quality, wheels, sdist] runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v8