Skip to content

Commit

Permalink
Add code signing (#496)
Browse files Browse the repository at this point in the history
  • Loading branch information
erri120 authored Aug 1, 2023
1 parent e594d75 commit e985aae
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 10 deletions.
53 changes: 49 additions & 4 deletions .github/workflows/build-windows-pupnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ on:
description: "Build an Archive?"
required: false
default: true
SignExecutable:
type: boolean
description: "Sign the executable on Windows?"
required: false
default: false
secrets:
PFX_BASE64:
description: "Base64 encoded string of the PFX file for signing"
required: false
PFX_KEY:
description: "Key for the PFX file used for signing"
required: false
outputs:
ArtifactNameWindowsArchive:
description: "Name of the Artifact that contains the Windows Archive"
Expand All @@ -40,6 +52,10 @@ on:
description: "Name of the Artifact that contains the Windows Inno Setup"
value: ${{ jobs.build.outputs.artifactNameWindowsInnoSetup }}

env:
SigningCertificate: "GitHubActionsWorkflow.pfx"
TimestampServer: "http://timestamp.digicert.com"

jobs:
build:
runs-on: windows-latest
Expand Down Expand Up @@ -69,15 +85,44 @@ jobs:
- name: Get PupNet
run: dotnet tool install -g KuiperZone.PupNet --version ${{ inputs.PupNetVersion }}

- name: Decode PFX
if: inputs.SignExecutable == true
shell: pwsh
run: |
$certBytes = [System.Convert]::FromBase64String("${{ secrets.PFX_BASE64 }}")
$certPath = Join-Path -Path ${{ steps.transformInputs.outputs.projectDir }} -ChildPath $env:SigningCertificate
[IO.File]::WriteAllBytes("$certPath", $certBytes)
- name: Create Archive
if: ${{ inputs.BuildArchive }}
if: inputs.BuildArchive == true
working-directory: ${{ steps.transformInputs.outputs.projectDir }}
run: pupnet -y -v ${{ inputs.AppVersion }} -k zip -p DefineConstants=INSTALLATION_METHOD_ARCHIVE
env:
SignExecutable: ${{ inputs.SignExecutable }}
SigningCertificatePassword: ${{ secrets.PFX_KEY }}

- name: Create Setup
if: ${{ inputs.BuildInnoSetup }}
if: inputs.BuildInnoSetup == true
working-directory: ${{ steps.transformInputs.outputs.projectDir }}
run: pupnet -y -v ${{ inputs.AppVersion }} -k Setup -p DefineConstants=INSTALLATION_METHOD_INNO_SETUP
env:
SignExecutable: ${{ inputs.SignExecutable }}
SigningCertificatePassword: ${{ secrets.PFX_KEY }}

- name: Sign Setup
if: inputs.BuildInnoSetup == true && inputs.SignExecutable == true
working-directory: ${{ steps.transformInputs.outputs.projectDir }}
run: ../../scripts/sign.ps1 Deploy/OUT
env:
SignExecutable: ${{ inputs.SignExecutable }}
SigningCertificatePassword: ${{ secrets.PFX_KEY }}

- name: Remove PFX
if: inputs.SignExecutable == true
shell: pwsh
run: |
$certPath = Join-Path -Path ${{ steps.transformInputs.outputs.projectDir }} -ChildPath $env:SigningCertificate
Remove-Item -Path $certPath
- name: Set outputs
id: setOutputs
Expand All @@ -87,7 +132,7 @@ jobs:
echo "artifactNameWindowsInnoSetup=${{ steps.transformInputs.outputs.projectName }}-${{ github.sha }}-Windows-Setup" >> $env:GITHUB_OUTPUT
- name: Upload Archive
if: ${{ inputs.BuildArchive }}
if: inputs.BuildArchive == true
uses: actions/upload-artifact@v3
with:
name: ${{ steps.setOutputs.outputs.artifactNameWindowsArchive }}
Expand All @@ -96,7 +141,7 @@ jobs:
retention-days: ${{ inputs.RetentionDays }}

- name: Upload Setup
if: ${{ inputs.BuildInnoSetup }}
if: inputs.BuildInnoSetup == true
uses: actions/upload-artifact@v3
with:
name: ${{ steps.setOutputs.outputs.artifactNameWindowsInnoSetup }}
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ jobs:
# https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
ProjectFile: ${{ needs.transformInputs.outputs.ProjectFile }}
RetentionDays: 1
SignExecutable: true
secrets:
PFX_BASE64: ${{ secrets.PFX_BASE64 }}
PFX_KEY: ${{ secrets.PFX_KEY }}

release-github:
runs-on: ubuntu-latest
Expand Down
49 changes: 49 additions & 0 deletions scripts/sign.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
if ($env:SignExecutable -ne "true") {
Write-Host $env:SignExecutable
Write-Host "Signing the executable has been disabled."
exit 0
}

$searchDirectory = $args[0];
if ($searchDirectory) {
Write-Host "Using search directory $searchDirectory"
$executableToSign = Get-ChildItem -Path $searchDirectory | Where-Object { $_.Extension -eq ".exe" } | Select-Object -First 1
} else {
$executableToSign = [System.IO.Path]::Combine($env:BUILD_APP_BIN, $env:APP_BASE_NAME + ".exe")
}

Write-Host $executableToSign

if (Test-Path $executableToSign -PathType Leaf) {
Write-Host "Signing $executableToSign";
} else {
Write-Error "File $executableToSign doesn't exist!";
exit 1;
}

# https://github.com/actions/runner-images/blob/main/images/win/Windows2022-Readme.md#installed-windows-sdks
$rootDirectory = "C:\Program Files (x86)\Windows Kits\10\bin\";
$sdkDirectory = Get-ChildItem -Path $rootDirectory -Name | Where-Object { $_ -like "10*" } | Sort-Object -Descending | Select-Object -First 1
Write-Host "Sdk Directory: $sdkDirectory"

$signToolPath = [System.IO.Path]::Combine($rootDirectory, $sdkDirectory, "x64", "signtool.exe")
Write-Host "signtool path: $signToolPath"

if (Test-Path $signToolPath -PathType Leaf) {
Write-Host "Found signtool.exe at: $signToolPath";
} else {
Write-Error "Singing tool at $signToolPath doesn't exist!";
exit 1;
}

Write-Host "Signing $executableToSign";

& $signToolPath sign /f "$env:SigningCertificate" /p "$env:SigningCertificatePassword" /td sha256 /fd sha256 /tr "$env:TimestampServer" $executableToSign
$exitCode = $LASTEXITCODE

if ($exitCode -eq 0) {
Write-Host "Signing completed"
} else {
Write-Error "Signing failed with code $exitCode"
exit $exitCode
}
5 changes: 0 additions & 5 deletions src/NexusMods.App/NexusMods.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,4 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<Folder Include="Downloaders\" />
<Folder Include="Models\" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/NexusMods.App/app.pupnet.conf
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ IconFiles =
DotnetProjectPath =
DotnetPublishArgs = -p:Version=${APP_VERSION} --self-contained true -c Release -p:TieredCompilation=true -p:PublishReadyToRun=true -p:PublishSingleFile=true
DotnetPostPublish =
DotnetPostPublishOnWindows =
DotnetPostPublishOnWindows = sign.bat

# PACKAGE OUTPUT
PackageName = NexusMods.App
Expand Down
5 changes: 5 additions & 0 deletions src/NexusMods.App/sign.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
echo %~f0%

set "scriptPath=..\..\scripts\sign.ps1"

powershell.exe -ExecutionPolicy Bypass -File "%scriptPath%"

0 comments on commit e985aae

Please sign in to comment.