diff --git a/.bazelrc b/.bazelrc index 76db13b480..76f81ade40 100644 --- a/.bazelrc +++ b/.bazelrc @@ -29,10 +29,6 @@ common:linux --test_env=PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin common:macos --test_env=PATH=/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin # Pass through some env vars Windows needs to use powershell? -# CI overrides PATH in `.github/scripts/run-bazel-ci.sh` with a cache-stable -# allow-list so unrelated GitHub Windows image tool updates do not invalidate -# BuildBuddy action/test cache entries. -common:windows --test_env=PATH common:windows --test_env=SYSTEMROOT common:windows --test_env=COMSPEC common:windows --test_env=WINDIR diff --git a/.github/actions/setup-bazel-ci/action.yml b/.github/actions/setup-bazel-ci/action.yml index 7c605c60b7..e249a37a5e 100644 --- a/.github/actions/setup-bazel-ci/action.yml +++ b/.github/actions/setup-bazel-ci/action.yml @@ -122,6 +122,77 @@ runs: } } + - name: Compute cache-stable Windows Bazel PATH + if: runner.os == 'Windows' + shell: pwsh + run: | + # Bazel action/test cache keys include PATH when it is forwarded into the + # execution environment. Filter the runner PATH down to the tool + # locations these Windows Bazel jobs actually need so hosted-image churn + # such as Maven updates does not invalidate otherwise reusable entries. + $stablePathEntries = New-Object System.Collections.Generic.List[string] + $seenEntries = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) + $windowsAppsPath = Join-Path $env:LOCALAPPDATA 'Microsoft\WindowsApps' + $windowsDir = if ($env:WINDIR) { $env:WINDIR } else { $env:SystemRoot } + + function Add-StablePathEntry { + param([string]$PathEntry) + + if ([string]::IsNullOrWhiteSpace($PathEntry)) { + return + } + + if ($seenEntries.Add($PathEntry)) { + [void]$stablePathEntries.Add($PathEntry) + } + } + + foreach ($pathEntry in ($env:PATH -split ';')) { + if ([string]::IsNullOrWhiteSpace($pathEntry)) { + continue + } + + if ( + $pathEntry -like '*Microsoft Visual Studio*' -or + $pathEntry -like '*Windows Kits*' -or + $pathEntry -like '*Microsoft SDKs*' -or + $pathEntry -like 'C:\Program Files\Git\*' -or + $pathEntry -like 'C:\Program Files\PowerShell\*' -or + $pathEntry -like 'C:\hostedtoolcache\windows\node\*' -or + $pathEntry -eq 'D:\a\_temp\install-dotslash\bin' -or + ($windowsDir -and ($pathEntry -eq $windowsDir -or $pathEntry -like "${windowsDir}\*")) -or + ($windowsAppsPath -and $pathEntry -eq $windowsAppsPath) + ) { + Add-StablePathEntry $pathEntry + } + } + + $gitCommand = Get-Command git -ErrorAction SilentlyContinue + if ($gitCommand) { + Add-StablePathEntry (Split-Path $gitCommand.Source -Parent) + } + + $nodeCommand = Get-Command node -ErrorAction SilentlyContinue + if ($nodeCommand) { + Add-StablePathEntry (Split-Path $nodeCommand.Source -Parent) + } + + $pwshCommand = Get-Command pwsh -ErrorAction SilentlyContinue + if ($pwshCommand) { + Add-StablePathEntry (Split-Path $pwshCommand.Source -Parent) + } + + if (Test-Path $windowsAppsPath) { + Add-StablePathEntry $windowsAppsPath + } + + if ($stablePathEntries.Count -eq 0) { + throw 'Failed to derive cache-stable Windows PATH.' + } + + $stablePath = $stablePathEntries -join ';' + "CODEX_BAZEL_WINDOWS_PATH=$stablePath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - name: Enable Git long paths (Windows) if: runner.os == 'Windows' shell: pwsh diff --git a/.github/scripts/run-bazel-ci.sh b/.github/scripts/run-bazel-ci.sh index 0e976eace9..cf2d4ce340 100755 --- a/.github/scripts/run-bazel-ci.sh +++ b/.github/scripts/run-bazel-ci.sh @@ -323,46 +323,15 @@ if [[ "${RUNNER_OS:-}" == "Windows" ]]; then fi done - # The GitHub Windows image puts many unrelated versioned tools on PATH. Those - # entries are still part of Bazel action/test keys when PATH is forwarded, so - # image churn such as Maven minor-version updates can invalidate otherwise - # reusable cache entries. Keep only the PATH segments Bazel actions/tests need. - windows_cache_stable_path_entries=() - if [[ -n "${PATH:-}" ]]; then - windows_path="${PATH}" - if command -v cygpath >/dev/null 2>&1; then - windows_path="$(cygpath -w -p "${PATH}")" - fi - - IFS=';' read -r -a windows_path_entries <<< "${windows_path}" - for path_entry in "${windows_path_entries[@]}"; do - case "${path_entry}" in - *'Microsoft Visual Studio'* | \ - *'Windows Kits'* | \ - *'Microsoft SDKs'* | \ - 'C:\Program Files\Git\'* | \ - 'C:\Program Files\PowerShell\'* | \ - 'C:\Users\runneradmin\AppData\Local\Microsoft\WindowsApps' | \ - 'C:\hostedtoolcache\windows\node\'* | \ - 'C:\Windows' | \ - 'C:\Windows\'* | \ - 'D:\a\_temp\install-dotslash\bin') - windows_cache_stable_path_entries+=("${path_entry}") - ;; - esac - done - fi - - if (( ${#windows_cache_stable_path_entries[@]} == 0 )); then - echo "Failed to derive cache-stable Windows PATH from runner PATH." >&2 + if [[ -z "${CODEX_BAZEL_WINDOWS_PATH:-}" ]]; then + echo "CODEX_BAZEL_WINDOWS_PATH must be set for Windows Bazel CI." >&2 exit 1 fi - stable_windows_path="$(IFS=';'; printf '%s' "${windows_cache_stable_path_entries[*]}")" post_config_bazel_args+=( - "--action_env=PATH=${stable_windows_path}" - "--host_action_env=PATH=${stable_windows_path}" - "--test_env=PATH=${stable_windows_path}" + "--action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}" + "--host_action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}" + "--test_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}" ) fi