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 つではなく 、自分でワークフローを設定 するオプションを選択します。

次のコードをワークフロー ファイルにコピー/貼り付け、更新します。...

  1. ソリューションの名前として Solution_Name を設定する
  2. dotnet-version8.0.x に変更します(または、プロジェクトの対象となる .NET バージョンに変更します)

成果物をアップロードする手順 (以下の最後の手順) では、ビルド出力がソリューションを含むフォルダーに格納されていない場合は、 env.Solution_Namegithub.workspace (GitHub actions Workspace フォルダー) に置き換えます。

# 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 アプリを含む成果物が生成される必要があります。

コマンド ラインからのビルド

コマンド ラインを使用するか、他の CI システムを使用してソリューションをビルドする場合は、これらの引数を指定して MSBuild を実行します。 GenerateAppxPackageOnBuild プロパティを使用すると、MSIX パッケージが生成されます。

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

手順 1: ワークフローを設定する

GitHub リポジトリで、[アクション] タブに移動し、新しいワークフローを作成します。 ワークフロー テンプレートの 1 つではなく 、自分でワークフローを設定 するオプションを選択します。

次のコードをワークフロー ファイルにコピー/貼り付け、更新します。...

  1. ソリューションの名前として Solution_Name を設定する
  2. dotnet-version から 8.0.x へ(または、プロジェクトの対象となる任意の .NET バージョン)

成果物をアップロードする手順 (以下の最後の手順) では、ビルド出力がソリューションを含むフォルダーに格納されていない場合は、 env.Solution_Namegithub.workspace (GitHub actions Workspace フォルダー) に置き換えます。

# 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 パイプラインは、パッケージ化された MSIX WinUI アプリを Windows エージェントにビルドします。

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 publishの代わりにVSBuildを使用します。 詳細については、上記のコマンド ライン セクションを参照してください。

パイプラインで MSIX パッケージに署名するには、証明書をセキュリティで保護されたファイルAzure Pipelines格納し、DownloadSecureFile タスクを使用してビルド中にアクセスします。

Important

署名証明書またはそのパスワードをソース管理に保存しないでください。 証明書のパスワードにはパイプラインのシークレット変数を使用し、証明書自体には Azure Pipelines の Secure Files を使用します。