Skip to content

[build-tools] Fix CI download failures, upgrade xa-prep-tasks and BootstrapTasks to net10.0#10886

Merged
jonathanpeppers merged 6 commits intomainfrom
dev/peppers/fix-bundletool
Mar 5, 2026
Merged

[build-tools] Fix CI download failures, upgrade xa-prep-tasks and BootstrapTasks to net10.0#10886
jonathanpeppers merged 6 commits intomainfrom
dev/peppers/fix-bundletool

Conversation

@jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Mar 4, 2026

Description

Fix transient SSL/TLS download failures in CI by adding retry logic and adopting the same fail-open CRL revocation policy used by dotnet/arcade. Also upgrades xa-prep-tasks and BootstrapTasks from netstandard2.0 to net10.0 (required for SocketsHttpHandler APIs), and fixes resulting obsolete API warnings.

Context

macOS CI runners intermittently fail SSL handshakes when CRL/OCSP endpoints are unreachable. The DOTNET_SYSTEM_NET_SECURITY_NOREVOCATIONCHECKBYDEFAULT env var is set in CI (variables.yaml), but code explicitly setting CheckCertificateRevocationList = true overrides it.

Changes

1. Retry logic with exponential backoff (ec45d3ca1)

  • DownloadUri task now retries up to 3 times (configurable via MaxRetries)
  • Exponential backoff delays: 5s → 15s → 30s
  • Partial temp files cleaned up between attempts

2. Code review fixes (d334caf26)

  • File.OpenWriteFile.Create to properly truncate on retries
  • Wrap Task.Delay in try/catch for cancellation handling

3. SocketsHttpHandler with fail-open CRL policy (b5aac5f5a)

  • Replaced HttpClientHandler with SocketsHttpHandler + SslClientAuthenticationOptions
  • Uses X509ChainPolicy with IgnoreEndRevocationUnknown | IgnoreCertificateAuthorityRevocationUnknown
  • Still checks revocation, but treats unreachable CRL endpoints as non-fatal
  • Matches dotnet/arcade's DownloadFile approach

4. Upgrade BootstrapTasks to net10.0 (876262d5a)

  • SocketsHttpHandler and X509ChainPolicy require net10.0 (not available in netstandard2.0)
  • Updated xa-prep-tasks.csproj and BootstrapTasks.csproj TFMs
  • Updated PrepTasksAssembly and BootstrapTasksAssembly paths in Directory.Build.props

5. Fix SYSLIB0045: HashAlgorithm.Create(string) obsolete (891a9f3a5)

  • Replaced with switch expression mapping to parameterless factory methods
  • Removed MD5 support (CA5351), suppressed CA5350 for SHA1 (content hashing only)

6. Fix SYSLIB0037 and CS8604 in BootstrapTasks (f28bb68ac)

  • CreateFrameworkList: AssemblyName.ProcessorArchitecture is obsolete — hardcode MSIL
  • GenerateSupportedPlatforms: throw on invalid VersionCodeFull instead of passing null

…ri task

Transient network errors (e.g. SSL handshake failures) during file
downloads would cause immediate build failures. Add retry support
with configurable MaxRetries (default 3) and exponential backoff
delays of 5s, 15s, and 30s. Partial temp files are cleaned up
between attempts. Cancellation is respected during retries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 4, 2026 22:53
@jonathanpeppers jonathanpeppers added the copilot `copilot-cli` or other AIs were used to author this label Mar 4, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds retry support to the Xamarin.Android.BuildTools.PrepTasks.DownloadUri MSBuild task to reduce build failures from transient network download errors during repo/tooling preparation.

Changes:

  • Introduces configurable MaxRetries (default: 3) and a fixed backoff schedule (5s/15s/30s).
  • Wraps download logic in a retry loop and cleans up the temp download file between attempts.
  • Logs attempt counts and retry warnings, and uses cancellation tokens for the backoff delay.

jonathanpeppers and others added 5 commits March 5, 2026 10:07
- Use File.Create instead of File.OpenWrite to truncate temp files,
  preventing corrupted output with trailing bytes on retries.
