# Copyright Advanced Micro Devices, Inc. # SPDX-License-Identifier: MIT name: Build WSL ROCDXG Artifacts on: workflow_call: inputs: stage_name: type: string required: true description: "Stage name" stage_display_name: type: string required: true description: "Human-readable display name for the job" timeout_minutes: type: number required: true description: "Job timeout in minutes" dist_amdgpu_families: type: string required: true description: "Semicolon-separated list of all GPU families for dist targets" rocm_package_version: type: string required: true description: "ROCm package version string" build_variant_cmake_preset: type: string required: false default: "" description: "CMake preset name for this build variant (optional)" release_type: description: 'Release type: "ci", "dev", "nightly", or "prerelease"' type: string default: ci repository: description: "Repository to checkout. Defaults to github.repository." type: string default: "" ref: description: "Branch, tag, or SHA to checkout. Defaults to the triggering ref." type: string default: "" external_repo_config: description: "JSON config for external repo checkout (generated by detect_external_repo_config.py)" type: string default: "" permissions: contents: read jobs: build_stage: name: ${{ inputs.stage_display_name }} runs-on: group: ROCR-Runtime-libhsakmt-WSL timeout-minutes: ${{ inputs.timeout_minutes }} permissions: contents: read id-token: write defaults: run: shell: bash env: STAGE_NAME: ${{ inputs.stage_name }} RELEASE_TYPE: ${{ inputs.release_type }} THEROCK_HOST_WORKSPACE: ${{ github.workspace }} EXTERNAL_FETCH_SOURCES_ARGS: ${{ inputs.external_repo_config != '' && fromJSON(inputs.external_repo_config).fetch_sources_args || '' }} MANYLINUX_IMAGE: ghcr.io/rocm/therock_build_manylinux_x86_64@sha256:a382085df3ba2419b58aa9051350883a0d0b732a4bc0a4ef60458f8161bb08c6 # Clean, space-free mount target for the Windows SDK shared include dir # inside the container. Avoids the raw "(x86)" path segment that /bin/sh # misparses during nested subproject configure. THEROCK_WSL_WIN_SDK_MOUNT: /opt/winsdk-shared # Injects Windows env vars into WSL WSLENV: THEROCK_HOST_WORKSPACE/p:GITHUB_REPOSITORY:GITHUB_EVENT_NAME:GITHUB_EVENT_PATH/p:RELEASE_TYPE:MANYLINUX_IMAGE:THEROCK_WSL_WIN_SDK_MOUNT:THEROCK_WIN_SDK_SHARED/p steps: # Enable git longpaths before checkout (needed for external repos with long paths) - name: Enable git longpaths if: ${{ inputs.external_repo_config != '' }} run: git config --system core.longpaths true - name: Checkout Repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ inputs.repository || github.repository }} ref: ${{ inputs.ref }} - name: Checkout external repository if: ${{ inputs.external_repo_config != '' }} uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ fromJSON(inputs.external_repo_config).repository }} ref: ${{ fromJSON(inputs.external_repo_config).ref }} path: ${{ fromJSON(inputs.external_repo_config).checkout_path }} - name: Setting up Python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.12" - name: Install python deps run: pip install -r requirements.txt - name: Runner health status run: python build_tools/health_status.py - name: Adjust git config run: | git config --global core.symlinks true git config --global core.longpaths true git config fetch.parallel 10 - name: Configure MSVC uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 - name: Detect Windows SDK version id: detect_sdk shell: powershell env: WINDOWS_SDK_INCLUDE_ROOT: C:\Program Files (x86)\Windows Kits\10\Include run: | if (-not (Test-Path $env:WINDOWS_SDK_INCLUDE_ROOT)) { throw "Windows SDK not found at $env:WINDOWS_SDK_INCLUDE_ROOT" } $versions = Get-ChildItem $env:WINDOWS_SDK_INCLUDE_ROOT -Directory | Sort-Object Name -Descending if ($versions.Count -eq 0) { throw "No Windows SDK versions found under $env:WINDOWS_SDK_INCLUDE_ROOT" } $latestVersion = $versions[0].Name "sdk_version=$latestVersion" >> $env:GITHUB_OUTPUT - uses: iterative/setup-dvc@6c05772f52d19792ed73aedb6c2bf65ec92adebb # v3.0.0 with: version: "3.62.0" - name: Fetch sources timeout-minutes: 30 run: python build_tools/fetch_sources.py --stage ${STAGE_NAME} --jobs 12 --depth 1 ${EXTERNAL_FETCH_SOURCES_ARGS} - name: Set up WSL with Ubuntu uses: Vampire/setup-wsl@d1da7f2c0322a5ee4f24975344f67fc0f5baf364 # v7.0.0 with: distribution: Ubuntu-24.04 update: true additional-packages: docker.io python3 python3-pip python3-psutil python3-venv rsync - name: Start Docker in WSL shell: wsl-bash {0} run: | # WSL2 has no init system here, so launch the daemon detached and wait # for the socket before any docker run. nohup dockerd >/tmp/dockerd.log 2>&1 & for _ in $(seq 1 30); do if docker info >/dev/null 2>&1; then break fi sleep 1 done if ! docker info >/dev/null 2>&1; then echo "dockerd failed to start" cat /tmp/dockerd.log exit 1 fi docker pull "${MANYLINUX_IMAGE}" - name: Set up WSL venv shell: wsl-bash {0} run: | # setup-wsl's default wsl-bash wrapper runs `bash --noprofile --norc -euo pipefail`. # Explicitly bridged path vars from the Windows host are available in wsl-bash via # WSLENV. Keep this path WSL-local. wsl_work_dir="${HOME}/therock-wsl-rocdxg" wsl_venv_dir="${wsl_work_dir}/.venv" python3 "${THEROCK_HOST_WORKSPACE}/build_tools/setup_venv.py" --clean "${wsl_venv_dir}" "${wsl_venv_dir}/bin/python" -m pip install -r "${THEROCK_HOST_WORKSPACE}/requirements.txt" - name: Get stage configuration id: stage_config # This is a pure topology calculation, so keep it on the Windows host # where GitHub step outputs are native. The explicit --platform=linux # still makes configure_stage.py emit Linux/WSL feature selections. run: | python build_tools/configure_stage.py \ --stage="${STAGE_NAME}" \ --dist-amdgpu-families="${{ inputs.dist_amdgpu_families }}" \ --platform=linux \ --gha-output - name: Install stage python deps if: ${{ steps.stage_config.outputs.pip_install_cmd }} shell: wsl-bash {0} run: | wsl_venv_dir="${HOME}/therock-wsl-rocdxg/.venv" "${wsl_venv_dir}/bin/python" -m pip install ${{ steps.stage_config.outputs.pip_install_cmd }} - name: Prepare WSL paths shell: wsl-bash {0} env: # Made available in WSL via job-level WSLENV THEROCK_WIN_SDK_SHARED: C:\Program Files (x86)\Windows Kits\10\Include\${{ steps.detect_sdk.outputs.sdk_version }}\shared run: | wsl_build_dir="${HOME}/therock-wsl-rocdxg/build" if [ ! -d "${THEROCK_WIN_SDK_SHARED}" ]; then echo "Windows SDK include path not found: ${THEROCK_WIN_SDK_SHARED}" exit 1 fi mkdir -p "${wsl_build_dir}" - name: Sync source tree to WSL shell: wsl-bash {0} run: | # Subproject source files are checked out on the Windows side via actions/checkout. # TheRock runs `git diff` against every subproject to check for changed files. # File operations between Windows and WSL filesystems have a lot of overhead, # so this method of diffing subprojects becomes very time consuming. # To resolve this, copy the entire tree in one sequential operation from Windows to WSL. # All `git diff` are now run on WSL-native files, giving a big speed boost. wsl_src_dir="${HOME}/therock-wsl-rocdxg/src" rm -rf "${wsl_src_dir}" mkdir -p "${wsl_src_dir}" rsync -a "${THEROCK_HOST_WORKSPACE}/" "${wsl_src_dir}/" - name: Fetch inbound artifacts shell: wsl-bash {0} run: | stage_name="${{ inputs.stage_name }}" wsl_venv_dir="${HOME}/therock-wsl-rocdxg/.venv" wsl_build_dir="${HOME}/therock-wsl-rocdxg/build" mkdir -p "${wsl_build_dir}" "${wsl_venv_dir}/bin/python" "${THEROCK_HOST_WORKSPACE}/build_tools/artifact_manager.py" fetch \ --run-id="${{ github.run_id }}" \ --run-github-repo="${{ github.repository }}" \ --platform=linux \ --stage="${stage_name}" \ --output-dir="${wsl_build_dir}" \ --bootstrap - name: Configure shell: wsl-bash {0} env: # Made available in WSL via job-level WSLENV THEROCK_WIN_SDK_SHARED: C:\Program Files (x86)\Windows Kits\10\Include\${{ steps.detect_sdk.outputs.sdk_version }}\shared run: | wsl_src_dir="${HOME}/therock-wsl-rocdxg/src" wsl_build_dir="${HOME}/therock-wsl-rocdxg/build" docker run --rm \ --mount "type=bind,src=${wsl_src_dir},dst=${wsl_src_dir}" \ --mount "type=bind,src=${wsl_build_dir},dst=${wsl_build_dir}" \ --mount "type=bind,src=${THEROCK_WIN_SDK_SHARED},dst=${THEROCK_WSL_WIN_SDK_MOUNT},readonly" \ -w "${wsl_src_dir}" \ -e "WSL_BUILD_DIR=${wsl_build_dir}" \ "${MANYLINUX_IMAGE}" \ bash -c ' set -euo pipefail git config --global --add safe.directory "*" pip install -r requirements.txt ${{ steps.stage_config.outputs.pip_install_cmd && format('pip install {0}', steps.stage_config.outputs.pip_install_cmd) || 'true' }} cmake -B "${WSL_BUILD_DIR}" -S . -G Ninja \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DTHEROCK_PACKAGE_VERSION=${{ inputs.rocm_package_version }} \ -DTHEROCK_WSL_WIN_SDK="'"${THEROCK_WSL_WIN_SDK_MOUNT}"'" \ ${{ inputs.build_variant_cmake_preset && format('--preset={0}', inputs.build_variant_cmake_preset) }} \ ${{ inputs.external_repo_config != '' && format('-DTHEROCK_{0}_SOURCE_DIR={1}', fromJSON(inputs.external_repo_config).source_package, fromJSON(inputs.external_repo_config).checkout_path) || '' }} \ ${{ inputs.external_repo_config != '' && fromJSON(inputs.external_repo_config).extra_cmake_options || '' }} \ ${{ steps.stage_config.outputs.cmake_args }} ' - name: Build stage shell: wsl-bash {0} env: # Made available in WSL via job-level WSLENV THEROCK_WIN_SDK_SHARED: C:\Program Files (x86)\Windows Kits\10\Include\${{ steps.detect_sdk.outputs.sdk_version }}\shared run: | stage_name="${{ inputs.stage_name }}" wsl_src_dir="${HOME}/therock-wsl-rocdxg/src" wsl_build_dir="${HOME}/therock-wsl-rocdxg/build" docker run --rm \ --mount "type=bind,src=${wsl_src_dir},dst=${wsl_src_dir}" \ --mount "type=bind,src=${wsl_build_dir},dst=${wsl_build_dir}" \ --mount "type=bind,src=${THEROCK_WIN_SDK_SHARED},dst=${THEROCK_WSL_WIN_SDK_MOUNT},readonly" \ -w "${wsl_src_dir}" \ -e "STAGE_NAME=${stage_name}" \ -e "WSL_BUILD_DIR=${wsl_build_dir}" \ "${MANYLINUX_IMAGE}" \ bash -c ' set -euo pipefail cmake --build "${WSL_BUILD_DIR}" --target "stage-${STAGE_NAME}" -- -k 0 ' - name: Report if: ${{ !cancelled() }} shell: wsl-bash {0} run: | wsl_build_dir="${HOME}/therock-wsl-rocdxg/build" echo "Artifacts:" ls -lh "${wsl_build_dir}"/artifacts/*.tar.xz 2>/dev/null || echo "No artifacts found" - name: Configure AWS credentials for artifact uploads if: ${{ always() && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork) }} uses: ./.github/actions/configure_aws_artifacts_credentials with: release_type: ${{ inputs.release_type }} - name: Push stage artifacts if: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork) }} shell: wsl-bash {0} env: # Append AWS creds set by the "Configure AWS credentials" step WSLENV: ${{ env.WSLENV }}:AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY:AWS_SESSION_TOKEN:AWS_DEFAULT_REGION:AWS_REGION run: | stage_name="${{ inputs.stage_name }}" wsl_venv_dir="${HOME}/therock-wsl-rocdxg/.venv" wsl_build_dir="${HOME}/therock-wsl-rocdxg/build" "${wsl_venv_dir}/bin/python" "${THEROCK_HOST_WORKSPACE}/build_tools/artifact_manager.py" push --run-id ${{ github.run_id }} \ --run-github-repo="${{ github.repository }}" \ --platform linux \ --stage="${stage_name}" \ --build-dir="${wsl_build_dir}" - name: Upload stage logs if: ${{ always() && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork) }} shell: wsl-bash {0} env: # Append AWS creds set by the "Configure AWS credentials" step WSLENV: ${{ env.WSLENV }}:AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY:AWS_SESSION_TOKEN:AWS_DEFAULT_REGION:AWS_REGION run: | wsl_venv_dir="${HOME}/therock-wsl-rocdxg/.venv" wsl_build_dir="${HOME}/therock-wsl-rocdxg/build" "${wsl_venv_dir}/bin/python" "${THEROCK_HOST_WORKSPACE}/build_tools/github_actions/post_stage_upload.py" \ --run-id=${{ github.run_id }} \ --platform=linux \ --stage="${{ inputs.stage_name }}" \ --build-dir="${wsl_build_dir}" \ --amdgpu-family=""