Skip to content

Commit 5e87dea

Browse files
committed
Task: Dependency track (#20670)
* Generate BOM files on build * Upload BOM to Dependency Track * Move Backoffice BOM generation to right after install The build and/or pack steps are deleting files that are needed for the BOM to be generated properly. * Split the BOM uploads into different jobs * Fix wrong usage of parameters * Move order of dependency track stage * Fix wrong umbracoVersion value * Small fixes * Log curl response headers * Correct version sent to dependency track * Adjusted curl flags * Fix bom file path * Fix dotnet bom file name * Add Login UI to dependency track * Generate BOM for E2E Tests * Move dependency track stage * Move acceptance test .env generation to e2e install template Needed as the post install script is expecting this to exist. * Use major version if public release * Missing ')' * Reverted npm install command changes in static assets project
1 parent 7af67d2 commit 5e87dea

File tree

4 files changed

+193
-27
lines changed

4 files changed

+193
-27
lines changed

build/azure-pipelines.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ parameters:
3434
displayName: Upload API docs
3535
type: boolean
3636
default: false
37+
- name: uploadDependencyTrack
38+
displayName: Upload BOMs to Dependency Track
39+
type: boolean
40+
default: false
3741
- name: forceReleaseTestFilter
3842
displayName: Force to use the release test filters
3943
type: boolean
@@ -103,6 +107,15 @@ stages:
103107
command: build
104108
projects: $(solution)
105109
arguments: "--configuration $(buildConfiguration) --no-restore --property:ContinuousIntegrationBuild=true --property:GeneratePackageOnBuild=true --property:PackageOutputPath=$(Build.ArtifactStagingDirectory)/nupkg"
110+
- powershell: |
111+
dotnet tool install --global CycloneDX
112+
dotnet-CycloneDX $(solution) --output $(Build.ArtifactStagingDirectory)/bom --filename bom-dotnet.xml
113+
displayName: 'Generate Backend BOM'
114+
- powershell: |
115+
npm install --global @cyclonedx/cyclonedx-npm
116+
cyclonedx-npm -o $(Build.ArtifactStagingDirectory)\bom\bom-login.xml --ignore-npm-errors --verbose
117+
displayName: Generate Login UI BOM
118+
workingDirectory: src/Umbraco.Web.UI.Login
106119
- task: PublishPipelineArtifact@1
107120
displayName: Publish nupkg
108121
inputs:
@@ -113,6 +126,11 @@ stages:
113126
inputs:
114127
targetPath: $(Build.SourcesDirectory)
115128
artifactName: build_output
129+
- task: PublishPipelineArtifact@1
130+
displayName: Publish Backend BOM
131+
inputs:
132+
targetPath: $(Build.ArtifactStagingDirectory)/bom
133+
artifactName: bom-backend
116134

117135
- job: B
118136
displayName: Build Bellissima Package
@@ -124,6 +142,11 @@ stages:
124142
lfs: false,
125143
fetchDepth: 500
126144
- template: templates/backoffice-install.yml
145+
- powershell: |
146+
npm install --global @cyclonedx/cyclonedx-npm
147+
cyclonedx-npm -o $(Build.ArtifactStagingDirectory)/bom/bom-backoffice.xml --ignore-npm-errors --verbose
148+
displayName: Generate Backoffice UI BOM
149+
workingDirectory: src/Umbraco.Web.UI.Client
127150
- script: npm run build:for:npm
128151
displayName: Run build:for:npm
129152
workingDirectory: src/Umbraco.Web.UI.Client
@@ -140,6 +163,35 @@ stages:
140163
inputs:
141164
targetPath: $(Build.ArtifactStagingDirectory)/npm
142165
artifactName: npm
166+
- publish: $(Build.ArtifactStagingDirectory)/bom
167+
artifact: bom-frontend
168+
displayName: 'Publish Frontend BOM'
169+
170+
- stage: E2E_BOM
171+
displayName: E2E Tests BOM Generation
172+
dependsOn: []
173+
jobs:
174+
- job:
175+
displayName: E2E Generate BOM
176+
pool:
177+
vmImage: "ubuntu-latest"
178+
steps:
179+
- checkout: self
180+
submodules: false
181+
lfs: false,
182+
fetchDepth: 500
183+
- template: templates/e2e-install.yml
184+
parameters:
185+
nodeVersion: ${{ variables.nodeVersion }}
186+
npm_config_cache: ${{ variables.npm_config_cache }}
187+
- powershell: |
188+
npm install --global @cyclonedx/cyclonedx-npm
189+
cyclonedx-npm -o $(Build.ArtifactStagingDirectory)/bom/bom-e2e.xml --ignore-npm-errors --verbose
190+
displayName: Generate E2E Tests BOM
191+
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
192+
- publish: $(Build.ArtifactStagingDirectory)/bom
193+
artifact: bom-e2e
194+
displayName: 'Publish E2E BOM'
143195

144196
- stage: Build_Docs
145197
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.buildApiDocs}}))
@@ -668,6 +720,34 @@ stages:
668720
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
669721
DatabaseType: ${{ variables.DatabaseType }}
670722

