Skip to content

Commit a95c324

Browse files
committed
Merge develop8
2 parents fe74203 + b333523 commit a95c324

File tree

79 files changed

+3992
-223
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+3992
-223
lines changed
Lines changed: 85 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This workflow will build, test, sign and pack the release branches for EPPlus.
2-
# It will also generate and publish an SBOM
2+
# It will also generate and publish an SBOM per target framework.
33
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
44

55
name: Build Release Branches
@@ -20,6 +20,18 @@ jobs:
2020
uses: actions/setup-dotnet@v4
2121
with:
2222
dotnet-version: '9.0.x'
23+
24+
# --- Read version and TFMs from csproj ---
25+
- name: Read version and target frameworks from csproj
26+
id: read_csproj
27+
run: |
28+
$xml = [xml](Get-Content ./src/EPPlus/EPPlus.csproj)
29+
$version = $xml.Project.PropertyGroup.Version | Where-Object { $_ } | Select-Object -First 1
30+
$tfms = $xml.Project.PropertyGroup.TargetFrameworks | Where-Object { $_ } | Select-Object -First 1
31+
echo "VERSION=$version" >> $env:GITHUB_ENV
32+
echo "TFMS=$tfms" >> $env:GITHUB_ENV
33+
shell: pwsh
34+
2335
- name: Restore dependencies
2436
run: dotnet restore ./src/EPPlus.sln
2537

@@ -47,7 +59,7 @@ jobs:
4759
- name: Test
4860
run: dotnet test ./src/EPPlus.sln --no-build --verbosity normal --configuration Release
4961
- name: Install AzureSignTool
50-
run: dotnet tool install --global AzureSignTool --version 6.0.0
62+
run: dotnet tool install --global AzureSignTool --version 6.0.0
5163
- name: Install NuGetKeyVaultSignTool
5264
run: dotnet tool install --global NuGetKeyVaultSignTool
5365

@@ -57,66 +69,93 @@ jobs:
5769
uses: Azure/login@v2
5870
with:
5971
creds: '{"clientId":"${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }}","clientSecret":"${{ secrets.EPPLUS_CODE_SIGNING_SECRET }}","subscriptionId":"${{ secrets.EPPLUS_CODE_SIGNING_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }}"}'
72+
73+
# --- Sign DLLs ---
6074
- name: Sign EPPlus.dll with AzureSignTool
6175
run: |
62-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus\bin\Release\net9.0\EPPlus.dll"
63-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus\bin\Release\net8.0\EPPlus.dll"
64-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus\bin\Release\netstandard2.1\EPPlus.dll"
65-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus\bin\Release\netstandard2.0\EPPlus.dll"
66-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus\bin\Release\net462\EPPlus.dll"
67-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus\bin\Release\net35\EPPlus.dll"
68-
- name: Sign EPPlus.Interface.dll with AzureSignTool
76+
$tfms = "${{ env.TFMS }}" -split ";"
77+
foreach ($tfm in $tfms) {
78+
$tfm = $tfm.Trim()
79+
if ([string]::IsNullOrEmpty($tfm)) { continue }
80+
$dll = ".\src\EPPlus\bin\Release\$tfm\EPPlus.dll"
81+
Write-Host "Signing $dll"
82+
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL }} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 "$dll"
83+
}
84+
shell: pwsh
85+
- name: Sign EPPlus.Interfaces.dll with AzureSignTool
6986
run: |
70-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.Interfaces\bin\Release\net9.0\EPPlus.Interfaces.dll"
71-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.Interfaces\bin\Release\net8.0\EPPlus.Interfaces.dll"
72-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.Interfaces\bin\Release\netstandard2.1\EPPlus.Interfaces.dll"
73-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.Interfaces\bin\Release\netstandard2.0\EPPlus.Interfaces.dll"
74-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.Interfaces\bin\Release\net462\EPPlus.Interfaces.dll"
75-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.Interfaces\bin\Release\net35\EPPlus.Interfaces.dll"
87+
$tfms = "${{ env.TFMS }}" -split ";"
88+
foreach ($tfm in $tfms) {
89+
$tfm = $tfm.Trim()
90+
if ([string]::IsNullOrEmpty($tfm)) { continue }
91+
$dll = ".\src\EPPlus.Interfaces\bin\Release\$tfm\EPPlus.Interfaces.dll"
92+
Write-Host "Signing $dll"
93+
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL }} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 "$dll"
94+
}
95+
shell: pwsh
7696
- name: Sign EPPlus.System.Drawing.dll with AzureSignTool
7797
run: |
78-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.System.Drawing\bin\Release\net9.0\EPPlus.System.Drawing.dll"
79-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.System.Drawing\bin\Release\net8.0\EPPlus.System.Drawing.dll"
80-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.System.Drawing\bin\Release\netstandard2.1\EPPlus.System.Drawing.dll"
81-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.System.Drawing\bin\Release\netstandard2.0\EPPlus.System.Drawing.dll"
82-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.System.Drawing\bin\Release\net462\EPPlus.System.Drawing.dll"
83-
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 ".\src\EPPlus.System.Drawing\bin\Release\net35\EPPlus.System.Drawing.dll"
98+
$tfms = "${{ env.TFMS }}" -split ";"
99+
foreach ($tfm in $tfms) {
100+
$tfm = $tfm.Trim()
101+
if ([string]::IsNullOrEmpty($tfm)) { continue }
102+
$dll = ".\src\EPPlus.System.Drawing\bin\Release\$tfm\EPPlus.System.Drawing.dll"
103+
Write-Host "Signing $dll"
104+
azuresigntool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL }} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -tr http://timestamp.globalsign.com/tsa/advanced -td sha256 "$dll"
105+
}
106+
shell: pwsh
107+
# --- Sign DLLs ---
108+
84109
- name: Pack NuGet package
85110
run: dotnet pack ./src/EPPlus.sln --configuration Release --output ./output
86111
- name: Sign NuGet package
87112
run: |
88-
NuGetKeyVaultSignTool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL}} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -tr http://timestamp.globalsign.com/tsa/advanced -fd sha256 -td sha256 -own EPPlusSoftware ".\output\*.nupkg"
113+
NuGetKeyVaultSignTool.exe sign -kvu ${{ secrets.EPPLUS_CODE_SIGNING_KEY_VAULT_URL }} -kvc ${{ secrets.EPPLUS_CODE_SIGNING_CERTIFICATE_NAME }} -kvi ${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }} -kvs ${{ secrets.EPPLUS_CODE_SIGNING_SECRET }} -kvt ${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }} -tr http://timestamp.globalsign.com/tsa/advanced -fd sha256 -td sha256 -own EPPlusSoftware ".\output\*.nupkg"
89114
- name: Upload NuGet package as artifact
90115
uses: actions/upload-artifact@v4
91116
with:
92-
name: signed-nuget-package
93-
path: ./output/*.nupkg
94-
# --- SBOM ---
95-
- name: Upload SBOM to Azure Blob Storage
117+
name: signed-nuget-package
118+
path: ./output/*.nupkg
119+
120+
# --- SBOM (after build to avoid CycloneDX overwriting project.assets.json) ---
121+
- name: Install CycloneDX
122+
run: dotnet tool install --global CycloneDX
123+
- name: Generate combined SBOM
124+
run: dotnet CycloneDX ./src/EPPlus/EPPlus.csproj -o ./sbom -F Json -st Library -sv ${{ env.VERSION }} -fn epplus-${{ env.VERSION }}.sbom.json -imp ./src/EPPlus/sbom-metadata-template.xml --spec-version 1.6
125+
- name: Generate per-TFM SBOMs
126+
run: |
127+
$tfms = "${{ env.TFMS }}" -split ";"
128+
foreach ($tfm in $tfms) {
129+
$tfm = $tfm.Trim()
130+
if ([string]::IsNullOrEmpty($tfm)) { continue }
131+
Write-Host "Generating SBOM for $tfm"
132+
dotnet CycloneDX ./src/EPPlus/EPPlus.csproj -o ./sbom -F Json -st Library -sv ${{ env.VERSION }} -fn "epplus-${{ env.VERSION }}.$tfm.sbom.json" -imp ./src/EPPlus/sbom-metadata-template.xml --framework $tfm --spec-version 1.6
133+
}
134+
shell: pwsh
135+
- name: Generate SHA-256 checksums for all SBOMs
96136
run: |
97-
az storage blob upload `
98-
--account-name eppluswebprod `
99-
--container-name sbom `
100-
--name epplus-${{ env.VERSION }}.sbom.json `
101-
--file ./sbom/epplus-${{ env.VERSION }}.sbom.json `
102-
--auth-mode login `
103-
--overwrite
137+
Get-ChildItem -Path "./sbom" -Filter "*.sbom.json" | ForEach-Object {
138+
$hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower()
139+
"$hash $($_.Name)" | Out-File -FilePath "$($_.FullName).sha256" -Encoding utf8NoBOM
140+
Write-Host "Checksum generated for $($_.Name): $hash"
141+
}
104142
shell: pwsh
105-
- name: Upload SBOM checksum to Azure Blob Storage
143+
- name: Upload all SBOMs to Azure Blob Storage
106144
run: |
107-
az storage blob upload `
108-
--account-name eppluswebprod `
109-
--container-name sbom `
110-
--name epplus-${{ env.VERSION }}.sbom.json.sha256 `
111-
--file ./sbom/epplus-${{ env.VERSION }}.sbom.json.sha256 `
112-
--auth-mode login `
113-
--overwrite
145+
Get-ChildItem -Path "./sbom" | ForEach-Object {
146+
Write-Host "Uploading $($_.Name)"
147+
az storage blob upload `
148+
--account-name eppluswebprod `
149+
--container-name sbom `
150+
--name $_.Name `
151+
--file $_.FullName `
152+
--auth-mode login `
153+
--overwrite
154+
}
114155
shell: pwsh
115-
- name: Upload SBOM as artifact
156+
- name: Upload all SBOMs as artifact
116157
uses: actions/upload-artifact@v4
117158
with:
118-
name: sbom
119-
path: |
120-
./sbom/epplus-${{ env.VERSION }}.sbom.json
121-
./sbom/epplus-${{ env.VERSION }}.sbom.json.sha256
159+
name: sbom
160+
path: ./sbom/
122161
# --- SBOM ---
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Generates and uploads SBOMs for a specific EPPlus version without running the full build pipeline.
2+
# Useful for backfilling SBOMs for older releases.
3+
# Triggered manually via workflow_dispatch with a version input.
4+
5+
name: Generate SBOM
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: 'EPPlus version to generate SBOMs for (e.g. 8.4.1)'
12+
required: true
13+
type: string
14+
15+
jobs:
16+
sbom:
17+
runs-on: windows-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
# Check out the release branch so that the csproj reflects the correct
22+
# version and dependencies for the requested version
23+
ref: release/epplus${{ github.event.inputs.version }}
24+
25+
- name: Fetch sbom-metadata-template.xml from develop8
26+
run: |
27+
git fetch origin develop8
28+
git checkout origin/develop8 -- src/EPPlus/sbom-metadata-template.xml
29+
shell: pwsh
30+
31+
- name: Setup .NET
32+
uses: actions/setup-dotnet@v4
33+
with:
34+
dotnet-version: |
35+
9.0.x
36+
10.0.x
37+
38+
- name: Read target frameworks from csproj
39+
run: |
40+
$xml = [xml](Get-Content ./src/EPPlus/EPPlus.csproj)
41+
$tfms = $xml.Project.PropertyGroup.TargetFrameworks | Where-Object { $_ } | Select-Object -First 1
42+
echo "VERSION=${{ github.event.inputs.version }}" >> $env:GITHUB_ENV
43+
echo "TFMS=$tfms" >> $env:GITHUB_ENV
44+
shell: pwsh
45+
46+
- name: Restore dependencies
47+
run: dotnet restore ./src/EPPlus.sln
48+
49+
- name: Install CycloneDX
50+
run: dotnet tool install --global CycloneDX
51+
52+
- name: Generate combined SBOM
53+
run: dotnet CycloneDX ./src/EPPlus/EPPlus.csproj -o ./sbom -F Json -st Library -sv ${{ env.VERSION }} -fn epplus-${{ env.VERSION }}.sbom.json -imp ./src/EPPlus/sbom-metadata-template.xml --spec-version 1.6
54+
55+
- name: Generate per-TFM SBOMs
56+
run: |
57+
$tfms = "${{ env.TFMS }}" -split ";"
58+
foreach ($tfm in $tfms) {
59+
$tfm = $tfm.Trim()
60+
if ([string]::IsNullOrEmpty($tfm)) { continue }
61+
Write-Host "Generating SBOM for $tfm"
62+
dotnet CycloneDX ./src/EPPlus/EPPlus.csproj -o ./sbom -F Json -st Library -sv ${{ env.VERSION }} -fn "epplus-${{ env.VERSION }}.$tfm.sbom.json" -imp ./src/EPPlus/sbom-metadata-template.xml --framework $tfm --spec-version 1.6
63+
}
64+
shell: pwsh
65+
66+
- name: Generate SHA-256 checksums for all SBOMs
67+
run: |
68+
Get-ChildItem -Path "./sbom" -Filter "*.sbom.json" | ForEach-Object {
69+
$hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower()
70+
"$hash $($_.Name)" | Out-File -FilePath "$($_.FullName).sha256" -Encoding utf8NoBOM
71+
Write-Host "Checksum generated for $($_.Name): $hash"
72+
}
73+
shell: pwsh
74+
75+
- name: Authenticate to Azure
76+
uses: Azure/login@v2
77+
with:
78+
creds: '{"clientId":"${{ secrets.EPPLUS_CODE_SIGNING_APPLICATION_ID }}","clientSecret":"${{ secrets.EPPLUS_CODE_SIGNING_SECRET }}","subscriptionId":"${{ secrets.EPPLUS_CODE_SIGNING_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.EPPLUS_CODE_SIGNING_TENENT_ID }}"}'
79+
80+
- name: Upload all SBOMs to Azure Blob Storage
81+
run: |
82+
Get-ChildItem -Path "./sbom" | ForEach-Object {
83+
Write-Host "Uploading $($_.Name)"
84+
az storage blob upload `
85+
--account-name eppluswebprod `
86+
--container-name sbom `
87+
--name $_.Name `
88+
--file $_.FullName `
89+
--auth-mode login `
90+
--overwrite
91+
}
92+
shell: pwsh
93+
94+
- name: Upload all SBOMs as artifact
95+
uses: actions/upload-artifact@v4
96+
with:
97+
name: sbom-${{ github.event.inputs.version }}
98+
path: ./sbom/

0 commit comments

Comments
 (0)