Skip to content

Commit 20b8557

Browse files
authored
workflow: Updated wind-turbine-anomaly-detection sample app workflow (open-edge-platform#356)
updates the wind-turbine-anomaly-detection sample app workflow by reorganizing the scanning jobs into separate, conditional executions and adding workflow_call support. The changes improve workflow modularity and enable selective scan execution. Reorganized the monolithic scan job into separate, conditional jobs for different scan types (trivy-fs, trivy-image, trivy-config-helm, etc.) Added workflow dispatch inputs and workflow_call capabilities to allow selective execution of specific scans Integrated the scan workflow into the pull request workflow to run all scans automatically Signed-off-by: Vellaisamy, Sathyendran <[email protected]>
1 parent c4975e1 commit 20b8557

File tree

3 files changed

+234
-44
lines changed

3 files changed

+234
-44
lines changed

.github/workflows/windturbine-sampleapp-pull-request.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ on:
1111
- 'manufacturing-ai-suite/wind-turbine-anomaly-detection/*'
1212
workflow_call:
1313
workflow_dispatch:
14-
permissions: {}
14+
15+
permissions:
16+
contents: read
17+
packages: read
18+
pull-requests: read
19+
security-events: write
20+
actions: read
1521

1622
jobs:
1723
windturbine-sample-app-pre-merge-build:
@@ -80,4 +86,9 @@ jobs:
8086
run: |
8187
cd "${{ github.workspace }}"
8288
cd ./timeseries/manufacturing-ai-suite/wind-turbine-anomaly-detection
83-
make down
89+
make down
90+
91+
wind-turbine-anomaly-detection-scans:
92+
uses: ./.github/workflows/windturbine-sampleapp-scans.yml
93+
with:
94+
target: all-scans

.github/workflows/windturbine-sampleapp-scans.yml

Lines changed: 220 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
# SPDX-FileCopyrightText: (C) 2025 Intel Corporation
33
# SPDX-License-Identifier: Apache-2.0
44

5-
name: "[WindTurbine Sample App] SDLe Scans - Trivy, DBS, Bandit and Virus Scan"
6-
run-name: "[WindTurbine Sample App] SDLe Scans - Trivy, DBS, Bandit and Virus Scans workflow (by @${{ github.actor }} via ${{ github.event_name }})"
5+
name: "[WindTurbine Sample App] SDLe Scans"
6+
run-name: "[WindTurbine Sample App] SDLe Scans workflow (by @${{ github.actor }} via ${{ github.event_name }})"
77

88

99
# Only run at most 1 workflow concurrently per PR, unlimited for branches
@@ -13,9 +13,31 @@ concurrency:
1313

1414
on:
1515
workflow_dispatch:
16+
inputs:
17+
target:
18+
description: 'Which Scans to run'
19+
type: choice
20+
options:
21+
- all-scans
22+
- trivy-fs-scan
23+
- trivy-image-scan
24+
- trivy-config-scan
25+
- trivy-dockerfile-scan
26+
- trivy-helm-scan
27+
- bandit-scan
28+
- virus-scan
29+
- dbs-scan
30+
31+
workflow_call:
32+
inputs:
33+
target:
34+
description: 'Which Scans to run'
35+
required: false
36+
type: string
1637

1738
jobs:
18-
trivy-scan-job:
39+
trivy-fs-scan:
40+
if: ${{ (inputs.target == 'trivy-fs-scan') || (inputs.target == 'all-scans') }}
1941
permissions:
2042
contents: read
2143
packages: read # needed for actions/checkout
@@ -80,6 +102,77 @@ jobs:
80102
trivy fs . --format template --template "@trivy-html.tpl" -o "trivy_fs_full_report_code_scan.html"
81103
trivy fs --list-all-pkgs --format template --template "@csv.tpl" --output trivy-fs-full-report.csv .
82104
trivy fs --ignore-unfixed . | tee trivy-fs-full-report-ignore-unfixed.txt
105+
106+
- name: Upload Trivy FS Scan Report
107+
continue-on-error: true
108+
if: always()
109+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
110+
with:
111+
name: Trivy Report - Filesystem Scan
112+
path: |
113+
manufacturing-ai-suite/wind-turbine-anomaly-detection/trivy*
114+
115+
trivy-image-scan:
116+
if: ${{ (inputs.target == 'trivy-image-scan') || (inputs.target == 'all-scans') }}
117+
permissions:
118+
contents: read
119+
packages: read # needed for actions/checkout
120+
runs-on: ubuntu-24.04
121+
steps:
122+
- name: Checkout Code
123+
uses: actions/checkout@v4
124+
with:
125+
persist-credentials: false
126+
- name: Install Trivy from Aqua Security APT repo
127+
run: |
128+
sudo apt-get update
129+
sudo apt-get install -y gnupg lsb-release wget apt-transport-https curl jq
130+
curl -fsSL https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy.gpg
131+
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -cs) main" | \
132+
sudo tee /etc/apt/sources.list.d/trivy.list > /dev/null
133+
sudo apt-get update
134+
sudo apt-get install -y trivy
135+
- name: Install Trivy
136+
continue-on-error: true
137+
shell: bash
138+
run: |
139+
pwd
140+
cd manufacturing-ai-suite/wind-turbine-anomaly-detection/
141+
trivy --version
142+
which trivy
143+
trivy image --download-db-only
144+
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl
145+
cat << 'EOF' > csv.tpl
146+
{{ range . }}
147+
Trivy Vulnerability Scan Results ({{- .Target -}})
148+
VulnerabilityID,Severity,CVSS Score,Title,Library,Vulnerable Version,Fixed Version,Information URL,Triage Information
149+
{{ range .Vulnerabilities }}
150+
{{- .VulnerabilityID }},
151+
{{- .Severity }},
152+
{{- range $key, $value := .CVSS }}
153+
{{- if (eq $key "nvd") }}
154+
{{- .V3Score -}}
155+
{{- end }}
156+
{{- end }},
157+
{{- quote .Title }},
158+
{{- quote .PkgName }},
159+
{{- quote .InstalledVersion }},
160+
{{- quote .FixedVersion }},
161+
{{- .PrimaryURL }}
162+
{{ else -}}
163+
No vulnerabilities found at this time.
164+
{{ end }}
165+
Trivy Dependency Scan Results ({{ .Target }})
166+
ID,Name,Version,Notes
167+
{{ range .Packages -}}
168+
{{- quote .ID }},
169+
{{- quote .Name }},
170+
{{- quote .Version }}
171+
{{ else -}}
172+
No dependencies found at this time.
173+
{{ end }}
174+
{{ end }}
175+
EOF
83176
84177
- name: Trivy Image Scan
85178
continue-on-error: true
@@ -93,20 +186,20 @@ jobs:
93186
sed -i -e "s|MQTT_PUBLISHER_IMAGE=.*|MQTT_PUBLISHER_IMAGE=ia-mqtt-publisher:latest|g" .env
94187
make build
95188
96-
trivy image ia-opcua-server:latest --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_image_scan_opcua_server.html
97-
trivy image ia-opcua-server:latest --ignore-unfixed --format template --template "@csv.tpl" -o trivy_image_scan_opcua_server.csv
98-
trivy image --quiet --format spdx-json --output trivy_image_scan_opcua_server.spdx.json ia-opcua-server:latest
189+
trivy image ia-opcua-server:latest --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy-image-scan-opcua-server-ignore-unfixed.html
190+
trivy image ia-opcua-server:latest --ignore-unfixed --format template --template "@csv.tpl" -o trivy-image-scan-opcua-server-ignore-unfixed.csv
191+
trivy image --quiet --format spdx-json --output trivy-image-scan-opcua-server.spdx.json ia-opcua-server:latest
99192
100-
trivy image --list-all-pkgs --format template --template "@csv.tpl" --output trivy-fs-opcua.csv ia-opcua-server:latest
101-
trivy image --ignore-unfixed ia-opcua-server:latest | tee trivy-fs-opcua-ignore-unfixed.txt
193+
trivy image --list-all-pkgs --format template --template "@csv.tpl" --output trivy-image-scan_opcua-server-list-all-pkgs.csv ia-opcua-server:latest
194+
trivy image --ignore-unfixed ia-opcua-server:latest | tee trivy-image-scan-opcua-server-ignore-unfixed.txt
102195
103196
104-
trivy image ia-mqtt-publisher:latest --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_image_scan_mqtt_publisher.html
105-
trivy image ia-mqtt-publisher:latest --ignore-unfixed --format template --template "@csv.tpl" -o trivy_image_scan_mqtt_publisher.csv
106-
trivy image --quiet --format spdx-json --output trivy_image_scan_mqtt_publisher.spdx.json ia-mqtt-publisher:latest
197+
trivy image ia-mqtt-publisher:latest --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy-image-scan-mqtt-publisher-ignore-unfixed.html
198+
trivy image ia-mqtt-publisher:latest --ignore-unfixed --format template --template "@csv.tpl" -o trivy-image-scan-mqtt-publisher-ignore-unfixed.csv
199+
trivy image --quiet --format spdx-json --output trivy-image-scan-mqtt-publisher.spdx.json ia-mqtt-publisher:latest
107200
108-
trivy image --list-all-pkgs --format template --template "@csv.tpl" --output trivy-fs-mqttpublisher.csv ia-mqtt-publisher:latest
109-
trivy image --ignore-unfixed ia-mqtt-publisher:latest | tee trivy-fs-mqttpublisher-ignore-unfixed.txt
201+
trivy image --list-all-pkgs --format template --template "@csv.tpl" --output trivy-image-scan-mqtt-publisher-list-all-pkgs.csv ia-mqtt-publisher:latest
202+
trivy image --ignore-unfixed ia-mqtt-publisher:latest | tee trivy-image-scan-mqtt-publisher-ignore-unfixed.txt
110203
111204
echo "completed Wind Turbine Sample App Image scanning"
112205
@@ -115,54 +208,111 @@ jobs:
115208
if: always()
116209
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
117210
with:
118-
name: Trivy Scan report fs and image
211+
name: Trivy Report - Image Scan
119212
path: |
120-
manufacturing-ai-suite/wind-turbine-anomaly-detection/trivy*
213+
manufacturing-ai-suite/wind-turbine-anomaly-detection/trivy-image-scan*
214+
215+
trivy-config-helm-scan:
216+
if: ${{ (inputs.target == 'trivy-config-scan') || (inputs.target == 'trivy-helm-scan') || (inputs.target == 'all-scans') }}
217+
permissions:
218+
contents: read
219+
packages: read # needed for actions/checkout
220+
runs-on: ubuntu-24.04
221+
steps:
222+
- name: Checkout Code
223+
uses: actions/checkout@v4
224+
with:
225+
persist-credentials: false
226+
- name: Install Trivy from Aqua Security APT repo
227+
run: |
228+
sudo apt-get update
229+
sudo apt-get install -y gnupg lsb-release wget apt-transport-https curl jq
230+
curl -fsSL https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy.gpg
231+
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -cs) main" | \
232+
sudo tee /etc/apt/sources.list.d/trivy.list > /dev/null
233+
sudo apt-get update
234+
sudo apt-get install -y trivy
235+
- name: Install Trivy
236+
continue-on-error: true
237+
shell: bash
238+
run: |
239+
pwd
240+
cd manufacturing-ai-suite/wind-turbine-anomaly-detection/
241+
trivy --version
242+
which trivy
243+
trivy image --download-db-only
244+
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl
245+
cat << 'EOF' > csv.tpl
246+
{{ range . }}
247+
Trivy Vulnerability Scan Results ({{- .Target -}})
248+
VulnerabilityID,Severity,CVSS Score,Title,Library,Vulnerable Version,Fixed Version,Information URL,Triage Information
249+
{{ range .Vulnerabilities }}
250+
{{- .VulnerabilityID }},
251+
{{- .Severity }},
252+
{{- range $key, $value := .CVSS }}
253+
{{- if (eq $key "nvd") }}
254+
{{- .V3Score -}}
255+
{{- end }}
256+
{{- end }},
257+
{{- quote .Title }},
258+
{{- quote .PkgName }},
259+
{{- quote .InstalledVersion }},
260+
{{- quote .FixedVersion }},
261+
{{- .PrimaryURL }}
262+
{{ else -}}
263+
No vulnerabilities found at this time.
264+
{{ end }}
265+
Trivy Dependency Scan Results ({{ .Target }})
266+
ID,Name,Version,Notes
267+
{{ range .Packages -}}
268+
{{- quote .ID }},
269+
{{- quote .Name }},
270+
{{- quote .Version }}
271+
{{ else -}}
272+
No dependencies found at this time.
273+
{{ end }}
274+
{{ end }}
275+
EOF
121276
122277
- name: Trivy config scan for helm charts
123278
run: |
124279
cd manufacturing-ai-suite/wind-turbine-anomaly-detection/
125280
make gen_helm_charts
126281
cd helm
127-
trivy config . >> trivy_helm.txt
282+
trivy config . >> trivy-wind-turbine-helm.txt
128283
129284
- name: Upload Scan artifact to Github
130285
uses: actions/upload-artifact@v4
131286
with:
132-
name: Trivy Config Scan for Helm
133-
path: manufacturing-ai-suite/wind-turbine-anomaly-detection/helm/trivy_*
287+
name: Trivy Report - Config scan for Helm
288+
path: manufacturing-ai-suite/wind-turbine-anomaly-detection/helm/trivy-wind-turbine-helm.txt
134289

