Skip to content
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
48 changes: 44 additions & 4 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ on:
pull_request:
branches:
- main
- release/1.0.0
- "release/**"
push:
branches:
- main
- release/1.0.0
- "release/**"
workflow_dispatch:

permissions:
Expand All @@ -27,7 +27,7 @@ jobs:
# first failure, so a single-version incompatibility is easy to isolate.
fail-fast: false
# Python 3.15 is intentionally absent: it is still a prerelease during the
# 1.0 release work and is not claimed as a supported version.
# 1.1 release work and is not claimed as a supported version.
matrix:
python-version:
- "3.10"
Expand All @@ -48,13 +48,53 @@ jobs:
virtualenvs-create: true
virtualenvs-in-project: true
- name: Install dependencies
run: poetry install --no-interaction
run: poetry install --no-interaction -E async
- name: Run offline tests
run: |
poetry run pytest \
tests/ \
--ignore=tests/external_tests

sync-only:
name: Sync-only installation
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.14
uses: actions/setup-python@v5
with:
python-version: "3.14"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true

- name: Install dependencies without async extra
run: poetry install --no-interaction --only main

- name: Verify sync-only installation
run: |
poetry run python - <<'PY'
import importlib.util

assert importlib.util.find_spec("httpx") is None, (
"HTTPX should not be installed without the async extra"
)

import mlbstatsapi
from mlbstatsapi import Mlb, MlbDataAdapter

assert mlbstatsapi.Mlb is Mlb
assert mlbstatsapi.MlbDataAdapter is MlbDataAdapter

print("Sync-only installation verified without HTTPX")
PY


build-package:
name: Build and validate package
needs: offline-tests
Expand Down
31 changes: 18 additions & 13 deletions tests/test_release_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
)

# Deterministic CI contract for the 1.0 release.
RELEASE_BRANCH = "release/1.0.0"
STALE_RELEASE_BRANCH = "release/0.9.0"
# Deterministic CI contract for maintained release branches.
RELEASE_BRANCH_PATTERN = 'release/**'
SUPPORTED_PYTHON_VERSIONS = ("3.10", "3.11", "3.12", "3.13", "3.14")
CI_VALIDATED_PYTHON_RANGE = "3.10 through 3.14"
# Prerelease during this work, so it is deliberately excluded from the matrix.
Expand Down Expand Up @@ -921,22 +921,27 @@ def _matrix_python_versions() -> list[str]:
assert match is not None, "no python-version matrix found in the offline workflow"
return re.findall(r'- "([^"]+)"', match.group(1))


def test_ci_watches_the_current_release_branch() -> None:
"""Pull requests and pushes must watch main and release/1.0.0.

The trigger is asserted literally instead of being derived from the package
version, which is still 0.9.0 until the release bump lands.
"""
def test_ci_watches_main_and_release_branches() -> None:
"""Pull requests and pushes must watch main and release branches."""
text = OFFLINE_WORKFLOW.read_text(encoding="utf-8")

assert text.count(f"- {RELEASE_BRANCH}") == 2, text
assert text.count(f'- "{RELEASE_BRANCH_PATTERN}"') == 2, text
assert text.count("- main") == 2, text
assert STALE_RELEASE_BRANCH not in text, (
f"the stale {STALE_RELEASE_BRANCH} trigger must be removed"
)
assert "workflow_dispatch:" in text

def test_ci_matrix_installs_the_async_extra() -> None:
text = OFFLINE_WORKFLOW.read_text(encoding="utf-8")

assert "poetry install --no-interaction -E async" in text

def test_ci_preserves_a_sync_only_installation_check() -> None:
text = OFFLINE_WORKFLOW.read_text(encoding="utf-8")

assert "sync-only:" in text
assert "poetry install --no-interaction --only main" in text
assert 'find_spec("httpx") is None' in text
assert "from mlbstatsapi import Mlb, MlbDataAdapter" in text


def test_ci_matrix_covers_every_supported_python_version() -> None:
assert _matrix_python_versions() == list(SUPPORTED_PYTHON_VERSIONS)
Expand Down
Loading