Skip to content

Replace Step_CopyExtraResultFilesForCI with a YAML template#11568

Merged
jonathanpeppers merged 3 commits into
mainfrom
jonathanpeppers/remove-copy-extra-result-files-step
Jun 3, 2026
Merged

Replace Step_CopyExtraResultFilesForCI with a YAML template#11568
jonathanpeppers merged 3 commits into
mainfrom
jonathanpeppers/remove-copy-extra-result-files-step

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Part of slowly removing xaprepare.

The CopyExtraResultFilesForCI scenario existed only to copy build/test artifacts into $(Build.StagingDirectory) on Azure DevOps before PublishPipelineArtifact — something the built-in CopyFiles@2 task can do natively.

Changes

  • New build-tools/automation/yaml-templates/copy-extra-result-files.yaml reproducing the C# step's file globs and destination layout (Build$(Configuration), Test$(Configuration), test-extras/, compatibility/) using CopyFiles@2. A small pwsh step uses [System.IO.Path]::GetTempPath() to match the original Path.GetTempPath() behavior for llc.exe-* collection.
  • Updated upload-results.yaml (the only caller) to invoke the new template instead of run-xaprepare.yaml --s=CopyExtraResultFilesForCI.
  • Deleted build-tools/xaprepare/xaprepare/Steps/Step_CopyExtraResultFilesForCI.cs and build-tools/xaprepare/xaprepare/Scenarios/Scenario_CopyExtraResultFilesForCI.cs.

Behavior parity

The YAML reproduces the C# step file-for-file:

C# logic YAML
Recursive search of repo for Configuration.OperatingSystem.props, Configuration.Override.props, config.log, config.status, config.h, android-*.config.cache (preserve relative paths) **/<pattern> with flattenFolders: false
Top-level repo CMakeFiles/*.log (preserve paths) CMakeFiles/*.log with flattenFolders: false
external/Java.Interop/bin/Build$(Config)/*.props (preserve paths) Same path with flattenFolders: false
bin/Build$(Config)/<pattern> flat (XABuildConfig.cs, .binlog, preparelog, *.json, *.mk, *.projitems, *.cmake, .targets, CMakeCache.txt, .ninja_log, clang-tidy.log) flattenFolders: true
bin/Test$(Config)/<pattern> flat (.apkdesc, .aabdesc, logcat-.txt, log, TestOutput-.txt, Timing_, *.runsettings) flattenFolders: true
bin/Test$(Config)/compatibility/*Test$(Config)/compatibility/ Separate CopyFiles@2
Repo-root TestResult*.xml, *.csvTest$(Config)/test-extras/ (top-level only) flattenFolders: true
Temp llc.exe-*Test$(Config)/test-extras/ pwsh step using [System.IO.Path]::GetTempPath()

Two no-ops from the C# step are intentionally dropped:

  • Recursive packages/ cleanup of the destination — the narrow filename patterns will never copy anything from a packages directory.
  • Empty-directory pruning — CopyFiles@2 does not create empty directories.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Part of slowly removing xaprepare. The CopyExtraResultFilesForCI scenario
existed only to copy build/test artifacts into $(Build.StagingDirectory)
on Azure DevOps -- something the built-in CopyFiles@2 task can do natively.

Adds build-tools/automation/yaml-templates/copy-extra-result-files.yaml,
which reproduces the file globs and destination layout (Build$(Configuration),
Test$(Configuration), test-extras, compatibility) using CopyFiles@2 plus
a small pwsh step for [System.IO.Path]::GetTempPath()-based llc.exe-*
collection.

The only caller, upload-results.yaml, now invokes the new template
instead of run-xaprepare.yaml --s=CopyExtraResultFilesForCI.

Also deletes Step_CopyExtraResultFilesForCI.cs and
Scenario_CopyExtraResultFilesForCI.cs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 3, 2026 13:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR continues the effort to remove xaprepare usage by replacing the CopyExtraResultFilesForCI scenario/step with a dedicated Azure Pipelines YAML template that stages build/test artifacts directly via CopyFiles@2 (plus a small pwsh helper for temp llc.exe-* files).

Changes:

  • Added a new copy-extra-result-files.yaml template that reproduces the previous globbing + destination layout in $(Build.StagingDirectory).
  • Updated upload-results.yaml to call the new template instead of run-xaprepare.yaml --s=CopyExtraResultFilesForCI.
  • Deleted the obsolete xaprepare step + scenario C# implementations.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
build-tools/automation/yaml-templates/copy-extra-result-files.yaml New YAML template to stage CI artifacts using CopyFiles@2 + pwsh.
build-tools/automation/yaml-templates/upload-results.yaml Switches artifact staging to the new YAML template.
build-tools/xaprepare/xaprepare/Steps/Step_CopyExtraResultFilesForCI.cs Removes the old xaprepare step implementation.
build-tools/xaprepare/xaprepare/Scenarios/Scenario_CopyExtraResultFilesForCI.cs Removes the old xaprepare scenario wiring.

Comment thread build-tools/automation/yaml-templates/copy-extra-result-files.yaml Outdated
Comment thread build-tools/automation/yaml-templates/copy-extra-result-files.yaml Outdated
Comment thread build-tools/automation/yaml-templates/copy-extra-result-files.yaml Outdated
Comment thread build-tools/automation/yaml-templates/copy-extra-result-files.yaml
jonathanpeppers and others added 2 commits June 3, 2026 09:31
- Use repo root as sourceFolder for the bin/Build, bin/Test, and compatibility CopyFiles@2 steps so a missing folder produces 0 matches instead of erroring (matches the original C# Directory.Exists guards). Patterns now include the bin/Build$(Configuration)/ or bin/Test$(Configuration)/ prefix; flattenFolders: true keeps the destination layout flat as before.

- Rename $matches to $llcFiles in the llc.exe-* pwsh step to avoid shadowing PowerShell's $Matches automatic regex variable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Step_CopyExtraResultFilesForCI was the sole caller; deleting it left this method orphaned. Also drop the stale CopyFilesSimple reference from the new YAML template's comment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@jonathanpeppers

Copy link
Copy Markdown
Member Author

/review

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

Android PR Reviewer completed successfully!

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ LGTM

Clean replacement of the Step_CopyExtraResultFilesForCI xaprepare step with a native YAML template. Verified behavior parity across all file groups:

  • ✅ Recursive config file collection (**/config.log, etc.) with path preservation matches SearchOption.AllDirectories + relative path copy
  • ✅ Flat bin/Build$(Configuration) and bin/Test$(Configuration) copies match the C# CopyFilesSimple behavior
  • compatibility/ subfolder, TestResult*.xml/*.csv, and llc.exe-* temp file collection all match
  • continueOnError: true on every step handles missing directories gracefully (equivalent to Directory.Exists guards)
  • CopyFilesSimple has no remaining callers — safe to remove
  • ✅ Intentionally dropped no-ops (packages cleanup, empty dir pruning) are well-documented in the PR description

CI: dotnet-android ✅, license/cla ✅. Xamarin.Android-PR not yet triggered (normal).

One minor 💡 suggestion about glob scope posted inline — not blocking.

Generated by Android PR Reviewer for issue #11568 · ● 12M

**/config.h
**/android-*.config.cache
CMakeFiles/*.log
external/Java.Interop/bin/Build${{ parameters.configuration }}/*.props

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 💡 Performance — The **/config.h and **/config.log patterns are very broad recursive globs that will walk the entire source tree (including external/, packages/, etc.). This matches the original C# behavior (SearchOption.AllDirectories), so it's correct for parity — but a future follow-up could scope these to known subtrees (e.g. src/**/config.h) to speed up artifact collection on large workspaces.

