Konfigurowanie ciągłej integracji dla aplikacji WinUI

Za pomocą funkcji GitHub Actions można skonfigurować kompilacje ciągłej integracji dla projektów WinUI. W tym artykule przyjrzymy się różnym sposobom tego wykonania. Pokażemy również, jak wykonać te zadania przy użyciu wiersza polecenia, aby umożliwić integrację z dowolnym innym systemem kompilacji.

Wymagania wstępne

Krok 1. Konfigurowanie certyfikatu

Aby można było zainstalować aplikacje MSIX, należy się zalogować. Jeśli masz już certyfikat, możesz pominąć ten krok. Certyfikat testowy można łatwo utworzyć, otwierając aplikację w programie Visual Studio, klikając prawym przyciskiem myszy projekt WinUI, a następnie wybierając pozycję Package and Publish -> (Utwórz pakiety aplikacji).

Następnie wybierz przycisk Dalej , aby przejść do strony Wybierz metodę podpisywania , a następnie kliknij przycisk Utwórz... w celu utworzenia nowego certyfikatu. Wybierz nazwę wydawcy i zostaw pole hasła puste, a następnie utwórz certyfikat.

Następnie zamknij/anuluj okno dialogowe i zwróć uwagę, że w projekcie został utworzony nowy plik pfx . Jest to certyfikat, za pomocą którego możesz podpisać plik MSIX!

Krok 2: Dodaj swój certyfikat do tajnych danych Akcji

Należy unikać przesyłania certyfikatów do repozytorium, jeśli jest to możliwe, a narzędzie Git domyślnie je ignoruje. Aby bezpiecznie zarządzać poufnymi plikami, takimi jak certyfikaty, GitHub obsługuje tajne dane .

Aby przesłać certyfikat dla kompilacji automatycznej:

  1. Zakoduj certyfikat jako ciąg base 64: Otwórz program PowerShell w katalogu zawierającym certyfikat i wykonaj następujące polecenie, zastępując nazwę pliku pfx nazwą pliku certyfikatu.
$pfx_cert = Get-Content 'App1_TemporaryKey.pfx' -AsByteStream

[System.Convert]::ToBase64String($pfx_cert) | Out-File 'App1_TemporaryKey_Base64.txt'
  1. W repozytorium GitHub przejdź do strony Ustawienia i kliknij Sekrety po lewej stronie.
  2. Kliknij nowy sekret repozytorium, nadaj mu nazwę BASE64_ENCODED_PFXi skopiuj i wklej tekst z pliku tekstowego w wyjściu programu PowerShell do wartości sekretu.

Krok 3. Konfigurowanie przepływu pracy

Następnie w repozytorium przejdź do karty Akcje i utwórz nowy przepływ pracy. Wybierz opcję samodzielne skonfigurowanie przepływu pracy zamiast jednego z szablonów przepływu pracy.

Skopiuj/wklej następujący kod do pliku przepływu pracy, a następnie zaktualizuj...

  1. Solution_Name do nazwy twojego rozwiązania
  2. dotnet-version to 8.0.x (lub w zależności od wersji docelowej projektu .NET)

Uwaga / Notatka

Aby wykonać krok przekazywania artefaktu (ostatni krok poniżej), jeśli dane wyjściowe kompilacji nie znajdują się w folderze zawierającym rozwiązanie, zastąp env.Solution_Name na github.workspace (folder Obszar roboczy funkcji 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

Krok 4. Zatwierdzanie przepływu pracy i obserwowanie jego uruchomienia.

Zatwierdź plik przepływu pracy w gałęzi głównej, a następnie przejdź do karty Akcje w repozytorium GitHub i obejrzyj przebieg przepływu pracy. Powinno ono zostać pomyślnie uruchomione i wygenerować artefakty zawierające skompilowana aplikację MSIX.

Budowanie z wiersza polecenia

Jeśli chcesz skompilować rozwiązanie przy użyciu wiersza polecenia lub dowolnego innego systemu ciągłej integracji, uruchom program MSBuild z tymi argumentami. Właściwość GenerateAppxPackageOnBuild powoduje wygenerowanie pakietu MSIX.

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

Krok 1. Konfigurowanie przepływu pracy

W repozytorium GitHub przejdź do karty Akcje i utwórz nowy przepływ pracy. Wybierz opcję samodzielne skonfigurowanie przepływu pracy zamiast jednego z szablonów przepływu pracy.

Skopiuj/wklej następujący kod do pliku przepływu pracy, a następnie zaktualizuj...

  1. Solution_Name do nazwy twojego rozwiązania
  2. dotnet-version do 8.0.x (lub dowolnej wersji platformy .NET, na którą jest przeznaczony projekt)

Uwaga / Notatka

Aby wykonać krok przekazywania artefaktu (ostatni krok poniżej), jeśli dane wyjściowe kompilacji nie znajdują się w folderze zawierającym rozwiązanie, zastąp env.Solution_Name na github.workspace (folder Obszar roboczy funkcji 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

Krok 2. Zatwierdzanie przepływu pracy i obserwowanie jego uruchomienia.

Zatwierdź plik przepływu pracy w gałęzi głównej, a następnie przejdź do karty Akcje w repozytorium GitHub i obejrzyj przebieg przepływu pracy. Powinno ono zostać pomyślnie uruchomione i wygenerować artefakty zawierające Twoją skompilowaną aplikację.

Budowanie z wiersza polecenia

Jeśli chcesz skompilować rozwiązanie przy użyciu wiersza polecenia lub użyć dowolnego innego systemu ciągłej integracji, uruchom program MSBuild z argumentem /t:Publish .

Azure Pipelines

Jeśli twój zespół korzysta z Azure DevOps, możesz tworzyć aplikacje WinUI 3 za pomocą Azure Pipelines. Następujący potok YAML tworzy spakowaną aplikację MSIX WinUI przy użyciu agenta 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'

Uwaga / Notatka

W przypadku kompilacji bez pakietu usuń argumenty MSBuild /p:Appx* i użyj dotnet publish zamiast VSBuild. Aby uzyskać szczegółowe informacje, zobacz sekcję wiersza polecenia powyżej.

Do podpisywania pakietów MSIX w potoku zapisz certyfikat w plikach bezpiecznych usługi Azure Pipelines i użyj zadania DownloadSecureFile, aby uzyskać do niego dostęp podczas kompilacji.

Important

Nigdy nie przechowuj certyfikatów podpisywania ani ich haseł w systemie kontroli wersji. Użyj zmiennych tajnych potoku do hasła certyfikatu oraz Azure Pipelines Secure Files dla samego certyfikatu.