Files
TheRock/build_tools/github_actions/configure_multi_arch_ci_summary.py
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

313 lines
11 KiB
Python

"""Formats the GITHUB_STEP_SUMMARY markdown for configure_multi_arch_ci.py.
Produces human-readable markdown explaining what CI will do and why.
"""
from configure_multi_arch_ci import (
CIInputs,
CIOutputs,
)
from pathlib import Path
import sys
THIS_SCRIPT_DIR = Path(__file__).resolve().parent
THEROCK_DIR = THIS_SCRIPT_DIR.parent.parent
sys.path.insert(0, str(THEROCK_DIR / "build_tools"))
from _therock_utils.workflow_outputs import WorkflowOutputRoot
# Hardcoded for now — prebuilt artifacts are always fetched from ROCm/TheRock
# workflow runs. TODO(#3399): when baseline_run_id carries a repo qualifier,
# pass the repo slug through from CIInputs instead of hardcoding.
_REPO_SLUG = "ROCm/TheRock"
def format_summary(
ci_inputs: CIInputs,
outputs: CIOutputs,
) -> str:
"""Generate the full step summary markdown."""
lines = []
lines.append(
"## Multi-Arch CI Configuration (tips: [ci_behavior_manipulation.md](https://github.com/ROCm/TheRock/blob/main/docs/development/ci_behavior_manipulation.md))"
)
lines.append("")
if not outputs.is_ci_enabled:
return _format_skipped_ci(lines, ci_inputs)
if not outputs.jobs:
return "\n".join(lines)
# One-liner: trigger, branch, variant
lines.append(
f"Trigger: `{ci_inputs.event_name}` on `{ci_inputs.commit_ref}`, "
f"`{ci_inputs.build_variant}` variant."
)
lines.append("")
# Nothing to build (e.g. workflow_dispatch with no families selected)
if outputs.builds.linux is None and outputs.builds.windows is None:
lines.append("No GPU families selected — nothing to build or test.")
return "\n".join(lines)
# Highlight noteworthy non-default settings ahead of the standard output.
highlights = _non_default_highlights(ci_inputs)
if highlights:
lines.append("> [!NOTE]")
lines.append("> **Non-default configuration:**")
for callout in highlights:
lines.append(f"> - {callout}")
lines.append("")
lines.append("### build-rocm")
lines.append("")
_append_build_rocm(lines, ci_inputs, outputs)
lines.append("### test-rocm")
lines.append("")
_append_test_rocm(lines, outputs)
lines.append("### build-pytorch")
lines.append("")
_append_build_pytorch(lines, outputs)
lines.append("### build-jax")
lines.append("")
_append_build_jax(lines, outputs)
return "\n".join(lines)
def _format_skipped_ci(lines: list[str], ci_inputs: CIInputs) -> str:
# Determine skip reason (same priority order as should_skip_ci).
if "ci:skip" in ci_inputs.pr_labels:
reason = "`ci:skip` PR label"
else:
reason = "no CI-relevant files changed"
lines.append(f"CI was **skipped**: {reason}. See logs for details.")
return "\n".join(lines)
def _non_default_highlights(ci_inputs: CIInputs) -> list[str]:
highlights: list[str] = []
if ci_inputs.release_type:
highlights.append(f"Release type: {ci_inputs.release_type}")
# Explicit family selection (workflow_dispatch)
if ci_inputs.is_workflow_dispatch:
parts = []
if ci_inputs.linux_amdgpu_families:
families = ", ".join(ci_inputs.linux_amdgpu_families)
parts.append(f"Linux: `[{families}]`")
if ci_inputs.windows_amdgpu_families:
families = ", ".join(ci_inputs.windows_amdgpu_families)
parts.append(f"Windows: `[{families}]`")
if parts:
highlights.append(f"Explicit family selection — {', '.join(parts)}")
# PR labels that affect behavior
for label in ci_inputs.pr_labels:
if label.startswith("gfx"):
highlights.append(
f"Label `{label}`: added family `{label}` "
f"(not in default presubmit set)"
)
elif label.startswith("test_filter:"):
filter_type = label.split(":")[1]
highlights.append(
f"Label `{label}`: overrode test level to `{filter_type}`"
)
elif label.startswith("test_runner:"):
kernel = label.split(":")[1]
highlights.append(
f"Label `{label}`: using `{kernel}` kernel-specific test runners"
)
elif label.startswith("test:"):
highlights.append(f"Label `{label}`: requested component tests")
elif label.startswith("ci:"):
highlights.append(f"Label `{label}`")
# Explicit test labels (workflow_dispatch)
if ci_inputs.is_workflow_dispatch:
if ci_inputs.linux_test_labels:
highlights.append(
f"Explicit Linux test labels: `{ci_inputs.linux_test_labels}`"
)
if ci_inputs.windows_test_labels:
highlights.append(
f"Explicit Windows test labels: `{ci_inputs.windows_test_labels}`"
)
return highlights
def _append_build_rocm(
lines: list[str], ci_inputs: CIInputs, outputs: CIOutputs
) -> None:
# Note: this assumes that the build_rocm job is never skipped.
# We may decide to skip it under certain conditions in the future
# (e.g. only editing pytorch-related files, no ROCm-related files).
# This code will need to adapt then.
jobs = outputs.jobs
# Prebuilt info
prebuilt = jobs.build_rocm.prebuilt_stages
if prebuilt:
stage_list = ", ".join(prebuilt)
run_id = jobs.build_rocm.baseline_run_id
repo = _REPO_SLUG
lines.append(
f"Using prebuilt artifacts for stages: `[{stage_list}]` "
f"from run [{run_id}]"
f"(https://github.com/{repo}/actions/runs/{run_id}). "
f"Remaining stages build from source."
)
else:
lines.append("Building all stages from source.")
lines.append("")
# Platform table
lines.append("| Platform | Families | Artifact Group |")
lines.append("|----------|----------|----------------|")
for platform, config in [
("Linux", outputs.builds.linux),
("Windows", outputs.builds.windows),
]:
if config is None:
lines.append(f"| {platform} | — | — |")
else:
families = ", ".join(
f"`{f}`" for f in config.dist_amdgpu_families.split(";")
)
lines.append(f"| {platform} | {families} | `{config.artifact_group}` |")
lines.append("")
# Link to log, artifact, and manifest index pages
lines.extend(
[
"## Build outputs",
"",
"Platform | 📋 Logs | 📦 Artifacts | 📄 Manifests",
"-- | -- | -- | --",
]
)
linux_output_root = None
for platform_name in ["linux", "windows"]:
output_root = WorkflowOutputRoot.from_workflow_run(
run_id=ci_inputs.run_id, platform=platform_name
)
if platform_name == "linux":
linux_output_root = output_root
log_url = output_root.log_root_index().https_url
artifact_url = output_root.artifact_index().https_url
manifest_url = output_root.manifests_index().https_url
lines.append(
f"{platform_name.capitalize()} | {log_url} | {artifact_url} | {manifest_url}"
)
manifest_diff_url = linux_output_root.log_file(
"manifest-diff", "index.html"
).https_url
lines.append(f"Manifest diff *(if produced)* | {manifest_diff_url} | — | —")
lines.append("")
lines.append(
"> The manifest-diff report compares submodules across the CI commit range. "
"Expect no changes when this run does not advance any submodule pointers. "
"The report is generated after the setup job completes and the link may be "
"unavailable until then; it is not produced on ASAN workflows."
)
def _append_build_pytorch(lines: list[str], outputs: CIOutputs) -> None:
lines.append("| Platform | Python | PyTorch ref | Families |")
lines.append("|----------|--------|-------------|----------|")
rows = 0
for platform, config in [
("Linux", outputs.builds.linux),
("Windows", outputs.builds.windows),
]:
if config is None:
continue
for row in config.pytorch_build_matrix:
families = ", ".join(
f"`{family}`" for family in row["amdgpu_families"].split(";")
)
lines.append(
f"| {platform} | `{row['python_version']}` | "
f"`{row['pytorch_git_ref']}` | {families} |"
)
rows += 1
if rows == 0:
lines.append("| — | — | — | — |")
lines.append("")
def _append_build_jax(lines: list[str], outputs: CIOutputs) -> None:
lines.append("| Platform | Python | JAX ref | Repository | GFX arch |")
lines.append("|----------|--------|---------|------------|----------|")
rows = 0
for platform, config in [
("Linux", outputs.builds.linux),
("Windows", outputs.builds.windows),
]:
if config is None:
continue
for row in config.jax_build_matrix:
gfx_arch = row["gfx_arch"] or "—"
lines.append(
f"| {platform} | `{row['python_version']}` | "
f"`{row['jax_ref']}` | `{row['jax_repository']}` | {gfx_arch} |"
)
rows += 1
if rows == 0:
lines.append("| — | — | — | — | — |")
lines.append("")
def _append_test_rocm(lines: list[str], outputs: CIOutputs) -> None:
# Note: this assumes that the test_rocm job is never skipped.
# We may decide to skip it under certain conditions in the future
# (e.g. only editing pytorch-related files, no ROCm-related files).
# This code will need to adapt then.
jobs = outputs.jobs
test_rocm = jobs.test_rocm
lines.append(
f"Test level: **{test_rocm.test_type}** ({test_rocm.test_type_reason})"
)
# Component test labels (per platform)
if outputs.linux_test_labels:
lines.append(f"Component tests (Linux): `{outputs.linux_test_labels}`")
if outputs.windows_test_labels:
lines.append(f"Component tests (Windows): `{outputs.windows_test_labels}`")
lines.append("")
# Per-family test runner table
lines.append("| Platform | Family | Runner Label | Scope |")
lines.append("|----------|--------|--------------|-------|")
for platform, config in [
("Linux", outputs.builds.linux),
("Windows", outputs.builds.windows),
]:
if config is None:
continue
per_family = config.per_family_info
for entry in per_family:
family = f"`{entry['amdgpu_family']}`"
runner = f"`{entry['test-runs-on']}`" if entry["test-runs-on"] else "—"
if entry.get("sanity_check_only_for_family"):
scope = "sanity check only"
else:
scope = test_rocm.test_type
lines.append(f"| {platform} | {family} | {runner} | {scope} |")
lines.append("")