Rule: Behavioral parity acknowledged

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not fixing, to keep behavior the same as before.

@jonathanpeppers jonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 3, 2026
@jonathanpeppers jonathanpeppers merged commit 34d5e36 into main Jun 3, 2026
2 of 3 checks passed
@jonathanpeppers jonathanpeppers deleted the jonathanpeppers/remove-copy-extra-result-files-step branch June 3, 2026 21:24
simonrozsival pushed a commit that referenced this pull request Jun 8, 2026
## Why

`bin/configuration.mk` exists only to persist `CONFIGURATION=<value>` between Unix `make` invocations. Removing it lets us delete the only meaningful contents of `Step_GenerateFiles.Unix.cs`, continuing the slow removal of `xaprepare` (see precedent: #11568, #11529).

## What

- Drop `-include bin/configuration.mk` from the top of `Makefile`. The `CONFIGURATION ?= Debug` fallback at the top of the file is unchanged.
- Delete `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.Unix.cs` entirely (it contained `GeneratedConfigurationFile` and a one-line `AddUnixPostBuildSteps` partial that registered it).

The `partial void AddUnixPostBuildSteps (Context context, List<GeneratedFile> steps);` declaration in `Step_GenerateFiles.cs` is intentionally left in place — partial methods without an implementation are legal in C#, and the call site becomes a zero-cost no-op. `Step_GenerateFiles.Windows.cs` implements a *different* partial (`AddOSSpecificSteps`) and is unaffected.

## Why this is safe

| Caller | Pre-change behavior | Post-change behavior |
| --- | --- | --- |
| All CI YAML (`build-linux-steps.yaml`, `build-macos-steps.yaml`, `commercial-build.yaml`, `azure-pipelines-apidocs.yaml`) | Passes `CONFIGURATION=$(XA.Build.Configuration)` on every `make` call | Same — explicit value still wins |
| `build.sh` (`make prepare && make jenkins && make pack-dotnet`) | First `make prepare` runs against an empty `bin/`, so the `-include` no-ops and `?= Debug` takes effect | Identical — `?= Debug` still takes effect |
| Fresh local checkout, bare `make all` | `?= Debug` (no `bin/configuration.mk` yet) | Same |
| Local dev who runs `make prepare CONFIGURATION=Release` then bare `make all` | Persisted Release via `bin/configuration.mk` | Now defaults back to Debug — must pass `CONFIGURATION=Release` on every invocation |

That last case is the only behavior change. It was never documented as a contract anywhere in `Documentation/` or `README.md`, and developers building Release locally should be passing the flag explicitly anyway.

## Verification

- `git grep "configuration\.mk"` and `git grep "GeneratedConfigurationFile"`: zero matches after this change.
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj`: 0 warnings, 0 errors.
- Rubber-duck review: no remaining `Path.Combine(..., "configuration.mk")` references, no Makefile target depends on `bin/configuration.mk` as a prerequisite, and the leftover partial-method declaration is benign.
jonathanpeppers added a commit that referenced this pull request Jun 9, 2026
…11608)

`Mono.Android.Apis.projitems` was previously generated at prepare time by
`GeneratedMonoAndroidProjitemsFile` (in xaprepare) from the
`BuildAndroidPlatforms.AllPlatforms` list. Both had exactly one consumer
(each other), so check in the projitems as a source file and drop the
generator plumbing.

Changes:

  * Add `src/Mono.Android/Mono.Android.Apis.projitems` — content matches
    the generator's output byte-for-byte; only the header comment now
    points at `Documentation/workflow/HowToAddNewApiLevel.md` instead of
    declaring "GENERATED FILE".
  * Repoint the 4 importers (`Mono.Android.targets` x2,
    `create-installers.targets`, `create-android-api.csproj`,
    `Xamarin.Android.Build.Tasks.targets`) at the new path and drop the
    `Condition="Exists(...)"` guards — the file is always present now.
  * Delete `GeneratedMonoAndroidProjitemsFile.cs` and `AndroidPlatform.cs`
    (whole files — `AndroidPlatform` class and `AndroidPlatformExtensions`
    both become unused).
  * Drop the `new GeneratedMonoAndroidProjitemsFile()` registration in
    `Step_GenerateFiles.cs`.
  * Remove `BuildAndroidPlatforms.AllPlatforms` and the now-unused
    `using System.Collections.Generic;`. Keep the NDK constants
    (`AndroidNdkVersion`, `AndroidNdkPkgRevision`, `NdkMinimumAPI`,
    `NdkMinimumAPILegacy32`) — they still have consumers.
  * Update `Documentation/workflow/HowToAddNewApiLevel.md` with the
    XML-based instructions for adding a new API level.
  * Narrow the `build-tools/xaprepare/README.md` blurb for
    `BuildAndroidPlatforms.cs` to NDK metadata.
  * Fix stale doc comment in `GenerateSupportedPlatforms.cs` pointing
    at the old generated path.

Continues the xaprepare cleanup started in PRs #11568 and #11580.

### [docs] Fix Stable=True/False contradiction in HowToAddNewApiLevel

The added prose said Stable should be False for preview API levels, but the
example (CANARY) sets <Stable>True</Stable>, and every entry in
Mono.Android.Apis.projitems is True. Rewrite the prose to match the data and
briefly explain what setting Stable=False would actually do (excludes entry
from default stable framework selection).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jun 9, 2026
* Localized file check-in by OneLocBuild Task (#11610)

Build definition ID 17928: Build ID 14320800

* [xaprepare] Check in `Mono.Android.Apis.projitems`, remove generator (#11608)

`Mono.Android.Apis.projitems` was previously generated at prepare time by
`GeneratedMonoAndroidProjitemsFile` (in xaprepare) from the
`BuildAndroidPlatforms.AllPlatforms` list. Both had exactly one consumer
(each other), so check in the projitems as a source file and drop the
generator plumbing.

Changes:

  * Add `src/Mono.Android/Mono.Android.Apis.projitems` — content matches
    the generator's output byte-for-byte; only the header comment now
    points at `Documentation/workflow/HowToAddNewApiLevel.md` instead of
    declaring "GENERATED FILE".
  * Repoint the 4 importers (`Mono.Android.targets` x2,
    `create-installers.targets`, `create-android-api.csproj`,
    `Xamarin.Android.Build.Tasks.targets`) at the new path and drop the
    `Condition="Exists(...)"` guards — the file is always present now.
  * Delete `GeneratedMonoAndroidProjitemsFile.cs` and `AndroidPlatform.cs`
    (whole files — `AndroidPlatform` class and `AndroidPlatformExtensions`
    both become unused).
  * Drop the `new GeneratedMonoAndroidProjitemsFile()` registration in
    `Step_GenerateFiles.cs`.
  * Remove `BuildAndroidPlatforms.AllPlatforms` and the now-unused
    `using System.Collections.Generic;`. Keep the NDK constants
    (`AndroidNdkVersion`, `AndroidNdkPkgRevision`, `NdkMinimumAPI`,
    `NdkMinimumAPILegacy32`) — they still have consumers.
  * Update `Documentation/workflow/HowToAddNewApiLevel.md` with the
    XML-based instructions for adding a new API level.
  * Narrow the `build-tools/xaprepare/README.md` blurb for
    `BuildAndroidPlatforms.cs` to NDK metadata.
  * Fix stale doc comment in `GenerateSupportedPlatforms.cs` pointing
    at the old generated path.

Continues the xaprepare cleanup started in PRs #11568 and #11580.

### [docs] Fix Stable=True/False contradiction in HowToAddNewApiLevel

The added prose said Stable should be False for preview API levels, but the
example (CANARY) sets <Stable>True</Stable>, and every entry in
Mono.Android.Apis.projitems is True. Rewrite the prose to match the data and
briefly explain what setting Stable=False would actually do (excludes entry
from default stable framework selection).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [Xamarin.AndroidTools] Remove dead VS Mac / legacy code (#11607)

Context: after the `android-platform-support` repo was inlined here
(see c22cdcf), `src/Xamarin.AndroidTools/` carries a large amount of
code that was only used by old VS Mac / installer / debugger-host
workflows that are no longer part of the .NET for Android product. None
of these types have callers anywhere in this repo, in
`external/xamarin-android-tools/`, or in `external/Java.Interop/`.

Removed (13 files):

  * `PublicationUtilities/PublishAndroidApplication.cs`
  * `PublicationUtilities/PackageSigningTasks.cs`
  * `PublicationUtilities/KeyManagement.cs`
  * `PublicationUtilities/KeystoreEntry.cs`
  * `Sessions/AndroidDeploySession.cs`
  * `Sessions/AndroidConnectCommandSession.cs`
  * `Sessions/AndroidCommandSession.cs`
  * `Sessions/AndroidDeploymentException.cs`
  * `Devices/AndroidPackageList.cs`
  * `Devices/AndroidPackageListExtensions.cs`
  * `Debugging/MonoDroidProcessMonitor.cs`
  * `PlatformPackage.cs`
  * `IProgressNotifier.cs`
  * `AndroidSigningOptions.cs`

Moved (still needed by `ProcessUtils.cs`):

  * `PublicationUtilities/AndroidSdkToolException.cs` ->
    `AndroidSdkToolException.cs` (namespace unchanged)

Pruned from `Devices/AndroidDeviceExtensions.cs` (the methods only
referenced the just-deleted types and had no in-tree callers):

  * `StartActivityWithCommandSession` (used `AndroidCommandSession`)
  * `GetDeploySession`, `GetPackagesAsync`, `GetPackages` (used
    `AndroidDeploySession` / `IProgressNotifier`)
  * `InstallSharedRuntime*` and `InstallSharedPlatform*` overloads
    that took `IProgressNotifier`
  * `GetPackageRemotePath`/`GetPackageRemotePathAsync` (used
    `AndroidDeploymentException`)
  * `GetFastDevRemotePath`/`GetFastDevRemotePathAsync` and the inner
    `FastDevRemotePathInfo` class (only consumer was
    `GetPackageRemotePathAsync`)

Kept methods in `AndroidDeviceExtensions.cs` are the ones still used
by `Xamarin.Android.Build.Debugging.Tasks` (`EnsureProperties`,
`KillProcessAndWaitForExit`, `PushAndInstallPackageAsync`) and by
`DebuggingExtensions` (`SetFastDevPropertyFile`, `GetProcessIDAsync`,
`SetDebugPropertiesAsync`).

Also cleaned up:

  * `Properties/Resources.resx` (English source): removed seven
    `CreateKeyError_*` strings that only `KeyManagement.cs` used.
  * `Properties/Resources.Designer.cs`: removed the seven matching
    properties.
  * `MonoDroidSdk.cs`: two `[Obsolete]` messages referenced the
    now-deleted `PlatformPackage`; changed to `"Do not use."`.

Non-English `Resources.*.resx` and `Localize/loc/**/*.lcl` are left
alone per repo policy (auto-regenerated by OneLocBuild).

Build verified locally:

  * `src/Xamarin.AndroidTools/Xamarin.AndroidTools.csproj`
  * `src/Mono.AndroidTools/Mono.AndroidTools.csproj`
  * `src/Xamarin.Android.Build.Debugging.Tasks/Xamarin.Android.Build.Debugging.Tasks.csproj`
  * `src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK.csproj`

Net change: -4225 / +2 lines across 19 files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [NUnitLite] Add OneTimeSetUp/OneTimeTearDown attribute shims

NUnit 3.x renamed [TestFixtureSetUp]/[TestFixtureTearDown] to [OneTimeSetUp]/[OneTimeTearDown]. dotnet/java-interop#1437 migrated the Java.Interop test suite to the new names.

The bundled Xamarin.Android.NUnitLite (src-ThirdParty/NUnitLite/) only defines the legacy names. Add no-op subclasses for the new names so test source using [OneTimeSetUp]/[OneTimeTearDown] still compiles against bundled NUnitLite once the Java.Interop submodule is bumped past dotnet/java-interop#1437.

These shims become unnecessary once dotnet/android moves off bundled NUnitLite to stock NUnit (tracked in PR #11224).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: VS MobileTools Engineering Service 2 <vsmobiletoolsengsvc2@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 11, 2026
…#11613)

Continues the slow `xaprepare` removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped `Step_PrepareExternalGitDependencies`).

## What

`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props` (inside the submodule) by substituting two placeholders into `build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The substituted properties (`_XamarinAndroidCecilVersion`, `UtilityOutputFullPathCoreApps`, `XamarinAndroidToolsDirectory`) are now supplied directly via the checked-in static file `external/Java.Interop.override.props`, which Java.Interop's own `Directory.Build.props` already auto-imports via the parent-dir convention added in dotnet/java-interop#872.

The shared version values (`MonoCecilVersion`, `AndroidPackVersion`, `AndroidPackVersionSuffix`) move into `eng/Versions.props`. `Directory.Build.props` and `external/Java.Interop.override.props` both `<Import>` it. No duplicate-import sentinel is needed because every code path that imports `Configuration.props` has already loaded `Directory.Build.props` (either via MSBuild auto-load or via the explicit `<Import>` in `external/xamarin-android-tools.override.props`).

`MicrosoftAndroidSdkPackName` stays in `Configuration.props` (it is OS-conditioned, not version-shaped, so it doesn't belong in `Versions.props`). The same 3-line OS-conditioned block is mirrored privately in `external/Java.Interop.override.props` as `_MicrosoftAndroidSdkPackName`, used only to compute `UtilityOutputFullPathCoreApps` for the Java.Interop build.

Also dropped:
- `Configurables.Paths.InstallMSBuildDir` and its backing field — the only consumer was `Step_PrepareProps`.
- The dead `UtilityOutputFullPath` line in the old template — Java.Interop's `TargetFrameworkDependentValues.props` unconditionally routes it to `$(UtilityOutputFullPathCoreApps)` anyway, so it was a no-op.

Updated `build-tools/scripts/XAVersionInfo.targets` (the `GitBlame` for `<AndroidPackVersion>` now points at `eng/Versions.props`) and `Documentation/guides/HowToBranch.md` to reflect the moves.

## Why not just `<Import>` `Directory.Build.props` from the Java.Interop override?

That was the original idea. I prototyped it: importing dotnet/android's full props chain from `external/Java.Interop.override.props` flips `DotNetTargetFrameworkVersion` from `10.0` to `11.0` inside Java.Interop, and `dotnet restore Java.Interop.csproj` then fails with:

```
NETSDK1045: The current .NET SDK does not support targeting .NET 11.0
```

`xamarin-android-tools.override.props` gets away with the same trick only because its sole csproj sets `AndroidToolsDisableMultiTargeting=true`, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.

`eng/Versions.props` is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no `<Import>` of its own, and is the safe minimal shared file.

## Verification

On Windows:
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj` — 0 warnings, 0 errors.
- From `src/Xamarin.Android.Build.Tasks/`: `dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir` — values unchanged from baseline.
- From `external/Java.Interop/src/Java.Interop/`:
  - `dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps` returns `net10.0`, `0.11.5`, the expected packs/tools path.
  - `dotnet restore Java.Interop.csproj` succeeds (no `NETSDK1045`).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jun 12, 2026
### Context

`Get_Omnisharp_Json` in `Step_GenerateFiles` substituted two placeholders into `build-tools/scripts/omnisharp.json.in` and wrote `omnisharp.json` at the repo root for OmniSharp / VS Code C# extension users. The generated file was always `.gitignore`d and **nothing in the repo, build, or CI consumes it** — it was purely a local-dev convenience.

Anyone who actually wants an `omnisharp.json` can keep their own local copy (it remains gitignored). Removing this generation slice is another small step in the slow xaprepare reduction, continuing the pattern from #11568, #11580, #11608, and #11613.

### Audit

Before this change `git grep -in "omnisharp"` returned five hits. After it returns only one — the unrelated MSBuild-context guard in `xaprepare.csproj` that prevents xaprepare's targets from importing under OmniSharp's MSBuild process:

```
build-tools/xaprepare/xaprepare/xaprepare.csproj:52:
  <Import Project="xaprepare.targets" Condition=" $(MSBuildToolsPath.IndexOf('omnisharp')) < 0 " />
```

That guard is intentional and is **not** touched by this PR.

### Changes

- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`: drop the `Get_Omnisharp_Json (context)` entry from the generated-files list and delete the `Get_Omnisharp_Json` method.
- Delete `build-tools/scripts/omnisharp.json.in`.

The shared properties used by the deleted method (`MicrosoftDotnetSdkInternalPackageVersion`, `DotNetPreviewPath`) are still referenced by `Step_InstallDotNetPreview` and `xaprepare.targets`, so they remain.

### Verification

- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug` — 0 warnings, 0 errors.
- `git grep -in "omnisharp"` — returns only the unrelated `xaprepare.csproj` guard described above.
- No `Documentation/` references to omnisharp; no `.vscode/` folder in the repo.
- Diff: 3 files, 35 deletions, 0 additions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jun 25, 2026
Mirrors #11608 (which checked in `Mono.Android.Apis.projitems` the same way). See also #11568, #11580, #11613, #11631, #11657, #11658.

## What

`build-tools/scripts/Ndk.projitems.in` was a template with `@NDK_*@` placeholders that the `Get_Ndk_projitems` generator in xaprepare filled in from constants in `BuildAndroidPlatforms.cs`. Those substitution values only change on rare NDK bumps, so generating the file on every build adds no value.

This PR checks in the resolved file as a static `build-tools/scripts/Ndk.projitems` and removes the generator.

## Changes

- **Add** `build-tools/scripts/Ndk.projitems` — the static, checked-in file. Rather than hardcoding values, it sources them from the existing properties in `Configuration.props` (which is imported before `Ndk.targets`):
  - `AndroidNdkVersion` → `$(_XAAndroidNdkRelease)`
  - `AndroidNdkPkgRevision` → `$(_XAAndroidNdkPkgRevision)`
  - the per-ABI `AndroidNdkApiLevel_*` → `$(AndroidMinimumDotNetApiLevel)`

  So there is nothing to keep in sync on an NDK/API bump.
- **`build-tools/scripts/Ndk.targets`** — point `ProjitemsFile` at the new in-tree location (`$(MSBuildThisFileDirectory)Ndk.projitems`) instead of `bin/Build$(Configuration)/Ndk.projitems`.
- **Delete** `build-tools/scripts/Ndk.projitems.in`.
- **`Step_GenerateFiles.cs`** — remove the `Get_Ndk_projitems` method and its dispatch entry.
- **`Configurables.cs`** — update a doc comment reference from `Ndk.projitems.in` → `Ndk.projitems`.

### Simplifications (from review)

- **Collapsed the dead legacy/NET API-level split.** The legacy 32-bit minimum API level used to be lower than the .NET minimum, but they are identical now. Removed the two per-ABI properties that nothing references (`AndroidNdkApiLevel_Arm`, `AndroidNdkApiLevel_X86_Legacy`). The `arm64-v8a`/`x86_64` properties are kept because shipped targets (`Build.Tasks.targets`, `Common.props.in`, `NativeAOT.targets`) still consume them by name.
- **Removed the `ApiLevelNET` item metadata.** `ApiLevelNET` was the .NET (.NET 6+) Android minimum API level vs. the legacy Xamarin.Android/Mono `ApiLevel`; the two are identical now and this repo is .NET-only. Its only consumer was `src/native/common/libunwind/libunwind-xamarin.targets`, which now reads `ApiLevel`. Dropped `ApiLevelNET` from all four `AndroidSupportedTargetJitAbi` items.

The NDK constants in `BuildAndroidPlatforms.cs` are intentionally left untouched — they're still consumed by `Get_XABuildConfig_cs` and the cmake presets generator.

## Verification

- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug` → 0 errors / 0 warnings.
- Evaluated the import chain via a standalone MSBuild harness (importing the real `Configuration.props`); it produces all four `AndroidSupportedTargetJitAbi` items with `ApiLevel`=24 and the expected `AndroidRID` metadata, matching prior generator output (NDK `28c` / pkg `28.2.13676358`).
- Audits clean: `git grep Ndk.projitems.in`, `git grep Ndk_projitems`, `git grep ApiLevelNET`, and the old `bin/Build$(Configuration)/Ndk.projitems` path all return 0 hits.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 26, 2026
Many xaprepare provisioning steps have been removed over the past year (#11332, #11348, #11399, #11440, #11441, #11636 and follow-up cleanups in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737). The supporting scaffolding around those steps was left behind. This PR removes the verified-dead pieces in two passes.

## Files removed (first pass — original audit)

| File | Justification |
| --- | --- |
| `Application/TestAssembly.cs` | Orphan test infra; only referenced by `TestAssemblyType.cs`. |
| `Application/TestAssemblyType.cs` | Only referenced by `TestAssembly.cs`. |
| `Application/StepWithDownloadProgress.cs` | No subclasses remain. |
| `Application/NDKTool.cs` | NDK provisioning moved to MSBuild in #11440. Last consumer was the also-dead `Configurables.NDKTools` collection (removed below). |
| `ToolRunners/SnRunner.cs` | Strong-naming tool runner; never instantiated. |
| `ToolRunners/SnRunner.OutputSink.cs` | Partial sibling of `SnRunner`. |
| `ToolRunners/CMakeRunner.cs` | Never instantiated. |
| `ToolRunners/CMakeRunner.OutputSink.cs` | Partial sibling of `CMakeRunner`. |

## Files removed (second pass — repo-wide re-audit)

| File | Justification |
| --- | --- |
| `ToolRunners/MakeRunner.Linux.cs` | Partial of `MakeRunner`; type never instantiated. |
| `ToolRunners/MakeRunner.MacOS.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MakeRunner.OutputSink.Unix.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MakeRunner.Unix.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MSBuildRunner.cs` | Never instantiated. |
| `ToolRunners/MSBuildRunner.OutputSink.cs` | Partial sibling of `MSBuildRunner`. |
| `ToolRunners/NinjaRunner.cs` | Never instantiated. |
| `ToolRunners/NinjaRunner.OutputSink.cs` | Partial sibling of `NinjaRunner`. |
| `Application/ScenarioNoStandardEndSteps.cs` | Abstract class with zero subclasses. |

## Cascading cleanup

- `ConfigAndData/Configurables.cs` — removed the dead `NDKTools` `List<NDKTool>` collection (lines 132–145). Rest of the file unchanged.

## Removed from initial deletion list after verification

- `Application/Extensions.DictionaryOfProgramVersionParser.cs` — initial name-only audit flagged it as dead, but its `Add` extension method is consumed via dictionary collection-initializer syntax in `Application/VersionFetchers.cs`. The consumer never references the static class by name, which is why the first audit missed it. The file stays.
- `Scenarios/Scenario_Required.cs` — looks unreferenced by static grep, but `Scenario` subclasses are reflectively discovered via the `[Scenario]` attribute in `Context.cs` (`Utilities.GetTypesWithCustomAttribute<ScenarioAttribute> ()`). Live. The file stays.

## Verification

- `git grep -n -w <TypeName>` for each deleted type now returns 0 real hits (only unrelated `"TestAssembly"` string literals in `tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/` remain — those are assembly-name strings, not the C# type).
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug` → 0 warnings, 0 errors.

## Deferred follow-up

The csproj conditionally excludes `*MacOS*` files from compilation when `HostOS != Darwin`, so static dead-code analysis from a Windows/Linux host can't see whether the macOS-only consumers are themselves live. These candidates need verification on a Mac host (or a build matrix) before deletion:

- `Application/PkgProgram.MacOS.cs`
- `Application/HomebrewProgram.MacOS.cs`
- `ToolRunners/BrewRunner.MacOS.cs`
- `ToolRunners/PkgutilRunner.MacOS.cs`
- `ConfigAndData/Dependencies/MacOS.cs`
jonathanpeppers added a commit that referenced this pull request Jun 27, 2026
…ct (#11760)

Continues the incremental dismantling of `xaprepare` (see #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740). Two more generator methods come out, and the work they did moves into a small dedicated MSBuild project.

## What changes

Two xaprepare generators in `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs` are deleted:

* `Get_Cmake_XA_Build_Configuration` — produced `bin/Build$(Configuration)/xa_build_configuration.cmake`, included by `src/native/CMakeLists.txt`.
* `Get_Cmake_Presets` (and its `GetCmakePresetsCommon` helper) — produced `src/native/CMakePresets.json`, consumed by the `cmake` preset invocations in `src/native/native.targets`.

Both are now generated by a new project:

* **`src/native/cmake-config/cmake-config.csproj`** (`Microsoft.Build.NoTargets`) hosts `_GenerateCMakeFiles`, which uses the existing `ReplaceFileContents` MSBuild task to substitute the placeholders in `build-tools/scripts/xa_build_configuration.cmake.in` and `src/native/CMakePresets.json.in`.
* `native-mono.csproj`, `native-clr.csproj`, and `native-nativeaot.csproj` each `<ProjectReference>` this project.

### Why a dedicated project (not just a target in `native.targets`)

The three native csproj share two output files (`bin/Build$(Configuration)/xa_build_configuration.cmake` and `src/native/CMakePresets.json`). Hosting the generator in `native.targets` would either:

* Race on the shared outputs under parallel msbuild (`/m`), or
* Require a `'$(MSBuildProjectName)' == 'native-mono'` gate -- which breaks isolated `dotnet build native-clr.csproj` on a clean tree (the gitignored output files would never get generated).

A dedicated project with three incoming `<ProjectReference>`s solves both: single producer, and project-reference ordering guarantees the outputs exist before any consumer's `cmake` preset call -- including for isolated single-csproj builds.

### Incremental correctness

`_GenerateCMakeFiles` declares fully-anchored `Inputs`:

* `build-tools/scripts/xa_build_configuration.cmake.in`
* `src/native/CMakePresets.json.in`
* `Configuration.props` (`AndroidNdkDirectory`, `NinjaPath`, `MicrosoftAndroidSdkOutDir`, `XAPackagesDir`, `AndroidMinimumDotNetApiLevel`)
* `Directory.Build.props` (`TestOutputDirectory`)
* `eng/Versions.props` (`MicrosoftNETCoreAppRefPackageVersion`)

so editing any of those re-runs the target; a no-change rebuild skips it. (Note: `$(MSBuildAllProjects)` is intentionally **not** used -- it does not include imported `.props` files for SDK-style projects since MSBuild 16.0; verified empirically.)

### Cascading deletions in xaprepare

* `Configurables.NativeSourcesDir` (was used only by `Get_Cmake_Presets`).
* All eight `Configurables.Paths.NetcoreAppRuntimeAndroid*` / `CoreClrAppRuntimeAndroid*` properties (+ backing fields + the `GetNetcoreAppRuntimePath` / `GetCoreClrAppRuntimePath` helpers) -- the new MSBuild target reads `$(XAPackagesDir)` / `$(MicrosoftNETCoreAppRefPackageVersion)` directly.
* The `Get_Cmake_*` entries in `Step_GenerateFiles.GetFilesToGenerate`.

`BuildAndroidPlatforms.NdkMinimumAPI` / `NdkMinimumAPILegacy32` are kept -- still used by `Get_XABuildConfig_cs` (a separate generator for a future PR).

### What stays

The `.in` template files are unchanged and still tracked in git -- the new MSBuild target reads them. The other generators in `Step_GenerateFiles.cs` (`Get_SourceLink_Json`, `Get_Configuration_OperatingSystem_props`, `Get_XABuildConfig_cs`, `AddOSSpecificSteps`) are out of scope and untouched.

## Verification

On Windows:

* `build.cmd Prepare -c Debug`
* `dotnet-local.cmd build src\native\native-mono.csproj -c Debug` -> 0 errors, generates both files
* `dotnet-local.cmd build src\native\native-clr.csproj -c Debug` -> 0 errors (incl. clean-tree isolated build)
* `dotnet-local.cmd build src\native\native-nativeaot.csproj -c Debug` -> 0 errors
* `dotnet-local.cmd build build-tools\xaprepare\xaprepare\xaprepare.csproj -c Debug` -> 0 errors

Incremental behaviour verified by walking through MSBuild diagnostic output:

* No-change rebuild: `Skipping target "_GenerateCMakeFiles" because all output files are up-to-date`.
* `touch eng/Versions.props` + rebuild: `Building target "_GenerateCMakeFiles" completely`, outputs re-written.

The generated `CMakePresets.json` and `xa_build_configuration.cmake` were diffed against the xaprepare baselines captured before the deletion; only the path separator normalisation (forward slashes throughout) differs, which both CMake and JSON accept on every platform.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 30, 2026
### Context

After #11636 (dotnet provisioning step removed) and #11731 (test-deps scenarios removed), `Context.AutoProvision` is `false` by default everywhere except hand-run dev provisioning, which is no longer in use. The per-OS package lists are populated at `OS.Init()` time but `EnsureDependencies` is effectively a no-op:

- `OS.EnsureDependencies()` returns early when `AutoProvision` is false (the default),
- nothing else in the codebase reads from the `Program` derivatives' install/uninstall paths,
- the `BuildToolsInventory` writer remains driven only from `EssentialTools.MacOS.cs` (homebrew version detection).

The `OS.Init() / InitializeDependencies() / EnsureDependencies()` machinery on `OS.cs` itself is intentionally **left in place** here — that's a larger refactor for a follow-up PR. This PR only strips the now-vestigial package-list data and the program/runner classes that fed it.

### Files deleted (Phase F — macOS, 4 files)

- `Application/HomebrewProgram.MacOS.cs`
- `Application/PkgProgram.MacOS.cs`
- `ToolRunners/BrewRunner.MacOS.cs`
- `ToolRunners/PkgutilRunner.MacOS.cs`

### Files deleted (Phase G — Linux, 5 files)

- `Application/Program.Linux.cs` (`LinuxProgram` base — orphan after subclasses go)
- `Application/Program.ArchLinux.cs`
- `Application/Program.DebianLinux.cs`
- `Application/Program.FedoraLinux.cs`
- `Application/Program.GentooLinux.cs`

### Files deleted (Phase 3 — orphan)

- `Application/IBuildInventoryItem.cs` (only implementor was `HomebrewProgram`; `BuildToolsInventory` itself stays, populated directly by `EssentialTools.MacOS.cs`).

### Files reduced to empty stubs

`ConfigAndData/Dependencies/`:
- `MacOS.cs` — `InitializeDependencies()` no-op (was Homebrew formula list + git fallback).
- `Linux.Arch.cs` — class kept (referenced by `distroMap`); package list removed.
- `Linux.Fedora.cs` — same.
- `Linux.Gentoo.cs` — same.
- `Linux.DebianCommon.cs` — common Debian/Ubuntu package list removed; `Flavor = "Debian"` kept.
- `Linux.UbuntuCommon.cs` — `libtoolPackages` + `NeedLibtool` virtual + `InitOS` override removed (all dead).
- `Linux.Debian.cs` — all per-version package lists (`packages`, `packagesPre10`, `packagesPreTrixie`, `packagesTrixieAndLater`, `packages10AndNewerBuildBots`) removed; release/codename detection (`EnsureVersionInformation`, `DebianUnstableVersionMap`, `IsDebian10OrNewer`, etc.) preserved as conservative scope.
- `Linux.Ubuntu.cs` — `preCosmicPackages`, `cosmicPackages`, `preDiscoPackages` lists + `NeedLibtool` override removed; `UbuntuRelease` + `EnsureVersionInformation` preserved.
- `Linux.Mint.cs` — `NeedLibtool` override removed (the property is gone from the base).

`ConfigAndData/Dependencies/Windows.cs` was already a no-op stub — no edit.

### Verification

Orphan audit (each `git grep -nw <Type> -- 'build-tools/xaprepare/*'` reports **0 hits**):

- `HomebrewProgram`, `PkgProgram`, `BrewRunner`, `PkgutilRunner`
- `ArchLinuxProgram`, `DebianLinuxProgram`, `FedoraLinuxProgram`, `GentooLinuxProgram`, `LinuxProgram`
- `IBuildInventoryItem`

Build:

```
dotnet build build-tools\xaprepare\xaprepare\xaprepare.csproj -c Debug
Build succeeded.  0 Warning(s)  0 Error(s)
```

### Out of scope (follow-up)

- Removing the abstract `OS.InitializeDependencies()` declaration and the surrounding `EnsureDependencies()` machinery from `OperatingSystems/OS.cs`.
- `VersionFetchers` / `ProgramVersionParser` / `RegexProgramVersionParser` / `SevenZipVersionParser` / `Extensions.DictionaryOfProgramVersionParser.cs` are kept — `Utilities.GetProgramVersion` still queries them from `Program.cs`, `ToolRunner.cs`, `EssentialTools.MacOS.cs`, and `OperatingSystems/MacOS.cs` (brew detection).

### Precedent

#11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)

## Summary

Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.

This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.

It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.

Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).

## How it works

`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:

- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.

The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).

`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.

## xaprepare cleanup

Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:

- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)

## Files

**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`

**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)

**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`

**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`

## Verification

- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)

Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.

The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.

We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.

Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
  `build-linux-steps.yaml`, `commercial-build.yaml` (call the new
  template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
  `SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`

Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:

    Baseline=3144 New=3144
    Total byte differences: 0

Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.

### Simplify generate-cgmanifest.yaml using ConvertTo-Json

Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.

But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:

  1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
  2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
  3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
  4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
     → external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
     `JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
     content.

Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.

This is the smallest-diff removal:

  * Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
  * Delete Resources/JdkInfo.Windows.props.in.
  * In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
    declaration and collapse GetFilesToGenerate so `atBuildStart == false`
    returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
    Scenario_Required.cs is unaffected.
  * In Scenario_Standard.cs, remove the AddEndSteps override — the only
    thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
    false).

Preserved (future slices will address these):
  * Get_Configuration_OperatingSystem_props (D1).
  * OperatingSystems/*.cs and Context.OS.* surface.
  * PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.

Verification:

  * dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
    → Build succeeded. 0 Warning(s). 0 Error(s).
  * build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
    external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
  * Compare-Object of the resulting JdkInfo.props before vs after this
    change → byte-identical (1493 bytes, SHA256
    DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
    confirming Java.Interop's overwrite is what always ends up on disk.
  * Grep audit under build-tools/xaprepare/: no remaining references to
    Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
    AddOSSpecificSteps.

Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)

Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:

1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.

## `Configuration.OperatingSystem.props.in` placeholder audit

| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |

## `$(MakeConcurrency)` audit

The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.

**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.

## xaprepare integration audit (grep-confirmed, patched here)

| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |

**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):

- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`

## Verification

- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.

## Diff stat

102 files changed, 25 insertions(+), 7891 deletions(-).

## Precedent chain

Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants