From beb0949bbd76f11b636212ad6c905590a149b40b Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 2 Apr 2026 20:36:38 +0900 Subject: [PATCH] Retry on bash startup failure on Windows --- .github/.cspell/project-dictionary.txt | 2 + CHANGELOG.md | 4 ++ action.yml | 22 +++++-- main.sh | 83 +++++++++++++------------- 4 files changed, 67 insertions(+), 44 deletions(-) diff --git a/.github/.cspell/project-dictionary.txt b/.github/.cspell/project-dictionary.txt index b25c2958..0e4c5c10 100644 --- a/.github/.cspell/project-dictionary.txt +++ b/.github/.cspell/project-dictionary.txt @@ -17,6 +17,7 @@ grcov gungraun insta knope +LASTEXITCODE libicu linkcheck mdbook @@ -38,6 +39,7 @@ sigstore syft tombi udeps +USERPROFILE wasmtime watchexec worktree diff --git a/CHANGELOG.md b/CHANGELOG.md index b8c8fe12..82bc3cd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com ## [Unreleased] +- Implement workaround for [windows-11-arm runner bug](https://github.com/actions/partner-runner-images/issues/169) which sometimes causes installation failure. ([#1657](https://github.com/taiki-e/install-action/pull/1657)) + + This addresses an issue that was attempted to be worked around in 2.71.0 but was insufficient. + - Update `mise@latest` to 2026.4.1. - Update `uv@latest` to 0.11.3. diff --git a/action.yml b/action.yml index 621f3429..0443de73 100644 --- a/action.yml +++ b/action.yml @@ -52,12 +52,26 @@ runs: DEFAULT_GITHUB_TOKEN: ${{ github.token }} ACTION_USER_AGENT: ${{ github.action_repository }} (${{ github.action_ref }}) if: runner.os != 'Windows' - # Workaround for https://github.com/actions/partner-runner-images/issues/169 - # TODO: Is it necessary to retry for main.sh call? Or is this sufficient? https://github.com/taiki-e/install-action/pull/1647 + # Use pwsh and retry on bash startup failure to work around windows-11-arm runner bug: https://github.com/actions/partner-runner-images/issues/169 - run: | Set-StrictMode -Version Latest - $action_path = $env:GITHUB_ACTION_PATH - & bash --noprofile --norc "${action_path}/main.sh" + for ($i=1; $i -le 10; $i++) { + $prev_err_action = $ErrorActionPreference + $ErrorActionPreference = "Continue" + & bash --noprofile --norc "$env:GITHUB_ACTION_PATH/main.sh" + $code = $LASTEXITCODE + $ErrorActionPreference = "$prev_err_action" + if (Test-Path "$env:USERPROFILE\.install-action\init") { + # If bash started successfully, main.sh creates init file. + Remove-Item "$env:USERPROFILE\.install-action\init" -Force + exit $code + } + if ($i -lt 10) { + Write-Output "::warning::installation failed due to bash startup failure (); retrying..." + } + } + Write-Output "::error::installation failed due to bash startup failure (); this maybe resolved by re-running job" + exit 1 shell: pwsh env: # NB: Sync with non-Windows case. diff --git a/main.sh b/main.sh index ce3185de..44f45722 100755 --- a/main.sh +++ b/main.sh @@ -436,46 +436,6 @@ canonicalize_windows_path() { esac } -# cargo-binstall may call `cargo install` on their fallback: https://github.com/taiki-e/install-action/pull/54#issuecomment-1383140833 -# cross calls rustup on `cross --version` if the current directly is cargo workspace. -export CARGO_NET_RETRY=10 -export RUSTUP_MAX_RETRIES=10 - -if [[ $# -gt 0 ]]; then - bail "invalid argument '$1'" -fi - -export DEBIAN_FRONTEND=noninteractive -manifest_dir="$(dirname -- "$0")/manifests" - -# Inputs -tool="${INPUT_TOOL:-}" -tools=() -if [[ -n "${tool}" ]]; then - while read -rd,; do - tools+=("${REPLY}") - done < <(normalize_comma_or_space_separated "${tool}") -fi -if [[ ${#tools[@]} -eq 0 ]]; then - warn "no tool specified; this could be caused by a dependabot bug where @ tags on this action are replaced by @ tags" - # Exit with 0 for backward compatibility. - # TODO: We want to reject it in the next major release. - exit 0 -fi - -enable_checksum="${INPUT_CHECKSUM:-}" -case "${enable_checksum}" in - true) ;; - false) enable_checksum='' ;; - *) bail "'checksum' input option must be 'true' or 'false': '${enable_checksum}'" ;; -esac - -fallback="${INPUT_FALLBACK:-}" -case "${fallback}" in - none | cargo-binstall | cargo-install) ;; - *) bail "'fallback' input option must be 'none', 'cargo-binstall', or 'cargo-install': '${fallback}'" ;; -esac - # Refs: https://github.com/rust-lang/rustup/blob/HEAD/rustup-init.sh base_distro='' exe='' @@ -590,6 +550,9 @@ cargo_bin="${CARGO_HOME:-"${home}/.cargo"}/bin" # is used ($CARGO_HOME/bin is most likely not included in the PATH), fallback to # $install_action_dir/bin. if [[ "${host_os}" == "windows" ]]; then + mkdir -p -- "${install_action_dir}" + # See action.yml. + touch -- "${install_action_dir}"/init if type -P cargo >/dev/null; then info "cargo is located at $(type -P cargo)" cargo_bin=$(dirname -- "$(type -P cargo)") @@ -604,6 +567,46 @@ elif [[ ! -e "${cargo_bin}" ]] || [[ "$(type -P cargo || true)" != "${cargo_bin} cargo_bin="${install_action_dir}/bin" fi +# cargo-binstall may call `cargo install` on their fallback: https://github.com/taiki-e/install-action/pull/54#issuecomment-1383140833 +# cross calls rustup on `cross --version` if the current directly is cargo workspace. +export CARGO_NET_RETRY=10 +export RUSTUP_MAX_RETRIES=10 + +if [[ $# -gt 0 ]]; then + bail "invalid argument '$1'" +fi + +export DEBIAN_FRONTEND=noninteractive +manifest_dir="$(dirname -- "$0")/manifests" + +# Inputs +tool="${INPUT_TOOL:-}" +tools=() +if [[ -n "${tool}" ]]; then + while read -rd,; do + tools+=("${REPLY}") + done < <(normalize_comma_or_space_separated "${tool}") +fi +if [[ ${#tools[@]} -eq 0 ]]; then + warn "no tool specified; this could be caused by a dependabot bug where @ tags on this action are replaced by @ tags" + # Exit with 0 for backward compatibility. + # TODO: We want to reject it in the next major release. + exit 0 +fi + +enable_checksum="${INPUT_CHECKSUM:-}" +case "${enable_checksum}" in + true) ;; + false) enable_checksum='' ;; + *) bail "'checksum' input option must be 'true' or 'false': '${enable_checksum}'" ;; +esac + +fallback="${INPUT_FALLBACK:-}" +case "${fallback}" in + none | cargo-binstall | cargo-install) ;; + *) bail "'fallback' input option must be 'none', 'cargo-binstall', or 'cargo-install': '${fallback}'" ;; +esac + case "${host_os}" in linux) if ! type -P jq >/dev/null || ! type -P curl >/dev/null || ! type -P tar >/dev/null; then