From b24d6c9b7e8b0f16d621b625b61327918571b7fa Mon Sep 17 00:00:00 2001 From: Vlad Chesnokov Date: Wed, 26 Aug 2026 11:49:09 +0200 Subject: [PATCH] Provide information about outdated Gradle versions in the job summary --- sources/src/gradle-support-status.ts | 7 +++ sources/src/job-summary.ts | 45 +++++++++++++++++-- sources/test/jest/job-summary.test.ts | 62 ++++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 6 deletions(-) diff --git a/sources/src/gradle-support-status.ts b/sources/src/gradle-support-status.ts index b8322a82..3b7638ba 100644 --- a/sources/src/gradle-support-status.ts +++ b/sources/src/gradle-support-status.ts @@ -28,6 +28,13 @@ export function getSupportStatus(version: GradleVersion, latestMajor: number): S } } +export function supportStatusOf(gradleVersion: string): SupportStatus | undefined { + if (LATEST_RELEASED_MAJOR === undefined) { + return undefined + } + return getSupportStatus(new GradleVersion(gradleVersion), LATEST_RELEASED_MAJOR) +} + export function reportSupportStatus(gradleVersions: string[]): void { if (LATEST_RELEASED_MAJOR === undefined) { return diff --git a/sources/src/job-summary.ts b/sources/src/job-summary.ts index 3f5b679c..5620f89f 100644 --- a/sources/src/job-summary.ts +++ b/sources/src/job-summary.ts @@ -6,6 +6,9 @@ import {CacheReport} from './cache-service' import {ProviderNote, renderCachingReport} from './caching-report' import {DependencyGraphConfig, getActionId, getGithubToken, getJobMatrix, SummaryConfig} from './configuration' import {Deprecation, getDeprecations, getErrors} from './deprecation-collector' +import {supportStatusOf} from './gradle-support-status' + +const FEATURE_LIFECYCLE_DOC = 'https://docs.gradle.org/current/userguide/feature_lifecycle.html#eol_support' export async function generateJobSummary( buildResults: BuildResult[], @@ -97,7 +100,7 @@ Note that this permission is never available for a workflow triggered from a rep } export function renderSummaryTable(results: BuildResult[]): string { - return `${renderDeprecations()}\n${renderBuildResults(results)}` + return `${renderDeprecations()}\n${renderBuildResults(results)}\n${renderOutdatedVersions(results)}` } function renderActionHeading(): string { @@ -147,8 +150,7 @@ function renderBuildResults(results: BuildResult[]): string { Build Outcome Build ScanĀ® ${results.map(result => renderBuildResultRow(result)).join('')} - - ` +` } function anyFailed(results: BuildResult[]): boolean { @@ -160,12 +162,47 @@ function renderBuildResultRow(result: BuildResult): string { ${truncateString(result.rootProjectName, 30)} ${truncateString(result.requestedTasks, 60)} - ${result.gradleVersion} + ${renderGradleVersion(result.gradleVersion)} ${renderOutcome(result)} ${renderBuildScan(result)} ` } +function renderGradleVersion(gradleVersion: string): string { + switch (supportStatusOf(gradleVersion)) { + case 'eol': + return `${gradleVersion} :warning:` + case 'maintenance': + return `${gradleVersion} :information_source:` + default: + return gradleVersion + } +} + +function renderOutdatedVersions(results: BuildResult[]): string { + const hasOutdatedVersion = results + .map(result => supportStatusOf(result.gradleVersion)) + .some(status => status === 'eol' || status === 'maintenance') + if (!hasOutdatedVersion) { + return '' + } + + return ` +

:warning: This Job uses an outdated Gradle version

+
+ Gradle release end-of-life policy +

For major versions, Gradle will backport critical fixes and security fixes to the last minor in the + previous major version. As such, each major Gradle release causes:

+ + Gradle feature lifecycle +
` +} + function renderOutcome(result: BuildResult): string { return result.buildFailed ? ':x:' : ':white_check_mark:' } diff --git a/sources/test/jest/job-summary.test.ts b/sources/test/jest/job-summary.test.ts index 1ec3c5ce..990dfb57 100644 --- a/sources/test/jest/job-summary.test.ts +++ b/sources/test/jest/job-summary.test.ts @@ -1,9 +1,20 @@ import dedent from 'dedent' import * as github from '@actions/github' -import {afterEach, describe, expect, it} from '@jest/globals' +import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals' import {BuildResult} from '../../src/build-results' -import {jobMarker, renderSummaryTable} from '../../src/job-summary' +import {SupportStatus} from '../../src/gradle-support-status' + +const mockSupportStatusOf = jest.fn<(gradleVersion: string) => SupportStatus | undefined>() +jest.unstable_mockModule('../../src/gradle-support-status', () => ({ + supportStatusOf: mockSupportStatusOf +})) + +const {jobMarker, renderSummaryTable} = await import('../../src/job-summary') + +beforeEach(() => { + mockSupportStatusOf.mockReturnValue('active') +}) const MATRIX_INPUT_ENV = 'INPUT_WORKFLOW-JOB-CONTEXT' @@ -185,6 +196,53 @@ describe('renderSummaryTable', () => { }) }) +describe('Gradle version support status', () => { + it('marks an outdated version and adds a details section', () => { + mockSupportStatusOf.mockReturnValue('eol') + const table = renderSummaryTable([successfulHelpBuild]) + expect(table.trim()).toBe(dedent` + + + + + + + + + + + + + + + +
Gradle Root ProjectRequested TasksGradle VersionBuild OutcomeBuild ScanĀ®
roothelp8.0 :warning::white_check_mark:Build Scan published
+ +

:warning: This Job uses an outdated Gradle version

+
+ Gradle release end-of-life policy +

For major versions, Gradle will backport critical fixes and security fixes to the last minor in the + previous major version. As such, each major Gradle release causes:

+ + Gradle feature lifecycle +
+ `); + }) + it('marks a maintenance-only version', () => { + mockSupportStatusOf.mockReturnValue('maintenance') + const table = renderSummaryTable([successfulHelpBuild]) + expect(table).toContain( + `8.0 :information_source:` + ) + expect(table).toContain('This Job uses an outdated Gradle version') + }) +}) + describe('jobMarker', () => { const original = process.env[MATRIX_INPUT_ENV]