Continue integratie instellen voor uw WinUI-app

U kunt GitHub Actions gebruiken om builds voor continue integratie in te stellen voor WinUI-projecten. In dit artikel bekijken we verschillende manieren om dit te doen. We laten u ook zien hoe u deze taken uitvoert met behulp van de opdrachtregel, zodat u kunt integreren met elk ander buildsysteem.

Vereiste voorwaarden

Stap 1: Uw certificaat instellen

MSIX-apps moeten zijn aangemeld om te kunnen worden geïnstalleerd. Als u al een certificaat hebt, kunt u deze stap overslaan. U kunt eenvoudig een testcertificaat maken door uw app te openen in Visual Studio, met de rechtermuisknop op uw WinUI-project te klikken en Package and Publish ->App Packages te selecteren.

Selecteer vervolgens Volgende om naar de pagina Ondertekeningsmethode selecteren te gaan en klik op de knop Maken... om een nieuw certificaat te maken. Kies de naam van de uitgever en laat het wachtwoordveld leeg en maak het certificaat.

Sluit/annuleer vervolgens de dialoogvensters en u ziet dat er een nieuw PFX-bestand in uw project is gemaakt. Dit is het certificaat waarmee u uw MSIX kunt ondertekenen.

Stap 2: Uw certificaat toevoegen aan de geheimen van de acties

U moet indien mogelijk voorkomen dat u certificaten naar uw opslagplaats verzendt, en standaard negeert git ze. GitHub ondersteunt geheimen om de veilige verwerking van gevoelige bestanden, zoals certificaten, te beheren.

Een certificaat uploaden voor uw geautomatiseerde build:

  1. codeer uw certificaat als een Base 64-tekenreeks: Open PowerShell en navigeer naar de map die uw certificaat bevat en voer het volgende commando uit, waarbij u de pfx-bestandsnaam vervangt door de bestandsnaam van uw certificaat.
$pfx_cert = Get-Content 'App1_TemporaryKey.pfx' -AsByteStream

[System.Convert]::ToBase64String($pfx_cert) | Out-File 'App1_TemporaryKey_Base64.txt'
  1. Ga in uw GitHub-opslagplaats naar de pagina Instellingen en klik aan de linkerkant op Geheimen .
  2. Klik op Nieuw opslagplaatsgeheim, geef het BASE64_ENCODED_PFXeen naam en kopieer/plak de tekst uit het tekstbestand in de PowerShell-uitvoer in de geheime waarde.

Stap 3: Uw werkstroom instellen

Ga vervolgens in uw opslagplaats naar het tabblad Acties en maak een nieuwe werkstroom. Kies de optie om zelf een workflow in te stellen in plaats van een van de werkstroomsjablonen.

Kopieer/plak het volgende in uw werkstroombestand en werk vervolgens bij...

  1. Solution_Name naar de naam van uw oplossing
  2. dotnet-version tot 8.0.x (of op welke .NET-versie uw project dan ook is gericht)

Opmerking

Voor de stap omtrent het uploaden van het artefact (de laatste stap hieronder), als de build-uitvoer niet in een map terechtkomt die uw oplossing bevat, vervangt u env.Solution_Name door github.workspace (de GitHub Actions Workspace-map).

# 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

Stap 4: Voer de werkstroom door en bekijk hoe deze wordt uitgevoerd.

Voer het werkstroombestand door naar uw hoofdbranch en ga vervolgens naar het tabblad Acties in uw GitHub-opslagplaats en bekijk hoe uw werkstroom wordt uitgevoerd. Het moet succesvol worden uitgevoerd en artefacten produceren die uw gebouwde MSIX-app bevatten.

Bouw een x86- en x64-bundel voor de Microsoft Store

In de voorgaande werkstroom wordt een matrix gebruikt om afzonderlijke x86- en x64-pakketten te maken voor sideloading. Als u één pakketuploadbestand voor de Microsoft Store wilt maken, bouwt u beide architecturen in één MSBuild-aanroep. De AppxBundlePlatforms eigenschap geeft de architecturen in de bundel op, AppxBundle=Always maakt de bundel en UapAppxPackageBuildMode=StoreUpload maakt het .msixupload bestand.

Gebruik de volgende werkstroom in plaats van de werkstroom in stap 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/**'

De Platform=x86 eigenschap selecteert de oplossingsconfiguratie die het verpakkingsdoel aanroept. AppxBundlePlatforms=x86|x64 bepaalt welke architecturen dat doel bouwt en in de bundel opneemt. De Microsoft Store ondertekent het pakket na indiening, dus in dit voorbeeld wordt pakketondertekening uitgeschakeld.

Voordat u het .msixupload bestand uploadt, moet u ervoor zorgen dat de pakketidentiteit in uw manifest overeenkomt met de identiteit die partnercentrum aan uw app toewijst. Zie Een app-inzending maken voor de resterende stappen voor verzending.

Bouwen vanaf de command line

Als u uw oplossing wilt bouwen met behulp van de opdrachtregel of met behulp van een ander CI-systeem, voert u MSBuild uit met deze argumenten. De GenerateAppxPackageOnBuild eigenschap zorgt ervoor dat het MSIX-pakket wordt gegenereerd.

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

Als u het uploadbestand voor het x86- en x64-pakket voor de Microsoft Store wilt maken vanaf de opdrachtregel, voert u het volgende uit:

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

Stap 1: Uw werkstroom instellen

Ga in uw GitHub-opslagplaats naar het tabblad Acties en maak een nieuwe werkstroom. Kies de optie om zelf een workflow in te stellen in plaats van een van de werkstroomsjablonen.

Kopieer/plak het volgende in uw werkstroombestand en werk vervolgens bij...

  1. Solution_Name naar de naam van uw oplossing
  2. dotnet-version tot 8.0.x (of op welke .NET-versie uw project dan ook is gericht)

Opmerking

Voor de stap omtrent het uploaden van het artefact (de laatste stap hieronder), als de build-uitvoer niet in een map terechtkomt die uw oplossing bevat, vervangt u env.Solution_Name door github.workspace (de GitHub Actions Workspace-map).

# 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

Stap 2: Voer de werkstroom door en bekijk hoe deze wordt uitgevoerd.

Voer het werkstroombestand door naar uw hoofdbranch en ga vervolgens naar het tabblad Acties in uw GitHub-opslagplaats en bekijk hoe uw werkstroom wordt uitgevoerd. Het zou succesvol moeten draaien en artefacten produceren die uw gebouwde app bevatten.

Bouwen vanaf de command line

Als u uw oplossing wilt bouwen met behulp van de opdrachtregel of met behulp van een ander CI-systeem, voert u MSBuild uit met het /t:Publish argument.

Azure-pipelines

Als uw team Azure DevOps gebruikt, kunt u WinUI 3-apps bouwen met Azure-pipelines. De volgende YAML-pijplijn bouwt een verpakte MSIX WinUI-app op een Windows-agent:

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'

Opmerking

Voor niet-verpakte builds verwijdert u de MSBuild-argumenten van /p:Appx* en gebruikt u dotnet publish in plaats van VSBuild. Zie de bovenstaande opdrachtregelsectie voor meer informatie.

Voor het ondertekenen van MSIX-pakketten in een pijplijn slaat u uw certificaat op in Azure-pipelines beveiligde bestanden en gebruikt u de DownloadSecureFile-taak om dit tijdens de build te openen.

Important

Sla handtekeningcertificaten of hun wachtwoorden nooit op in broncodebeheer. Gebruik pijplijngeheimvariabelen voor het certificaatwachtwoord en Azure-pipelines Secure Files voor het certificaat zelf.