-
-
Notifications
You must be signed in to change notification settings - Fork 3
wo4rkflow add file #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
wo4rkflow add file #4
Conversation
This workflow builds, tests, signs, and packages a .NET Core desktop application using GitHub Actions.
name: .NET Core Desktop CI/CD
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
strategy:
matrix:
configuration: [Debug, Release]
runs-on: windows-latest
env:
Solution_Name: MyApp.sln
Test_Project_Path: MyApp.Tests/MyApp.Tests.csproj
Wap_Project_Directory: MyApp.Package
Wap_Project_Path: MyApp.Package/MyApp.Package.wapproj
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install .NET 8 SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Run unit tests
run: dotnet test $env:Test_Project_Path
- name: Restore solution
run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
env:
Configuration: ${{ matrix.configuration }}
- name: Decode signing certificate
run: |
$pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}")
$certificatePath = Join-Path -Path $env:Wap_Project_Directory -ChildPath GitHubActionsWorkflow.pfx
[IO.File]::WriteAllBytes("$certificatePath", $pfx_cert_byte)
- name: Build and package MSIX
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: Remove temporary certificate
run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx
- name: Upload MSIX artifacts
uses: actions/upload-artifact@v4
with:
name: MSIX Package
path: ${{ env.Wap_Project_Directory }}\AppPackages
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: windows-latest
strategy:
matrix:
configuration: [Debug, Release]
env:
Solution_Name: MyApp.sln
Test_Project_Path: MyApp.Tests/MyApp.Tests.csproj
Wap_Project_Directory: MyApp.Package
Wap_Project_Path: MyApp.Package/MyApp.Package.wapproj
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Run unit tests
run: dotnet test ${{ env.Test_Project_Path }}
- name: Restore solution
run: msbuild ${{ env.Solution_Name }} /t:Restore /p:Configuration=${{ matrix.configuration }}
- name: Decode signing certificate
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
[IO.File]::WriteAllBytes("$certificatePath", $pfx_cert_byte)
- name: Build and package MSIX
run: msbuild ${{ env.Wap_Project_Path }} /p:Configuration=${{ matrix.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
- name: Remove temporary certificate
if: secrets.Base64_Encoded_Pfx != ''
run: Remove-Item -Path "${{ env.Wap_Project_Directory }}\GitHubActionsWorkflow.pfx" -ErrorAction SilentlyContinue
- name: Upload MSIX artifacts
if: matrix.configuration == 'Release'
uses: actions/upload-artifact@v4
with:
name: MSIX Package
path: ${{ env.Wap_Project_Directory }}/AppPackages
not how github works
# .NET Desktop CI/CD workflow # # Purpose # Build, test, sign, and package a WPF or Windows Forms desktop application on Windows runners. # # Required repository secrets # - Base64_Encoded_Pfx : Base64 string of the signing .pfx file (do not commit the .pfx to the repo). # - Pfx_Key : Password for the .pfx file. # # Required environment variables (set in the workflow env section) # - Solution_Name : Solution file name, e.g., MyApp.sln # - Test_Project_Path : Path to test project, e.g., MyApp.Tests/MyApp.Tests.csproj # - Wap_Project_Directory : Packaging project directory, e.g., MyApp.Package # - Wap_Project_Path : Packaging project file, e.g., MyApp.Package/MyApp.Package.wapproj # # Signing instructions # 1. Create or obtain a .pfx signing certificate locally. # 2. Encode it to Base64 using PowerShell: # $pfx = Get-Content '.\SigningCertificate.pfx' -Encoding Byte # [System.Convert]::ToBase64String($pfx) | Out-File 'SigningCertificate_Encoded.txt' # 3. Copy the Base64 string into the repository secret Base64_Encoded_Pfx and add the password as Pfx_Key. # # Security notes # - Never commit the .pfx file or its password to the repository. # - Use repository secrets and restrict who can modify workflow files. # - Protect the main branch and require this workflow to pass before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds a new GitHub Actions workflow for building, testing, signing, and packaging a .NET Desktop application (WPF or Windows Forms). The workflow includes certificate-based signing using repository secrets and produces MSIX packages for both Debug and Release configurations.
Changes:
- Added a complete CI/CD workflow for .NET Desktop applications with matrix strategy for Debug and Release builds
- Implemented secure certificate handling using Base64-encoded secrets for code signing
- Configured automated testing, building, and MSIX package artifact uploads
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.github/workflows/dotnet-desktop.yml
Outdated
| - name: Upload MSIX artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: MSIX Package |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The artifact name is static and will cause conflicts when uploading artifacts from different matrix configurations. Since the workflow runs with both Debug and Release configurations, the second upload will overwrite the first. The artifact name should include the matrix configuration to distinguish between builds, for example: 'MSIX-Package-${{ matrix.configuration }}'.
| name: MSIX Package | |
| name: MSIX-Package-${{ matrix.configuration }} |
|
|
||
| - name: Decode signing certificate | ||
| run: | | ||
| $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}") |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The certificate file is created but there's no error handling if the Base64_Encoded_Pfx secret is missing or invalid. If the secret is not set, this step will fail silently or create an invalid certificate file, leading to confusing build failures in subsequent steps. Consider adding validation or using the 'if' conditional to check if secrets are available.
| $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}") | |
| if (-not "${{ secrets.Base64_Encoded_Pfx }}") { | |
| Write-Error "The 'Base64_Encoded_Pfx' secret is not set or is empty. Please configure this secret in the repository settings." | |
| exit 1 | |
| } | |
| try { | |
| $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}") | |
| } | |
| catch { | |
| Write-Error "Failed to decode 'Base64_Encoded_Pfx' secret. Ensure it contains a valid Base64-encoded PFX certificate." | |
| exit 1 | |
| } |
| Configuration: ${{ matrix.configuration }} | ||
|
|
||
| - name: Remove temporary certificate | ||
| run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The certificate cleanup step uses a hardcoded backslash path separator which works on Windows but is inconsistent with the forward slash used in line 46. While both work on Windows, consider using consistent path separators throughout the workflow or using PowerShell's Join-Path for platform independence.
| run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx | |
| run: | | |
| $certificatePath = Join-Path -Path $env:Wap_Project_Directory -ChildPath GitHubActionsWorkflow.pfx | |
| Remove-Item -Path $certificatePath |
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: MSIX Package | ||
| path: ${{ env.Wap_Project_Directory }}\bin\${{ matrix.configuration }} |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The artifact upload path uses backslash separators and may not work correctly if the directory structure changes. Consider using forward slashes or the format '${{ env.Wap_Project_Directory }}/bin/${{ matrix.configuration }}' for better cross-platform compatibility and consistency with GitHub Actions conventions.
| path: ${{ env.Wap_Project_Directory }}\bin\${{ matrix.configuration }} | |
| path: ${{ env.Wap_Project_Directory }}/bin/${{ matrix.configuration }} |
cjmanca
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently it's set to sign both release and debug builds. No reason to sign debug, just increases risk of key exposure.
I think a keyless signing method would be preferable to minimize risk.
Probably should only sign for releases with version numbers, to avoid leaking on possibly risky PR merges before final release review. Can split sign job out from build, so build can run for PRs without signing.
Co-authored-by: C.J. Manca <cjmanca@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
.github/workflows/dotnet-desktop.yml
.NET Desktop CI/CD workflow
Purpose
Build, test, sign, and package a WPF or Windows Forms desktop application on Windows runners.
Required repository secrets
- Base64_Encoded_Pfx : Base64 string of the signing .pfx file (do not commit the .pfx to the repo).
- Pfx_Key : Password for the .pfx file.
Required environment variables (set in the workflow env section)
- Solution_Name : Solution file name, e.g., MyApp.sln
- Test_Project_Path : Path to test project, e.g., MyApp.Tests/MyApp.Tests.csproj
- Wap_Project_Directory : Packaging project directory, e.g., MyApp.Package
- Wap_Project_Path : Packaging project file, e.g., MyApp.Package/MyApp.Package.wapproj
Signing instructions
1. Create or obtain a .pfx signing certificate locally.
2. Encode it to Base64 using PowerShell:
$pfx = Get-Content '.\SigningCertificate.pfx' -Encoding Byte
[System.Convert]::ToBase64String($pfx) | Out-File 'SigningCertificate_Encoded.txt'
3. Copy the Base64 string into the repository secret Base64_Encoded_Pfx and add the password as Pfx_Key.
Security notes
- Never commit the .pfx file or its password to the repository.
- Use repository secrets and restrict who can modify workflow files.
- Protect the main branch and require this workflow to pass before merging.