diff --git a/docs/contributing.md b/docs/contributing.md
index c845a9c9ab5..c19be318a76 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -31,6 +31,14 @@ Or, if you are using Visual Studio:
Make sure you [build the repo](#build-the-repo) from command line at least once. Then use `./start-code.sh` (macOS and Linux) or `.\start-code.cmd` to start VS Code.
+## Native build
+
+The default build includes native builds for `Aspire.Cli` which produces Native AOT binaries for some platforms. These projects are in `eng/clipack/Aspire.Cli.*`.
+
+By default it builds the cli native project for the current Runtime Identifier. A specific RIDs can be specified too by setting `$(TargetRids)` to a colon separated list like `/p:TargetRids=osx-x64:osx-arm64`.
+
+Native build can be disabled with `/p:SkipNativeBuild=true`. And to only the native bits use `/p:SkipManagedBuild=true`.
+
## View Dashboard
When you start the sample app in Visual Studio, it will automatically open your browser to show the dashboard.
diff --git a/eng/Build.props b/eng/Build.props
index 4f78cedd9a6..dddc4194a9a 100644
--- a/eng/Build.props
+++ b/eng/Build.props
@@ -1,9 +1,17 @@
-
-
+
+
+ $([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier)
+
+
+ $(BuildRid)
+
+
+
-
+
+
+
+
+
+
+ <_TargetRidItem Include="$(TargetRids.Split(':'))" />
+ <_NativeProjectToBuild Include="@(_TargetRidItem -> '$(RepoRoot)eng\clipack\Aspire.Cli.%(Identity).csproj')" />
+
+
+
true
diff --git a/eng/Publishing.props b/eng/Publishing.props
index bab22932604..4427480789f 100644
--- a/eng/Publishing.props
+++ b/eng/Publishing.props
@@ -23,10 +23,28 @@
<_InstallersToPublish Include="$(ArtifactsDir)**\*.wixpack.zip" Condition="'$(PostBuildSign)' == 'true'" />
<_InstallerManifestFilesToPublish Include="$(ArtifactsDir)VSSetup\$(Configuration)\Insertion\**\*.zip" />
<_DashboardFilesToPublish Include="$(DashboardPublishedArtifactsOutputDir)\**\*.zip" />
- <_CliFilesToPublish Include="$(ArtifactsShippingPackagesDir)\aspire-cli-*" />
+
+
+ <_ArchiveFiles Include="$(ArtifactsPackagesDir)\**\aspire-cli-*.zip" />
+ <_ArchiveFiles Include="$(ArtifactsPackagesDir)\**\aspire-cli-*.tar.gz" />
+
+ <_CliPackProjects Include="$(RepoRoot)eng\clipack\Aspire.Cli.*.csproj" />
+ <_ExpectedRids Include="@(_CliPackProjects->'%(Filename)'->Replace('Aspire.Cli.', ''))" />
+
+
+ <_FoundRidInCliArchiveFile Include="$([System.Text.RegularExpressions.Regex]::Match(%(_ArchiveFiles.FileName), 'aspire-cli-(.*)-\d+.*').Groups[1].Value)" />
+
+ <_MissingRids Include="@(_ExpectedRids)" Exclude="@(_FoundRidInCliArchiveFile)" />
+ <_UnexpectedRids Include="@(_FoundRidInCliArchiveFile)" Exclude="@(_ExpectedRids)" />
+
+
+
+
+
+
+ <_CliFileToPublish Include="@(_ArchiveFiles)" />
+
+
+
+
+
+ <_CliFileToPublish Include="@(GenerateChecksumItems->'%(DestinationPath)')" />
+
+
true
@@ -55,7 +84,7 @@
true
$(_UploadPathRoot)/$(_PackageVersion)/%(Filename)%(Extension)
-
+
false
true
$(_UploadPathRoot)/$(_PackageVersion)/%(Filename)%(Extension)
diff --git a/eng/Signing.props b/eng/Signing.props
index 6ad92ed9be0..31dc37bc66b 100644
--- a/eng/Signing.props
+++ b/eng/Signing.props
@@ -34,6 +34,10 @@
+
+
+
+
@@ -45,6 +49,8 @@
+
+
diff --git a/eng/clipack/Common.projitems b/eng/clipack/Common.projitems
index 4480dc2f9e8..00213ed3fc7 100644
--- a/eng/clipack/Common.projitems
+++ b/eng/clipack/Common.projitems
@@ -3,10 +3,11 @@
$(DefaultTargetFramework)
aspire-cli-$(CliRuntime)
- tar.gz
- zip
+ zip
+ tar.gz
-
+
true
true
true
@@ -48,6 +49,10 @@
Properties="@(AdditionalProperties)"
RemoveProperties="OutputPath;TargetFramework" />
+
+ <_OutputBinaryPath>$(OutputPath)/aspire
+
+
diff --git a/eng/pipelines/azure-pipelines.yml b/eng/pipelines/azure-pipelines.yml
index 5736a072273..49b4710f057 100644
--- a/eng/pipelines/azure-pipelines.yml
+++ b/eng/pipelines/azure-pipelines.yml
@@ -112,11 +112,43 @@ extends:
stages:
+ - stage: build_sign_native
+ displayName: Build+Sign native packages
+
+ jobs:
+ - template: /eng/pipelines/templates/build_sign_native.yml@self
+ parameters:
+ agentOs: macos
+ targetRidsForSameOS:
+ - osx-arm64
+ - osx-x64
+ codeSign: true
+ teamName: $(_TeamName)
+ extraBuildArgs: >-
+ /p:Configuration=$(_BuildConfig)
+ $(_SignArgs)
+ $(_OfficialBuildIdArgs)
+
+ - template: /eng/pipelines/templates/build_sign_native.yml@self
+ parameters:
+ agentOs: linux
+ targetRidsForSameOS:
+ - linux-x64
+ # no need to sign ELF binaries on linux
+ codeSign: false
+ teamName: $(_TeamName)
+ extraBuildArgs: >-
+ /p:Configuration=$(_BuildConfig)
+ $(_SignArgs)
+ $(_OfficialBuildIdArgs)
+
# ----------------------------------------------------------------
# This stage performs build, test, packaging
# ----------------------------------------------------------------
- stage: build
displayName: Build
+ dependsOn:
+ - build_sign_native
jobs:
- template: /eng/common/templates-official/jobs/jobs.yml@self
parameters:
@@ -160,6 +192,21 @@ extends:
clean: true
steps:
+ - task: DownloadPipelineArtifact@2
+ displayName: 🟣Download All Native Archives
+ inputs:
+ itemPattern: |
+ **/aspire-cli-*.zip
+ **/aspire-cli-*.tar.gz
+ targetPath: '$(Build.SourcesDirectory)/artifacts/packages/$(_BuildConfig)'
+
+ - task: PowerShell@2
+ displayName: 🟣List artifacts packages contents
+ inputs:
+ targetType: 'inline'
+ script: |
+ Get-ChildItem -Path "$(Build.SourcesDirectory)\artifacts\packages" -File -Recurse | Select-Object FullName, @{Name="Size(MB)";Expression={[math]::Round($_.Length/1MB,2)}} | Format-Table -AutoSize
+
- template: /eng/pipelines/templates/BuildAndTest.yml
parameters:
dotnetScript: $(Build.SourcesDirectory)/dotnet.cmd
@@ -169,40 +216,14 @@ extends:
repoLogPath: $(Build.Arcade.LogsPath)
repoTestResultsPath: $(Build.Arcade.TestResultsPath)
isWindows: true
-
- - ${{ if eq(variables._RunAsPublic, True) }}:
- - job: Linux
- ${{ if or(startswith(variables['Build.SourceBranch'], 'refs/heads/release/'), startswith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), eq(variables['Build.Reason'], 'Manual')) }}:
- # If the build is getting signed, then the timeout should be increased.
- timeoutInMinutes: 120
- ${{ else }}:
- # timeout accounts for wait times for helix agents up to 30mins
- timeoutInMinutes: 90
-
- pool:
- name: NetCore1ESPool-Internal
- image: 1es-mariner-2
- os: linux
-
- variables:
- - name: _buildScript
- value: $(Build.SourcesDirectory)/build.sh --ci
-
- preSteps:
- - checkout: self
- fetchDepth: 1
- clean: true
-
- steps:
- - template: /eng/pipelines/templates/BuildAndTest.yml
- parameters:
- dotnetScript: $(Build.SourcesDirectory)/dotnet.sh
- buildScript: $(_buildScript)
- buildConfig: $(_BuildConfig)
- repoArtifactsPath: $(Build.Arcade.ArtifactsPath)
- repoLogPath: $(Build.Arcade.LogsPath)
- repoTestResultsPath: $(Build.Arcade.TestResultsPath)
- isWindows: false
+ targetRids:
+ # aot
+ - win-x64
+ - win-arm64
+ # non-aot - single file builds
+ - win-x86
+ - linux-arm64
+ - linux-musl-x64
- ${{ if and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/main')) }}:
- template: /eng/common/templates-official/job/onelocbuild.yml@self
diff --git a/eng/pipelines/templates/BuildAndTest.yml b/eng/pipelines/templates/BuildAndTest.yml
index 225c5af136f..2ba3dfaaa87 100644
--- a/eng/pipelines/templates/BuildAndTest.yml
+++ b/eng/pipelines/templates/BuildAndTest.yml
@@ -16,6 +16,9 @@ parameters:
type: string
- name: dotnetScript
type: string
+ - name: targetRids
+ type: object
+ default: ''
- name: runHelixTests
type: boolean
default: false
@@ -38,14 +41,15 @@ steps:
/bl:${{ parameters.repoLogPath }}/build.binlog
$(_OfficialBuildIdArgs)
$(_InternalBuildArgs)
+ /p:TargetRids=${{ join(':', parameters.targetRids) }}
/p:SkipTestProjects=true
- displayName: Build
+ displayName: 🟣Build
- script: ${{ parameters.dotnetScript }}
build
tests/workloads.proj
/p:SkipPackageCheckForTemplatesTesting=true
- displayName: Prepare sdks for templates testing
+ displayName: 🟣Prepare sdks for templates testing
- script: ${{ parameters.buildScript }}
-build
@@ -63,7 +67,7 @@ steps:
DEV_TEMP: $(Build.SourcesDirectory)\..
DOTNET_ROOT: $(Build.SourcesDirectory)\.dotnet
TEST_LOG_PATH: $(Build.SourcesDirectory)\artifacts\log\$(_BuildConfig)\Aspire.Templates.Tests
- displayName: Run Template tests
+ displayName: 🟣Run Template tests
# Public pipeline - helix tests
- ${{ if eq(parameters.runAsPublic, 'true') }}:
diff --git a/eng/pipelines/templates/build_sign_native.yml b/eng/pipelines/templates/build_sign_native.yml
new file mode 100644
index 00000000000..e55bd6b4007
--- /dev/null
+++ b/eng/pipelines/templates/build_sign_native.yml
@@ -0,0 +1,81 @@
+parameters:
+ # values: windows/mac/linux
+ agentOs: 'windows'
+ targetRidsForSameOS:
+ - linux-x64
+ extraBuildArgs: ''
+ codeSign: false
+ teamName: ''
+
+jobs:
+
+- ${{ each targetRid in parameters.targetRidsForSameOS }}:
+ - template: /eng/common/templates-official/jobs/jobs.yml@self
+ parameters:
+ enableMicrobuild: ${{ eq(parameters.codeSign, true) }}
+ enableMicrobuildForMacAndLinux: ${{ and(eq(parameters.codeSign, true), ne(parameters.agentOs, 'windows')) }}
+ enableTelemetry: true
+ # Publish build logs
+ enablePublishBuildArtifacts: true
+
+ jobs:
+ - job: BuildNative_${{ replace(targetRid, '-', '_') }}
+ displayName: ${{ replace(targetRid, '-', '_') }}
+ timeoutInMinutes: 40
+
+ variables:
+ - TeamName: ${{ parameters.teamName }}
+ - ${{ if eq(parameters.codeSign, true) }}:
+ - _buildArgs: '--sign'
+ - ${{ else }}:
+ - _buildArgs: ''
+
+ - ${{ if eq(parameters.agentOs, 'windows') }}:
+ - scriptName: build.cmd
+ - ${{ else }}:
+ - scriptName: build.sh
+
+ pool:
+ ${{ if eq(parameters.agentOs, 'windows') }}:
+ name: NetCore1ESPool-Internal
+ image: windows.vs2022preview.amd64
+ os: windows
+ ${{ if eq(parameters.agentOs, 'linux') }}:
+ name: NetCore1ESPool-Internal
+ image: 1es-mariner-2
+ os: linux
+ ${{ if eq(parameters.agentOs, 'macos') }}:
+ name: Azure Pipelines
+ vmImage: macOS-latest-internal
+ os: macOS
+
+ preSteps:
+ - checkout: self
+ fetchDepth: 1
+ clean: true
+
+ # Installing Microbuild plugin fails due to https://github.com/dotnet/arcade/issues/15946#issuecomment-3045780552
+ # because of the preview sdk. To fix that `restore` from `global.json` so the above step
+ # does not have to install anything.
+ - script: $(Build.SourcesDirectory)/$(scriptName) -restore /p:Configuration=$(_BuildConfig)
+ displayName: 🟣Restore
+
+ steps:
+ - script: >-
+ $(Build.SourcesDirectory)/$(scriptName)
+ --ci
+ --build
+ --restore
+ /p:SkipManagedBuild=true
+ /p:TargetRids=${{ targetRid }}
+ $(_buildArgs)
+ ${{ parameters.extraBuildArgs }}
+ /bl:$(Build.Arcade.LogsPath)Build.binlog
+ displayName: 🟣Build native packages
+
+ - task: 1ES.PublishBuildArtifacts@1
+ displayName: 🟣Publish Artifacts
+ condition: always()
+ inputs:
+ PathtoPublish: '$(Build.Arcade.ArtifactsPath)packages/'
+ ArtifactName: native_archives_${{ replace(targetRid, '-', '_') }}