fix: harden output boundaries and provider verification #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: ci | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| workflow_dispatch: | |
| jobs: | |
| metadata: | |
| # Properties of the files, not of the interpreter, so this runs once on a | |
| # fixed version rather than in the matrix — `tomllib` only exists on 3.11+ | |
| # and the floor of the support range is 3.10. | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Refuse third-party dependencies | |
| run: | | |
| python - <<'PY' | |
| import pathlib, sys, tomllib | |
| data = tomllib.loads(pathlib.Path("pyproject.toml").read_text()) | |
| declared = data["project"].get("dependencies", []) | |
| if declared: | |
| # Zero dependencies is what makes this package vendorable into a | |
| # Skill and installable with `pip install --target`. Enforce it | |
| # rather than trusting review. | |
| sys.exit(f"::error::deckflow-core must declare no dependencies, found {declared}") | |
| print("zero runtime dependencies") | |
| PY | |
| - name: Verify the provider matrix tracks the package version | |
| run: | | |
| python - <<'PY' | |
| import json, pathlib, sys, tomllib | |
| version = tomllib.loads(pathlib.Path("pyproject.toml").read_text())["project"]["version"] | |
| matrix = json.loads( | |
| pathlib.Path("src/deckflow_core/providers/providers.json").read_text() | |
| ) | |
| if matrix["core_version"] != version: | |
| sys.exit(f"::error::providers.json says {matrix['core_version']}, pyproject says {version}") | |
| floating = [n for n, s in matrix["providers"].items() if s["version"] in ("latest", "*", "")] | |
| if floating: | |
| sys.exit(f"::error::providers are not pinned: {floating}") | |
| print(f"matrix {version}:", {n: s["version"] for n, s in matrix["providers"].items()}) | |
| PY | |
| test: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # The floor and the current release. Core is pure standard library, so | |
| # the interesting risk is a stdlib or platform difference, not a | |
| # dependency conflict — which is why Windows is in the matrix. | |
| python-version: ["3.10", "3.13"] | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| # Installing rather than setting PYTHONPATH: the path separator differs | |
| # between platforms, and an install is what users actually get. | |
| - name: Install the package | |
| run: python -m pip install --upgrade pip && python -m pip install -e . | |
| - name: Run the test suite | |
| working-directory: tests | |
| run: python -m unittest discover -s . -v | |
| package: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Build and install into a clean directory | |
| run: | | |
| set -euo pipefail | |
| python -m pip install --upgrade build | |
| python -m build | |
| python -m pip install --target "${RUNNER_TEMP}/smoke" --no-input dist/*.whl | |
| PYTHONPATH="${RUNNER_TEMP}/smoke" python -m deckflow_core --version | |
| # Listing providers has no side effects, so it is safe on a runner | |
| # with nothing installed. | |
| PYTHONPATH="${RUNNER_TEMP}/smoke" python -m deckflow_core providers --json > /dev/null | |
| PYTHONPATH="${RUNNER_TEMP}/smoke" python -c " | |
| from deckflow_core import schemas_dir | |
| assert (schemas_dir() / 'envelope.schema.json').is_file(), 'schemas missing from the wheel' | |
| print('schemas ship with the wheel') | |
| " |