- Catch OperationCanceledException from Task.Delay during backoff
  so cancellation exits the retry loop cleanly instead of throwing
  an unhandled exception.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On macOS CI, SSL handshake failures occur when CRL/OCSP endpoints
are unreachable and CheckCertificateRevocationList is set to true.
Switch to SocketsHttpHandler with an X509ChainPolicy that still
checks revocation but treats RevocationStatusUnknown as non-fatal,
matching the approach in dotnet/arcade's DownloadFile task:
https://github.com/dotnet/arcade/blob/a07b621/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs#L122-L145

This requires upgrading xa-prep-tasks from netstandard2.0 to
net10.0 (DotNetStableTargetFramework) for SocketsHttpHandler APIs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BootstrapTasks has a ProjectReference to xa-prep-tasks, which now
targets net10.0 instead of netstandard2.0. Update BootstrapTasks
to match, fixing NU1201 compatibility error.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
HashAlgorithm.Create(string) is obsolete in net10.0. Use the
parameterless factory methods (SHA1.Create(), etc.) instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- CreateFrameworkList: AssemblyName.ProcessorArchitecture is obsolete
  in net10.0, hardcode 'MSIL' since all managed assemblies use it.
- GenerateSupportedPlatforms: throw on invalid VersionCodeFull
  instead of passing null to AndroidVersion constructor.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers changed the title [xa-prep-tasks] Add retry logic with exponential backoff to DownloadUri task [build-tools] Fix CI download failures, upgrade xa-prep-tasks and BootstrapTasks to net10.0 Mar 5, 2026
@jonathanpeppers
Copy link
Member Author

This is green enough, I'm merging as it blocks all other PRs.

