Repository navigation
ci: wire native Windows MSI build into CI with build_native_windows opt-in (1/2) - #9370
Conversation
…pt-in Part 1 of 2 splitting the Milestone 4 MSI wiring (#1987). This PR wires the MSI build into the CI (nightly) path and lands the shared pieces both CI and release need; a follow-up PR adds the release-bucket publish + install-test dispatch on top. CI wiring: - multi_arch_ci_windows.yml: add build_native_msi_packages, gated behind build_native_windows so CI in other repos (not building all of ROCm) skips it. Builds the runtime MSI from this run's artifacts and uploads it to the run's artifacts bucket. No release-bucket publish here. - build_native_windows flag plumbed like build_native_linux: input on multi_arch_ci.yml, exported by setup_multi_arch.yml, read into CIInputs/BuildConfig by configure_multi_arch_ci.py (windows-scoped, auto-disabled on partial builds), PR-label overrides ci:build/skip-native-windows (configure_ci_labels.py + docs). Shared core (also needed by the release follow-up): - multi_arch_build_native_windows_packages.yml: derive a WiX-legal numeric MSI ProductVersion (major.minor.<days-since-2016-04-01>.0) from the PEP440 wheel version, which WiX rejects (WIX0108); keep the full version as the display version. compute_rocm_package_version.py gains package_type=msi; generator gains --display-version and per-major.minor UpgradeCode coexistence. - skip-ci-config.toml: register the build workflow (now transitively reached from multi_arch_ci.yml) so configure_ci_path_filters stays green. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
✅ All Checks Passed — Ready for Review
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
🎉 All checks passed! This PR is ready for review. |
ScottTodd
left a comment
There was a problem hiding this comment.
Structurally looks reasonable. High level:
- Please follow the style guide. No inline bash, definitely no inline python. Pass the values that are already computed through the workflows instead of converting between formats.
- This could still be split further into 2+ pull requests. One for the version changes (is the build number and internal version for dev/nightly/stable all matching in the RFC?), then one for the CI integration
- Builds failed (flaky, unrelated?) on CI so I can't review the logs from the actual packaging step at https://github.com/ROCm/TheRock/actions/runs/39306325198/job/118296602107?pr=9370 . Hard to review without that.
| # 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). | ||
| if package_type == "msi": |
There was a problem hiding this comment.
Rather than add msi before python packages and native linux packages, can you sort this as:
- Python
- Native Linux
- Native Windows
matching what we have in the versioning.md and releases.md docs?
So something like this in code:
if package_type == "wheel":
...
elif package_type == "deb" or package_type == "rpm":
...
elif package_type == "msi":
...
else:
raise AssertionError(f"Unexpected package type: {package_type}")There was a problem hiding this comment.
Done in b0f3450 — reordered the branches to wheel → deb/rpm → msi and added an explicit else: raise AssertionError(f"Unexpected package type: {package_type}").
| def test_keeps_major_minor_and_zero_fourth_field(self): | ||
| for release_type in self.RELEASE_TYPES: | ||
| with self.subTest(release_type=release_type): | ||
| major, minor, _build, fourth = self._compute(release_type).split(".") | ||
| self.assertEqual((major, minor), ("10", "2")) | ||
| self.assertEqual(fourth, "0") |
There was a problem hiding this comment.
nit: this test would be easier to read if it called compute_version() directly instead of using a _compute() helper function. As it is, the connection between base="10.2.0" in the helper function and what the test is asserting takes a bit of effort to spot.
Also, 10.2.0 is a real version (what is currently used), so it could be read as "the current version", which would need to be updated when the version changes. Other tests in the file use 8.1.0 and other older versions, or intentionally fake versions that stand out.
There was a problem hiding this comment.
Done in b0f3450 — dropped the _compute helper (each test calls compute_version() directly) and switched the base version to a stand-out 8.1.0 so it no longer reads as the current version.
| # MSI: major.minor.<days-since-epoch>.0 (no dev suffix). | ||
| build_field = compute_rocm_package_version.compute_msi_build_field() | ||
| self.assertEqual(outputs["rocm_msi_package_version"], f"7.99.{build_field}.0") |
There was a problem hiding this comment.
nit: could mock compute_msi_build_field() or the clock in these tests instead of calling the function. https://testing.googleblog.com/2014/07/testing-on-toilet-dont-put-logic-in.html
There was a problem hiding this comment.
Done in b0f3450 — MsiPackageVersionTest now patches compute_msi_build_field to a constant so each expected version is a literal (e.g. 8.1.3800.0), no recomputation in the test. Split the tests that exercise compute_msi_build_field itself into a separate MsiBuildFieldTest that asserts literal day-counts for fixed dates.
| build_native_linux = ci_inputs.build_native_linux | ||
| # Native Windows (MSI) packages are built only on the windows platform. | ||
| build_native_windows = ci_inputs.build_native_windows and platform == "windows" |
There was a problem hiding this comment.
Looks like build_native_linux should also get and platform == "linux"?
Then I don't think the comment is useful
- of course Linux requires Linux and Windows requires Windows
- what type of windows package it is (MSI) isn't relevant here
There was a problem hiding this comment.
Done in b0f3450 — build_native_linux is now and platform == "linux" (matching windows), and dropped the comment.
| if "ci:build-native-windows" in pr_labels: | ||
| build_native_windows = True | ||
| elif "ci:skip-native-windows" in pr_labels: | ||
| build_native_windows = False |
There was a problem hiding this comment.
should also check if platform == "linux" here too? Or if not, why check for Windows?
There was a problem hiding this comment.
Done in b0f3450 — the native-linux overrides are now wrapped in if platform == "linux":, symmetric with the windows block, so each platform consults only its own labels.
| build_native_windows: | ||
| description: "Build native Windows packages (MSI)." | ||
| type: boolean | ||
| default: true |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
| # Build the native Windows MSI installer(s) from this run's artifacts. In CI | ||
| # the MSI is produced and uploaded to the run's artifacts bucket (a build | ||
| # artifact) to exercise the packaging path; it is not published to a release | ||
| # bucket here (that happens only in the release workflow). |
There was a problem hiding this comment.
This comment is not necessary. All CI workflows are designed in this way.
See:
| # Only the runtime package is published in nightly artifacts today; core's | ||
| # Windows artifacts (core-amdsmi, core-runtime) are not yet available. | ||
| packages: runtime |
There was a problem hiding this comment.
This is a CI workflow. Why does it mention "nightly" artifacts?
Dev -> Nightly -> Prod. This is dev.
There was a problem hiding this comment.
Done in b0f3450 — reworded from "nightly" to "CI" artifacts (this is the dev/CI path).
| uses: ./.github/workflows/multi_arch_build_native_windows_packages.yml | ||
| with: | ||
| artifact_run_id: ${{ github.run_id }} | ||
| rocm_version: ${{ inputs.rocm_package_version }} |
There was a problem hiding this comment.
Is this the version you want to pass?
Native Linux packaging workflows pass the deb/rpm version here:
TheRock/.github/workflows/multi_arch_ci_linux.yml
Lines 169 to 176 in 0e75336
I would suggest passing both the user-facing version and the build version as two separate inputs.
There was a problem hiding this comment.
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).
| # The incoming rocm_version is the PEP440 wheel version (e.g. | ||
| # 10.2.0.dev0+<sha>), which WiX rejects (WIX0108: the MSI ProductVersion | ||
| # must be numeric #.#.#.#). Derive the numeric MSI ProductVersion | ||
| # (major.minor.<days-since-2016-04-01>.0) for Package/@Version; the full | ||
| # rocm_version is kept as the display version (ARP + discovery key). Writes | ||
| # to GITHUB_ENV rather than capturing stdout, since the helper logs there. | ||
| - name: Compute MSI version | ||
| run: | | ||
| python - <<'PY' | ||
| import os, re | ||
| from compute_rocm_package_version import compute_msi_build_field | ||
|
|
||
| rocm_version = os.environ["ROCM_VERSION"] | ||
| m = re.match(r"^(\d+)\.(\d+)\.", rocm_version) | ||
| if not m: | ||
| raise SystemExit(f"cannot parse major.minor from {rocm_version!r}") | ||
| major, minor = m.group(1), m.group(2) | ||
| msi_version = f"{major}.{minor}.{compute_msi_build_field()}.0" | ||
| with open(os.environ["GITHUB_ENV"], "a") as f: | ||
| f.write(f"MSI_PACKAGE_VERSION={msi_version}\n") | ||
| print(f"MSI ProductVersion: {msi_version} (display {rocm_version})") | ||
| PY | ||
| env: | ||
| PYTHONPATH: ${{ github.workspace }}/build_tools |
There was a problem hiding this comment.
Relating to my other comment - no logic in workflow files! ESPECIALLY inline python like this, that is significantly worse than inline bash. Follow the style guide: https://github.com/ROCm/TheRock/blob/main/docs/development/style_guides/github_actions_style_guide.md#prefer-python-scripts-over-inline-bash
The versions are already computed at the start of the CI pipeline, just pass them through to this workflow. No need to say "well you passed me a python version so now I'll convert it to the version I actually want" - just pass the versions that the script wants directly.
There was a problem hiding this comment.
Done in b0f3450 — removed the inline-python step entirely. The WiX-legal MSI ProductVersion is now computed once upstream (setup_multi_arch.yml already runs compute_rocm_package_version.py, which emits rocm_msi_package_version) and threaded through multi_arch_ci.yml → multi_arch_ci_windows.yml → the build workflow as a new msi_version input, mirroring how the deb/rpm versions are passed. The build workflow now receives both the display version (rocm_version) and the numeric ProductVersion (msi_version) directly.
…eanups Addresses ScottTodd's review on #9370. Version passing (no inline logic in workflows): - Compute the WiX-legal MSI ProductVersion once in setup_multi_arch.yml (the script already emits rocm_msi_package_version) and thread it through multi_arch_ci.yml -> multi_arch_ci_windows.yml -> the build workflow as a new `msi_version` input, mirroring how deb/rpm versions are passed. Delete the inline-python "Compute MSI version" step from the build workflow; it now receives both the display version (rocm_version) and the numeric ProductVersion (msi_version) directly. Follows the github_actions style guide (no inline logic; compute upstream, pass through). configure_multi_arch_ci.py: - Gate build_native_linux with `and platform == "linux"` to match build_native_windows, and wrap the native-linux label overrides in `if platform == "linux":` so each platform consults only its own labels. Drop the now-redundant comment. compute_rocm_package_version.py: - Reorder the package-type branches to wheel -> deb/rpm -> msi (matching versioning.md / releases.md) and add an explicit `else: raise AssertionError` for unexpected types. Tests / wording: - MsiPackageVersionTest: call compute_version() directly (drop the _compute helper), use a stand-out base version (8.1.0), and patch compute_msi_build_field to a constant so expected versions are literals. Split the build-field-function tests into MsiBuildFieldTest. - Trim "MSI" -> "native windows" in CI test docstrings; drop the inaccurate "nightly" wording and an unnecessary comment in multi_arch_ci_windows.yml. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Follows the build-workflow contract change in the CI PR (#9370), which made msi_version a required input computed upstream instead of inside the build workflow. Surface rocm_msi_package_version from multi_arch_release.yml into multi_arch_release_windows.yml and pass it as msi_version to the native MSI build job, mirroring how the deb/rpm versions are threaded on the Linux path. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
| - name: Generate WiX source and build MSI | ||
| run: | | ||
| # Generate one .wxs per requested package straight into MSI_DIR; the | ||
| # generator names each file <output_stem>.wxs, so the workflow needs no | ||
| # knowledge of the package-to-filename mapping. | ||
| python build_tools/packaging/windows/generate_msi_wxs.py \ | ||
| --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. | ||
| shopt -s nullglob | ||
| for wxs in "${MSI_DIR}"/*.wxs; do | ||
| wix build "${wxs}" -arch x64 -o "${wxs%.wxs}.msi" | ||
| done |
There was a problem hiding this comment.
This could use more logging (in generate_msi_wxs.py)
Fetching all 75 artifacts
Using generic (host) artifacts only
Retrieving bucket info for workflow run...
github_repository: ROCm/TheRock
release_type: ci
is_pr_from_fork: False
bucket: therock-ci-artifacts
Using backend: s3://therock-ci-artifacts/39458231723-windows
Found 236 artifacts in backend
Excluding artifact components: dbg, dev, doc, run, test
Downloading 27 artifacts...
++ Downloading amd-dbgapi_lib_generic.tar.zst
++ Downloading amd-llvm_lib_generic.tar.zst
...
Downloaded 27 artifacts, extracted 27
Fetching artifacts for run 39458231723 (windows) ...
Written: D:\a\TheRock\TheRock\msi-output\amdrocm-runtime.wxs
Files: 7
Install: [ProgramFiles64Folder]\AMD\ROCm\core-10.2\
I would expect logs for:
- Which packages were requested and are being built
- Details about what is getting constructed (generating files, constructing packages, writing to output directories)
- etc.
See the deb/rpm package builds for some comparison:
There was a problem hiding this comment.
Done in cccd032. The step will now log which packages are being built, the MSI and display versions, the install path, each payload file and its artifact source, and the legacy System32 DLLs. Example output:
Building packages: runtime
Fetching artifacts for run 39458231723 (windows) ...
Package: AMD ROCm Runtime
Version: 10.2.3850.0 (display: 10.2.0)
Install: [ProgramFiles64Folder]\AMD\ROCm\core-10.2Files: 7
bin\amdhip64_7.dll <- amdhip64_7.dll
...
Legacy System32 DLLs (5):
amdhip64_6.dll <- ...
Written: .../amdrocm-runtime.wxs
Add package-level and file-level logging to generate_msi_wxs.py so the
CI step shows which packages are being built, the MSI and display versions,
the install path, each payload file and where it came from, and which legacy
System32 DLLs are included.
Before:
Fetching artifacts for run 39458231723 (windows) ...
Written: .../amdrocm-runtime.wxs
Files: 7
Install: [ProgramFiles64Folder]\AMD\ROCm\core-10.2\
After:
Building packages: runtime
Fetching artifacts for run 39458231723 (windows) ...
Package: AMD ROCm Runtime
Version: 10.2.3850.0 (display: 10.2.0)
Install: [ProgramFiles64Folder]\AMD\ROCm\core-10.2\
Files: 7
bin\amdhip64_7.dll <- amdhip64_7.dll
...
Legacy System32 DLLs (5):
amdhip64_6.dll <- ...
...
Written: .../amdrocm-runtime.wxs
Co-Authored-By: Claude <noreply@anthropic.com>
Follows the build-workflow contract change in the CI PR (#9370), which made msi_version a required input computed upstream instead of inside the build workflow. Surface rocm_msi_package_version from multi_arch_release.yml into multi_arch_release_windows.yml and pass it as msi_version to the native MSI build job, mirroring how the deb/rpm versions are threaded on the Linux path. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
| - name: Generate WiX source and build MSI | ||
| run: | | ||
| # Generate one .wxs per requested package straight into MSI_DIR; the | ||
| # generator names each file <output_stem>.wxs, so the workflow needs no | ||
| # knowledge of the package-to-filename mapping. | ||
| python build_tools/packaging/windows/generate_msi_wxs.py \ |
There was a problem hiding this comment.
This is failing in rocm-libraries: https://github.com/ROCm/rocm-libraries/actions/runs/40533716406/job/122412258648?pr=14471#step:7:50
Fetching all 75 artifacts
Using generic (host) artifacts only
Retrieving bucket info for workflow run...
github_repository: ROCm/TheRock
release_type: ci
is_pr_from_fork: False
bucket: therock-ci-artifacts
Using backend: s3://therock-ci-artifacts/40533716406-windows
Found 0 artifacts in backend
Excluding artifact components: dbg, dev, doc, run, test
Traceback (most recent call last):
File "D:\a\rocm-libraries\rocm-libraries\build_tools\artifact_manager.py", line 1477, in <module>
main()
File "D:\a\rocm-libraries\rocm-libraries\build_tools\artifact_manager.py", line 1473, in main
args.func(args)
File "D:\a\rocm-libraries\rocm-libraries\build_tools\artifact_manager.py", line 526, in do_fetch
raise RuntimeError(
RuntimeError: ERROR: No matching artifacts found in s3://therock-ci-artifacts/40533716406-windows for target families: generic
Traceback (most recent call last):
Building packages: runtime
Fetching artifacts for run 40533716406 (windows) ...
File "D:\a\rocm-libraries\rocm-libraries\build_tools\packaging\windows\generate_msi_wxs.py", line 1366, in <module>
build_all(parse_args())
File "D:\a\rocm-libraries\rocm-libraries\build_tools\packaging\windows\generate_msi_wxs.py", line 1349, in build_all
artifact_dir = resolve_artifact_dir(args)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\a\rocm-libraries\rocm-libraries\build_tools\packaging\windows\generate_msi_wxs.py", line 761, in resolve_artifact_dir
return fetch_artifacts(
^^^^^^^^^^^^^^^^
File "D:\a\rocm-libraries\rocm-libraries\build_tools\packaging\windows\generate_msi_wxs.py", line 243, in fetch_artifacts
subprocess.run(cmd, check=True)
File "C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['C:\\hostedtoolcache\\windows\\Python\\3.12.10\\x64\\python.exe', 'D:\\a\\rocm-libraries\\rocm-libraries\\build_tools\\artifact_manager.py', 'fetch', '--run-id=40533716406', '--platform=windows', '--stage=all', '--generic-only', '--exclude-components=dbg,dev,doc,run,test', '--output-dir=D:\\a\\rocm-libraries\\rocm-libraries\\build_tools\\packaging\\windows\\artifact-cache', '--download-cache-dir=D:\\a\\rocm-libraries\\rocm-libraries\\build_tools\\packaging\\windows\\artifact-cache\\_downloads', '--run-github-repo=ROCm/TheRock']' returned non-zero exit status 1.
--run-github-repo "${ARTIFACT_GITHUB_REPO}" should be rocm-libraries, not TheRock there.
|
For the rocm-libraries failure (r4393646020): addressed in #9547 — artifact fetch moved to a dedicated workflow step mirroring the Linux pattern, and |
## Motivation * Fixes #9579 * Follow-up to #7280 * Follow-up to #9370 See the documentation at https://github.com/ROCm/TheRock/blob/main/docs/development/s3_buckets.md#authentication. Workflows need credentials to upload to our S3 buckets. These can come from two sources: 1. Non-fork PRs use OIDC 2. Fork PRs use runner base credentials **so they must be self-hosted runners** We want to enable debugging with github-hosted runners when this organization's self-hosted runners are unavailable (see https://github.com/ROCm/TheRock/blob/main/docs/development/github_actions_debugging.md#working-effectively-from-forks). For that, the workflows support building packages without uploading them using github-hosted runners. ## Test Plan * Run the new unit test before/after ``` pytest build_tools\github_actions\tests\workflow_self_hosted_runners_test.py E AssertionError: Jobs using configure_aws_artifacts_credentials must allow self-hosted runners with baseline storage credentials for fork PRs. E Use a self-hosted runner label or a conditional runner input, as in multi_arch_build_native_linux_packages.yml. E See docs/development/s3_buckets.md#authentication. E - multi_arch_build_native_linux_packages.yml: jobs.stage_repo_setup_package: runs-on: 'ubuntu-26.04' E - multi_arch_build_native_windows_packages.yml: jobs.build: runs-on: 'windows-2022' build_tools\github_actions\tests\workflow_self_hosted_runners_test.py:69: AssertionError ``` * Watch CI runs on PRs from forks ## Submission Checklist - [x] Look over the contributing guidelines at https://github.com/ROCm/TheRock/blob/main/CONTRIBUTING.md.
Follows the build-workflow contract change in the CI PR (#9370), which made msi_version a required input computed upstream instead of inside the build workflow. Surface rocm_msi_package_version from multi_arch_release.yml into multi_arch_release_windows.yml and pass it as msi_version to the native MSI build job, mirroring how the deb/rpm versions are threaded on the Linux path. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
…2/2) (#9371) ## Summary Adds the release-side plumbing: - Re-adds publish_native_windows_packages() to publish_rocm_to_release_buckets.py, now that #9370 wires in the build - The publish_to_release_buckets job now depends on build_native_msi_packages to prevent the "unable to find msi" errors previously observed - Dispatches the MSI install test after each release build. Requires ROCm/rockrel#130 to be merged first (stub workflow for the dispatch). ## Test plan - [x] `quartz_tracking_id_propagation_test.py`, `configure_ci_path_filters_test.py`, `workflow_dispatch_inputs_test.py`, `workflow_step_timeouts_test.py` — pass - [x] `publish_rocm_to_release_buckets_test.py` (windows MSI copy) — pass - [x] pre-commit (black + actionlint) — green --------- Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com> Co-authored-by: Scott Todd <Scott.Todd@amd.com>
Summary
Part 1 of 2 splitting the Milestone 4 MSI wiring (#1987), per review feedback on #9025 to separate CI wiring from release wiring. This PR wires the native Windows MSI build into the CI (nightly) path and lands the shared pieces both CI and release need. The release-bucket publish + install-test dispatch follow in stacked PR #9371.
CI wiring
multi_arch_ci_windows.yml: newbuild_native_msi_packagesjob, gated behindbuild_native_windowsso CI in other repositories (not building all of ROCm) skips it. Builds the runtime MSI from this run's artifacts and uploads it to the run's artifacts bucket. No release-bucket publish here.build_native_windowsflag plumbed exactly likebuild_native_linux: input onmulti_arch_ci.yml, exported bysetup_multi_arch.yml, read intoCIInputs/BuildConfigbyconfigure_multi_arch_ci.py(windows-scoped, auto-disabled on partial builds), with PR-label overridesci:build-native-windows/ci:skip-native-windows(configure_ci_labels.py+ docs).Shared core (also needed by the release follow-up)
multi_arch_build_native_windows_packages.yml: derive a WiX-legal numeric MSIProductVersion(major.minor.<days-since-2016-04-01>.0) from the PEP440 wheel version, which WiX rejects (WIX0108); keep the full version as the display version.compute_rocm_package_version.pygainspackage_type="msi"; generator gains--display-versionand per-major.minorUpgradeCode coexistence.skip-ci-config.toml: register the build workflow (now transitively reached frommulti_arch_ci.yml).Supersedes the CI half of #9025 (kept open until these land).
Addressed #9025 review comments (CI-side)
r4296724405— "make this job optional, CI in other repos should skip packaging": thebuild_native_msi_packagesjob is now gated behindbuild_native_windows(mirroringbuild_native_linux), withci:build/skip-native-windowslabel overrides.r4289101570— dev-version build failure (WIX0108, PEP440 version not valid forPackage/@Version): fixed by deriving a numeric MSI ProductVersion incompute_rocm_package_version.py(package_type="msi"), keeping the full version as the display version. Added version-parse tests.The two remaining
multi_arch_release_windows.yml"omit comment" threads (r4289106318,r4289108399) touch the release workflow and are addressed in #9371.Test plan
configure_multi_arch_ci_test.py(build_native_windows field, platform gating, label overrides) — passconfigure_ci_path_filters_test.py,quartz_tracking_id_propagation_test.py,workflow_dispatch_inputs_test.py— passcompute_rocm_package_version_test.py,generate_msi_wxs_test.py— pass🤖 Generated with Claude Code