From 2b57cf417c4a2ccfc278cf5c175dec2cbefd1397 Mon Sep 17 00:00:00 2001
From: daz <daz@gradle.com>
Date: Mon, 1 Jan 2024 12:31:36 -0700
Subject: [PATCH] Allow job-summary only on failure

Instead of a binary true/false option, it is now possible to only add
a Job Summary when the build failed. This applies both to the overall
Job Summary added to the workflow run, and to the new PR comment feature.
---
 .github/workflows/demo-job-summary.yml        | 23 ++++++++++++-
 .../workflows/demo-pr-build-scan-comment.yml  | 33 +++++++++++++++++--
 action.yml                                    | 18 ++++++----
 src/input-params.ts                           | 29 +++++++++++++---
 src/job-summary.ts                            | 29 ++++++++++++----
 5 files changed, 112 insertions(+), 20 deletions(-)

diff --git a/.github/workflows/demo-job-summary.yml b/.github/workflows/demo-job-summary.yml
index 4a7871d..803dac7 100644
--- a/.github/workflows/demo-job-summary.yml
+++ b/.github/workflows/demo-job-summary.yml
@@ -8,7 +8,7 @@ env:
   GRADLE_BUILD_ACTION_CACHE_DEBUG_ENABLED: true
 
 jobs:
-  run-gradle-builds:
+  many-gradle-builds:
     runs-on: ubuntu-latest
     steps:
     - name: Checkout sources
@@ -42,6 +42,27 @@ jobs:
       continue-on-error: true
       run: ./gradlew not-a-real-task
 
+  successful-builds-with-no-summary:
+    runs-on: ubuntu-latest
+    steps:
+    - name: Checkout sources
+      uses: actions/checkout@v4
+    - name: Build distribution
+      shell: bash
+      run: |
+        npm install
+        npm run build
+    - name: Setup Gradle
+      uses: ./
+      with:
+        add-job-summary: on-failure
+    - name: Build kotlin-dsl project
+      working-directory: .github/workflow-samples/kotlin-dsl
+      run: ./gradlew assemble
+    - name: Build kotlin-dsl project without Build ScanĀ®
+      working-directory: .github/workflow-samples/kotlin-dsl
+      run: ./gradlew assemble check --no-scan
+
   pre-existing-gradle-home:
     runs-on: ubuntu-latest
     steps:
diff --git a/.github/workflows/demo-pr-build-scan-comment.yml b/.github/workflows/demo-pr-build-scan-comment.yml
index 43d3a8d..079cb73 100644
--- a/.github/workflows/demo-pr-build-scan-comment.yml
+++ b/.github/workflows/demo-pr-build-scan-comment.yml
@@ -3,7 +3,7 @@ on:
   pull_request:
     types: [assigned, review_requested]
 jobs:
-  gradle:
+  successful-build-with-always-comment:
     runs-on: ubuntu-latest
     steps:
     - name: Checkout project sources
@@ -11,8 +11,37 @@ jobs:
     - name: Setup Gradle
       uses: ./
       with:
-        add-pr-comment: true
+        add-job-summary-as-pr-comment: always
     - name: Run build with Gradle wrapper
       id: gradle
       working-directory: .github/workflow-samples/kotlin-dsl
       run: ./gradlew build --scan
+
+  successful-build-with-comment-on-failure:
+    runs-on: ubuntu-latest
+    steps:
+    - name: Checkout project sources
+      uses: actions/checkout@v4
+    - name: Setup Gradle
+      uses: ./
+      with:
+        add-job-summary-as-pr-comment: on-failure
+    - name: Run build with Gradle wrapper
+      id: gradle
+      working-directory: .github/workflow-samples/kotlin-dsl
+      run: ./gradlew build --scan
+
+  failing-build-with-comment-on-failure:
+    runs-on: ubuntu-latest
+    steps:
+    - name: Checkout project sources
+      uses: actions/checkout@v4
+    - name: Setup Gradle
+      uses: ./
+      with:
+        add-job-summary-as-pr-comment: on-failure
+    - name: Run build with Gradle wrapper
+      id: gradle
+      working-directory: .github/workflow-samples/kotlin-dsl
+      run: ./gradlew no-a-real-task --scan
+      continue-on-error: true
diff --git a/action.yml b/action.yml
index a6fd27a..d73e0aa 100644
--- a/action.yml
+++ b/action.yml
@@ -58,15 +58,15 @@ inputs:
     required: false
     default: false
 
-  generate-job-summary:
-    description: When 'false', no Job Summary will be generated for the Job.
+  add-job-summary:
+    description: Specifies when a Job Summary should be inluded in the action results. Valid values are 'never', 'always' (default), and 'on-failure'.
     required: false
-    default: true
+    default: 'always'
 
-  add-pr-comment:
-    description: When 'true', a summary of the Gradle builds will be added as a PR comment. No action will be taken if the workflow was not triggered from a pull request.
+  add-job-summary-as-pr-comment:
+    description: Specifies when each Job Summary should be added as a PR comment. Valid values are 'never' (default), 'always', and 'on-failure'. No action will be taken if the workflow was not triggered from a pull request.
     required: false
-    default: false
+    default: 'never'
 
   dependency-graph:
     description: Specifies if a GitHub dependency snapshot should be generated for each Gradle build, and if so, how. Valid values are 'disabled' (default), 'generate', 'generate-and-submit', 'generate-and-upload' and 'download-and-submit'.
