Skip to content

Commit 6303235

Browse files
Refactor Azure pipeline for build and publish process
1 parent eecee00 commit 6303235

File tree

1 file changed

+167
-141
lines changed

1 file changed

+167
-141
lines changed
Lines changed: 167 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,174 @@
1-
trigger:
2-
tags:
3-
include:
4-
- '*'
5-
# This pipeline is meant to build & deploy upon tagging. It's not meant to be a part of PR validation.
6-
pr: none
7-
8-
name: $(Build.SourceBranchName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)
9-
10-
variables:
11-
- group: Code_Signing_Certificate_2023_2026
12-
- name: prId
13-
value: $[coalesce(variables['System.PullRequest.PullRequestId'], '000')]
14-
- name: prIteration
15-
value: $[counter(variables['prId'], 1)]
16-
- name: buildConfiguration
17-
value: Release
18-
- name: releaseTag
19-
value: $(Build.SourceBranchName)
20-
21-
stages:
22-
- stage: BuildAndPublish
23-
condition: succeeded()
24-
jobs:
25-
- job: BuildAndSign
26-
pool:
27-
vmImage: 'windows-latest'
1+
name: Build and Publish
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
env:
9+
BUILD_CONFIGURATION: Release
10+
DOTNET_VERSION: '9.x'
11+
12+
jobs:
13+
build-sign-publish:
14+
runs-on: windows-latest
15+
environment: nuget-org-publish
16+
permissions:
17+
id-token: write
18+
contents: read
2819

