@@ -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+ 
201214name : 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
256269name : Upload artifacts (reports) 
257270        uses : actions/upload-artifact@v4 
0 commit comments