135-
trivy-config-opcua-dockerfile-scan:
290+
trivy-config-dockerfile-scan:
291+
if: ${{ (inputs.target == 'trivy-config-scan') || (inputs.target == 'trivy-dockerfile-scan') || (inputs.target == 'all-scans') }}
136292
permissions:
137293
contents: read
138294
packages: read # needed for actions/checkout
139-
name: Scan OPCUA Dockerfile
140-
strategy:
141-
fail-fast: false
142-
uses: open-edge-platform/edge-ai-libraries/.github/workflows/trivy-config-mode.yaml@e6e04af3dbca805db9118b85a22ad2998f7eec39
143-
with:
144-
dockerfile-path: manufacturing-ai-suite/wind-turbine-anomaly-detection/simulator/opcua-server/Dockerfile
145-
trivy-report-format: 'json'
146-
severity-levels: 'HIGH,CRITICAL'
147-
output-report-path: trivy-opcua-dockerfile.json
148-
name: Time Series OPCUA Dockerfile
149-
150-
trivy-config-mqttpublisher-dockerfile-scan:
151-
permissions:
152-
contents: read
153-
packages: read # needed for actions/checkout
154-
name: Scan mqttpublisher Dockerfile
295+
name: Scan Dockerfiles (OPCUA & mqttpublisher)
155296
strategy:
156297
fail-fast: false
298+
matrix:
299+
include:
300+
- dockerfile-path: manufacturing-ai-suite/wind-turbine-anomaly-detection/simulator/opcua-server/Dockerfile
301+
output-report-path: trivy-opcua-dockerfile.json
302+
scan-name: Time Series OPCUA Dockerfile
303+
- dockerfile-path: manufacturing-ai-suite/wind-turbine-anomaly-detection/simulator/mqtt-publisher/Dockerfile
304+
output-report-path: trivy-mqttpublisher-dockerfile.json
305+
scan-name: Time Series mqttpublisher Dockerfile
157306
uses: open-edge-platform/edge-ai-libraries/.github/workflows/trivy-config-mode.yaml@e6e04af3dbca805db9118b85a22ad2998f7eec39
158307
with:
159-
dockerfile-path: manufacturing-ai-suite/wind-turbine-anomaly-detection/simulator/mqtt-publisher/Dockerfile
308+
dockerfile-path: ${{ matrix.dockerfile-path }}
160309
trivy-report-format: 'json'
161310
severity-levels: 'HIGH,CRITICAL'
162-
output-report-path: trivy-mqttpublisher-dockerfile.json
163-
name: Time Series mqttpublisher Dockerfile
311+
output-report-path: ${{ matrix.output-report-path }}
312+
name: ${{ matrix.scan-name }}
164313