@jonathanpeppers jonathanpeppers merged commit 3087ddd into main Mar 5, 2026
2 of 6 checks passed
@jonathanpeppers jonathanpeppers deleted the dev/peppers/fix-bundletool branch March 5, 2026 22:45
jonathanpeppers added a commit that referenced this pull request Mar 5, 2026
…tstrapTasks to net10.0 (#10886)

Fix transient SSL/TLS download failures in CI by adding retry logic
and adopting the same fail-open CRL revocation policy used by
[dotnet/arcade](https://github.com/dotnet/arcade/blob/a07b621/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs#L122-L145).
Also upgrades `xa-prep-tasks` and `BootstrapTasks` from
`netstandard2.0` to `net10.0` (required for `SocketsHttpHandler`
APIs), and fixes resulting obsolete API warnings.

### Context

macOS CI runners intermittently fail SSL handshakes when CRL/OCSP
endpoints are unreachable. The
`DOTNET_SYSTEM_NET_SECURITY_NOREVOCATIONCHECKBYDEFAULT` env var is set
in CI
([variables.yaml](https://github.com/dotnet/android/blob/main/build-tools/automation/yaml-templates/variables.yaml#L75)),
but code explicitly setting `CheckCertificateRevocationList = true`
overrides it.

### Changes

#### 1. Retry logic with exponential backoff

- `DownloadUri` task now retries up to 3 times (configurable via
  `MaxRetries`)
- Exponential backoff delays: 5s → 15s → 30s
- Partial temp files cleaned up between attempts

#### 2. Code review fixes

- `File.OpenWrite` → `File.Create` to properly truncate on retries
- Wrap `Task.Delay` in try/catch for cancellation handling

#### 3. SocketsHttpHandler with fail-open CRL policy

- Replaced `HttpClientHandler` with `SocketsHttpHandler` +
  `SslClientAuthenticationOptions`
- Uses `X509ChainPolicy` with `IgnoreEndRevocationUnknown |
  IgnoreCertificateAuthorityRevocationUnknown`
- Still checks revocation, but treats unreachable CRL endpoints as
  non-fatal
- Matches [dotnet/arcade's DownloadFile
  approach](https://github.com/dotnet/arcade/blob/a07b621/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs#L122-L145)

#### 4. Upgrade BootstrapTasks to `net10.0`

- `SocketsHttpHandler` and `X509ChainPolicy` require `net10.0` (not
  available in `netstandard2.0`)
- Updated `xa-prep-tasks.csproj` and `BootstrapTasks.csproj` TFMs
- Updated `PrepTasksAssembly` and `BootstrapTasksAssembly` paths in
  `Directory.Build.props`

#### 5. Fix SYSLIB0045: `HashAlgorithm.Create(string)` obsolete

- Replaced with switch expression mapping to parameterless factory
  methods
- Removed MD5 support (CA5351), suppressed CA5350 for SHA1 (content
  hashing only)

#### 6. Fix SYSLIB0037 and CS8604 in BootstrapTasks

- `CreateFrameworkList`: `AssemblyName.ProcessorArchitecture` is
  obsolete — hardcode `MSIL`
- `GenerateSupportedPlatforms`: throw on invalid `VersionCodeFull`
  instead of passing null
jonathanpeppers added a commit that referenced this pull request Mar 6, 2026
…tstrapTasks to net10.0 (#10886)

Fix transient SSL/TLS download failures in CI by adding retry logic
and adopting the same fail-open CRL revocation policy used by
[dotnet/arcade](https://github.com/dotnet/arcade/blob/a07b621/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs#L122-L145).
Also upgrades `xa-prep-tasks` and `BootstrapTasks` from
`netstandard2.0` to `net10.0` (required for `SocketsHttpHandler`
APIs), and fixes resulting obsolete API warnings.

### Context

macOS CI runners intermittently fail SSL handshakes when CRL/OCSP
endpoints are unreachable. The
`DOTNET_SYSTEM_NET_SECURITY_NOREVOCATIONCHECKBYDEFAULT` env var is set
in CI
([variables.yaml](https://github.com/dotnet/android/blob/main/build-tools/automation/yaml-templates/variables.yaml#L75)),
but code explicitly setting `CheckCertificateRevocationList = true`
overrides it.

### Changes

#### 1. Retry logic with exponential backoff

- `DownloadUri` task now retries up to 3 times (configurable via
  `MaxRetries`)
- Exponential backoff delays: 5s → 15s → 30s
- Partial temp files cleaned up between attempts

#### 2. Code review fixes

- `File.OpenWrite` → `File.Create` to properly truncate on retries
- Wrap `Task.Delay` in try/catch for cancellation handling

#### 3. SocketsHttpHandler with fail-open CRL policy

- Replaced `HttpClientHandler` with `SocketsHttpHandler` +
  `SslClientAuthenticationOptions`
- Uses `X509ChainPolicy` with `IgnoreEndRevocationUnknown |
  IgnoreCertificateAuthorityRevocationUnknown`
- Still checks revocation, but treats unreachable CRL endpoints as
  non-fatal
- Matches [dotnet/arcade's DownloadFile
  approach](https://github.com/dotnet/arcade/blob/a07b621/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs#L122-L145)

#### 4. Upgrade BootstrapTasks to `net10.0`

- `SocketsHttpHandler` and `X509ChainPolicy` require `net10.0` (not
  available in `netstandard2.0`)
- Updated `xa-prep-tasks.csproj` and `BootstrapTasks.csproj` TFMs
- Updated `PrepTasksAssembly` and `BootstrapTasksAssembly` paths in
  `Directory.Build.props`

#### 5. Fix SYSLIB0045: `HashAlgorithm.Create(string)` obsolete

- Replaced with switch expression mapping to parameterless factory
  methods
- Removed MD5 support (CA5351), suppressed CA5350 for SHA1 (content
  hashing only)

#### 6. Fix SYSLIB0037 and CS8604 in BootstrapTasks

- `CreateFrameworkList`: `AssemblyName.ProcessorArchitecture` is
  obsolete — hardcode `MSIL`
- `GenerateSupportedPlatforms`: throw on invalid `VersionCodeFull`
  instead of passing null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot `copilot-cli` or other AIs were used to author this

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants