|
30 | 30 | required: false |
31 | 31 | docker_images: |
32 | 32 | type: string |
33 | | - description: JSON array of docker image references to scan when docker scanning is enabled. |
| 33 | + description: comma separated list of docker image references to scan when docker scanning is enabled. |
34 | 34 | default: "[]" |
35 | 35 | required: false |
36 | 36 |
|
37 | 37 | jobs: |
38 | 38 | quality_checks: |
39 | | - outputs: |
40 | | - docker_images: ${{ steps.normalized_docker_images.outputs.images }} |
41 | 39 | runs-on: ubuntu-22.04 |
42 | 40 | steps: |
43 | 41 | - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 |
@@ -249,34 +247,6 @@ jobs: |
249 | 247 |
|
250 | 248 | - name: Run unit tests |
251 | 249 | run: make test |
252 | | - - name: Build docker images |
253 | | - if: ${{ inputs.run_docker_scan == true }} |
254 | | - run: | |
255 | | - make docker-build |
256 | | - - name: Determine docker images to scan |
257 | | - id: normalized_docker_images |
258 | | - run: | |
259 | | - if [ "${{ inputs.run_docker_scan }}" != "true" ]; then |
260 | | - echo "Docker scanning disabled; emitting empty image list." |
261 | | - echo 'images=[]' >> "$GITHUB_OUTPUT" |
262 | | - exit 0 |
263 | | - fi |
264 | | -
|
265 | | - INPUT='${{ inputs.docker_images }}' |
266 | | -
|
267 | | -
|
268 | | - if [ -z "$INPUT" ]; then |
269 | | - INPUT="[]" |
270 | | - fi |
271 | | -
|
272 | | - if [ "$INPUT" = "[]" ]; then |
273 | | - echo "No docker images provided" |
274 | | - exit 1 |
275 | | - else |
276 | | - echo "Using provided docker images: $INPUT" |
277 | | - echo "images=$INPUT" >> "$GITHUB_OUTPUT" |
278 | | - fi |
279 | | -
|
280 | 250 | - name: Generate SBOM |
281 | 251 | uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 |
282 | 252 | with: |
@@ -383,13 +353,130 @@ jobs: |
383 | 353 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
384 | 354 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} |
385 | 355 |
|
| 356 | + docker_image_build: |
| 357 | + outputs: |
| 358 | + docker_images: ${{ steps.normalized_docker_images.outputs.images }} |
| 359 | + runs-on: ubuntu-22.04 |
| 360 | + steps: |
| 361 | + - name: Checkout code |
| 362 | + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
| 363 | + with: |
| 364 | + ref: ${{ env.BRANCH_NAME }} |
| 365 | + fetch-depth: 0 |
| 366 | + # using git commit sha for version of action to ensure we have stable version |
| 367 | + - name: Install asdf |
| 368 | + uses: asdf-vm/actions/setup@b7bcd026f18772e44fe1026d729e1611cc435d47 |
| 369 | + with: |
| 370 | + asdf_version: ${{ inputs.asdfVersion }} |
| 371 | + |
| 372 | + - name: Cache asdf |
| 373 | + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb |
| 374 | + with: |
| 375 | + path: | |
| 376 | + ~/.asdf |
| 377 | + key: ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }}-${{ inputs.asdfVersion }} |
| 378 | + restore-keys: | |
| 379 | + ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }}-${{ inputs.asdfVersion }} |
| 380 | +
|
| 381 | + - name: Install asdf dependencies in .tool-versions |
| 382 | + uses: asdf-vm/actions/install@b7bcd026f18772e44fe1026d729e1611cc435d47 |
| 383 | + with: |
| 384 | + asdf_version: ${{ inputs.asdfVersion }} |
| 385 | + env: |
| 386 | + PYTHON_CONFIGURE_OPTS: --enable-shared |
| 387 | + |
| 388 | + - name: Reinstall poetry |
| 389 | + if: ${{ inputs.reinstall_poetry }} |
| 390 | + run: | |
| 391 | + poetry_tool_version=$(cat .tool-versions | grep poetry) |
| 392 | + poetry_version=${poetry_tool_version//"poetry "} |
| 393 | + asdf uninstall poetry "$poetry_version" |
| 394 | + asdf install poetry |
| 395 | +
|
| 396 | + - name: Setting up .npmrc |
| 397 | + env: |
| 398 | + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 399 | + run: | |
| 400 | + echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc |
| 401 | + echo "@nhsdigital:registry=https://npm.pkg.github.com" >> ~/.npmrc |
| 402 | +
|
| 403 | + - name: Cache npm dependencies |
| 404 | + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb |
| 405 | + with: |
| 406 | + path: ./node_modules |
| 407 | + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} |
| 408 | + restore-keys: | |
| 409 | + ${{ runner.os }}-node- |
| 410 | +
|
| 411 | + - name: make install |
| 412 | + run: | |
| 413 | + make install |
| 414 | + - name: Build docker images |
| 415 | + if: ${{ inputs.run_docker_scan == true }} |
| 416 | + run: | |
| 417 | + make docker-build |
| 418 | + - name: Determine docker images to scan |
| 419 | + id: normalized_docker_images |
| 420 | + run: | |
| 421 | + if [ "${{ inputs.run_docker_scan }}" != "true" ]; then |
| 422 | + echo "Docker scanning disabled; emitting empty image list." |
| 423 | + echo 'images=[]' >> "$GITHUB_OUTPUT" |
| 424 | + exit 0 |
| 425 | + fi |
| 426 | +
|
| 427 | + INPUT='${{ inputs.docker_images }}' |
| 428 | +
|
| 429 | +
|
| 430 | + if [ -z "$INPUT" ]; then |
| 431 | + INPUT="[]" |
| 432 | + fi |
| 433 | +
|
| 434 | + normalize_to_json_array() { |
| 435 | + local raw="$1" |
| 436 | +
|
| 437 | + # If the input already looks like JSON, return as-is |
| 438 | + if echo "$raw" | grep -q '^[[:space:]]*\['; then |
| 439 | + echo "$raw" |
| 440 | + return |
| 441 | + fi |
| 442 | +
|
| 443 | + local json="[" |
| 444 | + local first=true |
| 445 | + IFS=',' read -ra ITEMS <<< "$raw" |
| 446 | + for item in "${ITEMS[@]}"; do |
| 447 | + # Trim whitespace around each image reference |
| 448 | + item=$(echo "$item" | xargs) |
| 449 | + if [ -z "$item" ]; then |
| 450 | + continue |
| 451 | + fi |
| 452 | + if [ "$first" = true ]; then |
| 453 | + first=false |
| 454 | + else |
| 455 | + json+=", " |
| 456 | + fi |
| 457 | + json+="\"$item\"" |
| 458 | + done |
| 459 | + json+="]" |
| 460 | + echo "$json" |
| 461 | + } |
| 462 | +
|
| 463 | + NORMALIZED=$(normalize_to_json_array "$INPUT") |
| 464 | +
|
| 465 | + if [ "$NORMALIZED" = "[]" ]; then |
| 466 | + echo "No docker images provided" |
| 467 | + exit 1 |
| 468 | + fi |
| 469 | +
|
| 470 | + echo "Using provided docker images: $NORMALIZED" |
| 471 | + echo "images=$NORMALIZED" >> "$GITHUB_OUTPUT" |
| 472 | +
|
386 | 473 | docker_vulnerability_scan: |
387 | 474 | runs-on: ubuntu-22.04 |
388 | | - needs: quality_checks |
| 475 | + needs: docker_image_build |
389 | 476 | if: ${{ inputs.run_docker_scan == true }} |
390 | 477 | strategy: |
391 | 478 | matrix: |
392 | | - docker_image: ${{ fromJson(needs.quality_checks.outputs.docker_images) }} |
| 479 | + docker_image: ${{ fromJson(needs.docker_image_build.outputs.docker_images) }} |
393 | 480 | steps: |
394 | 481 | - name: Checkout code |
395 | 482 | uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
@@ -425,7 +512,6 @@ jobs: |
425 | 512 | cat dependency_results_docker.txt |
426 | 513 | fi |
427 | 514 |
|
428 | | - # CloudFormation validation (runs only if templates exist, ~3-5 minutes) |
429 | 515 | IaC-validation: |
430 | 516 | runs-on: ubuntu-22.04 |
431 | 517 | steps: |
|
0 commit comments