初步DevOps和.NET MAUI使用指南

400 阅读5分钟

.NET多平台应用UI(.NET MAUI)将Android、iOS、macOS和Windows UI框架统一到一个框架中,因此你可以编写一个在许多平台上原生运行的应用程序。在这篇文章中,我们将看看使用GitHub Actions和Azure DevOps为.NET MAUI应用实现基本的DevOps管道是多么容易。

开始吧

在设置管道之前,我们需要确保准备好一些文件:

  • 对于iOS ,你需要一个签名证书和一个配置文件。本指南将指导你如何获得这些文件。
  • (对于Android ,你需要钥匙库文件以及钥匙库密码和钥匙库别名的值。本指南将指导你如何获得这些文件。
  • 对于Windows ,你需要创建和导出一个用于包签名的证书。你可以按照本指南的步骤进行。

list of files required for pipelines

我们现在准备开始为.NET MAUI应用程序创建管道。我们将查看添加到dotnet/maui-samplesrepo的样本管道,作为Weather21应用程序的一部分,在devops文件夹下。

管线源文件

注意 这些是用于基本测试和构建的启动管道,非常适合用于PR检查。这些步骤并不包括发布到存储或签署分发。这已经超出了本篇文章的范围,将在以后的文章中介绍。

GitHub 操作示例

Azure DevOps样本

管线概述

我们为GitHub Actions和Azure DevOps准备了2个管道文件,一个在macos-12 VM上运行,构建iOSMacCatalyst 目标。另一个在windows-2022 VM上运行,构建AndroidWindows 目标。

每个管道都被分解成以下子步骤:

  1. 设置.NET版本
  2. 安装.NET MAUI工作负载
  3. 安装签名文件(根据需要)
  4. 为TargetFramework构建/发布应用程序
  5. 运行单元测试(如果需要)。
  6. 上传工件

这个简化的DevOps流程都要归功于我们现在可以使用的dotnet 命令行工具。我们能够为所有TargetFramework类型dotnet builddotnet publish 。不需要复杂和曲折的脚本来管理msbuildVS preview 的安装。

让我们分解每个管道中的任务。

管线任务

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

summary of completed github actions pipeline

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

summary of completed azure devops pipeline

两个管道的共同任务是Setup .NET SDK VersionInstall .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-maccatalystnet6.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 DevOpsAzure 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-androidnet6.0-windows10.0.19041.0

对于Github Actions ,发布工件的步骤保持不变,GitHub ActionUpload a Build ArtifactMacWindows 代理都有效。

对于Azure Devops复制文件任务发布构建工件任务在MacWindows 代理上都可以工作。

对于Windows ,有两个额外的任务。第一个是存储和解码签名证书文件。

GitHub Actions ,它的过程如下:

  1. 创建的签名证书文件需要被编码为Base64。这可以用certutil ,在Windows ,按照文档的要求进行。在Mac ,你可以运行base64 -i <cert_file>.pfx | pbcopy
  2. Base64编码的字符串需要按照GitHub Actions加密的秘密文档来存储在GitHub Actions的秘密中。
  3. 在管道任务中对秘密进行解码。

- 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 DevOpsAndroid Signing ,本指南一步一步地展示了如何签署你的Android应用程序。它显示了如何安全地上传签名文件,然后如何配置Android签名Azure DevOps 任务。

总结

我希望这能帮助你开始使用GitHub ActionsAzure DevOps 为.NET MAUI应用程序设置DevOps。yaml 文件的样本。

请在dotnet/maui-samples查看更多的样本。请尝试使用.NET MAUI,提交问题,或在dot.net/maui上了解更多信息!