@@ -133,27 +133,42 @@ jobs:
133133 (($id + "|" + $pv + "|" + (($m.vulnerability.severity // "") | ascii_upcase)))
134134 ] | .[]' "$B_GRYPE" | sort -u > /tmp/b_entries.txt || true
135135
136- # unimos y normalizamos
136+ # union de entradas (unique)
137137 cat /tmp/a_entries.txt /tmp/b_entries.txt | sort -u > /tmp/all_entries.txt || true
138138
139+ # --- crear archivo ordenado por severidad desc (rank) y luego por ID ---
140+ awk -F'|' '
141+ BEGIN {
142+ map["CRITICAL"]=5; map["HIGH"]=4; map["MEDIUM"]=3; map["LOW"]=2; map["UNKNOWN"]=1;
143+ }
144+ {
145+ id=$1; pv=$2; sev=toupper($3);
146+ rank = (sev in map ? map[sev] : 0);
147+ # output: rank|sev|id|pv
148+ printf("%d|%s|%s|%s\n", rank, sev, id, pv);
149+ }
150+ ' /tmp/all_entries.txt | sort -t'|' -k1,1nr -k3,3 | cut -d'|' -f2- > /tmp/all_sorted.txt || true
151+
139152 # --- START MD FILE ---
140153 echo "# Vulnerability comparison: ${A_BRANCH} **vs** ${B_BRANCH}" > "${OUT}"
141154 echo "" >> "${OUT}"
142155
143- # --- TABLE requested: VulnerabilityID | package:version | Severity | branches ---
144- echo "| VulnerabilityID | package:version | Severity | branches |" >> "${OUT}"
156+ # --- TABLE requested: Severity | VulnerabilityID | package:version | branches ---
157+ echo "| Severity | VulnerabilityID | package:version | branches |" >> "${OUT}"
145158 echo "|---|---|---|---|" >> "${OUT}"
146159
147- if [ -s /tmp/all_entries .txt ]; then
160+ if [ -s /tmp/all_sorted .txt ]; then
148161 while IFS= read -r line; do
149- # line format: ID|pkg:version|SEVERITY
150- id =$(echo "$line" | awk -F'|' '{print $1}')
151- pv =$(echo "$line" | awk -F'|' '{print $2}')
152- sev =$(echo "$line" | awk -F'|' '{print $3}')
162+ # line format: SEV| ID|PKG:VER
163+ sev =$(echo "$line" | awk -F'|' '{print $1}')
164+ id =$(echo "$line" | awk -F'|' '{print $2}')
165+ pv =$(echo "$line" | awk -F'|' '{print $3}')
153166
154167 inA=0; inB=0
155- if grep -Fxq "$line" /tmp/a_entries.txt 2>/dev/null; then inA=1; fi
156- if grep -Fxq "$line" /tmp/b_entries.txt 2>/dev/null; then inB=1; fi
168+ # membership checks use original a_entries/b_entries (ID|pkg|sev)
169+ entry="${id}|${pv}|${sev}"
170+ if grep -Fxq "$entry" /tmp/a_entries.txt 2>/dev/null; then inA=1; fi
171+ if grep -Fxq "$entry" /tmp/b_entries.txt 2>/dev/null; then inB=1; fi
157172
158173 if [ "$inA" -eq 1 ] && [ "$inB" -eq 1 ]; then
159174 branches="**BOTH**"
@@ -163,10 +178,8 @@ jobs:
163178 branches="${B_BRANCH}"
164179 fi
165180
166- # salida segura (escapa pipes en campos si hay)
167- # aquí asumimos que id/pv/sev no contienen pipes adicionales
168- echo "| ${id} | ${pv} | ${sev} | ${branches} |" >> "${OUT}"
169- done < /tmp/all_entries.txt
181+ echo "| ${sev} | ${id} | ${pv} | ${branches} |" >> "${OUT}"
182+ done < /tmp/all_sorted.txt
170183 else
171184 echo "| - | - | - | - |" >> "${OUT}"
172185 echo "" >> "${OUT}"
@@ -189,7 +202,6 @@ jobs:
189202 done
190203
191204 echo "" >> "${OUT}"
192- # añadimos secciones de detalle (opcionales) - mantenidas o puedes comentarlas si no quieres
193205 echo "----" >> "${OUT}"
194206 echo "Artifacts included:" >> "${OUT}"
195207 echo "- ${REPORT_DIR}/branchA-sbom.cdx.json" >> "${OUT}"
@@ -198,60 +210,61 @@ jobs:
198210 echo "- ${REPORT_DIR}/branchB-grype.json" >> "${OUT}"
199211 echo "- ${REPORT_DIR}/comparison-report.md (this file)" >> "${OUT}"
200212
213+
201214 - name : Create ZIP of reports
202215 run : |
203216 set -euo pipefail
204217 cd "${REPORT_DIR}"
205218 zip -r comparison-artifacts.zip . || true
206219
207- - name : " Publish table to GitHub Actions summary (only the table)"
220+ - name : " Publish table to GitHub Actions summary (only the table, sorted )"
208221 if : always()
209222 run : |
210223 set -euo pipefail
211224 SUMMARY="$GITHUB_STEP_SUMMARY"
212225 A_BRANCH="${{ github.event.inputs.branch_a }}"
213226 B_BRANCH="${{ github.event.inputs.branch_b }}"
214227
215- # Comprueba que exista la tabla (en /tmp/all_entries o en reports MD)
216- if [ ! -f /tmp/all_entries.txt ] || [ ! -s /tmp/all_entries.txt ]; then
217- # Si all_entries no tiene datos, intentamos extraer del MD
218- if [ -f "${REPORT_DIR}/comparison-report.md" ]; then
219- # extraemos la tabla completa entre el header y la línea en blanco que sigue
220- awk '
221- BEGIN {found=0}
222- /^\\| VulnerabilityID \\| package:version \\| Severity \\| branches \\|/ {found=1; print; next}
223- found==1 { if (/^$/) exit; print }
224- ' "${REPORT_DIR}/comparison-report.md" >> "$SUMMARY" || true
225- else
226- echo "No table available to show in summary." >> "$SUMMARY"
227- fi
228- exit 0
228+ # Si no hay sorted file, intenta generarlo a partir de /tmp/all_entries.txt
229+ if [ ! -s /tmp/all_sorted.txt ] && [ -s /tmp/all_entries.txt ]; then
230+ awk -F'|' '
231+ BEGIN { map["CRITICAL"]=5; map["HIGH"]=4; map["MEDIUM"]=3; map["LOW"]=2; map["UNKNOWN"]=1; }
232+ {
233+ id=$1; pv=$2; sev=toupper($3);
234+ rank = (sev in map ? map[sev] : 0);
235+ printf("%d|%s|%s|%s\n", rank, sev, id, pv);
236+ }
237+ ' /tmp/all_entries.txt | sort -t'|' -k1,1nr -k3,3 | cut -d'|' -f2- > /tmp/all_sorted.txt || true
229238 fi
230239
231- # Build the table header in the summary
232- echo "| VulnerabilityID | package:version | Severity | branches |" >> "$SUMMARY"
240+ # Header table for summary
241+ echo "| Severity | VulnerabilityID | package:version | branches |" >> "$SUMMARY"
233242 echo "|---|---|---|---|" >> "$SUMMARY"
234243
235- # For each entry in /tmp/all_entries.txt, build row with branches decision (same logic as in MD)
236- while IFS= read -r line; do
237- id=$(echo "$line" | awk -F'|' '{print $1}')
238- pv=$(echo "$line" | awk -F'|' '{print $2}')
239- sev=$(echo "$line" | awk -F'|' '{print $3}')
240-
241- inA=0; inB=0
242- if grep -Fxq "$line" /tmp/a_entries.txt 2>/dev/null; then inA=1; fi
243- if grep -Fxq "$line" /tmp/b_entries.txt 2>/dev/null; then inB=1; fi
244-
245- if [ "$inA" -eq 1 ] && [ "$inB" -eq 1 ]; then
246- branches="**BOTH**"
247- elif [ "$inA" -eq 1 ]; then
248- branches="${A_BRANCH}"
249- else
250- branches="${B_BRANCH}"
251- fi
252-
253- echo "| ${id} | ${pv} | ${sev} | ${branches} |" >> "$SUMMARY"
254- done < /tmp/all_entries.txt
244+ if [ -s /tmp/all_sorted.txt ]; then
245+ while IFS= read -r line; do
246+ sev=$(echo "$line" | awk -F'|' '{print $1}')
247+ id=$(echo "$line" | awk -F'|' '{print $2}')
248+ pv=$(echo "$line" | awk -F'|' '{print $3}')
249+
250+ inA=0; inB=0
251+ entry="${id}|${pv}|${sev}"
252+ if grep -Fxq "$entry" /tmp/a_entries.txt 2>/dev/null; then inA=1; fi
253+ if grep -Fxq "$entry" /tmp/b_entries.txt 2>/dev/null; then inB=1; fi
254+
255+ if [ "$inA" -eq 1 ] && [ "$inB" -eq 1 ]; then
256+ branches="**BOTH**"
257+ elif [ "$inA" -eq 1 ]; then
258+ branches="${A_BRANCH}"
259+ else
260+ branches="${B_BRANCH}"
261+ fi
262+
263+ echo "| ${sev} | ${id} | ${pv} | ${branches} |" >> "$SUMMARY"
264+ done < /tmp/all_sorted.txt
265+ else
266+ echo "| - | - | - | - |" >> "$SUMMARY"
267+ fi
255268
256269 - name : Upload artifacts (reports)
257270 uses : actions/upload-artifact@v4
0 commit comments