Skip to content

Commit a046cb6

Browse files
committed
ci: sign script now handles signing of either core packages and nativeshims package, or just nativeshims package
1 parent b64a675 commit a046cb6

File tree

1 file changed

+166
-95
lines changed

1 file changed

+166
-95
lines changed

build/sign.ps1

Lines changed: 166 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,48 @@ function Test-RequiredAssets {
5959
[Parameter(Mandatory = $true)]
6060
[string]$WorkingDirectory,
6161

62-
[Parameter(Mandatory = $true)]
62+
[Parameter(Mandatory = $false)]
6363
[string]$NuGetPackagesZip,
6464

65-
[Parameter(Mandatory = $true)]
66-
[string]$SymbolsPackagesZip
65+
[Parameter(Mandatory = $false)]
66+
[string]$SymbolsPackagesZip,
67+
68+
[Parameter(Mandatory = $false)]
69+
[string]$NativeShimsZip
6770
)
6871

6972
Write-Host "`nValidating required build assets..."
70-
$requiredFiles = @{
71-
$NuGetPackagesZip = "NuGet packages"
72-
$SymbolsPackagesZip = "Symbol packages"
73-
}
7473

75-
foreach ($required in $requiredFiles.GetEnumerator()) {
76-
$found = Get-ChildItem -Path $WorkingDirectory -Filter $required.Key -ErrorAction SilentlyContinue
77-
if (-not $found) {
78-
throw "Required build asset not found: $($required.Key)`nThis file should contain $($required.Value)"
74+
$hasCorePackages = -not [string]::IsNullOrWhiteSpace($NuGetPackagesZip) -and -not [string]::IsNullOrWhiteSpace($SymbolsPackagesZip)
75+
$hasNativeShims = -not [string]::IsNullOrWhiteSpace($NativeShimsZip)
76+
77+
if (-not $hasCorePackages -and -not $hasNativeShims) {
78+
throw "No package files specified. Please provide either core packages or native shims package paths."
79+
}
80+
81+
if ($hasCorePackages) {
82+
Write-Host " 🔍 Validating core packages..." -ForegroundColor Cyan
83+
$coreFiles = @{
84+
$NuGetPackagesZip = "NuGet packages"
85+
$SymbolsPackagesZip = "Symbol packages"
86+
}
87+
88+
foreach ($required in $coreFiles.GetEnumerator()) {
89+
$found = Get-ChildItem -Path $WorkingDirectory -Filter $required.Key -ErrorAction SilentlyContinue
90+
if (-not $found) {
91+
throw "Required build asset not found: $($required.Key)`nThis file should contain $($required.Value)"
92+
}
93+
Write-Host " ✅ Found $($required.Value) in: $($found.Name)" -ForegroundColor Green
7994
}
95+
}
8096

81-
Write-Host " ✅ Found $($required.Value) in: $($found.Name)" -ForegroundColor Green
97+
if ($hasNativeShims) {
98+
Write-Host " 🔍 Validating native shims package..." -ForegroundColor Cyan
99+
$found = Get-ChildItem -Path $WorkingDirectory -Filter $NativeShimsZip -ErrorAction SilentlyContinue
100+
if (-not $found) {
101+
throw "Required native shims asset not found: $NativeShimsZip"
102+
}
103+
Write-Host " ✅ Found Native Shims package in: $($found.Name)" -ForegroundColor Green
82104
}
83105
}
84106

@@ -110,6 +132,86 @@ function Initialize-DirectoryStructure {
110132
return $directories
111133
}
112134

135+
function Process-ZipPackage {
136+
[CmdletBinding()]
137+
param(
138+
[Parameter(Mandatory = $true)]
139+
[string]$ZipFile,
140+
141+
[Parameter(Mandatory = $true)]
142+
[hashtable]$Directories,
143+
144+
[Parameter(Mandatory = $true)]
145+
[string]$SignToolPath,
146+
147+
[Parameter(Mandatory = $true)]
148+
[string]$NuGetPath,
149+
150+
[Parameter(Mandatory = $true)]
151+
[string]$Thumbprint,
152+
153+
[Parameter(Mandatory = $true)]
154+
[string]$TimestampServer
155+
)
156+
157+
Write-Host "`n 🔄 Processing: $ZipFile" -ForegroundColor Cyan
158+
159+
$extractPath = Join-Path $Directories.Unsigned ([System.IO.Path]::GetFileNameWithoutExtension($ZipFile))
160+
Write-Host " 📂 Extracting to: $extractPath" -ForegroundColor Gray
161+
162+
$zipPath = Join-Path $Directories.WorkingDir $ZipFile
163+
Expand-Archive -Path $zipPath -DestinationPath $extractPath -Force
164+
165+
Write-Host " 📋 Copying packages to unsigned directory" -ForegroundColor Gray
166+
$packages = Get-ChildItem -Path $extractPath -Recurse -Include *.nupkg, *.snupkg
167+
foreach ($package in $packages) {
168+
Write-Host " 📦 Copying: $($package.Name)"
169+
170+
# Verify GitHub attestation
171+
if (-not (Test-GithubAttestation -FilePath $package.FullName -RepoName "Yubico/Yubico.NET.SDK")) {
172+
throw "Attestation verification failed for: $($package.Name)"
173+
}
174+
175+
Copy-Item -Path $package.FullName -Destination $Directories.Unsigned -Force
176+
}
177+
Write-Host " ✅ Copied $($packages.Count) package(s)"
178+
179+
# Process the packages
180+
$nugetPackages = Get-ChildItem -Path $Directories.Unsigned -Filter "*.nupkg"
181+
foreach ($package in $nugetPackages) {
182+
Write-Host "`n 📝 Signing contents of: $($package.Name)" -ForegroundColor White
183+
184+
$extractPath = Join-Path $Directories.Libraries ([System.IO.Path]::GetFileNameWithoutExtension($package.Name))
185+
Write-Host " 📂 Extracting to: $extractPath"
186+
Expand-Archive -Path $package.FullName -DestinationPath $extractPath -Force
187+
188+
Write-Debug " 🧹 Cleaning package structure"
189+
Get-ChildItem -Path $extractPath -Recurse -Include "_rels", "package" | Remove-Item -Force -Recurse
190+
Get-ChildItem -Path $extractPath -Recurse -Filter '[Content_Types].xml' | Remove-Item -Force
191+
192+
Write-Host " ✍️ Signing assemblies..."
193+
$dlls = Get-ChildItem -Path $extractPath -Include "*.dll" -Recurse
194+
foreach ($dll in $dlls) {
195+
$frameworkDir = Split-Path (Split-Path $dll.FullName -Parent) -Leaf
196+
$fileName = Split-Path $dll.FullName -Leaf
197+
Write-Host " 🔏 Signing: ..\$frameworkDir\$fileName" -ForegroundColor Gray
198+
Sign-SingleFile -FilePath $dll.FullName -Thumbprint $Thumbprint -SignToolPath $SignToolPath -TimestampServer $TimestampServer
199+
}
200+
201+
Write-Host " 📦 Repacking assemblies..." -ForegroundColor White
202+
Get-ChildItem -Path $extractPath -Recurse -Filter "*.nuspec" |
203+
ForEach-Object {
204+
Write-Host " 📥 Packing: $($_.Name)"
205+
$output = & $NuGetPath pack $_.FullName -OutputDirectory $Directories.Packages 2>&1
206+
207+
if ($LASTEXITCODE -ne 0) {
208+
$output | ForEach-Object { Write-Host $_ }
209+
throw "Packing failed for file: $($_.FullName)"
210+
}
211+
}
212+
}
213+
}
214+
113215
function Test-GithubAttestation {
114216
[CmdletBinding()]
115217
param(
@@ -120,23 +222,21 @@ function Test-GithubAttestation {
120222
[string]$RepoName
121223
)
122224

123-
# Get the parent directory name and the file name
124225
$fileName = (Get-ChildItem $FilePath).Name
125-
126-
Write-Host " 🔐 Verifying attestation for: ..$parentDir\$fileName" -ForegroundColor Gray
226+
Write-Host " 🔐 Verifying attestation for: $fileName" -ForegroundColor Gray
127227

128228
try {
129229
$output = gh attestation verify $FilePath --repo $RepoName 2>&1
130230
if ($LASTEXITCODE -ne 0) {
131231
Write-Host $output -ForegroundColor Red
132-
throw $output # This will trigger the catch block
232+
throw $output
133233
}
134234

135-
Write-Host " ✅ Verified" -ForegroundColor Green
235+
Write-Host " ✅ Verified" -ForegroundColor Green
136236
return $true
137237
}
138238
catch {
139-
Write-Host " ❌ Verification failed: $_" -ForegroundColor Red
239+
Write-Host " ❌ Verification failed: $_" -ForegroundColor Red
140240
return $false
141241
}
142242
}
@@ -146,17 +246,20 @@ function Test-GithubAttestation {
146246
Signs NuGet and Symbol packages using a smart card certificate.
147247
148248
.DESCRIPTION
149-
Signs NuGet packages (*.nupkg) and their corresponding symbol packages (*.snupkg) using a hardware-based certificate.
150-
The script processes the contents of two required zip files ('Nuget Packages.zip' and 'Symbols Packages.zip'),
151-
signs all assemblies within the NuGet packages, repacks them, and then signs both the NuGet and Symbol packages.
249+
Signs NuGet packages (*.nupkg), corresponding symbol packages (*.snupkg), and optionally native shim packages
250+
using a hardware-based certificate. The script can process:
251+
1. Core packages (NuGet and Symbol packages)
252+
2. Native shims package
253+
3. Both core packages and native shims
254+
255+
The script signs all assemblies within the packages, repacks them, and then signs the final packages.
152256
153257
How to use:
154258
1. Create a release folder on your machine e.g. ../releases/1.12
155-
2. Download the build assets "Nuget Packages.zip" and "Symbols Packages.zip" from the latest SDK build action
156-
to the newly created folder.
157-
3. Start a Powershell terminal, and load the script by running the following command:
259+
2. Download the build assets from the latest SDK build action to the newly created folder
260+
3. Start a Powershell terminal, and load the script:
158261
> . \.Yubico.NET.SDK\build\sign.ps1
159-
4. The script can be invoked by following the examples below.
262+
4. Follow the examples below to sign packages
160263
161264
Set $DebugPreference = "Continue" for verbose output
162265
@@ -176,19 +279,28 @@ Optional. Path to nuget.exe. Defaults to "nuget.exe" (expects it in PATH).
176279
Optional. URL of the timestamp server. Defaults to "http://timestamp.digicert.com".
177280
178281
.PARAMETER NuGetPackagesZip
179-
Optional. Name of the NuGet packages zip file. Defaults to "Nuget Packages.zip".
282+
Optional. Name of the NuGet packages zip file. Required if signing core packages.
180283
181284
.PARAMETER SymbolsPackagesZip
182-
Optional. Name of the symbols packages zip file. Defaults to "Symbols Packages.zip".
285+
Optional. Name of the symbols packages zip file. Required if signing core packages.
286+
287+
.PARAMETER NativeShimsZip
288+
Optional. Name of the native shims package zip file.
183289
184290
.PARAMETER CleanWorkingDirectory
185291
Optional switch. If specified, cleans the working directories before processing.
186292
187293
.EXAMPLE
188-
Invoke-NuGetPackageSigning -Thumbprint "0123456789ABCDEF" -WorkingDirectory "C:\Signing"
294+
# Sign only native shims
295+
Invoke-NuGetPackageSigning -Thumbprint "0123456789ABCDEF" -WorkingDirectory "C:\Signing" -NativeShimsZip "Yubico.NativeShims.nupkg.zip"
296+
297+
.EXAMPLE
298+
# Sign core packages
299+
Invoke-NuGetPackageSigning -Thumbprint "0123456789ABCDEF" -WorkingDirectory "C:\Signing" -NuGetPackagesZip "Nuget Packages.zip" -SymbolsPackagesZip "Symbols Packages.zip"
189300
190301
.EXAMPLE
191-
Invoke-NuGetPackageSigning -Thumbprint "0123456789ABCDEF" -WorkingDirectory "C:\Signing" -CleanWorkingDirectory -NuGetPath "C:\Tools\nuget.exe"
302+
# Sign both core packages and native shims
303+
Invoke-NuGetPackageSigning -Thumbprint "0123456789ABCDEF" -WorkingDirectory "C:\Signing" -NuGetPackagesZip "Nuget Packages.zip" -SymbolsPackagesZip "Symbols Packages.zip" -NativeShimsZip "Yubico.NativeShims.nupkg.zip"
192304
193305
.NOTES
194306
Requires:
@@ -217,10 +329,13 @@ function Invoke-NuGetPackageSigning {
217329
[string]$TimestampServer = "http://timestamp.digicert.com",
218330

219331
[Parameter(Mandatory = $false)]
220-
[string]$NuGetPackagesZip = "Nuget Packages.zip",
332+
[string]$NuGetPackagesZip,
221333

222334
[Parameter(Mandatory = $false)]
223-
[string]$SymbolsPackagesZip = "Symbols Packages.zip",
335+
[string]$SymbolsPackagesZip,
336+
337+
[Parameter(Mandatory = $false)]
338+
[string]$NativeShimsZip,
224339

225340
[Parameter(Mandatory = $false)]
226341
[switch]$CleanWorkingDirectory
@@ -244,7 +359,7 @@ function Invoke-NuGetPackageSigning {
244359
if (-not (Get-Command gh -ErrorAction SilentlyContinue)) {
245360
throw "GitHub CLI installed or not found in PATH"
246361
}
247-
Write-Host "✓ GitHub CLI found at: $NuGetPath"
362+
Write-Host "✓ GitHub CLI found"
248363

249364
# Verify certificate is available and log details
250365
$cert = Get-ChildItem Cert:\CurrentUser\My | Where-Object { $_.Thumbprint -eq $Thumbprint }
@@ -272,76 +387,32 @@ function Invoke-NuGetPackageSigning {
272387
$directories = Initialize-DirectoryStructure -BaseDirectory $WorkingDirectory
273388

274389
# Validate required zip files
275-
Test-RequiredAssets -WorkingDirectory $WorkingDirectory -NuGetPackagesZip $NuGetPackagesZip -SymbolsPackagesZip $SymbolsPackagesZip
276-
277-
# Process each zip file
278-
Write-Host "`n📦 Processing ZIP files..." -ForegroundColor Yellow
279-
$zipFiles = Get-ChildItem -Path $WorkingDirectory -Filter "*.zip"
280-
foreach ($zip in $zipFiles) {
281-
Write-Host "`n 🔄 Processing: $($zip.Name)" -ForegroundColor Cyan
282-
283-
$extractPath = Join-Path $directories.Unsigned ([System.IO.Path]::GetFileNameWithoutExtension($zip.Name))
284-
Write-Host " 📂 Extracting to: $extractPath" -ForegroundColor Gray
285-
Expand-Archive -Path $zip.FullName -DestinationPath $extractPath -Force
286-
287-
Write-Host " 📋 Copying packages to unsigned directory" -ForegroundColor Gray
288-
$packages = Get-ChildItem -Path $extractPath -Recurse -Include *.nupkg, *.snupkg
289-
foreach ($package in $packages) {
290-
Write-Host " Copying: $($package.Name)"
390+
Test-RequiredAssets -WorkingDirectory $WorkingDirectory -NuGetPackagesZip $NuGetPackagesZip -SymbolsPackagesZip $SymbolsPackagesZip -NativeShimsZip $NativeShimsZip
291391

292-
# Verify GitHub attestation (that the file has been downloaded from our repo)
293-
if (-not (Test-GithubAttestation -FilePath $package.FullName -RepoName "Yubico/Yubico.NET.SDK")) {
294-
throw "Attestation verification failed for: $($package.Name)"
295-
}
392+
# Determine which packages to process
393+
$hasCorePackages = -not [string]::IsNullOrWhiteSpace($NuGetPackagesZip) -and -not [string]::IsNullOrWhiteSpace($SymbolsPackagesZip)
394+
$hasNativeShims = -not [string]::IsNullOrWhiteSpace($NativeShimsZip)
296395

297-
Copy-Item -Path $package.FullName -Destination $directories.Unsigned -Force
298-
}
299-
Write-Host "✓ Copied $($packages.Count) package(s)"
300-
}
396+
# Process packages based on what was provided
397+
if ($hasCorePackages) {
398+
Write-Host "`n📦 Processing Core Packages..." -ForegroundColor Yellow
399+
# Process core packages
400+
Process-ZipPackage -ZipFile $NuGetPackagesZip -Directories $directories -SignToolPath $SignToolPath -NuGetPath $NuGetPath -Thumbprint $Thumbprint -TimestampServer $TimestampServer
301401

302-
# First process nupkg files to sign their contents
303-
Write-Host "`n📦 Processing NuGet packages..." -ForegroundColor Yellow
304-
$nugetPackages = Get-ChildItem -Path $directories.Unsigned -Filter "*.nupkg"
305-
foreach ($package in $nugetPackages) {
306-
Write-Host "`nSigning contents of: $($package.Name)"
402+
Write-Host "`n📦 Copying Symbol Packages..." -ForegroundColor Yellow
403+
$symbolsExtractPath = Join-Path $directories.Unsigned ([System.IO.Path]::GetFileNameWithoutExtension($SymbolsPackagesZip))
404+
Expand-Archive -Path (Join-Path $WorkingDirectory $SymbolsPackagesZip) -DestinationPath $symbolsExtractPath -Force
307405

308-
$extractPath = Join-Path $directories.Libraries ([System.IO.Path]::GetFileNameWithoutExtension($package.Name))
309-
Write-Host "Extracting to: $extractPath"
310-
Expand-Archive -Path $package.FullName -DestinationPath $extractPath -Force
311-
312-
Write-Debug "Cleaning package structure"
313-
Get-ChildItem -Path $extractPath -Recurse -Include "_rels", "package" | Remove-Item -Force -Recurse
314-
Get-ChildItem -Path $extractPath -Recurse -Filter '[Content_Types].xml' | Remove-Item -Force
315-
316-
Write-Host "Signing assemblies..."
317-
$dlls = Get-ChildItem -Path $extractPath -Include "*.dll" -Recurse
318-
foreach ($dll in $dlls) {
319-
# Get the parent directory name (framework target) and the file name
320-
$frameworkDir = Split-Path (Split-Path $dll.FullName -Parent) -Leaf
321-
$fileName = Split-Path $dll.FullName -Leaf
322-
Write-Host " ✍️ Signing: ..\$frameworkDir\$fileName" -ForegroundColor Gray
323-
Sign-SingleFile -FilePath $dll.FullName -Thumbprint $Thumbprint -SignToolPath $SignToolPath -TimestampServer $TimestampServer
324-
}
325-
326-
Write-Host "Repacking assemblies..."
327-
Get-ChildItem -Path $extractPath -Recurse -Filter "*.nuspec" |
328-
ForEach-Object {
329-
Write-Host " Packing: $($_.Name)"
330-
$output = & $NuGetPath pack $_.FullName -OutputDirectory $directories.Packages 2>&1
331-
332-
if ($LASTEXITCODE -ne 0) {
333-
$output | ForEach-Object { Write-Host $_ }
334-
throw "Signing failed for file: $FilePath"
335-
}
406+
$symbolPackages = Get-ChildItem -Path $symbolsExtractPath -Recurse -Filter "*.snupkg"
407+
foreach ($package in $symbolPackages) {
408+
Write-Host " Copying: $($package.Name)"
409+
Copy-Item -Path $package.FullName -Destination $directories.Packages -Force
336410
}
337411
}
338412

339-
# Copy symbol packages to output directory
340-
Write-Host "`nCopying symbol packages..." -ForegroundColor Yellow
341-
$symbolPackages = Get-ChildItem -Path $directories.Unsigned -Filter "*.snupkg"
342-
foreach ($package in $symbolPackages) {
343-
Write-Host " Copying: $($package.Name)"
344-
Copy-Item -Path $package.FullName -Destination $directories.Packages -Force
413+
if ($hasNativeShims) {
414+
Write-Host "`n🔧 Processing Native Shims Package..." -ForegroundColor Yellow
415+
Process-ZipPackage -ZipFile $NativeShimsZip -Directories $directories -SignToolPath $SignToolPath -NuGetPath $NuGetPath -Thumbprint $Thumbprint -TimestampServer $TimestampServer
345416
}
346417

347418
# Sign all final packages (both nupkg and snupkg)

0 commit comments

Comments
 (0)