2626 run_cbt :
2727 type : boolean
2828 description : " Scan with CVE-bin-tool"
29- default : true
29+ default : false
3030 send_slack_message :
3131 type : boolean
3232 description : " Send a Slack message"
3333 default : true
3434
35+
36+ env :
37+ ARCH : ${{ inputs.arch }}
38+ IMAGE_URL : ${{ inputs.image_url }}
39+ IMAGE_TYPE : ${{ inputs.image_type }}
40+
3541jobs :
3642 scan-image :
3743 name : Scan Docker Image for Vulnerabilities (${{ inputs.image_type }}, ${{ inputs.arch }})
8086
8187 - name : Download Docker Image
8288 run : |
83- curl -L "${{ inputs.image_url }} " -o "${{ env.CVE_DIR }}/image.tar.gz"
89+ curl -L "$IMAGE_URL " -o "${{ env.CVE_DIR }}/image.tar.gz"
8490
8591 - name : Load into Docker
92+ if : ${{ inputs.run_cbt }}
8693 run : |
8794 output="$(docker load -i '${{ env.CVE_DIR }}/image.tar.gz')"
8895
@@ -108,28 +115,14 @@ jobs:
108115 if : ${{ inputs.run_trivy }}
109116 run : |
110117 "${{ env.CVE_DIR }}/trivy/trivy" image --scanners vuln --input "${{ env.CVE_DIR }}/image.tar" > "${{ env.CVE_DIR }}/trivy-summary.txt"
111- "${{ env.CVE_DIR }}/trivy/trivy" image --scanners vuln --input "${{ env.CVE_DIR }}/image.tar" -f json > "${{ env.CVE_DIR }}/trivy-summary.json"
118+ "${{ env.CVE_DIR }}/trivy/trivy" image --scanners vuln --input "${{ env.CVE_DIR }}/image.tar" -f cyclonedx > "${{ env.CVE_DIR }}/trivy-summary.json"
112119
113- - name : Upload Trivy Report Summary Artifact
114- if : ${{ inputs.run_trivy }}
115- uses : actions/upload-artifact@v4
116- with :
117- name : ${{ inputs.image_type }}-${{ inputs.arch }}-trivy-summary
118- path : " ${{ env.CVE_DIR }}/trivy-summary.txt"
119-
120120 - name : Scan with Grype
121121 if : ${{ inputs.run_grype }}
122122 run : |
123123 "${{ env.CVE_DIR }}/grype/grype" "docker-archive:${{ env.CVE_DIR }}/image.tar" > "${{ env.CVE_DIR }}/grype-summary.txt"
124- "${{ env.CVE_DIR }}/grype/grype" "docker-archive:${{ env.CVE_DIR }}/image.tar" -o json > "${{ env.CVE_DIR }}/grype-summary.json"
124+ "${{ env.CVE_DIR }}/grype/grype" "docker-archive:${{ env.CVE_DIR }}/image.tar" -o cyclonedx- json > "${{ env.CVE_DIR }}/grype-summary.json"
125125
126- - name : Upload Grype Report Summary Artifact
127- if : ${{ inputs.run_grype }}
128- uses : actions/upload-artifact@v4
129- with :
130- name : ${{ inputs.image_type }}-${{ inputs.arch }}-grype-summary
131- path : " ${{ env.CVE_DIR }}/grype-summary.txt"
132-
133126 - name : Launch Docker Container
134127 if : ${{ inputs.run_cbt }}
135128 run : |
@@ -172,75 +165,79 @@ jobs:
172165
173166 - name : Upload cve-bin-tool Binary Scan Artifact
174167 if : ${{ inputs.run_cbt }}
175- uses : actions/upload-artifact@v4
168+ uses : actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
176169 with :
177170 name : ${{ inputs.image_type }}-${{ inputs.arch }}-cve-bin-tool-memgraph-summary
178171 path : " ${{ env.CVE_DIR }}/cve-bin-tool-memgraph-summary.json"
179172
180173 - name : Upload cve-bin-tool Language Scan Artifact
181174 if : ${{ inputs.run_cbt }}
182- uses : actions/upload-artifact@v4
175+ uses : actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
183176 with :
184177 name : ${{ inputs.image_type }}-${{ inputs.arch }}-cve-bin-tool-language-summary
185178 path : " ${{ env.CVE_DIR }}/cve-bin-tool-lang-summary.json"
186179
187180 - name : Upload cve-bin-tool APT Package Scan Artifact
188181 if : ${{ inputs.run_cbt }}
189- uses : actions/upload-artifact@v4
182+ uses : actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
190183 with :
191184 name : ${{ inputs.image_type }}-${{ inputs.arch }}-cve-bin-tool-apt-summary
192185 path : " ${{ env.CVE_DIR }}/cve-bin-tool-apt-summary.json"
193186
187+ # TODO(matt): cve-bin-tool is pretty broken, so we will not use it at
188+ # least until the next minor version release, after which we can handle
189+ # the JSON output from cve-bin-tool.
194190 - name : Combine Reports
195191 if : ${{ inputs.run_trivy || inputs.run_grype }}
192+ env :
193+ COLUMNS : 200
196194 run : |
195+ if [[ "$ARCH" == "amd64" ]]; then
196+ CYCLONEDXURL="https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.29.1/cyclonedx-linux-x64"
197+ else
198+ CYCLONEDXURL="https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.29.1/cyclonedx-linux-arm64"
199+ fi
200+
201+ curl -L -o cyclonedx "$CYCLONEDXURL"
202+ chmod +x cyclonedx
203+
204+ ./cyclonedx merge --input-files \
205+ "${{ env.CVE_DIR }}/trivy-summary.json" \
206+ "${{ env.CVE_DIR }}/grype-summary.json" \
207+ --output-format json \
208+ --output-file "${{ env.CVE_DIR }}/combined_report.json"
209+
210+ rm -v cyclonedx
197211 source "${{ env.CVE_DIR }}/env/bin/activate"
198- python3 scripts/combine_reports .py "${{ env.CVE_DIR }}/grype-summary .json" "${{ env.CVE_DIR }}/trivy-summary.json"
212+ python3 scripts/format_cve_table .py "${{ env.CVE_DIR }}/combined_report .json"
199213
200214 - name : Upload Combined Report Artifact
201215 if : ${{ inputs.run_trivy || inputs.run_grype }}
202- uses : actions/upload-artifact@v4
216+ uses : actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
203217 with :
204- name : ${{ inputs.image_type }}-${{ inputs.arch }}-combined-report
205- path : " ${{ env.CVE_DIR }}/combined_report.txt"
218+ name : ${{ inputs.image_type }}-${{ inputs.arch }}-cve-report
219+ path : |
220+ ${{ env.CVE_DIR }}/combined_report.json
221+ ${{ env.CVE_DIR }}/combined_report.txt
222+ ${{ env.CVE_DIR }}/trivy-summary.txt
223+ ${{ env.CVE_DIR }}/trivy-summary.json
224+ ${{ env.CVE_DIR }}/grype-summary.txt
225+ ${{ env.CVE_DIR }}/grype-summary.json
206226
207227 - name : Send Slack Message
208- if : ${{ inputs.send_slack_message && always() }}
228+ if : always()
209229 id : slack-message
210230 env :
211231 INFRA_WEBHOOK_URL : ${{ secrets.INFRA_WEBHOOK_URL }}
232+ SEND_MESSAGE : ${{ inputs.send_slack_message }}
212233 run : |
213- # Check if any summary files exist
214- files=(
215- trivy-summary.json
216- grype-summary.json
217- cve-bin-tool-memgraph-summary.json
218- cve-bin-tool-lang-summary.json
219- cve-bin-tool-apt-summary.json
220- )
221-
222- summary_files_exist=false
223- for file in "${files[@]}"; do
224- if [ -f "${{ env.CVE_DIR }}/$file" ]; then
225- summary_files_exist=true
226- break
227- fi
228- done
229-
230- if [ "$summary_files_exist" = true ]; then
234+ if [[ -f "${{ env.CVE_DIR }}/combined_report.json" ]]; then
231235 source "${{ env.CVE_DIR }}/env/bin/activate"
232- python3 scripts/cve_message.py "${{ inputs.arch }}" "${{ inputs.image_type }}"
236+ python3 scripts/cve_message.py "$ARCH" "$IMAGE_TYPE" "${{ env.SEND_MESSAGE }}"
233237 else
234- echo "No summary files found. Skipping Slack message"
238+ echo "No combined report found. Skipping Slack message"
235239 fi
236240
237- - name : Upload Full CVE List artifact
238- if : ${{ steps.slack-message.outputs.success }}
239- uses : actions/upload-artifact@v4
240- with :
241- name : full-cve-list-artifact
242- path : " ${{ env.CVE_DIR }}/full-cve-list.txt"
243-
244241 - name : Cleanup
245242 if : always()
246243 run : |
0 commit comments