.NET多平台应用UI(.NET MAUI)将Android、iOS、macOS和Windows UI框架统一到一个框架中,因此你可以编写一个在许多平台上原生运行的应用程序。在这篇文章中,我们将看看使用GitHub Actions和Azure DevOps为.NET MAUI应用实现基本的DevOps管道是多么容易。
开始吧
在设置管道之前,我们需要确保准备好一些文件:
- 对于
iOS,你需要一个签名证书和一个配置文件。本指南将指导你如何获得这些文件。 - (对于
Android,你需要钥匙库文件以及钥匙库密码和钥匙库别名的值。本指南将指导你如何获得这些文件。 - 对于
Windows,你需要创建和导出一个用于包签名的证书。你可以按照本指南的步骤进行。

我们现在准备开始为.NET MAUI应用程序创建管道。我们将查看添加到dotnet/maui-samplesrepo的样本管道,作为Weather21应用程序的一部分,在devops文件夹下。
管线源文件
注意 这些是用于基本测试和构建的启动管道,非常适合用于PR检查。这些步骤并不包括发布到存储或签署分发。这已经超出了本篇文章的范围,将在以后的文章中介绍。
GitHub 操作示例
- MacOS主机代理 :macos-build.yml
- Windows主机代理:windowsCI.yml
Azure DevOps样本
- MacOS主机代理:azdo_mac.yml
- Windows托管代理:azdo_windows.yml
管线概述
我们为GitHub Actions和Azure DevOps准备了2个管道文件,一个在macos-12 VM上运行,构建iOS 和MacCatalyst 目标。另一个在windows-2022 VM上运行,构建Android 和Windows 目标。
每个管道都被分解成以下子步骤:
- 设置.NET版本
- 安装.NET MAUI工作负载
- 安装签名文件(根据需要)
- 为TargetFramework构建/发布应用程序
- 运行单元测试(如果需要)。
- 上传工件
这个简化的DevOps流程都要归功于我们现在可以使用的dotnet 命令行工具。我们能够为所有TargetFramework类型dotnet build 和dotnet publish 。不需要复杂和曲折的脚本来管理msbuild 和VS preview 的安装。
让我们分解每个管道中的任务。
管线任务
快速提示通过查看此表,检查可用的GitHub托管的虚拟机镜像和安装的软件。

快速提示通过查看此表,检查可用的Azure DevOps托管的虚拟机镜像和已安装的软件。

两个管道的共同任务是Setup .NET SDK Version 和Install .NET MAUI 。
这是它在GitHub Actions :
- name: Setup .NET SDK ${{env.DOTNETVERSION}}
uses: actions/setup-dotnet@v1
with:
dotnet-version: '${{env.DOTNETVERSION}}'
- name: Install .NET MAUI
shell: bash
run: |
dotnet nuget locals all --clear
dotnet workload install maui --source https://aka.ms/dotnet6/nuget/index.json --source https://api.nuget.org/v3/index.json
dotnet workload install android ios maccatalyst tvos macos maui wasm-tools --source https://aka.ms/dotnet6/nuget/index.json --source https://api.nuget.org/v3/index.json
第一个任务使用GitHub ActionSetup .NET Core SDK,创建一个管道变量,使其更容易在未来改变版本。
这是它在Azure DevOps :
- task: UseDotNet@2
displayName: .NET Version
inputs:
packageType: 'sdk'
version: '$(DotNetVersion)'
- task: Bash@3
displayName: Install MAUI
inputs:
targetType: 'inline'
script: |
dotnet nuget locals all --clear
dotnet workload install maui --source https://aka.ms/dotnet6/nuget/index.json --source https://api.nuget.org/v3/index.json
dotnet workload install android ios maccatalyst tvos macos maui wasm-tools --source https://aka.ms/dotnet6/nuget/index.json --source https://api.nuget.org/v3/index.json
第一个任务使用Azure Devops使用.NET Core任务,并且创建一个管道变量使其在未来更容易改变版本。
下一个任务是通过内联脚本Install .NET MAUI workloads 。你可以调整--source ,以针对.NET MAUI工作负载的特定版本,你可以在.NET MAUI Wiki中了解更多关于改变来源的信息。
Mac构建代理流水线
构建/发布任务在.NET MAUI文档中解释:
例如,GitHub Actions 中的发布MacCatalyst任务:
- name : Publish MacCatalyst App
shell: bash
run: |
cd 6.0/Apps/WeatherTwentyOne/src
dotnet publish -f net6.0-maccatalyst -c Release -p:BuildIpa=True -o ./artifacts
和Azure DevOps 中的相同任务:
- task: Bash@3
displayName: Build MacCatalyst App
inputs:
targetType: 'inline'
script: |
cd 6.0/Apps/WeatherTwentyOne/src
dotnet publish -f net6.0-maccatalyst -c Release -p:BuildIpa=True -o ./artifacts
为了方便dotnet publish ,第一行导航到WeatherTwentyOne.sln 存在的文件夹。在一个更简单的版本库结构中,你将不需要这第一行。
让我们看一下dotnet publish 命令:
dotnet publish -f <target_framework> -c Release -p:BuildIpa=True -o <path_to_output_folder>
<target_framework> | 根据你建立的内容,被设置为net6.0-maccatalyst 或net6.0-ios |
-o <folder_path> | 允许你将发布文件夹从默认的bin/.../...重定向到你指定的文件夹路径。而不是你指定的文件夹路径。这对DevOps管道非常有用,所以更容易找到要发布的工件。 |
最后一项任务是将工件发布到GitHub管道中,它使用了GitHub的Upload a Build Artifact动作。
在Azure DevOps中,这是一个两步过程,拳头复制文件任务将文件复制到$(Build.ArtifactStagingDirectory) ,然后发布构建工件任务将工件发布。
对于iOS ,还有一个额外的步骤,我们在这里安装签名证书和供应配置文件。
这份GitHub文档解释了如何安装这些文件作为GitHub Actions 的管道的一部分。按照说明,这就是任务:
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode --output $PP_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning Profiles
在Azure DevOps ,Azure DevOps签署你的苹果应用程序,指导你完成将证书和配置文件添加到安全文件库的过程。一旦上传到那里,安装苹果证书任务和安装苹果配置文件任务将把它作为管道任务的一部分来安装。这就是流水线的样子:
- task: InstallAppleCertificate@2
inputs:
certSecureFile: 'DevelopmentCert.p12'
certPwd: '$(iOSCertPassword)'
keychain: 'temp'
- task: InstallAppleProvisioningProfile@1
inputs:
provisioningProfileLocation: 'secureFiles'
provProfileSecureFile: 'Development.mobileprovision'
Windows Build Agent管道
构建/发布任务在.NET MAUI文档中解释:
例如,GitHub Actions 中的Android发布任务:
- name : Build Android App
shell: bash
run: |
cd 6.0/Apps/WeatherTwentyOne/src
dotnet publish -f:net6.0-android -c:Release
和相同的任务在Azure DevOps :
- task: Bash@3
displayName: Build Android App
inputs:
targetType: 'inline'
script: |
cd 6.0/Apps/WeatherTwentyOne/src
dotnet publish -f net6.0-android -c Release
第一步导航到有WeatherTwentyOne.sln 的文件夹并运行dotnet publish 任务。让我们看一下dotnet publish 命令:
dotnet publish -f <target_framework> -c Release -p:BuildIpa=True -o ./artifacts | ||
|---|---|---|
<target_framework> | 是根据你建立的内容设置为net6.0-android 或net6.0-windows10.0.19041.0 |
对于Github Actions ,发布工件的步骤保持不变,GitHub ActionUpload a Build Artifact对Mac 和Windows 代理都有效。
对于Azure Devops ,复制文件任务和发布构建工件任务在Mac 和Windows 代理上都可以工作。
对于Windows ,有两个额外的任务。第一个是存储和解码签名证书文件。
在GitHub Actions ,它的过程如下:
- 创建的签名证书文件需要被编码为Base64。这可以用
certutil,在Windows,按照文档的要求进行。在Mac,你可以运行base64 -i <cert_file>.pfx | pbcopy。 - Base64编码的字符串需要按照GitHub Actions加密的秘密文档来存储在GitHub Actions的秘密中。
- 在管道任务中对秘密进行解码。
- name: Create signing pfx file from secrets
shell: pwsh
id: secret-file
env:
SIGN_CERT: ${{ secrets.WIN_SIGN_CERT }}
run: |
$secretFile = "WinSignCert.pfx";
$encodedBytes = [System.Convert]::FromBase64String($env:SIGN_CERT);
Set-Content $secretFile -Value $encodedBytes -AsByteStream;
Write-Output "::set-output name=SECRET_FILE::$secretFile";
在Azure DevOps ,遵循CI/CD管道概述指南,将文件上传到安全文件库。然后使用下载安全文件任务下载并安装该文件。
- task: DownloadSecureFile@1
inputs:
secureFile: 'DevelopmentCert.pfx'
第二个任务是使用这个证书文件来签署从dotnet publish 生成的MSIX。按照这个Azure DevOps指南,我们在GitHub Actions 中得到以下任务:
- name: Sign Windows App
shell: pwsh
env:
CERT_PASSWORD: ${{ secrets.WIN_CERT_PASSWORD }}
run: |
'"C:Program Files (x86)Windows Kits10App Certification KitSignTool" sign /a /fd SHA256 /f WinSignCert.pfx /p ($env:CERT_PASSWORD) 6.0AppsWeatherTwentyOnesrcWeatherTwentyOnebinReleasenet6.0-windows10.0.19041.0win10-x64AppPackagesWeatherTwentyOne_1.0.0.0_TestWeatherTwentyOne_1.0.0.0_x64.msix'
和Azure DevOps 中的相同任务,直接使用指南中提供的代码片断:
- script: '"C:Program Files (x86)Windows Kits10App Certification KitSignTool" sign /fd SHA256 /f $(Agent.TempDirectory)/XamCATFidCert.pfx /p $(WindowsCertSecret) $(Build.ArtifactStagingDirectory)6.0AppsWeatherTwentyOnesrcWeatherTwentyOnebinReleasenet6.0-windows10.0.19041.0win10-x64AppPackagesWeatherTwentyOne_1.0.0.0_TestWeatherTwentyOne_1.0.0.0_x64.msix'
displayName: 'Sign MSIX Package'
在GitHub Actions 对于Android Signing ,样本管道包含任务,根据需要取消注释并遵循链接。与Windows ,首先用Base64编码并解码Keystore文件。下一个任务是使用jarsigner 签署生成的apk 文件。
在Azure DevOps 为Android Signing ,本指南一步一步地展示了如何签署你的Android应用程序。它显示了如何安全地上传签名文件,然后如何配置Android签名的Azure DevOps 任务。
总结
我希望这能帮助你开始使用GitHub Actions 和Azure DevOps 为.NET MAUI应用程序设置DevOps。yaml 文件的样本。
-
GitHub行动样本
- MacOS主机代理 :macos-build.yml
- Windows主机代理:windowsCI.yml
-
Azure DevOps样本
- MacOS主机代理:azdo_mac.yml
- Windows托管代理:azdo_windows.yml
请在dotnet/maui-samples查看更多的样本。请尝试使用.NET MAUI,提交问题,或在dot.net/maui上了解更多信息!