Task Summary
Redesign the precheck's CI-skip computation so each label has an explicit list of stacks it requires, and the run set is the union across all labels on the PR. Replace the current ad-hoc rule cascade.
Current state
required-checks.yml's precheck applies hand-written rules:
- labels ⊆ {
docs, dev} → skip all stacks
- only
frontend (with optional docs/dev) → skip every non-frontend stack
- no
frontend label → skip frontend
- otherwise → run all
This works for the cases we have but does not generalize: every new shape (e.g. "python-only PR", "no engine label") needs another bespoke branch and another rule to reason about.
Proposed design
Define a static mapping from each labeler-applied label to the stacks it requires:
| label |
frontend |
scala |
python |
agent-service |
frontend |
✓ |
|
|
|
python |
|
✓ |
✓ |
|
engine |
|
✓ |
✓ |
|
service |
|
✓ |
|
✓ |
common |
|
✓ |
|
|
dependencies |
|
|
|
|
ddl-change |
|
✓ |
|
|
ci |
✓ |
✓ |
✓ |
✓ |
docs |
|
|
|
|
dev |
|
|
|
|
feature / fix / refactor (branch-name labels) |
(no stack opinion) |
|
|
|
precheck reads PR labels and outputs run_<stack> = stack ∈ ⋃ map[label]. Empty union → all skipped. release/* labels keep their existing role driving the backport matrix and contribute no stacks themselves.
Open questions for the design review
python triggers the scala stack as well because the scala backend tests shell out to PyAmber operators; a python-side regression in amber/src/main/python/** can break scala integration tests, so we run both whenever python changes.
service currently matches every *-service/** directory, which includes both the scala services and agent-service. The mapping above forces both stacks; if we want finer granularity we'd add a dedicated agent-service label (split *-service/** against agent-service/**).
dependencies is a no-op for stack selection. Every dependency manifest the labeler matches lives under a component directory and is already covered by that component's label (frontend/package.json → frontend, *-service/build.sbt → service, amber/requirements.txt → engine, etc.). The only manifests outside a top-level component are amber/{requirements,operator-requirements}.txt, which still sit under amber/** and therefore pick up the engine label that already runs both scala and python.
ci deliberately fans out to all stacks — workflow edits can affect anything, so it's the safety valve.
feature / fix / refactor are branch-name driven and orthogonal to file paths; suggest treating them as no-op for stack selection.
Migration
- Replace the current rule cascade with a
LABEL_STACKS map and Object.values(...).flat() style union.
- Keep the docs/dev "skip all" outcome as an emergent result (their rows are empty), not a special case.
- Keep the labeler wait already in precheck so labels are settled before the union is computed.
Priority
P2 – Medium
Task Type
Task Summary
Redesign the precheck's CI-skip computation so each label has an explicit list of stacks it requires, and the run set is the union across all labels on the PR. Replace the current ad-hoc rule cascade.
Current state
required-checks.yml's precheck applies hand-written rules:docs,dev} → skip all stacksfrontend(with optionaldocs/dev) → skip every non-frontend stackfrontendlabel → skip frontendThis works for the cases we have but does not generalize: every new shape (e.g. "
python-only PR", "noenginelabel") needs another bespoke branch and another rule to reason about.Proposed design
Define a static mapping from each labeler-applied label to the stacks it requires:
frontendpythonengineservicecommondependenciesddl-changecidocsdevfeature/fix/refactor(branch-name labels)precheck reads PR labels and outputs
run_<stack> = stack ∈ ⋃ map[label]. Empty union → all skipped.release/*labels keep their existing role driving the backport matrix and contribute no stacks themselves.Open questions for the design review
pythontriggers the scala stack as well because the scala backend tests shell out to PyAmber operators; a python-side regression inamber/src/main/python/**can break scala integration tests, so we run both whenever python changes.servicecurrently matches every*-service/**directory, which includes both the scala services andagent-service. The mapping above forces both stacks; if we want finer granularity we'd add a dedicatedagent-servicelabel (split*-service/**againstagent-service/**).dependenciesis a no-op for stack selection. Every dependency manifest the labeler matches lives under a component directory and is already covered by that component's label (frontend/package.json→frontend,*-service/build.sbt→service,amber/requirements.txt→engine, etc.). The only manifests outside a top-level component areamber/{requirements,operator-requirements}.txt, which still sit underamber/**and therefore pick up theenginelabel that already runs both scala and python.cideliberately fans out to all stacks — workflow edits can affect anything, so it's the safety valve.feature/fix/refactorare branch-name driven and orthogonal to file paths; suggest treating them as no-op for stack selection.Migration
LABEL_STACKSmap andObject.values(...).flat()style union.Priority
P2 – Medium
Task Type