From 0bec67d020b64b854ab9e5386c3c14f13081eaf4 Mon Sep 17 00:00:00 2001 From: Lars Bardgard Astveit Date: Tue, 27 Oct 2026 12:08:55 +0100 Subject: [PATCH 1/5] PF-2710 Upload test artifacts in ci-pr-checks-image.yml --- .github/workflows/ci-pr-checks-image.yml | 8 ++++++- .../ci-spring-boot-container-scan.yml | 19 ++++++++++++++- docs/pull-request-image.md | 23 +++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-pr-checks-image.yml b/.github/workflows/ci-pr-checks-image.yml index a6bd9444..f2599560 100644 --- a/.github/workflows/ci-pr-checks-image.yml +++ b/.github/workflows/ci-pr-checks-image.yml @@ -144,6 +144,11 @@ on: type: string required: false default: '' + test-report-path: + description: Only for Spring Boot. Path(s) to test reports (e.g. Cucumber, Surefire, Failsafe) to upload as an artifact if the Maven build fails. One path per line, relative to the repository root. Requires maven-skip-tests to be false + type: string + required: false + default: '' trivy-library-disable-scan: description: Disable Trivy library scan type: boolean @@ -201,7 +206,7 @@ jobs: if: | inputs.enable-container-image-scan == true && inputs.application-type == 'spring-boot' - uses: felleslosninger/github-workflows/.github/workflows/ci-spring-boot-container-scan.yml@main + uses: felleslosninger/github-workflows/.github/workflows/ci-spring-boot-container-scan.yml@PF-2710 permissions: contents: read with: @@ -215,6 +220,7 @@ jobs: maven-skip-tests: ${{ inputs.maven-skip-tests }} application-path: ${{ inputs.application-path }} module-name: ${{ inputs.module-name }} + test-report-path: ${{ inputs.test-report-path }} trivy-library-disable-scan: ${{ inputs.trivy-library-disable-scan }} trivy-library-ignore-unfixed: ${{ inputs.trivy-library-ignore-unfixed }} trivy-library-severity: ${{ inputs.trivy-library-severity }} diff --git a/.github/workflows/ci-spring-boot-container-scan.yml b/.github/workflows/ci-spring-boot-container-scan.yml index e7d1bdb9..eb8c4c5f 100644 --- a/.github/workflows/ci-spring-boot-container-scan.yml +++ b/.github/workflows/ci-spring-boot-container-scan.yml @@ -18,7 +18,9 @@ # 3. Set up JDK # 4. Build Spring Boot image using Paketo buildpacks. The image will be # built based on the application path or module name (if provided) -# 5. Run Trivy vulnerability scan on the built image +# 5. Upload test reports as an artifact if the build fails and +# 'test-report-path' is set +# 6. Run Trivy vulnerability scan on the built image # # Trigger: # Triggered by workflow calls (workflow_call) @@ -86,6 +88,11 @@ on: default: "" required: false type: string + test-report-path: + description: Path(s) to test reports (e.g. Cucumber, Surefire, Failsafe) to upload as an artifact if the Maven build fails. One path per line, relative to the repository root. If not provided, nothing is uploaded + type: string + required: false + default: "" trivy-library-disable-scan: description: Disable Trivy library scan type: boolean @@ -204,6 +211,16 @@ jobs: -Dspring-boot.build-image.imageName="$IMAGE_NAME:$IMAGE_TAG" \ -Dspring-boot.build-image.builder="paketobuildpacks/$IMAGE_PACK:$IMAGE_PACK_TAG" + - name: Upload test reports + if: | + failure() && + inputs.test-report-path != '' + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # pin@v7.0.2 + with: + name: test-reports-${{ inputs.image-name }} + path: ${{ inputs.test-report-path }} + if-no-files-found: ignore + - name: Run Trivy vulnerability scanner (image) uses: felleslosninger/github-workflows/.github/actions/trivy-scan@main with: diff --git a/docs/pull-request-image.md b/docs/pull-request-image.md index 5ea90e43..2bf7db90 100644 --- a/docs/pull-request-image.md +++ b/docs/pull-request-image.md @@ -219,6 +219,29 @@ These are applicable to Spring Boot and Quarkus application types. | `maven-lifecycle` | `string` | `install` | | `maven-skip-tests` | `boolean` | `true` | | `module-name` | `string` | Not set | +| `test-report-path` | `string` | Not set | + +> [!NOTE] +> **Test reports:** Set `test-report-path` to upload test reports (for example +> Cucumber HTML, Surefire or Failsafe reports) as the artifact +> `test-reports-` when the Maven build fails. Use one path per line: +> +> ```yaml +> maven-skip-tests: false +> test-report-path: | +> target/cucumber-reports/ +> target/failsafe-reports/ +> ``` +> +> - `maven-skip-tests` must be `false`, otherwise the tests do not run and no +> reports are generated. +> - Paths are relative to the repository root, not to `application-path`. If +> `application-path` is not the root, prefix the paths with it, for example +> `apps/my-app/target/cucumber-reports/`. +> - For multi-module projects built with `module-name`, the reports end up in +> each module's `target` folder. Use a glob such as +> `**/target/cucumber-reports/`. +> - If no files match, nothing is uploaded and the step does not fail. > [!NOTE] > **Multi-module projects:** If your application is part of a multi-module Maven From a818668ae1174ea89af43b7688168dbbcfacdfa7 Mon Sep 17 00:00:00 2001 From: Lars Bardgard Astveit Date: Tue, 27 Oct 2026 12:26:49 +0100 Subject: [PATCH 2/5] Update naming of test reports after copilot review --- .../workflows/ci-spring-boot-container-scan.yml | 14 +++++++++++++- docs/pull-request-image.md | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-spring-boot-container-scan.yml b/.github/workflows/ci-spring-boot-container-scan.yml index eb8c4c5f..177e43ca 100644 --- a/.github/workflows/ci-spring-boot-container-scan.yml +++ b/.github/workflows/ci-spring-boot-container-scan.yml @@ -211,13 +211,25 @@ jobs: -Dspring-boot.build-image.imageName="$IMAGE_NAME:$IMAGE_TAG" \ -Dspring-boot.build-image.builder="paketobuildpacks/$IMAGE_PACK:$IMAGE_PACK_TAG" + - name: Set test report artifact name + id: test-report-artifact + if: | + failure() && + inputs.test-report-path != '' + env: + IMAGE_NAME: ${{ inputs.image-name }} + run: | + # Image names may contain characters not allowed in artifact names (e.g. '/' and ':') + SAFE_NAME=$(printf '%s' "$IMAGE_NAME" | tr -c 'A-Za-z0-9._-' '-') + echo "name=test-reports-${SAFE_NAME}" >> "$GITHUB_OUTPUT" + - name: Upload test reports if: | failure() && inputs.test-report-path != '' uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # pin@v7.0.2 with: - name: test-reports-${{ inputs.image-name }} + name: ${{ steps.test-report-artifact.outputs.name }} path: ${{ inputs.test-report-path }} if-no-files-found: ignore diff --git a/docs/pull-request-image.md b/docs/pull-request-image.md index 2bf7db90..1a4c2f90 100644 --- a/docs/pull-request-image.md +++ b/docs/pull-request-image.md @@ -224,7 +224,9 @@ These are applicable to Spring Boot and Quarkus application types. > [!NOTE] > **Test reports:** Set `test-report-path` to upload test reports (for example > Cucumber HTML, Surefire or Failsafe reports) as the artifact -> `test-reports-` when the Maven build fails. Use one path per line: +> `test-reports-` when the Maven build fails. Characters in the image +> name that are not allowed in artifact names (such as `/` and `:`) are replaced +> with `-`. Use one path per line: > > ```yaml > maven-skip-tests: false From f398fe4f56e1a39ed09b2cd6999c5d1f032bf282 Mon Sep 17 00:00:00 2001 From: Lars Bardgard Astveit Date: Tue, 27 Oct 2026 12:31:35 +0100 Subject: [PATCH 3/5] typo --- docs/pull-request-image.md | 49 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/docs/pull-request-image.md b/docs/pull-request-image.md index 1a4c2f90..8f1d35a9 100644 --- a/docs/pull-request-image.md +++ b/docs/pull-request-image.md @@ -221,36 +221,37 @@ These are applicable to Spring Boot and Quarkus application types. | `module-name` | `string` | Not set | | `test-report-path` | `string` | Not set | -> [!NOTE] -> **Test reports:** Set `test-report-path` to upload test reports (for example -> Cucumber HTML, Surefire or Failsafe reports) as the artifact -> `test-reports-` when the Maven build fails. Characters in the image -> name that are not allowed in artifact names (such as `/` and `:`) are replaced -> with `-`. Use one path per line: -> -> ```yaml -> maven-skip-tests: false -> test-report-path: | -> target/cucumber-reports/ -> target/failsafe-reports/ -> ``` -> -> - `maven-skip-tests` must be `false`, otherwise the tests do not run and no -> reports are generated. -> - Paths are relative to the repository root, not to `application-path`. If -> `application-path` is not the root, prefix the paths with it, for example -> `apps/my-app/target/cucumber-reports/`. -> - For multi-module projects built with `module-name`, the reports end up in -> each module's `target` folder. Use a glob such as -> `**/target/cucumber-reports/`. -> - If no files match, nothing is uploaded and the step does not fail. - > [!NOTE] > **Multi-module projects:** If your application is part of a multi-module Maven > project, you should override `module-name` instead of `application-path`. The > workflow will automatically append the `-pl -am` flags to ensure > required internal dependencies are built before generating the image. +##### Test reports + +Set `test-report-path` to upload test reports (for example Cucumber HTML, +Surefire or Failsafe reports) as the artifact `test-reports-` when +the Maven build fails. Characters in the image name that are not allowed in +artifact names (such as `/` and `:`) are replaced with `-`. Use one path per +line: + +```yaml +maven-skip-tests: false +test-report-path: | + target/cucumber-reports/ + target/failsafe-reports/ +``` + +- `maven-skip-tests` must be `false`, otherwise the tests do not run and no + reports are generated. +- Paths are relative to the repository root, not to `application-path`. If + `application-path` is not the root, prefix the paths with it, for example + `apps/my-app/target/cucumber-reports/`. +- For multi-module projects built with `module-name`, the reports end up in + each module's `target` folder. Use a glob such as + `**/target/cucumber-reports/`. +- If no files match, nothing is uploaded and the step does not fail. + #### Container image scanning (Quarkus overrides) | Override | Type | Workflow default | From 9ec819619b282f27a2f6f33be6a695b6de023a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20B=C3=A5rdgard=20=C3=85stveit?= <5196432+larsbard@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:32:42 +0100 Subject: [PATCH 4/5] Use repository name as fallback for IMAGE_NAME Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .github/workflows/ci-spring-boot-container-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-spring-boot-container-scan.yml b/.github/workflows/ci-spring-boot-container-scan.yml index 177e43ca..2f14998b 100644 --- a/.github/workflows/ci-spring-boot-container-scan.yml +++ b/.github/workflows/ci-spring-boot-container-scan.yml @@ -217,7 +217,7 @@ jobs: failure() && inputs.test-report-path != '' env: - IMAGE_NAME: ${{ inputs.image-name }} + IMAGE_NAME: ${{ inputs.image-name || github.event.repository.name }} run: | # Image names may contain characters not allowed in artifact names (e.g. '/' and ':') SAFE_NAME=$(printf '%s' "$IMAGE_NAME" | tr -c 'A-Za-z0-9._-' '-') From 36c605d6c87c91ef431155e31ea3a4ada3c756f2 Mon Sep 17 00:00:00 2001 From: Lars Bardgard Astveit Date: Thu, 29 Oct 2026 10:13:55 +0100 Subject: [PATCH 5/5] PF-2710 Use artifact-name and artifact-path like ci-pr-checks-lib --- .github/workflows/ci-pr-checks-image.yml | 18 +++++--- .../ci-spring-boot-container-scan.yml | 42 ++++++++----------- docs/pull-request-image.md | 23 +++++----- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/.github/workflows/ci-pr-checks-image.yml b/.github/workflows/ci-pr-checks-image.yml index f2599560..bb4c1e42 100644 --- a/.github/workflows/ci-pr-checks-image.yml +++ b/.github/workflows/ci-pr-checks-image.yml @@ -50,6 +50,16 @@ on: type: string default: 'spring-boot' required: false + artifact-name: + description: Only for Spring Boot. Name of artifact to upload after the image build. If empty, no artifact will be uploaded + type: string + required: false + default: '' + artifact-path: + description: Only for Spring Boot. Path to the artifact to upload (e.g. Cucumber, Surefire or Failsafe reports), relative to the repository root. Requires maven-skip-tests to be false for test reports + type: string + required: false + default: '' auto-merge-types: description: "Comma-separated list of update types to auto-merge when 'enable-auto-merge-dependabot' is true. Supported values can be seen in 'update-types' under https://docs.github.com/en/code-security/reference/supply-chain-security/dependabot-options-reference#ignore--" type: string @@ -144,11 +154,6 @@ on: type: string required: false default: '' - test-report-path: - description: Only for Spring Boot. Path(s) to test reports (e.g. Cucumber, Surefire, Failsafe) to upload as an artifact if the Maven build fails. One path per line, relative to the repository root. Requires maven-skip-tests to be false - type: string - required: false - default: '' trivy-library-disable-scan: description: Disable Trivy library scan type: boolean @@ -220,7 +225,8 @@ jobs: maven-skip-tests: ${{ inputs.maven-skip-tests }} application-path: ${{ inputs.application-path }} module-name: ${{ inputs.module-name }} - test-report-path: ${{ inputs.test-report-path }} + artifact-name: ${{ inputs.artifact-name }} + artifact-path: ${{ inputs.artifact-path }} trivy-library-disable-scan: ${{ inputs.trivy-library-disable-scan }} trivy-library-ignore-unfixed: ${{ inputs.trivy-library-ignore-unfixed }} trivy-library-severity: ${{ inputs.trivy-library-severity }} diff --git a/.github/workflows/ci-spring-boot-container-scan.yml b/.github/workflows/ci-spring-boot-container-scan.yml index 2f14998b..c5fdcf52 100644 --- a/.github/workflows/ci-spring-boot-container-scan.yml +++ b/.github/workflows/ci-spring-boot-container-scan.yml @@ -18,8 +18,8 @@ # 3. Set up JDK # 4. Build Spring Boot image using Paketo buildpacks. The image will be # built based on the application path or module name (if provided) -# 5. Upload test reports as an artifact if the build fails and -# 'test-report-path' is set +# 5. Upload an artifact (e.g. test reports) if 'artifact-name' and +# 'artifact-path' are set # 6. Run Trivy vulnerability scan on the built image # # Trigger: @@ -44,6 +44,16 @@ on: default: "./" required: false type: string + artifact-name: + description: Name of artifact to upload after the image build. If empty, no artifact will be uploaded + default: "" + required: false + type: string + artifact-path: + description: Path to the artifact to upload, relative to the repository root + default: "" + required: false + type: string cache-path: description: Path to cache dependencies, relative to the repository root default: "**/pom.xml" @@ -88,11 +98,6 @@ on: default: "" required: false type: string - test-report-path: - description: Path(s) to test reports (e.g. Cucumber, Surefire, Failsafe) to upload as an artifact if the Maven build fails. One path per line, relative to the repository root. If not provided, nothing is uploaded - type: string - required: false - default: "" trivy-library-disable-scan: description: Disable Trivy library scan type: boolean @@ -211,26 +216,15 @@ jobs: -Dspring-boot.build-image.imageName="$IMAGE_NAME:$IMAGE_TAG" \ -Dspring-boot.build-image.builder="paketobuildpacks/$IMAGE_PACK:$IMAGE_PACK_TAG" - - name: Set test report artifact name - id: test-report-artifact - if: | - failure() && - inputs.test-report-path != '' - env: - IMAGE_NAME: ${{ inputs.image-name || github.event.repository.name }} - run: | - # Image names may contain characters not allowed in artifact names (e.g. '/' and ':') - SAFE_NAME=$(printf '%s' "$IMAGE_NAME" | tr -c 'A-Za-z0-9._-' '-') - echo "name=test-reports-${SAFE_NAME}" >> "$GITHUB_OUTPUT" - - - name: Upload test reports + - name: Upload artifact if: | - failure() && - inputs.test-report-path != '' + !cancelled() && + inputs.artifact-path != '' && + inputs.artifact-name != '' uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # pin@v7.0.2 with: - name: ${{ steps.test-report-artifact.outputs.name }} - path: ${{ inputs.test-report-path }} + name: ${{ inputs.artifact-name }} + path: ${{ inputs.artifact-path }} if-no-files-found: ignore - name: Run Trivy vulnerability scanner (image) diff --git a/docs/pull-request-image.md b/docs/pull-request-image.md index 8f1d35a9..4e7c6d8a 100644 --- a/docs/pull-request-image.md +++ b/docs/pull-request-image.md @@ -216,10 +216,11 @@ These are applicable to Spring Boot and Quarkus application types. | Override | Type | Workflow default | | -------- | ---- | ---------------- | +| `artifact-name` | `string` | Not set | +| `artifact-path` | `string` | Not set | | `maven-lifecycle` | `string` | `install` | | `maven-skip-tests` | `boolean` | `true` | | `module-name` | `string` | Not set | -| `test-report-path` | `string` | Not set | > [!NOTE] > **Multi-module projects:** If your application is part of a multi-module Maven @@ -227,23 +228,24 @@ These are applicable to Spring Boot and Quarkus application types. > workflow will automatically append the `-pl -am` flags to ensure > required internal dependencies are built before generating the image. -##### Test reports +##### Artifact upload -Set `test-report-path` to upload test reports (for example Cucumber HTML, -Surefire or Failsafe reports) as the artifact `test-reports-` when -the Maven build fails. Characters in the image name that are not allowed in -artifact names (such as `/` and `:`) are replaced with `-`. Use one path per -line: +Set both `artifact-name` and `artifact-path` to upload files from the build, +for example Cucumber HTML, Surefire or Failsafe reports, as an artifact. This +works the same way as in the [library workflow](pull-request-lib.md): the +artifact is uploaded after the image build whether the build succeeds or fails, +unless the run is cancelled. Use one path per line: ```yaml maven-skip-tests: false -test-report-path: | +artifact-name: test-reports +artifact-path: | target/cucumber-reports/ target/failsafe-reports/ ``` -- `maven-skip-tests` must be `false`, otherwise the tests do not run and no - reports are generated. +- `maven-skip-tests` must be `false` for test reports, otherwise the tests do + not run and no reports are generated. - Paths are relative to the repository root, not to `application-path`. If `application-path` is not the root, prefix the paths with it, for example `apps/my-app/target/cucumber-reports/`. @@ -251,6 +253,7 @@ test-report-path: | each module's `target` folder. Use a glob such as `**/target/cucumber-reports/`. - If no files match, nothing is uploaded and the step does not fail. +- Only applies to the `spring-boot` application type. #### Container image scanning (Quarkus overrides)