Skip to content

Add NativeAOT dotnet tool packaging and E2E smoke test#15955

Draft
radical wants to merge 31 commits intomicrosoft:mainfrom
radical:ankj/dotnet-tool-naot-azdo
Draft

Add NativeAOT dotnet tool packaging and E2E smoke test#15955
radical wants to merge 31 commits intomicrosoft:mainfrom
radical:ankj/dotnet-tool-naot-azdo

Conversation

@radical
Copy link
Copy Markdown
Member

@radical radical commented Apr 8, 2026

Summary

Adds CI plumbing and an E2E smoke test for the dotnet tool install packaging path of the Aspire CLI.

Changes

CI Workflow (build-cli-native-archives.yml, run-tests.yml):

  • Upload Aspire.Cli.{rid}.*.nupkg as a CI artifact from the native archives build
  • Download the linux-x64 nupkg in test jobs and set ASPIRE_CLI_TOOL_NUPKG_DIR env var

E2E Test (DotnetToolSmokeTests.cs):

  • Validates the full distribution chain: dotnet tool install → self-extracting bundle → aspire new + aspire run
  • Reuses existing Docker/Hex1b infrastructure with a custom install step
  • Skips gracefully when no linux-x64 nupkg is available

Motivation

The existing CLI E2E tests install the native binary directly (mount or download), but none test the dotnet tool packaging path. Since the dotnet tool wraps a native AOT binary via SelfExtractingBundle, we need a test that validates the full distribution chain.

Testing

  • Build compiles clean (0 warnings, 0 errors)
  • Test will run as its own CI job via SplitTestsOnCI=true

radical and others added 28 commits April 1, 2026 18:03
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-azdo

# Conflicts:
#	eng/pipelines/azure-pipelines-unofficial.yml
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
For RID-specific native AOT tools, the SDK may place the executable
in a nested path rather than directly at the tool-path root. Search
the tool-path tree to find the actual executable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add SmokeTestNativeBinary MSBuild target to eng/clipack/Common.projitems
that validates native binaries after build:
- File signature check (Unix, works for cross-compiled binaries)
- aspire --version execution (only when host arch matches target)
- Skips execution for musl binaries on glibc hosts

Invoke from both CI systems:
- GHA: build-cli-native-archives.yml (after build, before upload)
- AzDO: build_sign_native.yml (after tool package, before staging)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Microsoft.Build.NoTargets SDK evaluates OutputPath differently when
invoked standalone vs through the build infrastructure. Add a
_ResolveSmokeTestBinaryPath target that searches the artifacts tree for
the binary when the default path doesn't exist.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- build-cli-native-archives.yml: Upload Aspire.Cli.{rid}.*.nupkg per RID
- run-tests.yml: Download linux-x64 nupkg and set ASPIRE_CLI_TOOL_NUPKG_DIR

The test class that consumes these will be added in a follow-up.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tests the full distribution chain: dotnet tool install from nupkg →
self-extracting bundle extraction → aspire new + aspire run.

Reuses existing Docker/Hex1b infrastructure with a custom install step
that runs 'dotnet tool install --global Aspire.Cli.linux-x64' from
a mounted nupkg directory. Skips gracefully when no linux-x64 nupkg
is available.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 15955

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 15955"

The nupkg was never produced in CI because:
- build-packages.yml skips CLI with SkipBundleDeps=true
- build-cli-native-archives.yml only does Publish, never Pack

Add 'dotnet pack Aspire.Cli.Tool.csproj' step after the native build,
using the same BundlePayloadPath and RID. Also fix the install command
in DotnetToolSmokeTests to use 'Aspire.Cli' (main tool package) instead
of 'Aspire.Cli.linux-x64' (RID-specific runtime dependency).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
radical and others added 2 commits April 8, 2026 02:57
…er Release

- Exclude .symbols.nupkg from upload glob in build-cli-native-archives.yml
- Verify both pointer and RID nupkg exist before setting env var
- Prefer Release config when multiple nupkg directories found locally
- Add ID to download step + gate set-path on download success
- Update plan doc to reflect committed state

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous pack step set RuntimeIdentifier (singular) which puts dotnet
pack in single-RID mode, producing only the RID-specific nupkg. This broke
dotnet tool install because the pointer package (Aspire.Cli.{ver}.nupkg)
was missing.

Fix: remove RuntimeIdentifier from pack, keep only ToolPackageRuntimeIdentifiers.
Add PublishAot=false since the tool package contains the managed shim
(the native binary is embedded as a self-extracting bundle resource).

Also includes robustness fixes from review:
- Exclude .symbols.nupkg from upload glob
- Verify both pointer and RID nupkg exist before setting env var
- Prefer Release config when multiple nupkg directories found locally

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant