Skip to content

feat(ci): cheap matrix mode (matrix-mode input + CI_MATRIX_MODE variable)#27

Merged
monsieurleberre merged 4 commits into
devfrom
feat/cheap-ci-matrix-mode
Jun 17, 2026
Merged

feat(ci): cheap matrix mode (matrix-mode input + CI_MATRIX_MODE variable)#27
monsieurleberre merged 4 commits into
devfrom
feat/cheap-ci-matrix-mode

Conversation

@monsieurleberre

Copy link
Copy Markdown
Contributor

What

Adds a "cheap CI matrix mode" so paid GitHub-hosted matrix legs can be routed onto idle free self-hosted Hetzner runners during a refactor.

  • New matrix-mode input on csharp-ci.yaml and scala-ci.yaml (string, optional, default '').
  • New supported org/repo Actions variable CI_MATRIX_MODE.
  • scripts/normalize-ci-matrix.sh gains a 4th positional arg matrix_mode.

Behaviour

  • cheap (case-insensitive): collapse the matrix to a single shard on the free self-hosted Hetzner pool (["self-hosted","hetzner"], coverage on), ignoring os-list, build-matrix, and visibility. The Hetzner leg reuses the existing private_default definition — no duplicated JSON literal.
  • full / empty: existing behaviour unchanged.
  • Unknown value: fails loud to stderr with a non-zero exit.

Precedence

matrix-mode input > CI_MATRIX_MODE variable > normal matrix.

Implemented in the "Compute effective matrix" step via
MATRIX_MODE: ${{ inputs.matrix-mode != '' && inputs.matrix-mode || vars.CI_MATRIX_MODE }},
passed as the 4th arg to the helper. The visibility gh api lookup is also skipped in cheap mode.

How to use the org variable

Set CI_MATRIX_MODE = cheap as an org- or repo-level Actions variable to flip every consumer onto Hetzner at once. A single caller can opt back out with matrix-mode: full.

Tests

Added cases to test/normalize-ci-matrix_test.sh (wired into build-and-test.yaml): cheap overrides explicit build-matrix, cheap is case-insensitive, cheap ignores empty visibility, full/empty preserve existing behaviour, unknown mode errors. All pass; actionlint + shellcheck clean.

Docs

README input tables (C# + Scala) updated and a new "Cheap matrix mode" section documenting the variable and precedence. SPDX headers untouched.

…riable

Add a `matrix-mode` input to csharp-ci.yaml and scala-ci.yaml and a new
org/repo Actions variable CI_MATRIX_MODE. `cheap` collapses the build/test
matrix to a single free self-hosted Hetzner leg, overriding os-list and
build-matrix; `full` forces the normal matrix; empty defers to the variable.
Precedence: input > CI_MATRIX_MODE > normal matrix.

normalize-ci-matrix.sh gains a 4th positional arg reusing private_default as
the single source of the Hetzner leg, with loud failure on unknown modes.
Copilot AI review requested due to automatic review settings June 17, 2026 07:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Self-hosted Hetzner runners must not run public/fork-PR workloads, so
cheap mode now falls through to the normal matrix (with a warning) on
public repos. The reusable workflows always resolve repository
visibility before invoking the normalizer so the guard can apply.
Copilot AI review requested due to automatic review settings June 17, 2026 07:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Internal review: the cheap-mode guard checked only "= public", so any
non-public value (empty, garbled gh api response) collapsed to the
self-hosted Hetzner leg — fail-open on a security boundary. Switch to an
allowlist: private/internal collapse, public warns and falls through,
anything else errors and refuses to route to self-hosted runners.

Also qualify the README/CHANGELOG matrix-mode summaries as private/internal
only, and add an uppercase-CHEAP-on-public regression test.
@monsieurleberre monsieurleberre merged commit f770236 into dev Jun 17, 2026
2 checks passed
@monsieurleberre monsieurleberre deleted the feat/cheap-ci-matrix-mode branch June 17, 2026 07:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants