Skip to content

feat: --github-matrix#17

Open
JPHutchins wants to merge 3 commits into
mainfrom
feature/github-matrix
Open

feat: --github-matrix#17
JPHutchins wants to merge 3 commits into
mainfrom
feature/github-matrix

Conversation

@JPHutchins
Copy link
Copy Markdown
Owner

Summary

  • New --github-matrix flag emits a GitHub Actions matrix as JSON for the task's axes, so the matrix definition lives once in tasks.py instead of being duplicated in workflow YAML.
  • Output is the object-of-arrays form ({"PY": ["3.10", "3.11"]}), consumable either as the whole matrix (matrix: ${{ fromJSON(...) }}) or per-axis (PY: ${{ fromJSON(...).PY }}) — the latter lets you combine with extra YAML-side axes like os.
  • TTY-aware: indented JSON for interactive preview, compact one-liner for >> $GITHUB_OUTPUT.
  • Reuses existing override pipeline — camas matrix --github-matrix --PY 3.13 emits the filtered matrix.
  • Mutually exclusive with --dry-run; errors helpfully if the task has no matrix axes; rejects -- passthrough.
  • Per-task --help advertises [--github-matrix] when matrix axes exist.
$ camas matrix --github-matrix
{
  "PY": ["3.14", "3.13", "3.12", "3.11", "3.10", "3.15"]
}

$ camas matrix --github-matrix --PY 3.13,3.14 | cat
{"PY":["3.13","3.14"]}

Validation

Emitted JSON is tested against the GHA workflow schema's matrix subset, vendored from SchemaStore (tests/fixtures/github-actions-matrix-schema.json, sha dbc0fd17). Two adversarial tests against the fixture itself (empty axis / empty object) guard against fixture drift.

34 new tests covering pure helpers, schema conformance for six matrix shapes, CLI integration through dispatch, override + mutex + passthrough cases, TTY vs pipe formatting, and per-task help. All 643 existing tests still pass.

Dogfood

The check job's hardcoded python: ["3.10".."3.15"] is replaced by a new discover job that runs camas matrix --github-matrix; the check job consumes ${{ fromJSON(needs.discover.outputs.matrix).PY }}. .python-version becomes the single source of truth. Runner shape unchanged (4 OS × 6 PY = 24).

Test plan

  • uv run camas check passes locally (it does — minus pre-existing pyrefly worktree-path issue)
  • CI passes — discover job emits matrix; check jobs fan out across the emitted PY list
  • camas matrix --github-matrix in a TTY shows indented JSON
  • camas matrix --github-matrix | cat shows compact JSON
  • camas check --github-matrix fails with "no matrix axes" (since check has no matrix)
  • camas matrix --dry-run --github-matrix is rejected as mutex
  • Per-task help: camas matrix --help shows [--github-matrix]; camas test --help does not

🤖 Generated with Claude Code

Emit a GitHub Actions matrix as JSON from a camas matrix-bearing task, so
the matrix definition lives once in tasks.py instead of being duplicated
in workflow YAML. Output is the object-of-arrays form
({"PY": ["3.10", "3.11"]}), consumable as the whole matrix via
`matrix: ${{ fromJSON(...) }}` or one axis at a time via
`<axis>: ${{ fromJSON(...).<axis> }}`. TTY-aware: indented for
interactive preview, compact one-liner for `>> $GITHUB_OUTPUT`.

Validation: emitted JSON is tested against the GHA workflow schema's
matrix subset (vendored from SchemaStore, sha dbc0fd17).

Dogfooded in ci.yaml: the `check` job's hardcoded
`python: ["3.10"..."3.15"]` is replaced by a `discover` job that runs
`camas matrix --github-matrix`. `.python-version` becomes the single
source.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 26, 2026 22:08
@codecov
Copy link
Copy Markdown

codecov Bot commented May 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (8a7d633) to head (cc3d538).

Additional details and impacted files
@@            Coverage Diff             @@
##              main       #17    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files           52        54     +2     
  Lines         4773      4977   +204     
  Branches       257       263     +6     
==========================================
+ Hits          4773      4977   +204     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new CLI preview mode (--github-matrix) that emits a GitHub Actions-compatible matrix JSON derived from a task’s declared matrix axes, enabling CI workflows to source matrix definitions directly from tasks.py rather than duplicating them in YAML.

Changes:

  • Add --github-matrix CLI flag (mutually exclusive with --dry-run) and dispatch path to emit TTY-aware JSON.
  • Introduce camas.main.github_matrix helpers to project matrix axes and format JSON output.
  • Add schema-backed tests + vendored schema fixture; update CI workflow to “discover” the Python matrix dynamically.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/camas/main/parser.py Adds --github-matrix flag and reserves its name from axis overrides.
src/camas/main/dispatch.py Implements --github-matrix execution path (rejects passthrough, applies overrides, prints JSON).
src/camas/main/github_matrix.py New helper module to project matrix axes and format/emit JSON.
src/camas/main/format.py Updates per-task help usage line to optionally mention --github-matrix.
tests/main/test_github_matrix.py Adds extensive unit + CLI integration tests and schema validation.
tests/fixtures/github-actions-matrix-schema.json Vendors GHA matrix subschema used for validation tests.
.github/workflows/ci.yaml Adds discover job and uses emitted matrix for Python versions in check job.
pyproject.toml Adds jsonschema + types to dev dependencies for schema validation tests.
uv.lock Locks new dev dependencies (jsonschema, types-jsonschema, and transitive deps).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/camas/main/format.py Outdated
Comment thread src/camas/main/parser.py
Comment thread tests/fixtures/github-actions-matrix-schema.json Outdated
Comment thread tests/main/test_github_matrix.py
JPHutchins and others added 2 commits May 26, 2026 15:23
PR review:
- Per-task --help usage line now shows `[--dry-run | --github-matrix]` to
  reflect the argparse mutex (was: two independent optional flags, implying
  they could be combined).
- New `RESERVED_DESTS` constant (hyphen→underscore normalization of
  `RESERVED_FLAGS`); dispatch uses it when filtering axis names so an axis
  literally named `github_matrix` no longer silently shares argparse's
  auto-derived dest with `--github-matrix`.
- Fix malformed URL anchor in the vendored schema fixture description.
- Drop section-divider comments in test_github_matrix.py.

CI deps:
- Make jsonschema conditional on `python_version < '3.15'` — its transitive
  `rpds-py` dep currently won't build on 3.15 (PyO3 0.27.2 max-supports
  3.14). `pytest.importorskip("jsonschema")` lets schema-validation tests
  skip cleanly on 3.15 instead of erroring at import.
- Add `jsonschema` to wheels `CIBW_TEST_REQUIRES` and nix
  `nativeCheckInputs` so those test envs can run the new test file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous conditional on `jsonschema` alone wasn't sufficient:
`types-jsonschema` depends on `referencing` (unconditional), which
depends on `rpds-py` — so the whole rpds-py → PyO3 build chain still
fires on 3.15. Mirror the marker onto `types-jsonschema` so the entire
sub-tree is excluded on 3.15.

Test-side is unaffected: `pytest.importorskip("jsonschema")` returns
`Any`, so the stubs weren't doing static-type work on the test file
anyway.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants