為您的 WinUI 應用程式設定持續整合

你可以使用 GitHub Actions 為 WinUI 專案設定持續整合建置。 在本文中,我們將探討執行此作業的不同方式。 我們也會示範如何使用命令行來執行這些工作,以便與任何其他建置系統整合。

先決條件

步驟 1:設定您的憑證

必須簽署 MSIX 應用程式才能安裝。 如果您已經有憑證,您可以略過此步驟。 你可以在 Visual Studio 開啟應用程式,右鍵點擊 WinUI 專案,選擇 「套件與發佈 ->建立應用程式套件」來輕鬆建立測試憑證。

然後選取 [下一步] 移動到 [選取簽署方法] 頁面,然後按下 [建立...] 按鈕以建立新的憑證。 選擇發行者名稱和 將密碼欄位保留空白,然後建立憑證。

然後,關閉/取消對話框,並注意到已在專案中建立新的 .pfx 檔案。 這是您可以用來簽署 MSIX 的憑證!

步驟 2:將憑證新增至動作秘密

如果可能的話,您應該避免將憑證提交至存放庫,而 Git 預設會忽略這些憑證。 為了管理憑證等機密檔案的安全處理,GitHub 支援 秘密。

若要上傳自動化組建的憑證:

  1. 將憑證編碼為Base 64字串:將PowerShell開啟至包含憑證的目錄,然後執行下列命令,以憑證的檔名取代 pfx 檔名。
$pfx_cert = Get-Content 'App1_TemporaryKey.pfx' -AsByteStream

[System.Convert]::ToBase64String($pfx_cert) | Out-File 'App1_TemporaryKey_Base64.txt'
  1. 在您的 GitHub 存放庫中,移至 [設定] 頁面,然後在左側單擊 [機密]。
  2. 單擊 新增存放庫密碼,將它命名為 BASE64_ENCODED_PFX,然後將 PowerShell 輸出中文本檔中的文字複製並貼上到機密值。

步驟 3:設定工作流程

接下來,在您的存放庫中,移至 [動作] 索引標籤並建立新的工作流程。 選擇 自行設定工作流程 選項,而不是其中一個工作流程範本。

將下列內容複製/貼到您的工作流程檔案中,然後更新...

  1. Solution_Name 您的解決方案名稱
  2. dotnet-version 至 8.0.x(或您的專案所針對的 .NET 版本)

備註

針對上傳構建工件的步驟(下面的最後一個步驟),如果構建輸出未落入包含您解決方案的資料夾內,請將 env.Solution_Name 取代為 github.workspace (GitHub Actions 工作區資料夾)。

# This workflow will build, sign, and package a WinUI MSIX desktop application
# built on .NET.

name: WinUI MSIX app

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:

  build:

    strategy:
      matrix:
        configuration: [Release]
        platform: [x64, x86]

    runs-on: windows-latest  # For a list of available runner types, refer to
                             # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on

    env:
      Solution_Name: your-solution-name                         # Replace with your solution name, i.e. App1.sln.

    steps:
    - name: Checkout
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    # Install the .NET workload
    - name: Install .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: 8.0.x

    # Add  MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
    - name: Setup MSBuild.exe
      uses: microsoft/setup-msbuild@v2

    # Restore the application to populate the obj folder with RuntimeIdentifiers
    - name: Restore the application
      run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
      env:
        Configuration: ${{ matrix.configuration }}

    # Decode the base 64 encoded pfx and save the Signing_Certificate
    - name: Decode the pfx
      run: |
        $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.BASE64_ENCODED_PFX }}")
        $certificatePath = "GitHubActionsWorkflow.pfx"
        [IO.File]::WriteAllBytes("$certificatePath", $pfx_cert_byte)

    # Create the app package by building and packaging the project
    - name: Create the app package
      run: msbuild $env:Solution_Name /p:Configuration=$env:Configuration /p:Platform=$env:Platform /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:AppxPackageDir="$env:Appx_Package_Dir" /p:GenerateAppxPackageOnBuild=true
      env:
        Appx_Bundle: Never
        Appx_Package_Build_Mode: SideloadOnly
        Appx_Package_Dir: Packages\
        Configuration: ${{ matrix.configuration }}
        Platform: ${{ matrix.platform }}

    # Remove the pfx
    - name: Remove the pfx
      run: Remove-Item -path GitHubActionsWorkflow.pfx

    # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact
    - name: Upload MSIX package
      uses: actions/upload-artifact@v4
      with:
        name: MSIX Package - ${{ matrix.platform }}
        path: ${{ env.Solution_Name }}\\Packages

步驟 4:認可工作流程並監看它執行!

將工作流程文件提交到您的主要分支,然後前往 GitHub 存放庫上的 [動作] 標籤,並查看工作流程的執行! 它應該會成功執行併產生包含您建置 MSIX 應用程式的成品。

為 Microsoft Store 打造 x86 和 x64 套件

前述工作流程使用矩陣來建立獨立的 x86 與 x64 套件以進行側載。 若要建立一個 Microsoft Store 的套件上傳檔案,請在單一 MSBuild 調用中建置兩種架構。 屬性 AppxBundlePlatforms 指定了 bundle 中的架構、 AppxBundle=Always 建立 bundle 以及 UapAppxPackageBuildMode=StoreUpload 建立 .msixupload 檔案。

請使用以下工作流程,取代步驟3的工作流程:

name: WinUI Microsoft Store package

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: windows-latest

    env:
      Solution_Name: your-solution-name.sln
      Configuration: Release
      Bundle_Platforms: x86|x64
      Appx_Package_Dir: Packages\

    steps:
    - name: Checkout
      uses: actions/checkout@v4

    - name: Install .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: 8.0.x

    - name: Setup MSBuild.exe
      uses: microsoft/setup-msbuild@v2

    - name: Restore the application
      run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration

    - name: Create the Store package
      run: >
        msbuild $env:Solution_Name
        /p:Configuration=$env:Configuration
        /p:Platform=x86
        /p:AppxBundlePlatforms="$env:Bundle_Platforms"
        /p:AppxBundle=Always
        /p:UapAppxPackageBuildMode=StoreUpload
        /p:AppxPackageDir="$env:Appx_Package_Dir"
        /p:AppxPackageSigningEnabled=false
        /p:GenerateAppxPackageOnBuild=true

    - name: Upload the Store package
      uses: actions/upload-artifact@v4
      with:
        name: Microsoft Store package
        path: '**/Packages/**'

屬性 Platform=x86 選擇了呼叫封裝目標的解決方案配置。 AppxBundlePlatforms=x86|x64 控制該目標要建置哪些架構,並將其包含在套件中。 Microsoft Store 在提交後會簽署套件,因此此範例會關閉套件簽署。

在上傳 .msixupload 檔案前,請確認你的清單中的包裹身份與合作夥伴中心指派給你的應用程式的身份相符。 關於剩餘的提交步驟,請參見 建立應用程式提交。

從指令列建置

如果您想要使用命令行或任何其他 CI 系統來建置解決方案,請使用這些自變數執行 MSBuild。 GenerateAppxPackageOnBuild 屬性會導致產生 MSIX 套件。

/p:AppxPackageDir="Packages"
/p:UapAppxPackageBuildMode=SideloadOnly
/p:AppxBundle=Never
/p:GenerateAppxPackageOnBuild=true

要從命令列建立 Microsoft Store 的 x86 和 x64 套件上傳檔,請執行:

msbuild YourSolution.sln `
    /p:Configuration=Release `
    /p:Platform=x86 `
    /p:AppxBundlePlatforms="x86|x64" `
    /p:AppxBundle=Always `
    /p:UapAppxPackageBuildMode=StoreUpload `
    /p:AppxPackageDir="Packages\" `
    /p:AppxPackageSigningEnabled=false `
    /p:GenerateAppxPackageOnBuild=true

步驟 1:設定您的工作流程

在您的 GitHub 存放庫中,移至 [動作] 索引卷標並建立新的工作流程。 選擇 自行設定工作流程 選項,而不是其中一個工作流程範本。

將下列內容複製/貼到您的工作流程檔案中,然後更新...

  1. Solution_Name 您的解決方案名稱
  2. dotnet-version 至 8.0.x(或您的專案所針對的 .NET 版本)

備註

針對上傳構建工件的步驟(下面的最後一個步驟),如果構建輸出未落入包含您解決方案的資料夾內,請將 env.Solution_Name 取代為 github.workspace (GitHub Actions 工作區資料夾)。

# This workflow will build and publish a WinUI unpackaged desktop application
# built on .NET.

name: WinUI unpackaged app

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:

  build:

    strategy:
      matrix:
        configuration: [Release]
        platform: [x64, x86]

    runs-on: windows-latest  # For a list of available runner types, refer to
                             # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on

    env:
      Solution_Name: your-solution-name                         # Replace with your solution name, i.e. App1.sln.

    steps:
    - name: Checkout
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    # Install the .NET workload
    - name: Install .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: 8.0.x

    # Add  MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
    - name: Setup MSBuild.exe
      uses: microsoft/setup-msbuild@v2

    # Restore the application to populate the obj folder with RuntimeIdentifiers
    - name: Restore the application
      run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
      env:
        Configuration: ${{ matrix.configuration }}

    # Create the app by building and publishing the project
    - name: Create the app
      run: msbuild $env:Solution_Name /t:Publish /p:Configuration=$env:Configuration /p:Platform=$env:Platform
      env:
        Configuration: ${{ matrix.configuration }}
        Platform: ${{ matrix.platform }}

    # Upload the app
    - name: Upload app
      uses: actions/upload-artifact@v4
      with:
        name: Upload app - ${{ matrix.platform }}
        path: ${{ env.Solution_Name }}\\bin

步驟 2:認可工作流程並監看它執行!

將工作流程文件提交到您的主要分支,然後前往 GitHub 存放庫上的 [動作] 標籤,並查看工作流程的執行! 它應該會成功執行併產生包含您建置應用程式的成品。

從指令列建置

如果您想要使用命令行或任何其他 CI 系統來建置解決方案,請使用 /t:Publish 自變數執行 MSBuild。

Azure Pipelines

如果你的團隊使用 Azure DevOps,你可以用 Azure Pipelines 來建置 WinUI 3 應用程式。 以下 YAML 管線在 Windows 代理程式上建置一個封裝的 MSIX WinUI 應用程式:

trigger:
  - main

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'x64'
  buildConfiguration: 'Release'

steps:
- task: UseDotNet@2
  displayName: 'Install .NET SDK'
  inputs:
    packageType: 'sdk'
    version: '8.0.x'

- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  displayName: 'Build MSIX package'
  inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    msbuildArgs: |
      /p:AppxBundlePlatforms="$(buildPlatform)"
      /p:AppxPackageDir="$(Build.ArtifactStagingDirectory)\AppxPackages\\"
      /p:AppxBundle=Never
      /p:UapAppxPackageBuildMode=SideloadOnly
      /p:GenerateAppInstallerFile=false

- task: PublishBuildArtifacts@1
  displayName: 'Publish MSIX artifacts'
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)\AppxPackages'
    ArtifactName: 'msix-package'

備註

對於未封裝的建置,移除 /p:Appx* MSBuild 參數,改用 dotnet publishVSBuild取代 。 詳情請參見上方命令列區塊。

在管線中簽署 MSIX 套件時,請將憑證存放在 Azure Pipelines 的安全檔案中,並在建置過程中使用 DownloadSecureFile 任務存取。

Important

切勿將簽署憑證或其密碼存放在原始碼控制中。 請使用管線祕密變數來儲存憑證密碼,並使用 Azure Pipelines Secure Files 來儲存憑證本身。