723+
- stage: Dependency_Track
724+
displayName: Dependency Track
725+
dependsOn:
726+
- Build
727+
- E2E_BOM
728+
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.uploadDependencyTrack}}))
729+
variables:
730+
# Determine Umbraco version based on whether it's a public release or not. If public release, use major version, else use full NuGet package version.
731+
umbracoVersion: $[ iif(eq(stageDependencies.Build.A.outputs['build.NBGV_PublicRelease'], 'True'), stageDependencies.Build.A.outputs['build.NBGV_VersionMajor'], stageDependencies.Build.A.outputs['build.NBGV_NuGetPackageVersion']) ]
732+
jobs:
733+
- template: templates/dependency-track.yml
734+
parameters:
735+
projectName: "Umbraco-CMS"
736+
umbracoVersion: $(umbracoVersion)
737+
projects:
738+
- name: "Backend"
739+
artifact: "bom-backend"
740+
bomFilePath: "bom-dotnet.xml"
741+
- name: "Login"
742+
artifact: "bom-backend"
743+
bomFilePath: "bom-login.xml"
744+
- name: "Backoffice"
745+
artifact: "bom-frontend"
746+
bomFilePath: "bom-backoffice.xml"
747+
- name: "E2E"
748+
artifact: "bom-e2e"
749+
bomFilePath: "bom-e2e.xml"
750+
671751
###############################################
672752
## Release
673753
###############################################
@@ -874,3 +954,4 @@ stages:
874954
ContainerName: "$web"
875955
BlobPrefix: v$(umbracoMajorVersion)/ui-api
876956
CleanTargetBeforeCopy: true
957+

build/nightly-E2E-setup-template.yml

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,38 +26,18 @@ steps:
2626
artifact: nupkg
2727
path: $(Agent.BuildDirectory)/app/nupkg
2828

29-
- task: NodeTool@0
30-
displayName: Use Node.js $(nodeVersion)
31-
inputs:
32-
versionSpec: $(nodeVersion)
33-
3429
- task: UseDotNet@2
3530
displayName: Use .NET SDK from global.json
3631
inputs:
3732
useGlobalJson: true
3833

39-
- pwsh: |
40-
"UMBRACO_USER_LOGIN=${{ parameters.PlaywrightUserEmail }}
41-
UMBRACO_USER_PASSWORD=${{ parameters.PlaywrightPassword }}
42-
URL=${{ parameters.ASPNETCORE_URLS }}
43-
STORAGE_STAGE_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth/user.json
44-
CONSOLE_ERRORS_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/console-errors.json" | Out-File .env
45-
displayName: Generate .env
46-
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
47-
48-
# Cache and restore NPM packages
49-
- task: Cache@2
50-
displayName: Cache NPM packages
51-
inputs:
52-
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
53-
restoreKeys: |
54-
npm_e2e | "$(Agent.OS)"
55-
npm_e2e
56-
path: ${{ parameters.npm_config_cache }}
57-
58-
- script: npm ci --no-fund --no-audit --prefer-offline
59-
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
60-
displayName: Restore NPM packages
34+
- template: templates/e2e-install.yml
35+
parameters:
36+
nodeVersion: ${{ parameters.nodeVersion }}
37+
npm_config_cache: ${{ parameters.npm_config_cache }}
38+
PlaywrightUserEmail: ${{ parameters.PlaywrightUserEmail }}
39+
PlaywrightPassword: ${{ parameters.PlaywrightPassword }}
40+
ASPNETCORE_URLS: ${{ parameters.ASPNETCORE_URLS }}
6141

