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
316 lines
13 KiB
Markdown
316 lines
13 KiB
Markdown
# CI Workflow Outputs Layout
|
|
|
|
This document describes the directory layout for outputs produced by TheRock's
|
|
CI workflow runs, and the Python modules for computing paths, uploading, and
|
|
downloading those outputs.
|
|
|
|
## Overview
|
|
|
|
Every CI workflow run produces a set of outputs (build artifacts, logs,
|
|
manifests, python packages) that are uploaded to S3. Three modules in
|
|
`_therock_utils` handle the path computation and I/O:
|
|
|
|
| Module | Role | Key types |
|
|
| ------------------ | ---------------------------- | ----------------------------------------------------------- |
|
|
| `storage_location` | Backend-agnostic location | `StorageLocation` |
|
|
| `workflow_outputs` | CI path computation (no I/O) | `WorkflowOutputRoot` |
|
|
| `storage_backend` | Upload I/O (write) | `StorageBackend`, `S3StorageBackend`, `LocalStorageBackend` |
|
|
| `artifact_backend` | Download I/O (read) | `ArtifactBackend`, `S3Backend`, `LocalDirectoryBackend` |
|
|
|
|
`StorageLocation` is the bridge between path computation and I/O.
|
|
`WorkflowOutputRoot` produces `StorageLocation` instances; backends consume them.
|
|
|
|
```
|
|
WorkflowOutputRoot ──produces──> StorageLocation ──consumed by──> StorageBackend
|
|
ArtifactBackend
|
|
```
|
|
|
|
## S3 Layout
|
|
|
|
All outputs for a given run live under a common prefix:
|
|
|
|
```
|
|
s3://{bucket}/{external_repo}{run_id}-{platform}/
|
|
```
|
|
|
|
| Component | Example | Description |
|
|
| --------------- | ------------------------------- | --------------------------------------------------------------------- |
|
|
| `bucket` | `therock-ci-artifacts` | Selected based on repo, fork status, release type |
|
|
| `external_repo` | `""` or `"githubuser-TheRock/"` | Non-empty for forks and non-TheRock repos (format: `{owner}-{repo}/`) |
|
|
| `run_id` | `12345678901` | GitHub Actions workflow run ID |
|
|
| `platform` | `linux` or `windows` | Build platform |
|
|
|
|
### Directory structure
|
|
|
|
There are two CI pipeline architectures with different log layouts:
|
|
|
|
- **Single-stage CI** (`ci.yml`) — one monolithic build per artifact group.
|
|
Logs from all subprojects land in a single flat directory.
|
|
- **Multi-arch CI** (`multi_arch_ci.yml`) — the build is split into stages
|
|
(compiler-runtime, runtime-tests, math-libs, etc.). Each stage runs as a
|
|
separate job and uploads its own logs, organized by stage name and GPU family.
|
|
|
|
`artifact_group` is the CI matrix variant, composed of a target family plus an
|
|
optional variant suffix (e.g., `gfx94X-dcgpu`, `gfx94X-dcgpu-asan`). It is
|
|
used as the subdirectory key for logs, manifests, and packages. Artifact
|
|
filenames contain the `target_family` (e.g., `gfx94X`); see
|
|
[#3381](https://github.com/ROCm/TheRock/issues/3381) for ongoing work to
|
|
propagate artifact group naming consistently.
|
|
|
|
#### Single-stage CI layout
|
|
|
|
```
|
|
{prefix}/
|
|
{artifact_name}_{component}_{target_family}.tar.xz
|
|
{artifact_name}_{component}_{target_family}.tar.xz.sha256sum
|
|
index-{artifact_group}.html
|
|
|
|
logs/{artifact_group}/
|
|
{subproject}_build.log
|
|
{subproject}_configure.log
|
|
{subproject}_install.log
|
|
ninja_logs.tar.gz
|
|
build_observability.html (when generated)
|
|
index.html
|
|
therock-build-prof/ (resource profiling subdirectory)
|
|
comp-summary.html
|
|
comp-summary.md
|
|
comp-summary.html (flattened copy for direct linking)
|
|
comp-summary.md (flattened copy for direct linking)
|
|
|
|
manifests/{artifact_group}/
|
|
therock_manifest.json
|
|
|
|
python/{artifact_group}/
|
|
*.whl
|
|
*.tar.gz
|
|
index.html
|
|
|
|
tarballs/
|
|
therock-dist-{platform}-{family}-{version}.tar.gz
|
|
```
|
|
|
|
The `comp-summary.*` files appear both in the `therock-build-prof/` subdirectory
|
|
(uploaded as part of the recursive directory upload) and at the log root
|
|
(uploaded explicitly for direct linking).
|
|
|
|
#### Multi-arch CI layout
|
|
|
|
Logs are organized by stage, with a subdirectory per GPU family for per-arch
|
|
stages. Generic stages (compiler-runtime, runtime-tests, profiler-apps) have no family
|
|
subdirectory. Per-arch stages (e.g., math-libs) fan out across GPU
|
|
families in parallel, producing identically-named log files (e.g.,
|
|
`rocBLAS_build.log`) that are kept separate by the family subdirectory.
|
|
|
|
```
|
|
{prefix}/
|
|
{artifact_name}_{component}_{target_family}.tar.zst
|
|
{artifact_name}_{component}_{target_family}.tar.zst.sha256sum
|
|
|
|
logs/{stage_name}/ (generic stages)
|
|
{subproject}_build.log
|
|
{subproject}_configure.log
|
|
{subproject}_install.log
|
|
ninja_logs.tar.gz
|
|
|
|
logs/{stage_name}/{amdgpu_family}/ (per-arch stages)
|
|
{subproject}_build.log
|
|
{subproject}_configure.log
|
|
{subproject}_install.log
|
|
ninja_logs.tar.gz
|
|
|
|
packages/deb/ (APT repository)
|
|
pool/main/
|
|
*.deb
|
|
dists/stable/
|
|
Release
|
|
main/binary-amd64/
|
|
Packages
|
|
Packages.gz
|
|
|
|
packages/rpm/ (DNF/Zypper repository)
|
|
x86_64/
|
|
*.rpm
|
|
repodata/
|
|
repomd.xml
|
|
primary.xml.gz
|
|
...
|
|
|
|
python/
|
|
*.whl (generic wheels, e.g., rocm_sdk_core)
|
|
{amdgpu_family}/
|
|
*.whl (per-family wheels, e.g., rocm_sdk_devel)
|
|
*.tar.gz (sdist)
|
|
index.html
|
|
|
|
tarballs/
|
|
therock-dist-{platform}-{family}-{version}.tar.gz
|
|
therock-dist-{platform}-multiarch-{version}.tar.gz (KPACK split only)
|
|
```
|
|
|
|
Example for a run with compiler-runtime + runtime-tests + math-libs stages:
|
|
|
|
```
|
|
12345-linux/
|
|
logs/compiler-runtime/
|
|
amd-llvm_build.log
|
|
amd-llvm_configure.log
|
|
amd-llvm_install.log
|
|
ninja_logs.tar.gz
|
|
|
|
logs/runtime-tests/
|
|
hip-tests_build.log
|
|
rocrtst_build.log
|
|
ninja_logs.tar.gz
|
|
|
|
logs/math-libs/gfx1151/
|
|
rocBLAS_build.log
|
|
MIOpen_build.log
|
|
ninja_logs.tar.gz
|
|
|
|
logs/math-libs/gfx110X-all/
|
|
rocBLAS_build.log
|
|
MIOpen_build.log
|
|
ninja_logs.tar.gz
|
|
```
|
|
|
|
Artifacts in multi-arch CI use `.tar.zst` compression (vs `.tar.xz` in
|
|
single-stage CI) and are managed by `artifact_manager.py`, not
|
|
`post_build_upload.py`. Index pages for logs are generated server-side.
|
|
|
|
### Bucket selection
|
|
|
|
The bucket is determined by `_retrieve_bucket_info()` in `workflow_outputs.py`.
|
|
See [S3 Buckets](s3_buckets.md) for the full list of buckets and authentication
|
|
details.
|
|
|
|
```
|
|
RELEASE_TYPE=dev/nightly/prerelease? ──Yes──> therock-{RELEASE_TYPE}-artifacts
|
|
│
|
|
No (RELEASE_TYPE=ci)
|
|
│
|
|
ROCm/TheRock (not fork)? ─────────────Yes──> therock-ci-artifacts
|
|
│
|
|
No
|
|
│
|
|
└──────────────────────────────────> therock-ci-artifacts-external
|
|
```
|
|
|
|
Valid artifact `RELEASE_TYPE` values are `ci`, `dev`, `nightly`, and
|
|
`prerelease`.
|
|
|
|
## Python API
|
|
|
|
### StorageLocation
|
|
|
|
A frozen dataclass representing a single file or directory in S3 (or a local
|
|
staging directory). Backend-agnostic — usable for CI run outputs, release
|
|
artifacts, or any S3 path.
|
|
|
|
```python
|
|
from _therock_utils.storage_location import StorageLocation
|
|
|
|
loc = StorageLocation(
|
|
bucket="therock-ci-artifacts", relative_path="12345-linux/file.tar.xz"
|
|
)
|
|
loc.s3_uri # "s3://therock-ci-artifacts/12345-linux/file.tar.xz"
|
|
loc.https_url # "https://therock-ci-artifacts.s3.amazonaws.com/12345-linux/file.tar.xz"
|
|
loc.local_path(Path("/tmp/staging")) # Path("/tmp/staging/12345-linux/file.tar.xz")
|
|
```
|
|
|
|
### WorkflowOutputRoot
|
|
|
|
A frozen dataclass that computes `StorageLocation` for every output type.
|
|
|
|
```python
|
|
from _therock_utils.workflow_outputs import WorkflowOutputRoot
|
|
|
|
# Inside a CI workflow (env vars provide bucket info, no API call)
|
|
root = WorkflowOutputRoot.from_workflow_run(run_id="12345", platform="linux")
|
|
|
|
# Fetching artifacts from another run (API call for fork/cutover detection)
|
|
root = WorkflowOutputRoot.from_workflow_run(
|
|
run_id="12345", platform="linux", lookup_workflow_run=True
|
|
)
|
|
|
|
# For local development (no API calls, no env vars needed)
|
|
root = WorkflowOutputRoot.for_local(run_id="local", platform="linux")
|
|
|
|
# Location methods — each returns an StorageLocation
|
|
root.root()
|
|
root.artifact(filename="blas_lib_gfx94X.tar.xz")
|
|
root.artifact_index()
|
|
root.log_dir(artifact_group="gfx94X-dcgpu")
|
|
root.log_stage_dir(stage_name="math-libs", amdgpu_family="gfx1151")
|
|
root.log_stage_dir(stage_name="compiler-runtime") # generic stage, no family
|
|
root.log_file(artifact_group="gfx94X-dcgpu", filename="build.log")
|
|
root.log_index(artifact_group="gfx94X-dcgpu")
|
|
root.build_observability(artifact_group="gfx94X-dcgpu")
|
|
root.manifest_dir(artifact_group="gfx94X-dcgpu")
|
|
root.manifest(artifact_group="gfx94X-dcgpu")
|
|
root.native_linux_packages(
|
|
pkg_type="deb"
|
|
) # {run_id}-linux/packages/deb — APT repo root
|
|
root.native_linux_packages(
|
|
pkg_type="rpm"
|
|
) # {run_id}-linux/packages/rpm — DNF/Zypper repo root
|
|
root.python_packages(artifact_group="gfx110X-all")
|
|
root.tarballs()
|
|
```
|
|
|
|
The `lookup_workflow_run` parameter controls whether `from_workflow_run()` calls
|
|
the GitHub API to fetch workflow run metadata (for fork detection and bucket
|
|
cutover dating). Most callers running inside their own CI workflow do not need
|
|
this — environment variables (`GITHUB_REPOSITORY`, `IS_PR_FROM_FORK`) suffice.
|
|
Set `lookup_workflow_run=True` when looking up another repository's workflow
|
|
run, e.g. when fetching artifacts.
|
|
|
|
### StorageBackend
|
|
|
|
An abstract base class for uploading files to S3 or a local directory.
|
|
Use `create_storage_backend()` to get the right implementation.
|
|
|
|
```python
|
|
from _therock_utils.storage_backend import create_storage_backend
|
|
|
|
backend = create_storage_backend() # S3 (default)
|
|
backend = create_storage_backend(staging_dir=Path("/tmp/out")) # local directory
|
|
backend = create_storage_backend(dry_run=True) # print only
|
|
|
|
backend.upload_file(source_path, dest_location)
|
|
backend.upload_directory(source_dir, dest_location, include=["*.tar.xz*"])
|
|
```
|
|
|
|
Content-type is inferred from file extension — callers don't need to specify it.
|
|
|
|
### Adding new output types
|
|
|
|
To add a new output type:
|
|
|
|
1. Add a method to `WorkflowOutputRoot` that returns `StorageLocation`
|
|
1. Add tests to [`build_tools/tests/workflow_outputs_test.py`](/build_tools/tests/workflow_outputs_test.py)
|
|
1. Update this document
|
|
|
|
## Consumers
|
|
|
|
### Upload scripts
|
|
|
|
| File | Uses |
|
|
| ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- |
|
|
| [`post_build_upload.py`](/build_tools/github_actions/post_build_upload.py) | `WorkflowOutputRoot` + `StorageBackend` for artifacts, logs, manifests |
|
|
| [`upload_package_repo.py`](/build_tools/packaging/linux/upload_package_repo.py) | `WorkflowOutputRoot.native_linux_packages()` for deb/rpm package repositories |
|
|
| [`post_stage_upload.py`](/build_tools/github_actions/post_stage_upload.py) | `WorkflowOutputRoot` + `StorageBackend` for multi-arch stage logs |
|
|
| [`upload_tarballs.py`](/build_tools/github_actions/upload_tarballs.py) | `WorkflowOutputRoot` + `StorageBackend` for tarballs |
|
|
| [`upload_python_packages.py`](/build_tools/github_actions/upload_python_packages.py) | `WorkflowOutputRoot` + `StorageBackend` for Python wheels and index |
|
|
| [`upload_pytorch_manifest.py`](/build_tools/github_actions/upload_pytorch_manifest.py) | `WorkflowOutputRoot` + `StorageBackend` for PyTorch manifests |
|
|
| [`upload_test_report_script.py`](/build_tools/github_actions/upload_test_report_script.py) | `WorkflowOutputRoot` for S3 base URI (upload not yet migrated to backend) |
|
|
|
|
### Download scripts
|
|
|
|
| File | Uses |
|
|
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
| [`fetch_artifacts.py`](/build_tools/fetch_artifacts.py) | `WorkflowOutputRoot.from_workflow_run(lookup_workflow_run=True)` + `S3Backend` |
|
|
| [`find_artifacts_for_commit.py`](/build_tools/find_artifacts_for_commit.py) | `WorkflowOutputRoot.from_workflow_run(workflow_run=...)` for bucket/prefix |
|
|
| [`artifact_backend.py`](/build_tools/_therock_utils/artifact_backend.py) | `WorkflowOutputRoot` for `S3Backend` construction |
|
|
| [`artifact_manager.py`](/build_tools/artifact_manager.py) | Via `create_backend_from_env()` |
|