Configure integração contínua para a sua aplicação WinUI

Pode usar o GitHub Actions para configurar compilações de integração contínua para projetos WinUI. Neste artigo, veremos diferentes maneiras de fazer isso. Também mostraremos como executar essas tarefas usando a linha de comando para que você possa se integrar com qualquer outro sistema de compilação.

Pré-requisitos

Etapa 1: configurar o certificado

Os aplicativos MSIX devem estar assinados para serem instalados. Se já tiver um certificado, pode ignorar este passo. Pode facilmente criar um certificado de teste abrindo a sua aplicação no Visual Studio, clicando com o botão direito no seu projeto WinUI e selecionando Pacote e Publicar ->Criar Pacotes de Aplicação.

Em seguida, selecione Avançar para ir para a página Selecionar método de assinatura e clique no botão Criar... para criar um novo certificado. Escolha o nome do editor e deixe o campo de senha em branco, e crie o certificado.

Em seguida, feche/cancele as caixas de diálogo e observe que um novo arquivo de .pfx foi criado no seu projeto. Este é o certificado com o qual você pode assinar seu MSIX!

Etapa 2: Adicionar o seu certificado nos segredos do GitHub Actions.

Você deve evitar enviar certificados para seu repositório, se possível, e o git os ignora por padrão. Para gerenciar o manuseio seguro de arquivos confidenciais, como certificados, o GitHub suporta segredos.

Para carregar um certificado para sua compilação automatizada:

  1. Codifique seu certificado como uma cadeia de caracteres Base 64: abra o PowerShell no diretório que contém seu certificado e execute o seguinte comando, substituindo o nome do arquivo pfx pelo nome do arquivo do certificado.
$pfx_cert = Get-Content 'App1_TemporaryKey.pfx' -AsByteStream

[System.Convert]::ToBase64String($pfx_cert) | Out-File 'App1_TemporaryKey_Base64.txt'
  1. No repositório do GitHub, vá para a página Configurações e clique em Segredos à esquerda.
  2. Clique em Novo segredo do repositório, dê-lhe o nome de BASE64_ENCODED_PFXe copie/cole o texto do ficheiro de texto na saída do PowerShell como valor do segredo.

Etapa 3: configurar seu fluxo de trabalho

Em seguida, no repositório, vá para a guia Ações e crie um novo fluxo de trabalho. Escolha a opção de configurar o fluxo de trabalho você mesmo em vez de um dos modelos de fluxo de trabalho.

Copie/cole o seguinte no arquivo de fluxo de trabalho e atualize...

  1. Solution_Name para o nome da sua solução
  2. dotnet-version para 8.0.x (ou qualquer versão do .NET que o seu projeto visa)

Observação

Para a etapa de upload do artefato (a última etapa abaixo), se a saída da compilação não chegar a uma pasta que contenha sua solução, substitua env.Solution_Name por github.workspace (a pasta Espaço de trabalho de ações do 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

Passo 4: Confirme o fluxo de trabalho e veja-o correr!

Confirme o arquivo de fluxo de trabalho em sua ramificação principal e, em seguida, vá para a guia Ações no repositório do GitHub e veja seu fluxo de trabalho ser executado! Deve executar com sucesso e produzir artefatos que contenham o seu aplicativo MSIX compilado.

Construindo a partir da linha de comando

Se você quiser criar sua solução usando a linha de comando ou usando qualquer outro sistema CI, execute o MSBuild com esses argumentos. A GenerateAppxPackageOnBuild propriedade faz com que o pacote MSIX seja gerado.

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

Etapa 1: configurar seu fluxo de trabalho

No repositório do GitHub, vá para a guia Ações e crie um novo fluxo de trabalho. Escolha a opção de configurar o fluxo de trabalho você mesmo em vez de um dos modelos de fluxo de trabalho.

Copie/cole o seguinte no arquivo de fluxo de trabalho e atualize...

  1. Solution_Name para o nome da sua solução
  2. dotnet-version para 8.0.x (ou qualquer versão do .NET que o seu projeto visa)

Observação

Para a etapa de upload do artefato (a última etapa abaixo), se a saída da compilação não chegar a uma pasta que contenha sua solução, substitua env.Solution_Name por github.workspace (a pasta Espaço de trabalho de ações do 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

Passo 2: Confirme o fluxo de trabalho e veja-o correr!

Confirme o arquivo de fluxo de trabalho em sua ramificação principal e, em seguida, vá para a guia Ações no repositório do GitHub e veja seu fluxo de trabalho ser executado! Deve executar com sucesso e produzir artefactos que contenham o seu aplicativo criado.

Construindo a partir da linha de comando

Se você quiser criar sua solução usando a linha de comando ou usando qualquer outro sistema CI, execute o MSBuild com o /t:Publish argumento.

Azure Pipelines

Se a sua equipa usar Azure DevOps, pode construir aplicações WinUI 3 com Azure Pipelines. O seguinte pipeline YAML constrói uma aplicação MSIX WinUI empacotada num agente 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'

Observação

Para compilações não empacotadas, remova os argumentos do MSBuild /p:Appx* e utilize dotnet publish em vez de VSBuild. Consulte a secção da linha de comandos acima para mais detalhes.

Para assinar pacotes MSIX num pipeline, armazene o seu certificado em ficheiros seguros do Azure Pipelines e use a tarefa DownloadSecureFile para aceder a ele durante a compilação.

Important

Nunca guarde certificados de assinatura nem as respetivas palavras-passe no controlo de código-fonte. Use variáveis secretas de pipeline para a palavra-passe do certificado e Azure Pipelines Secure Files para o próprio certificado.