Fix signing for aspire-managed bundle payload#16016
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16016Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 16016" |
There was a problem hiding this comment.
Pull request overview
Updates the official build/signing pipeline so the aspire-managed bundle payload is signed before it is archived into bundle.tar.gz and embedded into the native Aspire CLI.
Changes:
- Register
aspire-managedineng/Signing.props(FileSignInfo+ItemsToSign) so Arcade signing can discover and sign the published binary. - Restructure the Windows official build template to
publish -> sign -> create layoutper RID before the main build/sign step. - Apply the same
publish -> (conditional) sign -> create layoutflow in the macOS/Linux native build template.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| eng/Signing.props | Adds signing metadata and discovery globs for aspire-managed publish outputs. |
| eng/pipelines/templates/BuildAndTest.yml | Splits bundle payload generation to ensure aspire-managed is signed before bundling (Windows stage). |
| eng/pipelines/templates/build_sign_native.yml | Mirrors the pre-bundle signing flow for macOS/Linux native build jobs (signing conditional). |
| - ${{ each targetRid in parameters.targetRids }}: | ||
| - script: ${{ parameters.dotnetScript }} | ||
| publish | ||
| $(Build.SourcesDirectory)/src/Aspire.Managed/Aspire.Managed.csproj | ||
| -c ${{ parameters.buildConfig }} | ||
| -r ${{ targetRid }} | ||
| --self-contained | ||
| /p:GenerateDocumentationFile=false | ||
| /p:EnforceCodeStyleInBuild=false | ||
| $(_OfficialBuildIdArgs) | ||
| /bl:${{ parameters.repoLogPath }}/PublishManaged-${{ targetRid }}.binlog | ||
| displayName: 🟣Publish aspire-managed (${{ targetRid }}) | ||
|
|
||
| - script: ${{ parameters.buildScript }} | ||
| -restore -sign $(_SignArgs) | ||
| -configuration ${{ parameters.buildConfig }} | ||
| $(_OfficialBuildIdArgs) | ||
| -projects $(Build.SourcesDirectory)/src/Aspire.Managed/Aspire.Managed.csproj | ||
| /bl:${{ parameters.repoLogPath }}/SignManaged-${{ targetRid }}.binlog | ||
| displayName: 🟣Sign aspire-managed (${{ targetRid }}) |
There was a problem hiding this comment.
The Sign aspire-managed step is executed once per targetRid even though ItemsToSign uses a broad $(ArtifactsBinDir)Aspire.Managed\**\publish\aspire-managed.exe glob. With multiple RIDs (win-x64 + win-arm64) this will re-run restore/sign and can end up re-processing already-signed artifacts, increasing build time and introducing avoidable variability. Consider publishing all RIDs first, then running a single signing pass, or narrow the signing invocation/glob to only the current RID’s publish directory.
There was a problem hiding this comment.
Good catch on the broad glob. We'll address this in a follow-up PR to keep the scope of this change focused.
| - script: >- | ||
| $(Build.SourcesDirectory)/$(dotnetScript) | ||
| publish | ||
| $(Build.SourcesDirectory)/src/Aspire.Managed/Aspire.Managed.csproj | ||
| -c $(_BuildConfig) | ||
| -r ${{ targetRid }} | ||
| --self-contained | ||
| /p:GenerateDocumentationFile=false | ||
| /p:EnforceCodeStyleInBuild=false | ||
| /bl:$(Build.Arcade.LogsPath)PublishManaged.binlog |
There was a problem hiding this comment.
Publish aspire-managed here doesn’t include ${{ parameters.extraBuildArgs }} (which in this pipeline is where $(_OfficialBuildIdArgs) is passed). That means the bundle payload’s aspire-managed binary may be version-stamped differently from the rest of the official build and from the Windows build path. Consider passing the same official/versioning args to the dotnet publish (and, if relevant, the Bundle.proj layout) step so the signed payload matches the build’s intended version metadata.
There was a problem hiding this comment.
Good catch - fixed. Added extraBuildArgs to the publish step so it gets the same OfficialBuildIdArgs for consistent versioning.
9416197 to
fc6cc93
Compare
Split the bundle payload pipeline step into three phases so that aspire-managed goes through Arcade's signing infrastructure before CreateLayout packs it into the bundle archive: 1. dotnet publish - produces the self-contained single-file binary 2. build.cmd/sh -restore -sign - Arcade signs it via ItemsToSign 3. Bundle.proj /t:_RestoreDcpPackage;_RunCreateLayout - creates the tar.gz archive with the already-signed binary Changes: - eng/Signing.props: Add FileSignInfo and ItemsToSign entries for aspire-managed.exe (Windows) and aspire-managed (Linux/macOS) - eng/pipelines/templates/BuildAndTest.yml: Split bundle payload step into publish, sign, and layout steps per RID - eng/pipelines/templates/build_sign_native.yml: Same restructuring for macOS/Linux native stage (sign step conditional on codeSign) Fixes microsoft#15989 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fc6cc93 to
3060546
Compare
JamesNK
left a comment
There was a problem hiding this comment.
Clean, well-structured fix. The three-phase publish → sign → layout split correctly ensures aspire-managed is signed before being packed into the bundle archive. Signing.props entries are consistent with existing patterns, and the pipeline restructuring in both BuildAndTest.yml and build_sign_native.yml is correct.
Fixes #15989
Description
Fix the CLI bundle signing gap where
aspire-managedwas not being signed before being packed into the bundle archive.Root cause: The managed bundle payload was published via
Bundle.projusing a standalonedotnet publishcall, which runs outside of Arcade's signing infrastructure. By the time Arcade's signing phase ran during the main build,aspire-managedwas already packed insidebundle.tar.gzand embedded in the nativeaspireCLI binary — unreachable by the signing tooling.Approach
Split the bundle payload pipeline step into three phases so that
aspire-managedgoes through Arcade's standard signing infrastructure beforeCreateLayoutpacks it into the archive:dotnet publish— produces the self-contained single-fileaspire-managedbinarybuild.cmd/sh -restore -sign— Arcade'sSignToolTaskdiscovers the binary viaItemsToSignglobs inSigning.propsand signs it in-place using ESRP/MicroBuildBundle.proj /t:_RestoreDcpPackage;_RunCreateLayout— creates thebundle.tar.gzarchive with the already-signed binaryChanges
eng/Signing.props: Registeraspire-managed.exe/aspire-managedinFileSignInfo(certificate mapping) andItemsToSign(glob pointing at publish output path)eng/pipelines/templates/BuildAndTest.yml: Replace single Bundle.proj step with the three-phase publish -> sign -> layout flow per target RIDeng/pipelines/templates/build_sign_native.yml: Same restructuring for macOS/Linux native stage. Sign step is conditional oncodeSign: true(macOS only; Linux ELF binaries are not signed)Validation
Tested via internal ADO build 2947441. The signing step reported:
Checklist