From 0ac73fae6def1a3508299aebe857be861c293f72 Mon Sep 17 00:00:00 2001 From: Ramon Smits Date: Fri, 16 Oct 2026 12:23:27 +0200 Subject: [PATCH 1/2] Retry access denied errors when the installer deletes a directory --- .../Validation/PackagedRavenDBTests.cs | 13 +++++++++++-- .../FileSystem/FileUtils.cs | 4 +++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/ServiceControlInstaller.Engine.UnitTests/Validation/PackagedRavenDBTests.cs b/src/ServiceControlInstaller.Engine.UnitTests/Validation/PackagedRavenDBTests.cs index 01de0bd0cb..478c4ac63f 100644 --- a/src/ServiceControlInstaller.Engine.UnitTests/Validation/PackagedRavenDBTests.cs +++ b/src/ServiceControlInstaller.Engine.UnitTests/Validation/PackagedRavenDBTests.cs @@ -77,9 +77,18 @@ await store.Maintenance.SendAsync(new PutIndexesOperation(new IndexDefinition finally { await StopServer(); - if (Directory.Exists(root)) + try + { + if (Directory.Exists(root)) + { + FileUtils.DeleteDirectory(root, recursive: true, contentsOnly: false); + } + } + catch (Exception ex) { - FileUtils.DeleteDirectory(root, recursive: true, contentsOnly: false); + // The server files can stay locked for a moment after the process exits. The temp folder is not + // what the test verifies, so a failed cleanup must not fail the test. + Assert.Warn($"Failed to delete {root}: {ex}"); } } diff --git a/src/ServiceControlInstaller.Engine/FileSystem/FileUtils.cs b/src/ServiceControlInstaller.Engine/FileSystem/FileUtils.cs index ecc2c82cf6..dd58e160f2 100644 --- a/src/ServiceControlInstaller.Engine/FileSystem/FileUtils.cs +++ b/src/ServiceControlInstaller.Engine/FileSystem/FileUtils.cs @@ -179,7 +179,9 @@ static void RunWithRetries(Action action) action(); break; } - catch (IOException ex) when (--attempts > 0) + // Windows reports a file that a process still holds, or that an antivirus scanner holds, as + // UnauthorizedAccessException, for example right after the process that loaded it exits + catch (Exception ex) when ((ex is IOException or UnauthorizedAccessException) && --attempts > 0) { Debug.WriteLine($"ServiceControlInstaller.Engine.FileSystem.FileUtils::RunWithRetries Action failed, {attempts} attempts remaining. Reason: {ex.Message} ({ex.GetType().FullName})"); // Yes, Task.Delay would be better but would require all calls to be async From 134015d59784b5c61330cf75ee7f8c7d96110cc6 Mon Sep 17 00:00:00 2001 From: Ramon Smits Date: Fri, 16 Oct 2026 12:23:27 +0200 Subject: [PATCH 2/2] Pin Azure CLI to 2.90.0 until the import deadlock fix ships --- .github/actions/upgrade-azure-cli/action.yml | 27 +++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/.github/actions/upgrade-azure-cli/action.yml b/.github/actions/upgrade-azure-cli/action.yml index 7211bf829c..522d5df271 100644 --- a/.github/actions/upgrade-azure-cli/action.yml +++ b/.github/actions/upgrade-azure-cli/action.yml @@ -3,11 +3,30 @@ description: Upgrades Azure CLI on Linux and Windows runners runs: using: composite steps: - - name: Upgrade Azure CLI on Linux + # Azure CLI 2.91.0 runs on Python 3.14 and deadlocks intermittently on module import during + # long-running operations such as creating a Service Bus namespace (Azure/azure-cli#33996). The fix, + # Azure/azure-cli#34201, is not in 2.91.0. Both steps install 2.90.0 instead of the latest version. + # Once a release that contains the fix is available, restore the upgrade: + # Linux: curl -fsSL 'https://azurecliprod.blob.core.windows.net/$root/deb_install.sh' | sudo bash + # Windows: az upgrade --yes + - name: Install Azure CLI 2.90.0 on Linux if: runner.os == 'Linux' shell: bash - run: curl -fsSL 'https://azurecliprod.blob.core.windows.net/$root/deb_install.sh' | sudo bash - - name: Upgrade Azure CLI on Windows + run: | + deb="azure-cli_2.90.0-1~$(lsb_release -cs)_amd64.deb" + curl -fsSL -o "$RUNNER_TEMP/$deb" "https://packages.microsoft.com/repos/azure-cli/pool/main/a/azure-cli/$deb" + sudo apt-get install -y --allow-downgrades "$RUNNER_TEMP/$deb" + az version + # The MSI refuses to install over the newer version on the runner image, so the ZIP distribution is + # extracted next to it and put first on PATH for the following steps. + - name: Install Azure CLI 2.90.0 on Windows if: runner.os == 'Windows' shell: pwsh - run: az upgrade --yes + run: | + $zip = Join-Path $env:RUNNER_TEMP 'azure-cli-2.90.0-x64.zip' + $dir = Join-Path $env:RUNNER_TEMP 'azure-cli-2.90.0' + Invoke-WebRequest -Uri 'https://azcliprod.blob.core.windows.net/zip/azure-cli-2.90.0-x64.zip' -OutFile $zip + Expand-Archive -Path $zip -DestinationPath $dir -Force + $bin = Join-Path $dir 'bin' + $bin | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + & (Join-Path $bin 'az.cmd') version