diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..6e84d49 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,92 @@ +# GitHub Actions Workflows + +This repository contains two GitHub Actions workflows for building the eComBox UWP application. + +## Workflows + +### 1. MSBuild UWP (`msbuild.yml`) + +This is a simple build workflow that compiles the UWP application without packaging. + +**Triggers:** +- Push to `master` branch +- Pull requests to `master` branch + +**What it does:** +- Builds the application for x64 and x86 platforms +- Uploads build artifacts (without signing) + +**Use this workflow for:** Quick CI builds and validation + +### 2. Build UWP MSIX (`dotnet-desktop.yml`) + +This is the full packaging workflow that creates MSIX packages. + +**Triggers:** +- Push to `master` branch +- Pull requests to `master` branch + +**What it does:** +- Builds the UWP application +- Creates MSIX packages +- Signs packages (if certificate secrets are configured) +- Uploads MSIX packages as artifacts + +**Use this workflow for:** Creating distributable MSIX packages + +## Certificate Configuration (Optional) + +To sign your MSIX packages, you need to add the following secrets to your GitHub repository: + +### Step 1: Encode your certificate + +```powershell +$pfx_cert = Get-Content '.\YourCertificate.pfx' -Encoding Byte +[System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt' +``` + +### Step 2: Add secrets to GitHub + +1. Go to your repository Settings → Secrets and variables → Actions +2. Add the following secrets: + - `Base64_Encoded_Pfx`: The base64-encoded certificate string from Step 1 + - `Pfx_Key`: The password for your certificate + +### Without Certificate Secrets + +If you don't configure the certificate secrets, the workflow will: +- Build unsigned MSIX packages (can still be sideloaded for testing) +- OR generate a self-signed test certificate automatically + +## Downloading Build Artifacts + +After a workflow run completes: + +1. Go to the Actions tab in your repository +2. Click on the workflow run +3. Scroll down to the "Artifacts" section +4. Download the artifacts you need: + - `UWP-Build-x64` / `UWP-Build-x86` (from MSBuild workflow) + - `MSIX-Package-x64-Release` (from Build UWP MSIX workflow) + +## Troubleshooting + +### Build fails with "Platform not specified" +- Make sure you're using the correct workflow that specifies platforms + +### "Certificate not found" errors +- Either add the certificate secrets or use the unsigned build option + +### NuGet restore fails +- The workflow should handle this automatically, but check that all package references are valid + +## Local Development + +To build locally, you need: +- Visual Studio 2019 or later with UWP workload +- Windows 10 SDK (version 10.0.18362.0 or later) + +Build command: +```powershell +msbuild eComBox.sln /p:Configuration=Release /p:Platform=x64 +``` diff --git a/.github/workflows/dotnet-desktop.yml b/.github/workflows/dotnet-desktop.yml index 2f06046..86dfdcb 100644 --- a/.github/workflows/dotnet-desktop.yml +++ b/.github/workflows/dotnet-desktop.yml @@ -1,42 +1,7 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# This workflow will build, test, sign and package a WPF or Windows Forms desktop application -# built on .NET Core. -# To learn how to migrate your existing application to .NET Core, -# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework -# -# To configure this workflow: -# -# 1. Configure environment variables -# GitHub sets default environment variables for every workflow run. -# Replace the variables relative to your project in the "env" section below. -# -# 2. Signing -# Generate a signing certificate in the Windows Application -# Packaging Project or add an existing signing certificate to the project. -# Next, use PowerShell to encode the .pfx file using Base64 encoding -# by running the following Powershell script to generate the output string: -# -# $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte -# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt' -# -# Open the output file, SigningCertificate_Encoded.txt, and copy the -# string inside. Then, add the string to the repo as a GitHub secret -# and name it "Base64_Encoded_Pfx." -# For more information on how to configure your signing certificate for -# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing -# -# Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key". -# See "Build the Windows Application Packaging project" below to see how the secret is used. -# -# For more information on GitHub Actions, refer to https://github.com/features/actions -# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications, -# refer to https://github.com/microsoft/github-actions-for-desktop-apps - -name: .NET Core Desktop +# This workflow builds and packages the UWP application as MSIX +# For signing with a certificate, add Base64_Encoded_Pfx and Pfx_Key secrets to the repository + +name: Build UWP MSIX on: push: @@ -50,16 +15,15 @@ jobs: strategy: matrix: - configuration: [Debug, Release] + configuration: [Release] + platform: [x64] - 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 + runs-on: windows-latest env: - Solution_Name: eComBox # Replace with your solution name, i.e. MyWpfApp.sln. - Test_Project_Path: eComBox.csproj # Replace with the path to your test project, i.e. MyWpfApp.Tests\MyWpfApp.Tests.csproj. - Wap_Project_Directory: eComBox.sln # Replace with the Wap project directory relative to the solution, i.e. MyWpfApp.Package. - # Replace with the path to your Wap project, i.e. MyWpf.App.Package\MyWpfApp.Package.wapproj. + Solution_Name: eComBox.sln + Project_Path: eComBox.csproj + AppxPackageDir: AppPackages\ steps: - name: Checkout @@ -67,49 +31,40 @@ jobs: with: fetch-depth: 0 - # Install the .NET Core workload - - name: Install .NET Core - 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 + - name: Setup MSBuild uses: microsoft/setup-msbuild@v2 - # Execute all unit tests in the solution - - name: Execute unit tests - run: dotnet test + - name: Restore NuGet packages + run: nuget restore $env:Solution_Name - # 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 }} + - name: Generate self-signed certificate (if secrets not available) + if: ${{ !secrets.Base64_Encoded_Pfx }} + run: | + New-SelfSignedCertificate -Type Custom -Subject "CN=eComBox Test Certificate" -KeyUsage DigitalSignature -FriendlyName "eComBox Test Cert" -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") + $thumbprint = (Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object {$_.Subject -match "eComBox Test Certificate"} | Select-Object -First 1).Thumbprint + Write-Host "Certificate thumbprint: $thumbprint" - # Decode the base 64 encoded pfx and save the Signing_Certificate - - name: Decode the pfx + - name: Decode the pfx (if secret available) + if: ${{ secrets.Base64_Encoded_Pfx }} run: | $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}") - $certificatePath = Join-Path -Path $env:Wap_Project_Directory -ChildPath GitHubActionsWorkflow.pfx + $certificatePath = "GitHubActionsWorkflow.pfx" [IO.File]::WriteAllBytes("$certificatePath", $pfx_cert_byte) - # Create the app package by building and packaging the Windows Application Packaging project - - name: Create the app package - run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }} - env: - Appx_Bundle: Always - Appx_Bundle_Platforms: x86|x64 - Appx_Package_Build_Mode: StoreUpload - Configuration: ${{ matrix.configuration }} + - name: Build MSIX package (with certificate) + if: ${{ secrets.Base64_Encoded_Pfx }} + run: msbuild $env:Solution_Name /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} /p:UapAppxPackageBuildMode=SideloadOnly /p:AppxBundle=Never /p:AppxPackageDir=$env:AppxPackageDir /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }} /p:AppxPackageSigningEnabled=true + + - name: Build MSIX package (without signing) + if: ${{ !secrets.Base64_Encoded_Pfx }} + run: msbuild $env:Solution_Name /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} /p:UapAppxPackageBuildMode=SideloadOnly /p:AppxBundle=Never /p:AppxPackageDir=$env:AppxPackageDir /p:AppxPackageSigningEnabled=false - # Remove the pfx - name: Remove the pfx - run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx + if: ${{ secrets.Base64_Encoded_Pfx }} + run: Remove-Item -path GitHubActionsWorkflow.pfx -ErrorAction SilentlyContinue - # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact - - name: Upload build artifacts + - name: Upload MSIX package uses: actions/upload-artifact@v4 with: - name: MSIX Package - path: ${{ env.Wap_Project_Directory }}\AppPackages + name: MSIX-Package-${{ matrix.platform }}-${{ matrix.configuration }} + path: ${{ env.AppxPackageDir }}**/*.msix diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 921f09e..ded0408 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -1,9 +1,6 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# This workflow builds the UWP application and creates MSIX packages -name: MSBuild +name: MSBuild UWP on: push: @@ -12,13 +9,9 @@ on: branches: [ "master" ] env: - # Path to the solution file relative to the root of the project. - SOLUTION_FILE_PATH: . - - # Configuration type to build. - # You can convert this to a build matrix if you need coverage of multiple configuration types. - # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + SOLUTION_FILE_PATH: eComBox.sln BUILD_CONFIGURATION: Release + BUILD_PLATFORM: x64 permissions: contents: read @@ -27,18 +20,28 @@ jobs: build: runs-on: windows-latest + strategy: + matrix: + platform: [x64, x86] + steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 - - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + - name: Setup MSBuild + uses: microsoft/setup-msbuild@v2 - name: Restore NuGet packages - working-directory: ${{env.GITHUB_WORKSPACE}} run: nuget restore ${{env.SOLUTION_FILE_PATH}} - - name: Build - working-directory: ${{env.GITHUB_WORKSPACE}} - # Add additional options to the MSBuild command line here (like platform or verbosity level). - # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference - run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} + - name: Build UWP application + run: msbuild ${{env.SOLUTION_FILE_PATH}} /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{matrix.platform}} /p:AppxPackageSigningEnabled=false /p:AppxBundle=Never + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + if: matrix.platform == 'x64' + with: + name: UWP-Build-${{matrix.platform}} + path: | + **/bin/${{matrix.platform}}/${{env.BUILD_CONFIGURATION}}/ + !**/bin/${{matrix.platform}}/${{env.BUILD_CONFIGURATION}}/**/*.pdb