From 7e494a69480a807125af578da8b62856ce7ed9a1 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Thu, 9 Apr 2026 11:48:44 +1000 Subject: [PATCH 1/3] Fix aspire-managed bundle signing Ensure the managed bundle payload participates in the same signing flow as aspire.exe by forwarding signing properties through Bundle.proj, registering aspire-managed for signing, and adding a CI verification step for the Windows bundle payload.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/Bundle.proj | 13 ++++++++++--- eng/Signing.props | 3 +++ eng/build.ps1 | 12 +++++++++--- eng/build.sh | 16 +++++++++------- eng/pipelines/templates/BuildAndTest.yml | 19 +++++++++++++++++++ eng/pipelines/templates/build_sign_native.yml | 1 + 6 files changed, 51 insertions(+), 13 deletions(-) diff --git a/eng/Bundle.proj b/eng/Bundle.proj index 626184870d4..7a56e53d80b 100644 --- a/eng/Bundle.proj +++ b/eng/Bundle.proj @@ -46,8 +46,15 @@ $(VersionPrefix)-$(VersionSuffix) $(VersionPrefix)-dev - + + <_ContinuousIntegrationBuildArg Condition="'$(ContinuousIntegrationBuild)' != ''">/p:ContinuousIntegrationBuild=$(ContinuousIntegrationBuild) <_VersionSuffixArg Condition="'$(VersionSuffix)' != ''">/p:VersionSuffix=$(VersionSuffix) + <_OfficialBuildIdArg Condition="'$(OfficialBuildId)' != ''">/p:OfficialBuildId=$(OfficialBuildId) + <_SignArg Condition="'$(Sign)' != ''">/p:Sign=$(Sign) + <_DotNetSignTypeArg Condition="'$(DotNetSignType)' != ''">/p:DotNetSignType=$(DotNetSignType) + <_DotNetPublishUsingPipelinesArg Condition="'$(DotNetPublishUsingPipelines)' != ''">/p:DotNetPublishUsingPipelines=$(DotNetPublishUsingPipelines) + <_TeamNameArg Condition="'$(TeamName)' != ''">/p:TeamName=$(TeamName) + <_PostBuildSignArg Condition="'$(PostBuildSign)' != ''">/p:PostBuildSign=$(PostBuildSign) <_BinlogArg Condition="'$(ContinuousIntegrationBuild)' == 'true'">-bl:$(ArtifactsLogDir) @@ -91,7 +98,7 @@ <_BundleArchivePath>$(ArtifactsDir)bundle\aspire-$(BundleVersion)-$(TargetRid).tar.gz - + @@ -100,7 +107,7 @@ - + diff --git a/eng/Signing.props b/eng/Signing.props index 2aa27b1a292..0bdfe351876 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -56,8 +56,11 @@ + + + diff --git a/eng/build.ps1 b/eng/build.ps1 index 611fc8cf22a..136a6355968 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -155,9 +155,15 @@ if ($bundle) { "/p:TargetRid=$rid" ) - # Pass through SkipNativeBuild if set - if ($properties -contains "/p:SkipNativeBuild=true") { - $bundleArgs += "/p:SkipNativeBuild=true" + foreach ($property in $properties) { + if ($property -eq "-sign") { + $bundleArgs += "/p:Sign=true" + continue + } + + if ($property.StartsWith("/p:", [System.StringComparison]::OrdinalIgnoreCase)) { + $bundleArgs += $property + } } # CI flag is passed to Bundle.proj which handles version computation via Versions.props diff --git a/eng/build.sh b/eng/build.sh index f23a40c25b4..18732aa286b 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -58,6 +58,7 @@ usage() arguments='' extraargs='' +bundle_passthrough_args=() build_bundle=false runtime_version="" config="Debug" @@ -169,6 +170,11 @@ while [[ $# > 0 ]]; do ;; *) + if [[ "$opt" == "-sign" ]]; then + bundle_passthrough_args+=("/p:Sign=true") + elif [[ "$1" == "/p:"* || "$1" == "-p:"* ]]; then + bundle_passthrough_args+=("$1") + fi extraargs="$extraargs $1" shift 1 ;; @@ -246,13 +252,9 @@ if [ "$build_bundle" = true ]; then "/p:TargetRid=$rid" ) - # Pass through SkipNativeBuild if set - for arg in "$@"; do - if [[ "$arg" == *"SkipNativeBuild=true"* ]]; then - bundle_args+=("/p:SkipNativeBuild=true") - break - fi - done + if [ ${#bundle_passthrough_args[@]} -gt 0 ]; then + bundle_args+=("${bundle_passthrough_args[@]}") + fi # CI flag is passed to Bundle.proj which handles version computation via Versions.props if [ "${CI:-}" = "true" ]; then diff --git a/eng/pipelines/templates/BuildAndTest.yml b/eng/pipelines/templates/BuildAndTest.yml index 5f3bf630398..42f8176dad8 100644 --- a/eng/pipelines/templates/BuildAndTest.yml +++ b/eng/pipelines/templates/BuildAndTest.yml @@ -52,9 +52,28 @@ steps: /p:BundleVersion=ci-bundlepayload /p:SkipNativeBuild=true /p:ContinuousIntegrationBuild=true + $(_SignArgs) + $(_OfficialBuildIdArgs) /bl:${{ parameters.repoLogPath }}/BundlePayload-${{ targetRid }}.binlog displayName: 🟣Build bundle payload (${{ targetRid }}) + - pwsh: | + $managedPath = Join-Path '${{ parameters.repoArtifactsPath }}/bin/Aspire.Managed/${{ parameters.buildConfig }}/net10.0/${{ targetRid }}/publish' 'aspire-managed.exe' + if (-not (Test-Path $managedPath)) { + Write-Host "##[error]aspire-managed.exe not found at $managedPath" + exit 1 + } + + $signature = Get-AuthenticodeSignature $managedPath + if ($signature.Status -eq [System.Management.Automation.SignatureStatus]::NotSigned) { + Write-Host "##[error]aspire-managed.exe is not signed: $managedPath" + exit 1 + } + + Write-Host "✅ aspire-managed.exe signature status: $($signature.Status)" + displayName: 🟣Verify managed bundle signature (${{ targetRid }}) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), in(variables['_SignType'], 'real', 'test'), startsWith('${{ targetRid }}', 'win-')) + - script: ${{ parameters.buildScript }} -restore -build -pack diff --git a/eng/pipelines/templates/build_sign_native.yml b/eng/pipelines/templates/build_sign_native.yml index 7ee70558dae..5f770eae348 100644 --- a/eng/pipelines/templates/build_sign_native.yml +++ b/eng/pipelines/templates/build_sign_native.yml @@ -73,6 +73,7 @@ jobs: /p:BundleVersion=ci-bundlepayload /p:SkipNativeBuild=true /p:ContinuousIntegrationBuild=true + ${{ parameters.extraBuildArgs }} /bl:$(Build.Arcade.LogsPath)BundlePayload.binlog displayName: 🟣Build bundle payload From 23d0c9d19308ae3d7a05fe9be3c7aac785b40775 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Thu, 9 Apr 2026 12:37:52 +1000 Subject: [PATCH 2/3] Trigger CI rerun Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> From eb4d202e3964e4c36c047c0a8b0c57279ab3ea01 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Thu, 9 Apr 2026 13:01:41 +1000 Subject: [PATCH 3/3] Address PR feedback on signing check Gate the new bundle signature validation on signing actually being enabled and allow the expected test-signing status while still rejecting missing or broken signatures.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/pipelines/templates/BuildAndTest.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/templates/BuildAndTest.yml b/eng/pipelines/templates/BuildAndTest.yml index 42f8176dad8..29d3fba6587 100644 --- a/eng/pipelines/templates/BuildAndTest.yml +++ b/eng/pipelines/templates/BuildAndTest.yml @@ -65,14 +65,19 @@ steps: } $signature = Get-AuthenticodeSignature $managedPath - if ($signature.Status -eq [System.Management.Automation.SignatureStatus]::NotSigned) { - Write-Host "##[error]aspire-managed.exe is not signed: $managedPath" + $allowedStatuses = @( + [System.Management.Automation.SignatureStatus]::Valid, + [System.Management.Automation.SignatureStatus]::NotTrusted + ) + + if ($signature.Status -notin $allowedStatuses) { + Write-Host "##[error]aspire-managed.exe has an unexpected signature status '$($signature.Status)': $managedPath" exit 1 } Write-Host "✅ aspire-managed.exe signature status: $($signature.Status)" displayName: 🟣Verify managed bundle signature (${{ targetRid }}) - condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), in(variables['_SignType'], 'real', 'test'), startsWith('${{ targetRid }}', 'win-')) + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['_Sign'], 'true'), in(variables['_SignType'], 'real', 'test'), startsWith('${{ targetRid }}', 'win-')) - script: ${{ parameters.buildScript }} -restore -build