2222 required : false
2323 type : boolean
2424 default : false
25+ prebuilt-image-artifact :
26+ description : ' Name of uploaded artifact containing a Docker image tar (skip Docker build if provided)'
27+ required : false
28+ type : string
29+ default : ' '
30+ prebuilt-image-names :
31+ description : ' Space-separated list of Docker image:tag names inside the prebuilt artifact tar'
32+ required : false
33+ type : string
34+ default : ' '
2535
2636jobs :
2737 grype-scan :
@@ -65,13 +75,29 @@ jobs:
6575 if : ${{ !inputs.grype-image-skip-aws }}
6676 uses : aws-actions/amazon-ecr-login@v2
6777
68- - name : Scan with Grype
69- id : grype-scan
78+ - name : Download prebuilt Docker image
79+ if : ${{ inputs.prebuilt-image-artifact != '' }}
80+ uses : actions/download-artifact@v4
81+ with :
82+ name : ${{ inputs.prebuilt-image-artifact }}
83+ path : /tmp
84+
85+ - name : Load prebuilt Docker image
86+ id : load-image
87+ if : ${{ inputs.prebuilt-image-artifact != '' }}
88+ run : |
89+ echo "Loading prebuilt images from artifact..."
90+ docker load -i /tmp/docker-image.tar
91+ echo "IMAGES=${{ inputs.prebuilt-image-names }}" >> "$GITHUB_OUTPUT"
92+ echo "Loaded images: ${{ inputs.prebuilt-image-names }}"
93+ docker images
94+
95+ - name : Build Docker image
96+ id : build-image
97+ if : ${{ inputs.prebuilt-image-artifact == '' }}
7098 env :
7199 GITHUB_TOKEN : ${{ secrets.GH_TOKEN }}
72100 run : |
73- SCAN_NAME="${{ github.repository }}"
74-
75101 if [ ! -f "Dockerfile" ]; then
76102 echo "❌ No Dockerfile found - this workflow requires a Dockerfile to scan Docker image"
77103 exit 1
@@ -100,13 +126,14 @@ jobs:
100126 export GITHUB_TOKEN="${{ secrets.GH_TOKEN }}"
101127 make compose-build
102128
103- echo "Detecting built images..."
104- docker compose images
105-
106- IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "^${REPO_NAME}" | grep -v "^<none>")
129+ echo "Detecting built images from compose config..."
130+ # Only get images from services that have a build section (not pulled images like postgres, grafana, etc.)
131+ IMAGES=$(docker compose config --format json 2>/dev/null | jq -r '.services[] | select(.build) | .image // empty' | sort -u | while read img; do
132+ if echo "$img" | grep -q ':'; then echo "$img"; else echo "${img}:latest"; fi
133+ done)
107134
108135 if [ -z "$IMAGES" ]; then
109- echo "No images found with prefix ${REPO_NAME}, scanning all recent images"
136+ echo "⚠️ Could not detect built images from compose config, falling back to docker images"
110137 IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "^<none>" | head -5)
111138 fi
112139 # Strategy 3: Fallback to standard docker build
@@ -121,6 +148,28 @@ jobs:
121148 exit 1
122149 fi
123150
151+ echo "IMAGES=$(echo $IMAGES | tr '\n' ' ')" >> "$GITHUB_OUTPUT"
152+ echo "Found images: $IMAGES"
153+
154+ - name : Determine scan targets
155+ id : scan-target
156+ run : |
157+ IMAGES="${{ steps.load-image.outputs.IMAGES || steps.build-image.outputs.IMAGES }}"
158+ if [ -z "$IMAGES" ]; then
159+ echo "❌ No images available to scan"
160+ exit 1
161+ fi
162+ echo "IMAGES=$IMAGES" >> "$GITHUB_OUTPUT"
163+ echo "Scan targets: $IMAGES"
164+
165+ - name : Scan with Grype
166+ id : grype-scan
167+ env :
168+ GITHUB_TOKEN : ${{ secrets.GH_TOKEN }}
169+ run : |
170+ SCAN_NAME="${{ github.repository }}"
171+ IMAGES="${{ steps.scan-target.outputs.IMAGES }}"
172+
124173 echo "Found images to scan:"
125174 echo "$IMAGES"
126175
0 commit comments