diff --git a/.github/workflows/pr-orchestrator.yml b/.github/workflows/pr-orchestrator.yml index f0c5dd7d..e1903d1d 100644 --- a/.github/workflows/pr-orchestrator.yml +++ b/.github/workflows/pr-orchestrator.yml @@ -131,7 +131,7 @@ jobs: if: needs.changes.outputs.skip_tests_dev_to_main != 'true' run: | python -m pip install --upgrade pip - pip install hatch coverage + pip install "hatch" "virtualenv<21" coverage - name: Cache hatch environments if: needs.changes.outputs.skip_tests_dev_to_main != 'true' @@ -224,7 +224,7 @@ jobs: - name: Install hatch run: | python -m pip install --upgrade pip - pip install hatch + pip install "hatch" "virtualenv<21" - name: Cache hatch environments uses: actions/cache@v4 with: @@ -271,7 +271,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install hatch + pip install "hatch" "virtualenv<21" - name: Cache hatch environments uses: actions/cache@v4 with: @@ -403,7 +403,7 @@ jobs: - name: Install hatch run: | python -m pip install --upgrade pip - pip install hatch + pip install "hatch" "virtualenv<21" - name: Cache hatch environments uses: actions/cache@v4 with: @@ -451,7 +451,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install hatch + pip install "hatch" "virtualenv<21" - name: Cache hatch environments uses: actions/cache@v4 @@ -500,7 +500,7 @@ jobs: - name: Install build tools run: | python -m pip install --upgrade pip - pip install build twine hatch + pip install build twine "hatch" "virtualenv<21" - name: Build package run: | diff --git a/openspec/changes/cli-val-05-ci-integration/TDD_EVIDENCE.md b/openspec/changes/cli-val-05-ci-integration/TDD_EVIDENCE.md new file mode 100644 index 00000000..15a48164 --- /dev/null +++ b/openspec/changes/cli-val-05-ci-integration/TDD_EVIDENCE.md @@ -0,0 +1,20 @@ +# TDD Evidence: cli-val-05-ci-integration + +## Pre-Implementation Failing Run + +- Timestamp (UTC): 2026-02-26T00:23:59Z +- Command: + - `python -m pytest tests/unit/specfact_cli/registry/test_signing_artifacts.py -k virtualenv_below_21 -q` +- Result: FAILED +- Failure summary: + - `test_pr_orchestrator_pins_virtualenv_below_21_for_hatch_jobs` + - Assertion error: missing `virtualenv<21` pin in workflow install command (`pip install hatch coverage`). + +## Post-Implementation Passing Run + +- Timestamp (UTC): 2026-02-26T00:24:14Z +- Command: + - `python -m pytest tests/unit/specfact_cli/registry/test_signing_artifacts.py -k virtualenv_below_21 -q` +- Result: PASSED +- Summary: + - Workflow install commands that include `hatch` now also include `virtualenv<21`. diff --git a/openspec/changes/cli-val-05-ci-integration/specs/cli-validation-ci-gates/spec.md b/openspec/changes/cli-val-05-ci-integration/specs/cli-validation-ci-gates/spec.md index 94a01108..de3d805c 100644 --- a/openspec/changes/cli-val-05-ci-integration/specs/cli-validation-ci-gates/spec.md +++ b/openspec/changes/cli-val-05-ci-integration/specs/cli-validation-ci-gates/spec.md @@ -64,3 +64,14 @@ The contract-first test system SHALL include CLI behavior contracts as a recogni - **WHEN** CLI behavior contract files exist in `tests/cli-contracts/` - **THEN** CLI scenario validation is included in the test run - **AND** results appear alongside existing contract/exploration/scenario tiers. + +### Requirement: Deterministic Hatch Toolchain in CI + +The CI pipeline SHALL install a deterministic, compatible Hatch toolchain for Python 3.12 test jobs. + +#### Scenario: Hatch install prevents virtualenv 21 incompatibility + +- **GIVEN** the workflow installs Hatch for Python 3.12 test execution +- **WHEN** dependencies are resolved in CI +- **THEN** the install command constrains `virtualenv` to `<21` +- **AND** the workflow avoids the runtime error `module 'virtualenv.discovery.builtin' has no attribute 'propose_interpreters'`. diff --git a/tests/unit/specfact_cli/registry/test_signing_artifacts.py b/tests/unit/specfact_cli/registry/test_signing_artifacts.py index 8bee9f63..36acd599 100644 --- a/tests/unit/specfact_cli/registry/test_signing_artifacts.py +++ b/tests/unit/specfact_cli/registry/test_signing_artifacts.py @@ -504,3 +504,14 @@ def test_sign_modules_workflow_uses_private_key_and_passphrase_secrets(): assert "SPECFACT_MODULE_PRIVATE_SIGN_KEY" in content assert "SPECFACT_MODULE_PRIVATE_SIGN_KEY_PASSPHRASE" in content assert "--enforce-version-bump" in content + + +def test_pr_orchestrator_pins_virtualenv_below_21_for_hatch_jobs(): + """PR orchestrator SHALL pin virtualenv<21 when installing hatch in CI jobs.""" + if not PR_ORCHESTRATOR_WORKFLOW.exists(): + pytest.skip("pr-orchestrator workflow not present") + content = PR_ORCHESTRATOR_WORKFLOW.read_text(encoding="utf-8") + install_commands = re.findall(r"pip install[^\n]*hatch[^\n]*", content) + assert install_commands, "Expected at least one pip install hatch command in workflow" + for command in install_commands: + assert "virtualenv<21" in command, f"Missing virtualenv<21 pin in command: {command}"