ci(e2e): deduplicate the self-hosted e2e lanes into a composite action

Abierto
#294 1 comentario 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@volen-silo ya está trabajando en esto.

Desde el 27/8/2026.

Evaluación

Este issue todavía no se ha evaluado.

Descripción

Problem

The self-hosted e2e lane definitions in .github/workflows/e2e-selfhosted.yml and .github/workflows/nightly.yml are largely copy-paste. Measured across the 10 lanes in those two files, 62% of step-body lines (502 of 806) sit inside a block that appears verbatim in at least one other lane.

Repeated block Copies Lines
GPU preflight (bounded wait…) bash 5 130
GPU preflight — advisory + PowerShell variants 2 + 2 128
Upload E2E report (differs only in name:) 10 60
Reclaim GPU from stray E2E processes 8 66
WSL bootstrap / toolchain / checkout various 106

The five copies of the GPU preflight script differ in exactly one integer (MIN_FREE_GIB, 16 vs 8); the other ~26 lines are byte-identical. The main Run E2E tests script only escapes exact matching because of path substitutions — by sequence similarity it is 97.1% identical between e2e-gpu and e2e-gpu-rad3, and 97.6% between their nightly equivalents.

The cost is drift, and it is already visible. Examples found while reviewing #278:

  • e2e-gpu-rad3 omits E2E_MERGE_QUEUE, which all four sibling lanes set — so it silently runs the cheap PR canary during merge-queue.
  • e2e-gpu-nightly is the only GPU lane with no preflight step at all.
  • The per-PR e2e-gpu-strix-windows lane has no E2E_SERVE_TIMEOUT_SECS while its nightly twin sets "300".
  • e2e-gpu-nightly-rad3 drops the pre-warm diagnostics its own comment says it mirrors.

Each of these is a one-line divergence in a block that is otherwise identical five ways over. There is no mechanism that would catch any of them.

Proposed approach

Extract the repeated blocks into a composite action (e.g. .github/actions/e2e-gpu-lane-linux/action.yml) parameterised on the axes that genuinely vary: min-free-gib, preflight strict-vs-advisory, shared uv cache dir, scenario name filter, artifact name.

A composite action cannot touch name:, if:, needs:, runs-on:, continue-on-error: or strategy:, so it is provably invisible to branch protection — job headers stay byte-identical. Eight Linux call sites (4 lanes × 2 files) collapse onto one definition; an individual lane goes from ~139 lines to ~25. Windows needs a second PowerShell-only action or stays inline.

Alternatives considered

Matrix — viable for check names (codeql.yml already proves the name: Analyze (${{ matrix.language }}) pattern here), but matrix is not in scope at jobs.<id>.if, so the per-lane inputs.platform == '…' gating would have to move into a step gate. That means waking a scale-to-zero runner just to no-op. It also needs strategy.fail-fast: false or one flaky self-hosted machine cancels the rest, and the PowerShell lane can't join. Reasonable as a second step, not the first.

workflow_call — should not be used to bridge ci.yml and e2e-selfhosted.yml. That split exists so a job queued on an offline self-hosted runner cannot stall a required check, and it is enforced by ci_yml_schedules_no_self_hosted_job and workflows_use_distinct_concurrency_groups in xtask/src/workflow_contract.rs. It also mangles check names to <caller> / <called>.

Non-goal: collapsing to one or two jobs

Four constraints set the floor, none of them stylistic:

  1. ci.yml's E2E tests and E2E consolidated report are required checks and must stay distinct.
  2. Self-hosted lanes must live in a separate workflow file for concurrency isolation — enforced by the two workflow_contract.rs tests above.
  3. Windows vs Linux is a hard job split (PowerShell 5.1 vs bash throughout).
  4. nightly.yml is a separate trigger and report tier.

Realistic floor is 8 jobs from the current 14, and only if the if:-to-step-gate refactor is accepted. Keeping all 14 jobs and applying composite actions alone removes ~500 duplicated lines at zero structural risk, which is the better trade and should be done first.

Also in scope: make the docs guard actually guard

hardware_testing_docs_cover_all_four_self_hosted_platforms in xtask/src/workflow_contract.rs compares docs/ci-hardware-testing.md against hardcoded expectations, never against e2e-selfhosted.yml / nightly.yml. It therefore cannot detect a newly added lane — it only fails when someone tries to fix the docs to match reality, which is backwards. Adding a lane in #278 left the doc table, the artifact list, two "the four self-hosted jobs" sentences and the dispatch-options list stale, with the test green throughout.

Derive the expected rows from the actual job list (runs_on_values() and friends already exist in that file) so adding a lane fails the build until the docs follow.

Acceptance
  • Repeated preflight / reclaim / build-and-run / upload blocks exist in one place each.
  • Every existing job name and required-check context is unchanged.
  • Adding a new lane without updating docs/ci-hardware-testing.md fails CI.
  • The four drift instances listed above are resolved or deliberately documented.
Lenguaje dominante
Rust
Estrellas
49
Forks
14
Merge medio
2 d 20 h
PR fusionados (30 d)
171

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de ROCm/rocm-cli

Todos los issues de ROCm/rocm-cli

Issues similares

Más issues de Rust

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.