@@ -93,6 +93,12 @@ inputs:
     required: false
     deprecation-message: Using the action to execute Gradle directly is deprecated in favor of using the action to setup Gradle, and executing Gradle in a subsequent Step. See https://github.com/gradle/gradle-build-action?tab=readme-ov-file#use-the-action-to-setup-gradle. 
 
+  generate-job-summary:
+    description: When 'false', no Job Summary will be generated for the Job.
+    required: false
+    default: true
+    deprecation-message: Superceded by the new 'add-job-summary' and 'add-job-summary-as-pr-comment' parameters.
+
   # EXPERIMENTAL & INTERNAL ACTION INPUTS
   # The following action properties allow fine-grained tweaking of the action caching behaviour.
   # These properties are experimental and not (yet) designed for production use, and may change without notice in a subsequent release of `gradle-build-action`.
diff --git a/src/input-params.ts b/src/input-params.ts
index 4947d8c..ade5d65 100644
--- a/src/input-params.ts
+++ b/src/input-params.ts
@@ -71,12 +71,25 @@ export function isJobSummaryEnabled(): boolean {
     return getBooleanInput('generate-job-summary', true)
 }
 
-export function isPRCommentEnabled(): boolean {
-    return getBooleanInput('add-pr-comment', false)
+export function getJobSummaryOption(): JobSummaryOption {
+    return parseJobSummaryOption('add-job-summary')
 }
 
-export function isDependencyGraphEnabled(): boolean {
-    return getBooleanInput('generate-dependency-graph', true)
+export function getPRCommentOption(): JobSummaryOption {
+    return parseJobSummaryOption('add-job-summary-as-pr-comment')
+}
+
+function parseJobSummaryOption(paramName: string): JobSummaryOption {
+    const val = core.getInput(paramName)
+    switch (val.toLowerCase().trim()) {
+        case 'never':
+            return JobSummaryOption.Never
+        case 'always':
+            return JobSummaryOption.Always
+        case 'on-failure':
+            return JobSummaryOption.OnFailure
+    }
+    throw TypeError(`The value '${val}' is not valid for ${paramName}. Valid values are: [never, always, on-failure].`)
 }
 
 export function getDependencyGraphOption(): DependencyGraphOption {
@@ -94,7 +107,7 @@ export function getDependencyGraphOption(): DependencyGraphOption {
             return DependencyGraphOption.DownloadAndSubmit
     }
     throw TypeError(
-        `The value '${val} is not valid for 'dependency-graph. Valid values are: [disabled, generate, generate-and-submit, generate-and-upload, download-and-submit]. The default value is 'disabled'.`
+        `The value '${val}' is not valid for 'dependency-graph'. Valid values are: [disabled, generate, generate-and-submit, generate-and-upload, download-and-submit]. The default value is 'disabled'.`
     )
 }
 
@@ -135,3 +148,9 @@ export enum DependencyGraphOption {
     GenerateAndUpload = 'generate-and-upload',
     DownloadAndSubmit = 'download-and-submit'
 }
+
+export enum JobSummaryOption {
+    Never = 'never',
+    Always = 'always',
+    OnFailure = 'on-failure'
+}
diff --git a/src/job-summary.ts b/src/job-summary.ts
index ce1516f..54118d4 100644
--- a/src/job-summary.ts
+++ b/src/job-summary.ts
@@ -10,7 +10,7 @@ export async function generateJobSummary(buildResults: BuildResult[], cacheListe
     const summaryTable = renderSummaryTable(buildResults)
     const cachingReport = generateCachingReport(cacheListener)
 
-    if (shouldGenerateJobSummary()) {
+    if (shouldGenerateJobSummary(buildResults)) {
         core.info('Generating Job Summary')
 
         core.summary.addRaw(summaryTable)
@@ -24,7 +24,7 @@ export async function generateJobSummary(buildResults: BuildResult[], cacheListe
         core.info('============================')
     }
 
-    if (shouldAddPRComment()) {
+    if (shouldAddPRComment(buildResults)) {
         await addPRComment(summaryTable)
     }
 }
@@ -111,15 +111,32 @@ function renderBuildScanBadge(outcomeText: string, outcomeColor: string, targetU
     return `<a href="${targetUrl}" rel="nofollow">${badgeHtml}</a>`
 }
 
-function shouldGenerateJobSummary(): boolean {
+function shouldGenerateJobSummary(buildResults: BuildResult[]): boolean {
     // Check if Job Summary is supported on this platform
     if (!process.env[SUMMARY_ENV_VAR]) {
         return false
     }
 
-    return params.isJobSummaryEnabled()
+    // Check if Job Summary is disabled using the deprecated input
+    if (!params.isJobSummaryEnabled()) {
+        return false
+    }
+
+    return shouldAddJobSummary(params.getJobSummaryOption(), buildResults)
 }
 
-function shouldAddPRComment(): boolean {
-    return params.isPRCommentEnabled()
+function shouldAddPRComment(buildResults: BuildResult[]): boolean {
+    return shouldAddJobSummary(params.getPRCommentOption(), buildResults)
+}
+
+function shouldAddJobSummary(option: params.JobSummaryOption, buildResults: BuildResult[]): boolean {
+    switch (option) {
+        case params.JobSummaryOption.Always:
+            return true
+        case params.JobSummaryOption.Never:
+            return false
+        case params.JobSummaryOption.OnFailure:
+            core.info(`Got these build results: ${JSON.stringify(buildResults)}`)
+            return buildResults.some(result => result.buildFailed)
+    }
 }