Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions .github/workflows/multi_arch_build_native_windows_packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ on:
type: string
default: runtime
rocm_version:
description: "ROCm version to stamp on the MSI (e.g. '7.15.0')."
description: "User-facing ROCm version shown in the installer (e.g. '7.15.0')."
type: string
required: true
msi_version:
description: "WiX-legal numeric MSI ProductVersion (e.g. '7.15.3800.0')."
type: string
required: true
release_type:
Expand All @@ -40,6 +44,13 @@ on:
description: "Branch, tag, or SHA to checkout. Defaults to the triggering ref."
type: string
default: ""
quartz_tracking_id:
description: >-
Leave empty. Internal Quartz tracking id, set automatically by the
top-level orchestrator to link this run to its release lineage. Do not
set it manually.
type: string
default: ""
workflow_call:
inputs:
artifact_github_repo:
Expand All @@ -54,6 +65,9 @@ on:
rocm_version:
type: string
required: true
msi_version:
type: string
required: true
release_type:
type: string
default: ci
Expand All @@ -63,6 +77,9 @@ on:
ref:
type: string
default: ""
quartz_tracking_id:
type: string
default: ""

permissions:
contents: read
Expand All @@ -84,7 +101,8 @@ jobs:
env:
ARTIFACT_RUN_ID: ${{ inputs.artifact_run_id }}
ARTIFACT_GITHUB_REPO: ${{ inputs.artifact_github_repo }}
PACKAGE_VERSION: ${{ inputs.rocm_version }}
ROCM_VERSION: ${{ inputs.rocm_version }}
MSI_VERSION: ${{ inputs.msi_version }}
PACKAGES: ${{ inputs.packages }}
MSI_DIR: ${{ github.workspace }}/msi-output
RELEASE_TYPE: ${{ inputs.release_type }}
Expand Down Expand Up @@ -131,7 +149,8 @@ jobs:
--packages "${PACKAGES}" \
--run-id "${ARTIFACT_RUN_ID}" \
--run-github-repo "${ARTIFACT_GITHUB_REPO}" \
--package-version "${PACKAGE_VERSION}" \
--package-version "${MSI_VERSION}" \
--display-version "${ROCM_VERSION}" \
--output-dir "${MSI_DIR}"

# Compile every generated .wxs into a matching .msi alongside it.
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/multi_arch_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ on:
type: boolean
default: true
description: "Build native Linux packages and run install tests"
build_native_windows:
type: boolean
default: true
description: "Build native Windows packages (MSI)"
# --- Artifact reuse ---
prebuilt_stages:
type: string
Expand Down Expand Up @@ -113,6 +117,9 @@ on:
build_native_linux:
type: boolean
default: true
build_native_windows:
type: boolean
default: true
prebuilt_stages:
type: string
default: ""
Expand Down Expand Up @@ -170,6 +177,7 @@ jobs:
build_pytorch: ${{ github.event_name != 'workflow_dispatch' || inputs.build_pytorch }}
build_jax: ${{ github.event_name != 'workflow_dispatch' || inputs.build_jax }}
build_native_linux: ${{ github.event_name != 'workflow_dispatch' || inputs.build_native_linux }}
build_native_windows: ${{ github.event_name != 'workflow_dispatch' || inputs.build_native_windows }}
build_stages: ${{ inputs.build_stages || '' }}

linux_build_and_test:
Expand Down Expand Up @@ -206,6 +214,7 @@ jobs:
build_config: ${{ needs.setup.outputs.windows_build_config }}
test_labels: ${{ needs.setup.outputs.windows_test_labels }}
rocm_package_version: ${{ needs.setup.outputs.rocm_package_version }}
rocm_msi_package_version: ${{ needs.setup.outputs.rocm_msi_package_version }}
test_type: ${{ needs.setup.outputs.test_type }}
changed_projects: ${{ inputs.changed_projects || '' }}
permissions:
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/multi_arch_ci_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ on:
type: string
rocm_package_version:
type: string
rocm_msi_package_version:
type: string
test_type:
type: string
release_type:
Expand Down Expand Up @@ -184,6 +186,25 @@ jobs:
contents: read
id-token: write