6242
# Install Template
6343
- pwsh: |
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
parameters:
2+
- name: projectName
3+
type: string
4+
- name: umbracoVersion
5+
type: string
6+
- name: projects
7+
type: object
8+
9+
jobs:
10+
- job: Create_DT_Project
11+
displayName: Create Dependency Track Project
12+
steps:
13+
- checkout: none
14+
15+
- bash: |
16+
project_id=$(curl --no-progress-meter -H "X-Api-Key: $(DT_API_KEY)" "$(DT_API_URL)/v1/project/lookup?name=${{ parameters.projectName }}&version=${{ parameters.umbracoVersion }}" | jq -r '.uuid')
17+
if [ "$project_id" != "null" ] && [ -n "$project_id" ]; then
18+
echo "Project '${{ parameters.projectName }}' with version '${{ parameters.umbracoVersion }}' already exists (ID: $project_id)."
19+
else
20+
project_id=$(curl --no-progress-meter \
21+
-X PUT "$(DT_API_URL)/v1/project" \
22+
-H "X-Api-Key: $(DT_API_KEY)" \
23+
-H "Content-Type: application/json" \
24+
-d '{"name": "${{ parameters.projectName }}", "version": "${{ parameters.umbracoVersion }}", "collectionLogic": "AGGREGATE_DIRECT_CHILDREN"}' \
25+
| jq -r '.uuid')
26+
if [ -z "$project_id" ] || [ "$project_id" == "null" ]; then
27+
echo "Failed to create project '${{ parameters.projectName }}' version '${{ parameters.umbracoVersion }}'."
28+
exit 1
29+
fi
30+
echo "Created project '${{ parameters.projectName }}' with version '${{ parameters.umbracoVersion }}' (ID: $project_id)."
31+
fi
32+
displayName: Ensure main project exists in Dependency Track
33+
34+
- ${{ each project in parameters.projects }}:
35+
- job:
36+
displayName: Upload ${{ project.name }} BOM
37+
dependsOn: Create_DT_Project
38+
steps:
39+
- checkout: none
40+
41+
- download: current
42+
artifact: ${{ project.artifact }}
43+
displayName: Download ${{ project.artifact }} artifact
44+
45+
- script: |
46+
curl --no-progress-meter --fail-with-body \
47+
-X POST "$(DT_API_URL)/v1/bom" \
48+
-H "X-Api-Key: $(DT_API_KEY)" \
49+
-H "Content-Type: multipart/form-data" \
50+
-F "autoCreate=true" \
51+
-F "projectName=${{ parameters.projectName }}-${{ project.name }}" \
52+
-F "projectVersion=${{ parameters.umbracoVersion }}" \
53+
-F "parentName=${{ parameters.projectName }}" \
54+
-F "parentVersion=${{ parameters.umbracoVersion }}" \
55+
-F "bom=@$(Pipeline.Workspace)/${{ project.artifact }}/${{ project.bomFilePath }}"
56+
displayName: Upload ${{ project.name }} BOM to Dependency Track

build/templates/e2e-install.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
parameters:
2+
- name: nodeVersion
3+
type: string
4+
default: ''
5+
6+
- name: npm_config_cache
7+
type: string
8+
default: ''
9+
10+
- name: PlaywrightUserEmail
11+
type: string
12+
default: ''
13+
14+
- name: PlaywrightPassword
15+
type: string
16+
default: ''
17+
18+
- name: ASPNETCORE_URLS
19+
type: string
20+
default: ''
21+
22+
steps:
23+
- task: NodeTool@0
24+
displayName: Use Node.js $(nodeVersion)
25+
inputs:
26+
versionSpec: $(nodeVersion)
27+
28+
- pwsh: |
29+
"UMBRACO_USER_LOGIN=${{ parameters.PlaywrightUserEmail }}
30+
UMBRACO_USER_PASSWORD=${{ parameters.PlaywrightPassword }}
31+
URL=${{ parameters.ASPNETCORE_URLS }}
32+
STORAGE_STAGE_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth/user.json
33+
CONSOLE_ERRORS_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/console-errors.json" | Out-File .env
34+
displayName: Generate .env
35+
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
36+
37+
# Cache and restore NPM packages
38+
- task: Cache@2
39+
displayName: Cache NPM packages
40+
inputs:
41+
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
42+
restoreKeys: |
43+
npm_e2e | "$(Agent.OS)"
44+
npm_e2e
45+
path: ${{ parameters.npm_config_cache }}
46+
47+
- script: npm ci --no-fund --no-audit --prefer-offline
48+
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
49+
displayName: Restore NPM packages

0 commit comments

Comments
 (0)