Configurer l’intégration continue pour votre application WinUI

Vous pouvez utiliser GitHub Actions pour configurer des builds d’intégration continue pour les projets WinUI. Dans cet article, nous allons examiner différentes façons de procéder. Nous allons également vous montrer comment effectuer ces tâches à l’aide de la ligne de commande afin que vous puissiez les intégrer avec n’importe quel autre système de construction.

Conditions préalables

Étape 1 : Configurer votre certificat

Les applications MSIX doivent être connectées pour être installées. Si vous disposez déjà d’un certificat, vous pouvez ignorer cette étape. Vous pouvez facilement créer un certificat de test en ouvrant votre application dans Visual Studio, en cliquant avec le bouton droit sur votre projet WinUI, puis en sélectionnant Package et Publier ->Créer des packages d’application.

Sélectionnez ensuite suivant pour accéder à la page Sélectionner la méthode de signature, puis cliquez sur le bouton Créer... pour créer un certificat. Choisissez le nom de l’éditeur et laissez le champ de mot de passe vide, puis créez le certificat.

Ensuite, fermez/annulez les dialogues et notez qu’un nouveau fichier .pfx a été créé dans votre projet. Il s’agit du certificat avec lequel vous pouvez signer votre MSIX !

Étape 2 : Ajouter votre certificat aux secrets d'Actions

Vous devez éviter d’envoyer des certificats à votre dépôt si possible, et git les ignore par défaut. Pour gérer la gestion sécurisée des fichiers sensibles tels que les certificats, GitHub prend en charge secrets.

Pour charger un certificat pour votre build automatisée :

  1. encoder votre certificat en tant que chaîne base 64: ouvrez PowerShell dans le répertoire qui contient votre certificat et exécutez la commande suivante, en remplaçant le nom de fichier pfx par le nom de fichier de votre certificat.
$pfx_cert = Get-Content 'App1_TemporaryKey.pfx' -AsByteStream

[System.Convert]::ToBase64String($pfx_cert) | Out-File 'App1_TemporaryKey_Base64.txt'
  1. Dans votre référentiel GitHub, accédez à la page Paramètres et cliquez sur Secrets sur la gauche.
  2. Cliquez sur nouveau secret de référentiel, nommez-le BASE64_ENCODED_PFX, puis copiez/collez le texte du fichier texte dans la sortie PowerShell dans la valeur secrète.

Étape 3 : Configurer votre flux de travail

Ensuite, dans votre référentiel, accédez à l’onglet Actions et créez un flux de travail. Choisissez l'option de configurer un flux de travail vous-même au lieu de l’un des modèles de flux de travail.

Copiez/collez les éléments suivants dans votre fichier de flux de travail, puis mettez à jour...

  1. Solution_Name comme nom de votre solution
  2. dotnet-version vers 8.0.x (ou selon la version .NET cible de votre projet)

Remarque

Pour l’étape de chargement de l’artefact (la dernière étape ci-dessous), si la sortie de build ne se trouve pas dans un dossier qui contient votre solution, remplacez env.Solution_Name par github.workspace (dossier Espace de travail Actions GitHub).

# 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

Étape 4 : Validez le flux de travail et regardez-le s’exécuter !

Validez le fichier de flux de travail dans votre branche principale, puis accédez à l’onglet Actions de votre dépôt GitHub et regardez l’exécution de votre flux de travail ! Elle doit s’exécuter et produire des éléments qui contiennent votre application MSIX créée.

Créer un ensemble x86 et x64 pour le Microsoft Store

Le flux de travail précédent utilise une matrice pour créer des packages x86 et x64 distincts pour le chargement indépendant. Pour créer un fichier de chargement de package pour le Microsoft Store, générez les deux architectures dans un seul appel MSBuild à la place. La AppxBundlePlatforms propriété spécifie les architectures du bundle, AppxBundle=Always crée le bundle et UapAppxPackageBuildMode=StoreUpload crée le .msixupload fichier.

Utilisez le flux de travail suivant au lieu du flux de travail à l’étape 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/**'

La Platform=x86 propriété sélectionne la configuration de la solution qui appelle la cible d’empaquetage. AppxBundlePlatforms=x86|x64 contrôle les architectures qui ciblent les builds et les inclut dans le bundle. Le Microsoft Store signe le package après l’envoi. Cet exemple désactive donc la signature du package.

Avant de charger le .msixupload fichier, vérifiez que l’identité du package dans votre manifeste correspond à l’identité que l’Espace partenaires attribue à votre application. Pour connaître les étapes restantes de soumission, consultez Créer une soumission d’application.

Compilation à partir de la ligne de commande

Si vous souhaitez générer votre solution à l’aide de la ligne de commande ou à l’aide d’un autre système CI, exécutez MSBuild avec ces arguments. La propriété GenerateAppxPackageOnBuild entraîne la génération du package MSIX.

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

Pour créer le fichier de chargement de package x86 et x64 pour l’Microsoft Store à partir de la ligne de commande, exécutez :

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

Étape 1 : Configurer votre flux de travail

Dans votre dépôt GitHub, accédez à l’onglet Actions et créez un flux de travail. Choisissez l'option de configurer un flux de travail vous-même au lieu de l’un des modèles de flux de travail.

Copiez/collez les éléments suivants dans votre fichier de flux de travail, puis mettez à jour...

  1. Solution_Name comme nom de votre solution
  2. dotnet-version vers 8.0.x (ou selon la version .NET cible de votre projet)

Remarque

Pour l’étape de chargement de l’artefact (la dernière étape ci-dessous), si la sortie de build ne se trouve pas dans un dossier qui contient votre solution, remplacez env.Solution_Name par github.workspace (dossier Espace de travail Actions GitHub).

# 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

Étape 2 : Validez le flux de travail et regardez-le s’exécuter !

Validez le fichier de flux de travail dans votre branche principale, puis accédez à l’onglet Actions de votre dépôt GitHub et regardez l’exécution de votre flux de travail ! Elle doit s’exécuter avec succès et produire des artéfacts qui contiennent votre application construite.

Compilation à partir de la ligne de commande

Si vous souhaitez générer votre solution à l’aide de la ligne de commande ou à l’aide d’un autre système CI, exécutez MSBuild avec l’argument /t:Publish.

Azure Pipelines

Si votre équipe utilise Azure DevOps, vous pouvez créer des applications WinUI 3 avec Azure Pipelines. Le pipeline YAML suivant génère une application MSIX WinUI empaquetée sur un agent 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'

Remarque

Pour les versions non empaquetées, supprimez les arguments MSBuild /p:Appx* et utilisez dotnet publish au lieu de VSBuild. Pour plus d’informations, consultez la section de ligne de commande ci-dessus.

Pour signer des packages MSIX dans un pipeline, stockez votre certificat dans Azure Pipelines fichiers sécurisés et utilisez la tâche DownloadSecureFile pour y accéder pendant la génération.

Important

Ne stockez jamais les certificats de signature ou leurs mots de passe dans le contrôle de code source. Utilisez des variables secrètes de pipeline pour le mot de passe du certificat et Azure Pipelines Fichiers sécurisés pour le certificat lui-même.