165314
bandit-scans:
315+
if: ${{ (inputs.target == 'bandit-scan') || (inputs.target == 'all-scans') }}
166316
permissions:
167317
contents: read
168318
packages: read # needed for actions/checkout
@@ -184,15 +334,43 @@ jobs:
184334
mkdir -p reports
185335
docker pull ghcr.io/pycqa/bandit/bandit
186336
echo "### Bandit Scan Results" >> $GITHUB_STEP_SUMMARY
187-
docker run --rm -v "${{ github.workspace }}:/src" ghcr.io/pycqa/bandit/bandit -r /src/manufacturing-ai-suite/wind-turbine-anomaly-detection/ -f txt -o /src/reports/bandit-report.txt || true >> $GITHUB_STEP_SUMMARY
337+
docker run --rm -v "${{ github.workspace }}:/src" ghcr.io/pycqa/bandit/bandit -r /src/manufacturing-ai-suite/wind-turbine-anomaly-detection/ -f json -o /src/reports/bandit-report.json || true >> $GITHUB_STEP_SUMMARY
188338
echo "Please find full report in bandit-report.txt" >> $GITHUB_STEP_SUMMARY
339+
ls -al
340+
pwd
341+
- name: Convert JSON to CSV
342+
run: |
343+
python3 <<EOF
344+
import json
345+
import csv
346+
347+
with open("reports/bandit-report.json") as f:
348+
data = json.load(f)
349+
350+
with open("reports/bandit-report.csv", "w", newline="") as csvfile:
351+
fieldnames = ["filename", "line_number", "issue_text", "severity", "confidence", "test_name"]
352+
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
353+
writer.writeheader()
354+
for issue in data.get("results", []):
355+
writer.writerow({
356+
"filename": issue["filename"],
357+
"line_number": issue["line_number"],
358+
"issue_text": issue["issue_text"],
359+
"severity": issue["issue_severity"],
360+
"confidence": issue["issue_confidence"],
361+
"test_name": issue["test_name"]
362+
})
363+
EOF
189364
- name: Upload Scan Reports
190365
uses: actions/upload-artifact@v4
191366
with:
192367
name: bandit-report
193-
path: reports/bandit-report.txt
368+
path: |
369+
reports/bandit-report.json
370+
reports/bandit-report.csv
194371
195372
virus-scans:
373+
if: ${{ (inputs.target == 'virus-scan') || (inputs.target == 'all-scans') }}
196374
permissions:
197375
contents: read
198376
packages: read # needed for actions/checkout
@@ -222,6 +400,7 @@ jobs:
222400
path: reports/clamav-report.txt
223401

224402
DBS_job:
403+
if: ${{ (inputs.target == 'dbs-scan') || (inputs.target == 'all-scans') }}
225404
runs-on: ubuntu-24.04
226405
permissions:
227406
contents: read
@@ -312,4 +491,4 @@ jobs:
312491
uses: actions/upload-artifact@v4
313492
with:
314493
name: DBS_time-series-analytics
315-
path: manufacturing-ai-suite/wind-turbine-anomaly-detection/dbs_scan_*
494+
path: manufacturing-ai-suite/wind-turbine-anomaly-detection/dbs_scan_*

manufacturing-ai-suite/wind-turbine-anomaly-detection/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,4 @@ MR_PSQL_PASSWORD=
7777
# MR_MINIO_ACCESS_KEY length must be a minimum of 10 alphanumeric characters with atleast one digit
7878
MR_MINIO_ACCESS_KEY=
7979
# MR_MINIO_SECRET_KEY length must be a minimum of 10 alphanumeric characters with atleast one digit
80-
MR_MINIO_SECRET_KEY=
80+
MR_MINIO_SECRET_KEY=

0 commit comments

Comments
 (0)