build_native_msi_packages:
needs: [build_multi_arch_stages]
name: Build Native MSI Packages
if: ${{ !failure() && !cancelled() && !contains(needs.*.result, 'cancelled') && fromJSON(inputs.build_config).build_native_windows == true }}
uses: ./.github/workflows/multi_arch_build_native_windows_packages.yml
with:
artifact_run_id: ${{ github.run_id }}
rocm_version: ${{ inputs.rocm_package_version }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the version you want to pass?

Native Linux packaging workflows pass the deb/rpm version here:

build_native_deb_packages:
needs: [build_multi_arch_stages]
name: Build DEB Packages
if: ${{ !failure() && !cancelled() && !contains(needs.*.result, 'cancelled') && fromJSON(inputs.build_config).build_native_linux == true }}
uses: ./.github/workflows/multi_arch_build_native_linux_packages.yml
with:
dist_amdgpu_families: ${{ fromJSON(inputs.build_config).dist_amdgpu_families }}
rocm_version: ${{ inputs.rocm_deb_package_version }}

I would suggest passing both the user-facing version and the build version as two separate inputs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in b0f3450 — now passing two separate inputs: rocm_version (user-facing display version) and msi_version (the WiX-legal numeric ProductVersion from setup.outputs.rocm_msi_package_version), matching the deb/rpm pattern you linked. The release path is wired the same way in the companion PR #9371 (commit 4847342).

msi_version: ${{ inputs.rocm_msi_package_version }}
# Only the runtime package is published in CI artifacts today; core's
# Windows artifacts (core-amdsmi, core-runtime) are not yet available.
packages: runtime
release_type: ${{ inputs.release_type }}
repository: ${{ inputs.repository }}
ref: ${{ inputs.ref }}
permissions:
contents: read
id-token: write

test_python_packages_per_family:
needs: [build_python_packages]
name: Test Python
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/setup_multi_arch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ on:
description: "Build native Linux packages (deb/rpm) and run their install tests."
type: boolean
default: true
build_native_windows:
description: "Build native Windows packages (MSI)."
type: boolean
default: true
Comment on lines +94 to +97

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we may want to set this explicitly in repositories that use TheRock CI, as is done for build_native_linux: https://github.com/ROCm/rocm-libraries/blob/04e9f86ab9e6e49e64c820ba97b4cea16e5a5fed/.github/workflows/therock-multi-arch-ci.yml#L178-L180

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point — noted. This PR keeps the default true so TheRock CI behavior is unchanged; I'll follow up to set build_native_windows explicitly in the downstream repo CI configs (rocm-libraries/rocm-systems) the same way build_native_linux is, as a separate change.

python_version:
description: "Single Python version for wheel builds; empty uses the default matrix."
type: string
Expand Down Expand Up @@ -150,6 +154,9 @@ on:
rocm_rpm_package_version:
description: ROCm RPM package version for native packages.
value: ${{ jobs.setup.outputs.rocm_rpm_package_version }}
rocm_msi_package_version:
description: ROCm MSI package version for native Windows packages.
value: ${{ jobs.setup.outputs.rocm_msi_package_version }}
ref:
description: >-
Resolved commit SHA from checkout. Use this instead of the input ref
Expand Down Expand Up @@ -177,6 +184,7 @@ jobs:
rocm_package_version: ${{ steps.rocm_package_version.outputs.rocm_package_version }}
rocm_deb_package_version: ${{ steps.rocm_package_version.outputs.rocm_deb_package_version }}
rocm_rpm_package_version: ${{ steps.rocm_package_version.outputs.rocm_rpm_package_version }}
rocm_msi_package_version: ${{ steps.rocm_package_version.outputs.rocm_msi_package_version }}
ref: ${{ steps.checkout.outputs.commit }}
external_repo_config: ${{ steps.external_repo_config.outputs.config_json }}
env:
Expand Down Expand Up @@ -246,6 +254,7 @@ jobs:
BUILD_PYTORCH: ${{ inputs.build_pytorch }}
BUILD_JAX: ${{ inputs.build_jax }}
BUILD_NATIVE_LINUX: ${{ inputs.build_native_linux }}
BUILD_NATIVE_WINDOWS: ${{ inputs.build_native_windows }}
PYTHON_VERSION: ${{ inputs.python_version }}
LINUX_AMDGPU_FAMILIES: ${{ inputs.linux_amdgpu_families }}
WINDOWS_AMDGPU_FAMILIES: ${{ inputs.windows_amdgpu_families }}
Expand Down
81 changes: 72 additions & 9 deletions build_tools/compute_rocm_package_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@
"""Computes a ROCm package version with an appropriate suffix for a given release type.

For usage from other Python scripts, call the `compute_version()` function
directly. When used from GitHub Actions, this writes all three version outputs
to GITHUB_OUTPUT:
directly. When used from GitHub Actions, this writes all version outputs to
GITHUB_OUTPUT:
- 'rocm_package_version' for wheel packages
- 'rocm_deb_package_version' for deb packages
- 'rocm_rpm_package_version' for rpm packages
- 'rocm_msi_package_version' for Windows MSI packages

Sample usage:

python compute_rocm_package_version.py --release-type=dev
# rocm_package_version=7.10.0.dev0+f689a8ea40232f3f6be1ec958354b108349023ff
# rocm_deb_package_version=7.10.0~dev20251203
# rocm_rpm_package_version=7.10.0~20251203gf689a8e
# rocm_msi_package_version=7.10.3929.0 (major.minor.<days-since-2016-04-01>.0)

python compute_rocm_package_version.py --release-type=prerelease --prerelease-version=2
# rocm_package_version=7.10.0rc2
Expand All @@ -43,7 +45,7 @@

import argparse
from collections.abc import Mapping
from datetime import datetime
from datetime import date, datetime
from pathlib import Path
import json
import os
Expand All @@ -56,6 +58,16 @@
THIS_SCRIPT_DIR = Path(__file__).resolve().parent
THEROCK_DIR = THIS_SCRIPT_DIR.parent

# Epoch for the MSI ProductVersion build field: the first ROCm release (ROCm 1.0,
# April 2016). The MSI version's third field is the number of days since this
# date, giving a strictly increasing, WiX-legal integer. See compute_msi_build_field.
MSI_EPOCH = date(2016, 4, 1)

# Windows Installer compares only the first three ProductVersion fields and caps
# the third (build) field at 65535. days-since-MSI_EPOCH stays under this until
# ~year 2195, after which a build would raise rather than silently wrap.
MSI_BUILD_FIELD_MAX = 65535


def _log(*args, **kwargs):
print(*args, **kwargs)
Expand Down Expand Up @@ -137,6 +149,27 @@ def get_current_date():
return datetime.today().strftime("%Y%m%d")


def compute_msi_build_field(today: date | None = None) -> int:
"""Return the MSI ProductVersion build field: days since MSI_EPOCH.

This is the third field of the four-field MSI version. It increases by one
per day, so a later build always outranks an earlier one within its
major.minor line (Windows Installer compares only the first three fields).
Raises if it would exceed the installer's 65535 limit.
"""
if today is None:
today = date.today()
days = (today - MSI_EPOCH).days
if days < 0:
raise ValueError(f"build date {today} precedes the MSI epoch {MSI_EPOCH}")
if days > MSI_BUILD_FIELD_MAX:
raise ValueError(
f"MSI build field {days} exceeds the Windows Installer limit of "
f"{MSI_BUILD_FIELD_MAX} (third ProductVersion field)"
)
return days


def compute_version(
package_type: str = "wheel",
release_type: str | None = None,
Expand All @@ -149,7 +182,7 @@ def compute_version(
"""Compute package version based on package type and release type.

Args:
package_type: Type of package ("wheel", "deb", or "rpm")
package_type: Type of package ("wheel", "deb", "rpm", or "msi")
release_type: Release type ("ci", "dev", "dev-bkc", "nightly",
"nightly-bkc", "prerelease", or "release")
custom_version_suffix: Custom suffix to override automatic suffix
Expand Down Expand Up @@ -217,8 +250,8 @@ def compute_version(

return rocm_package_version

# Handle native packages (deb/rpm)
else: # package_type in ["deb", "rpm"]
# Handle native Linux packages (deb/rpm)
elif package_type in ("deb", "rpm"):
if custom_version_suffix:
# Custom suffix uses the provided value
version_suffix_str = f"{custom_version_suffix}"
Expand Down Expand Up @@ -260,6 +293,36 @@ def compute_version(

return rocm_package_version

# Handle native Windows packages (MSI; WiX ProductVersion: numeric
# major.minor.build.0).
#
# Unlike the other package types, the MSI version does NOT carry a dev/nightly
# suffix: Windows Installer versions must be numeric #.#.#.# and it compares
# only the first three fields. We keep major.minor from version.json visible
# and put the build DATE (days since the ROCm 1.0 epoch) in the third field,
# so every build outranks the previous one within its major.minor line. The
# marketing patch (e.g. 10.2.0) is surfaced separately via the MSI's
# ARPDISPLAYVERSION property, not here. Cross-line coexistence (10.2 vs 10.3)
# is handled by a per-major.minor UpgradeCode in the generator, so this field
# never has to order across lines. All release types share one shape; a
# release simply has the highest build field in its line because it is built
# last (no further nightlies follow a major.minor's release).
elif package_type == "msi":
parts = base_version.split(".")
if len(parts) < 2 or not parts[0] or not parts[1]:
raise ValueError(
f"base version must be at least major.minor for msi (got "
f"{base_version!r})"
)
major, minor = parts[0], parts[1]
build_field = compute_msi_build_field()
rocm_package_version = f"{major}.{minor}.{build_field}.0"
_log(f"Full version : '{rocm_package_version}'")
return rocm_package_version

else:
raise AssertionError(f"Unexpected package type: {package_type}")


def main(argv):
parser = argparse.ArgumentParser(prog="compute_rocm_package_version")
Expand Down Expand Up @@ -315,9 +378,9 @@ def main(argv):

version_data = load_version_file()

# Compute versions for all three package types: wheel, deb, and rpm
# Compute versions for all package types: wheel, deb, rpm, and msi.
outputs = {}
for pkg_type in ["wheel", "deb", "rpm"]:
for pkg_type in ["wheel", "deb", "rpm", "msi"]:
version = compute_version(
package_type=pkg_type,
release_type=args.release_type,
Expand All @@ -331,7 +394,7 @@ def main(argv):
# Set appropriate output variable based on package type
if pkg_type == "wheel":
outputs["rocm_package_version"] = version
else: # deb or rpm
else: # deb, rpm, or msi
outputs[f"rocm_{pkg_type}_package_version"] = version

gha_set_output(outputs)
Expand Down
2 changes: 2 additions & 0 deletions build_tools/github_actions/configure_ci_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,12 @@ class Label:
Label("ci:build-pytorch", COLOR_CI_PACKAGING, "Opt-in to building PyTorch packages"),
Label("ci:build-jax", COLOR_CI_PACKAGING, "Opt-in to building JAX packages"),
Label("ci:build-native-linux", COLOR_CI_PACKAGING, "Opt-in to building native Linux packages"),
Label("ci:build-native-windows", COLOR_CI_PACKAGING, "Opt-in to building native Windows packages"),
Label("ci:build-python-packages", COLOR_CI_PACKAGING, "Opt-in to building Python packages"),
Label("ci:skip-pytorch", COLOR_CI_PACKAGING, "Skip PyTorch package builds"),
Label("ci:skip-jax", COLOR_CI_PACKAGING, "Skip JAX package builds"),
Label("ci:skip-native-linux", COLOR_CI_PACKAGING, "Skip native Linux package builds"),
Label("ci:skip-native-windows", COLOR_CI_PACKAGING, "Skip native Windows package builds"),
Label("ci:skip-python-packages", COLOR_CI_PACKAGING, "Skip Python package builds"),
]
# fmt: on
Expand Down
Loading
Loading