Configurar a integração contínua para seu aplicativo WinUI

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

Pré-requisitos

Etapa 1: Configurar seu certificado

Os aplicativos MSIX devem ser assinados para serem instalados. Se você já tiver um certificado, ignore esta etapa. Você pode criar facilmente um certificado de teste abrindo seu aplicativo no Visual Studio, clicando com o botão direito do mouse em seu projeto WinUI e selecionando Pacote e Publicar ->Criar Pacotes de Aplicativos.

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

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

Etapa 2: Adicionar seu certificado aos segredos do Actions

Você deve evitar enviar certificados ao repositório, se possível, e o Git os ignorará por padrão. Para gerenciar o tratamento seguro de arquivos confidenciais, como certificados, o GitHub dá suporte a segredos.

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

  1. Codificar 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 um nome BASE64_ENCODED_PFX e copie/cole o texto do arquivo de texto da saída do PowerShell no 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 configurar um fluxo de trabalho 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 seu projeto usa como destino)

Observação

Para a etapa de upload do artefato (a última etapa abaixo), se a saída da build não for armazenada em uma pasta que contenha sua solução, substitua env.Solution_Name por github.workspace (a pasta do espaço de trabalho das 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

Etapa 4: Confirmar o fluxo de trabalho e vê-lo ser executado!

Confirme o arquivo de fluxo de trabalho no branch principal e vá para a guia Ações no repositório GitHub e assista à execução do fluxo de trabalho! Ele deve executar com êxito e produzir artefatos que contenham seu aplicativo MSIX criado.

Compilação na linha de comando

Se você quiser criar sua solução usando a linha de comando ou usando qualquer outro sistema de 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 GitHub, vá para a guia Ações e crie um novo fluxo de trabalho. Escolha a opção configurar um fluxo de trabalho 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 seu projeto usa como destino)

Observação

Para a etapa de upload do artefato (a última etapa abaixo), se a saída da build não for armazenada em uma pasta que contenha sua solução, substitua env.Solution_Name por github.workspace (a pasta do espaço de trabalho das 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

Etapa 2: Confirmar o fluxo de trabalho e assistir à sua execução!

Confirme o arquivo de fluxo de trabalho no branch principal e vá para a guia Ações no repositório GitHub e assista à execução do fluxo de trabalho! Ele deve executar com êxito e produzir artefatos que contenham seu aplicativo criado.

Compilação na linha de comando

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

Azure Pipelines

Se sua equipe usar Azure DevOps, você poderá criar aplicativos WinUI 3 com Azure Pipelines. O pipeline yaml a seguir cria um aplicativo MSIX WinUI empacotado em um agente de 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 builds não empacotados, remova os argumentos do /p:Appx* MSBuild e use dotnet publish em vez de VSBuild. Consulte a seção de linha de comando acima para obter detalhes.

Para assinar pacotes MSIX em um pipeline, armazene seu certificado em arquivos seguros do Azure Pipelines e use a tarefa DownloadSecureFile para acessá-lo durante a compilação.

Importante

Nunca armazene certificados de assinatura ou suas senhas no controle do código-fonte. Use variáveis secretas do pipeline para a senha do certificado e arquivos seguros do Azure Pipelines para o certificado em si.