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
313 lines
11 KiB
Python
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("")
|