WinUI 앱에 대한 연속 통합 설정

GitHub Actions를 사용하여 WinUI 프로젝트에 대한 연속 통합 빌드를 설정할 수 있습니다. 이 문서에서는 이 작업을 수행하는 다양한 방법을 살펴보겠습니다. 다른 빌드 시스템과 통합할 수 있도록 명령줄을 사용하여 이러한 작업을 수행하는 방법도 설명합니다.

필수 조건

1단계: 인증서 설정

MSIX 앱을 설치하려면 서명해야 합니다. 인증서가 이미 있는 경우 이 단계를 건너뛸 수 있습니다. Visual Studio에서 앱을 열고, WinUI 프로젝트를 마우스 오른쪽 단추로 클릭하고, 패키지 및 게시 ->앱 패키지 만들기를 선택하여 테스트 인증서를 쉽게 만들 수 있습니다.

그런 다음 다음 을 선택하여 서명 방법 선택 페이지로 이동하고 만들기... 단추를 클릭하여 새 인증서를 만듭니다. 게시자 이름을 선택하고 암호 필드를 비워 두고 인증서를 만듭니다.

그런 다음 대화 상자를 닫거나 취소하고 프로젝트에 새 .pfx 파일이 만들어졌는지 확인합니다. MSIX에 서명할 수 있는 인증서입니다.

2단계: 작업 비밀에 인증서 추가

가능한 경우 리포지토리에 인증서를 제출하지 않아야 하며 git은 기본적으로 이를 무시합니다. 인증서와 같은 중요한 파일의 안전한 처리를 관리하기 위해 GitHub는 비밀을 지원합니다.

자동화된 빌드에 대한 인증서를 업로드하려면 다음을 수행합니다.

  1. 인증서를 Base 64 문자열로 인코딩합니다. 인증서가 포함된 디렉터리에 PowerShell을 열고 다음 명령을 실행하여 pfx 파일 이름을 인증서의 파일 이름으로 바꿉니다.
$pfx_cert = Get-Content 'App1_TemporaryKey.pfx' -AsByteStream

[System.Convert]::ToBase64String($pfx_cert) | Out-File 'App1_TemporaryKey_Base64.txt'
  1. GitHub 리포지토리에서 설정 페이지로 이동하고 왼쪽의 비밀 클릭합니다.
  2. 새 리포지토리 비밀을 클릭하고, 그것을 BASE64_ENCODED_PFX로 이름 지정한 후, PowerShell 출력의 텍스트 파일에서 해당 텍스트를 복사하여 비밀 값에 붙여넣습니다.

3단계: 워크플로 설정

그런 다음 리포지토리에서 작업 탭으로 이동하여 새 워크플로를 만듭니다. 워크플로 템플릿 중 하나 대신 직접 워크플로를 설정하는 옵션을 선택합니다.

워크플로 파일에 다음을 복사/붙여넣은 다음 업데이트...

  1. 솔루션 이름으로 Solution_Name 설정
  2. dotnet-version to 8.0.x(또는 프로젝트가 대상으로 하는 다른 .NET 버전)

비고

아티팩트를 업로드하는 단계(아래 마지막 단계)의 경우 빌드 출력이 솔루션이 포함된 폴더에 있지 않으면 env.Solution_Name를 GitHub 작업 영역 폴더인 github.workspace로 바꿉니다.

# 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

4단계: 워크플로 커밋 및 실행 감시!

워크플로 파일을 메인 브랜치에 커밋한 다음, GitHub 리포지토리의 작업 탭으로 이동하여 워크플로가 작동하는 것을 지켜보세요! MSIX 앱이 성공적으로 실행되고, 빌드된 앱을 포함하는 아티팩트가 생성되어야 합니다.

명령줄에서 빌드

명령줄을 사용하거나 다른 CI 시스템을 사용하여 솔루션을 빌드하려면 이러한 인수를 사용하여 MSBuild를 실행합니다. 이 GenerateAppxPackageOnBuild 속성으로 인해 MSIX 패키지가 생성됩니다.

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

1단계: 워크플로 설정

GitHub 리포지토리에서 작업 탭으로 이동하여 새 워크플로를 만듭니다. 워크플로 템플릿 중 하나 대신 직접 워크플로를 설정하는 옵션을 선택합니다.

워크플로 파일에 다음을 복사/붙여넣은 다음 업데이트...

  1. 솔루션 이름으로 Solution_Name 설정
  2. dotnet-version to 8.0.x (또는 프로젝트가 대상으로 하는 .NET 버전)

비고

아티팩트를 업로드하는 단계(아래 마지막 단계)의 경우 빌드 출력이 솔루션이 포함된 폴더에 있지 않으면 env.Solution_Name를 GitHub 작업 영역 폴더인 github.workspace로 바꿉니다.

# 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

2단계: 워크플로 커밋 및 실행 감시!

워크플로 파일을 메인 브랜치에 커밋한 다음, GitHub 리포지토리의 작업 탭으로 이동하여 워크플로가 작동하는 것을 지켜보세요! 성공적으로 실행되어 빌드된 앱을 포함하는 아티팩트가 생성되어야 합니다.

명령줄에서 빌드

명령줄을 사용하거나 다른 CI 시스템을 사용하여 솔루션을 빌드하려면 인수를 사용하여 MSBuild를 /t:Publish 실행합니다.

Azure Pipelines

팀에서 Azure DevOps 사용하는 경우 Azure Pipelines 사용하여 WinUI 3 앱을 빌드할 수 있습니다. 다음 YAML 파이프라인은 Windows 에이전트에 패키지된 MSIX WinUI 앱을 빌드합니다.

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'

비고

패키지되지 않은 빌드의 경우 MSBuild 인수를 /p:Appx* 제거하고 대신 사용합니다 dotnet publishVSBuild. 자세한 내용은 위의 명령줄 섹션을 참조하세요.

파이프라인에서 MSIX 패키지에 서명하려면 인증서를 Azure Pipelines 보안 파일에 저장하고 DownloadSecureFile 작업을 사용하여 빌드 중에 액세스합니다.

Important

서명 인증서 또는 해당 암호를 소스 제어에 저장하지 마세요. 인증서 암호에는 파이프라인 비밀 변수를 사용하고, 인증서 자체에는 Azure Pipelines Secure Files를 사용하세요.