2920
steps:
30-
- checkout: self
31-
fetchDepth: 0
32-
33-
- task: UseDotNet@2
34-
inputs:
35-
packageType: 'sdk'
36-
version: '9.x'
37-
38-
- task: DownloadSecureFile@1
39-
name: cert
40-
inputs:
41-
secureFile: 'code-signing-certificate-2023-2026.pfx'
42-
43-
- task: DotNetCoreCLI@2
44-
displayName: 'Build Project'
45-
inputs:
46-
command: 'build'
47-
projects: 'Infragistics.QueryBuilder.Executor.csproj'
48-
arguments: >
49-
-c $(buildConfiguration)
50-
/p:Version=$(releaseTag)
51-
52-
- powershell: |
53-
$outputDir = "$(Build.SourcesDirectory)\bin\$(buildConfiguration)\net9.0"
54-
Write-Host "Listing contents of: $outputDir"
55-
if (-Not (Test-Path $outputDir)) {
56-
Write-Error "Output folder not found: $outputDir"
57-
exit 1
58-
}
59-
Get-ChildItem $outputDir -Recurse | ForEach-Object {
60-
Write-Host $_.FullName
61-
}
62-
displayName: 'Debug: List build output contents'
63-
64-
- powershell: |
65-
$dllFolder = "$(Build.SourcesDirectory)\bin\$(buildConfiguration)\net9.0"
66-
Write-Host "Signing DLLs in folder: $dllFolder"
67-
68-
# Find the latest signtool.exe
69-
Write-Host "##[section]Starting search for signtool.exe at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff')"
70-
71-
$signtoolPath = $null
72-
$searchPaths = @(
73-
"C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe",
74-
"C:\Program Files (x86)\Windows Kits\10\bin\*\x86\signtool.exe",
75-
"C:\Program Files (x86)\Microsoft SDKs\Windows\*\bin\*\signtool.exe",
76-
"C:\Program Files (x86)\Microsoft SDKs\Windows\*\bin\signtool.exe"
77-
)
78-
79-
foreach ($searchPath in $searchPaths) {
80-
$foundPaths = Get-ChildItem -Path $searchPath -ErrorAction SilentlyContinue | Sort-Object -Property FullName -Descending
81-
if ($foundPaths) {
82-
$signtoolPath = $foundPaths[0].FullName
83-
break
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0
25+
26+
- name: Setup .NET
27+
uses: actions/setup-dotnet@v4
28+
with:
29+
dotnet-version: ${{ env.DOTNET_VERSION }}
30+
31+
- name: Get version from tag
32+
id: version
33+
shell: pwsh
34+
run: |
35+
$version = "${{ github.ref_name }}"
36+
Write-Host "Version: $version"
37+
echo "version=$version" >> $env:GITHUB_OUTPUT
38+
39+
- name: Build
40+
run: |
41+
dotnet build Infragistics.QueryBuilder.Executor.csproj `
42+
-c ${{ env.BUILD_CONFIGURATION }} `
43+
/p:Version=${{ steps.version.outputs.version }}
44+
45+
- name: Debug - List build output contents
46+
shell: pwsh
47+
run: |
48+
$outputDir = "${{ github.workspace }}\bin\${{ env.BUILD_CONFIGURATION }}\net9.0"
49+
Write-Host "Listing contents of: $outputDir"
50+
if (-Not (Test-Path $outputDir)) {
51+
Write-Error "Output folder not found: $outputDir"
52+
exit 1
53+
}
54+
Get-ChildItem $outputDir -Recurse | ForEach-Object {
55+
Write-Host $_.FullName
56+
}
57+
58+
- name: Decode signing certificate
59+
shell: pwsh
60+
run: |
61+
$certBytes = [Convert]::FromBase64String("${{ secrets.SIGNING_CERTIFICATE_BASE64 }}")
62+
$certPath = "${{ runner.temp }}\certificate.pfx"
63+
[IO.File]::WriteAllBytes($certPath, $certBytes)
64+
Write-Host "Certificate written to: $certPath"
65+
66+
- name: Sign all DLL files
67+
shell: pwsh
68+
env:
69+
CERT_PASS: ${{ secrets.SIGNING_CERTIFICATE_PASSWORD }}
70+
TIMESTAMP_URL: ${{ vars.SIGNING_CERTIFICATE_TIMESTAMP_URL }}
71+
run: |
72+
$dllFolder = "${{ github.workspace }}\bin\${{ env.BUILD_CONFIGURATION }}\net9.0"
73+
$certPath = "${{ runner.temp }}\certificate.pfx"
74+
Write-Host "Signing DLLs in folder: $dllFolder"
75+
76+
# Find the latest signtool.exe
77+
Write-Host "##[section]Starting search for signtool.exe at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff')"
78+
79+
$signtoolPath = $null
80+
$searchPaths = @(
81+
"C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe",
82+
"C:\Program Files (x86)\Windows Kits\10\bin\*\x86\signtool.exe",
83+
"C:\Program Files (x86)\Microsoft SDKs\Windows\*\bin\*\signtool.exe",
84+
"C:\Program Files (x86)\Microsoft SDKs\Windows\*\bin\signtool.exe"
85+
)
86+
87+
foreach ($searchPath in $searchPaths) {
88+
$foundPaths = Get-ChildItem -Path $searchPath -ErrorAction SilentlyContinue | Sort-Object -Property FullName -Descending
89+
if ($foundPaths) {
90+
$signtoolPath = $foundPaths[0].FullName
91+
break
92+
}
8493
}
85-
}
86-
87-
if (-not $signtoolPath) {
88-
Write-Error "signtool.exe not found in any of the well-known locations"
89-
exit 1
90-
}
91-
92-
Write-Host "##[section]Found signtool.exe at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff')"
93-
Write-Host "Using signtool at: $signtoolPath"
94-
95-
$dllFiles = Get-ChildItem -Path $dllFolder -Filter *.dll -Recurse
96-
foreach ($dll in $dllFiles) {
97-
Write-Host "Signing $($dll.FullName)..."
98-
& $signtoolPath sign /f $(cert.secureFilePath) /p $env:CERT_PASS /tr $(SigningCertificateTimestampUrl) /td sha256 /fd sha256 $dll.FullName
94+
95+
if (-not $signtoolPath) {
96+
Write-Error "signtool.exe not found in any of the well-known locations"
97+
exit 1
98+
}
99+
100+
Write-Host "##[section]Found signtool.exe at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff')"
101+
Write-Host "Using signtool at: $signtoolPath"
102+
103+
$dllFiles = Get-ChildItem -Path $dllFolder -Filter *.dll -Recurse
104+
foreach ($dll in $dllFiles) {
105+
Write-Host "Signing $($dll.FullName)..."
106+
& $signtoolPath sign /f $certPath /p $env:CERT_PASS /tr $env:TIMESTAMP_URL /td sha256 /fd sha256 $dll.FullName
107+
108+
if ($LASTEXITCODE -ne 0) {
109+
Write-Error "Signing failed for $($dll.FullName)"
110+
exit 1
111+
}
112+
}
113+
114+
- name: Pack NuGet package
115+
shell: pwsh
116+
run: |
117+
$packageOutputDir = "${{ github.workspace }}\nupkg"
118+
$packageVersion = "${{ steps.version.outputs.version }}"
119+
120+
Write-Host "Packing project from existing build output..."
121+
dotnet pack ./Infragistics.QueryBuilder.Executor.csproj `
122+
--no-build `
123+
--configuration ${{ env.BUILD_CONFIGURATION }} `
124+
-p:PackageVersion=$packageVersion `
125+
-o $packageOutputDir
99126
100127
if ($LASTEXITCODE -ne 0) {
101-
Write-Error "Signing failed for $($dll.FullName)"
128+
Write-Error "dotnet pack failed"
102129
exit 1
103130
}
104-
}
105-
displayName: 'Sign all DLL files with PFX certificate'
106-
env:
107-
CERT_PASS: $(SigningCertificatePassword)
108-
109-
- powershell: |
110-
$packageOutputDir = "$(Build.ArtifactStagingDirectory)\nuget"
111-
$packageVersion = "$(releaseTag)"
112-
113-
Write-Host "Packing project from existing build output..."
114-
dotnet pack ./Infragistics.QueryBuilder.Executor.csproj `
115-
--no-build `
116-
--configuration $(buildConfiguration) `
117-
-p:PackageVersion=$packageVersion `
118-
-o $packageOutputDir
119-
120-
if ($LASTEXITCODE -ne 0) {
121-
Write-Error "dotnet pack failed"
122-
exit 1
123-
}
124-
displayName: 'Pack NuGet Package using PowerShell'
125-
126-
- task: PowerShell@2
127-
displayName: 'Sign NuGet package'
128-
env:
129-
CERT_PASS: $(SigningCertificatePassword)
130-
inputs:
131-
targetType: 'inline'
132-
script: |
133-
nuget.exe sign $(Build.ArtifactStagingDirectory)\nuget\*.nupkg -CertificatePath $(cert.secureFilePath) -CertificatePassword $env:CERT_PASS -Timestamper $(SigningCertificateTimestampUrl)
134-
135-
- task: PublishBuildArtifacts@1
136-
inputs:
137-
PathtoPublish: '$(Build.ArtifactStagingDirectory)/nuget'
138-
ArtifactName: 'NuGetPackage'
139-
publishLocation: 'Container'
140-
displayName: 'Publish NuGet Package as Build Artifact'
141-
142-
- task: NuGetCommand@2
143-
inputs:
144-
command: 'push'
145-
packagesToPush: '$(Build.ArtifactStagingDirectory)/nuget/*.nupkg'
146-
nuGetFeedType: 'external'
147-
publishFeedCredentials: 'NuGet.Org'
148-
displayName: 'Publish to NuGet.org'
131+
132+
- name: Sign NuGet package
133+
shell: pwsh
134+
env:
135+
CERT_PASS: ${{ secrets.SIGNING_CERTIFICATE_PASSWORD }}
136+
TIMESTAMP_URL: ${{ vars.SIGNING_CERTIFICATE_TIMESTAMP_URL }}
137+
run: |
138+
$certPath = "${{ runner.temp }}\certificate.pfx"
139+
$nupkgPath = "${{ github.workspace }}\nupkg\*.nupkg"
140+
141+
dotnet nuget sign $nupkgPath `
142+
--certificate-path $certPath `
143+
--certificate-password $env:CERT_PASS `
144+
--timestamper $env:TIMESTAMP_URL `
145+
--overwrite
146+
147+
- name: Upload NuGet package artifact
148+
uses: actions/upload-artifact@v4
149+
with:
150+
name: NuGetPackage
151+
path: ${{ github.workspace }}/nupkg/*.nupkg
152+
retention-days: 5
153+
154+
- name: NuGet login (OIDC Trusted Publishing)
155+
uses: nuget/login@v1
156+
id: nuget-login
157+
with:
158+
user: ${{ secrets.NUGET_ORG_USER }}
159+
160+
- name: Publish to NuGet.org
161+
run: |
162+
dotnet nuget push "${{ github.workspace }}\nupkg\*.nupkg" `
163+
--api-key ${{ steps.nuget-login.outputs.nuget-api-key }} `
164+
--source https://api.nuget.org/v3/index.json
165+
166+
- name: Clean up certificate
167+
if: always()
168+
shell: pwsh
169+
run: |
170+
$certPath = "${{ runner.temp }}\certificate.pfx"
171+
if (Test-Path $certPath) {
172+
Remove-Item $certPath -Force
173+
Write-Host "Certificate cleaned up"
174+
}

0 commit comments

Comments
 (0)