Emit deprecation warnings for derecated inputs

- Adds an upgrade-guide to assist with resolving deprecations
- Emit a warning when deprecated features are used
- List all deprecated features in Job Summary and link to upgrade guide
This commit is contained in:
daz
2024-04-09 10:51:09 -06:00
parent 2e02e6624e
commit 9d0de74673
7 changed files with 194 additions and 1 deletions

View File

@@ -12,6 +12,7 @@ import {
DependencyGraphOption,
GradleExecutionConfig
} from '../input-params'
import {saveDeprecationState} from '../deprecation-collector'
/**
* The main entry point for the action, called by Github Actions for the step.
@@ -49,6 +50,8 @@ export async function run(): Promise<void> {
)
await dependencyGraph.complete(config)
saveDeprecationState()
} catch (error) {
core.setFailed(String(error))
if (error instanceof Error && error.stack) {

View File

@@ -0,0 +1,54 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
const DEPRECATION_UPGRADE_PAGE = 'https://github.com/gradle/actions/blob/main/docs/deprecation-upgrade-guide.md'
const recordedDeprecations: Deprecation[] = []
export class Deprecation {
constructor(readonly message: string) {}
getDocumentationLink(): string {
const deprecationAnchor = this.message
.toLowerCase()
.replace(/[^\w\s-]|_/g, '')
.replace(/ /g, '-')
return `${DEPRECATION_UPGRADE_PAGE}#${deprecationAnchor}`
}
}
export function recordDeprecation(message: string): void {
if (!recordedDeprecations.some(deprecation => deprecation.message === message)) {
recordedDeprecations.push(new Deprecation(message))
}
}
export function getDeprecations(): Deprecation[] {
return recordedDeprecations
}
export function emitDeprecationWarnings(): void {
if (recordedDeprecations.length > 0) {
core.warning(
`This job uses deprecated functionality from the '${github.context.action}' action. Consult the Job Summary for more details.`
)
for (const deprecation of recordedDeprecations) {
core.info(`DEPRECATION: ${deprecation.message}. See ${deprecation.getDocumentationLink()}`)
}
}
}
export function saveDeprecationState(): void {
core.saveState('deprecations', JSON.stringify(recordedDeprecations))
}
export function restoreDeprecationState(): void {
const stringRep = core.getState('deprecations')
if (stringRep === '') {
return
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
JSON.parse(stringRep).forEach((obj: any) => {
recordedDeprecations.push(new Deprecation(obj.message))
})
}

View File

@@ -1,6 +1,7 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import * as cache from '@actions/cache'
import * as deprecator from './deprecation-collector'
import {SUMMARY_ENV_VAR} from '@actions/core/lib/summary'
import {parseArgsStringToArgv} from 'string-argv'
@@ -215,6 +216,11 @@ export class BuildScanConfig {
if (newProp !== '') {
return newProp
}
const oldProp = core.getInput(oldPropName)
if (oldProp !== '') {
deprecator.recordDeprecation('The `build-scan-terms-of-service` input parameters have been renamed')
return oldProp
}
return core.getInput(oldPropName)
}
}
@@ -236,6 +242,11 @@ export class GradleExecutionConfig {
getArguments(): string[] {
const input = core.getInput('arguments')
if (input.length !== 0) {
deprecator.recordDeprecation(
'Using the action to execute Gradle via the `arguments` parameter is deprecated'
)
}
return parseArgsStringToArgv(input)
}

View File

@@ -4,6 +4,7 @@ import {RequestError} from '@octokit/request-error'
import {BuildResult} from './build-results'
import {SummaryConfig, getGithubToken} from './input-params'
import {Deprecation, getDeprecations} from './deprecation-collector'
export async function generateJobSummary(
buildResults: BuildResult[],
@@ -78,8 +79,30 @@ Note that this permission is never available for a workflow triggered from a rep
}
function renderSummaryTable(results: BuildResult[]): string {
return `${renderDeprecations()}\n${renderBuildResults(results)}`
}
function renderDeprecations(): string {
const deprecations = getDeprecations()
if (deprecations.length === 0) {
return ''
}
return `
<h4>Deprecated usages of ${github.context.action}</h4>
<ul>
${deprecations.map(deprecation => `<li>${getDeprecationHtml(deprecation)}</li>`).join('')}
</ul>
<h4>Gradle Build Results</h4>`
}
function getDeprecationHtml(deprecation: Deprecation): string {
return `<a href="${deprecation.getDocumentationLink()}" target="_blank">${deprecation.message}</a>`
}
function renderBuildResults(results: BuildResult[]): string {
if (results.length === 0) {
return 'No Gradle build results detected.'
return '<b>No Gradle build results detected.</b>'
}
return `

View File

@@ -4,6 +4,7 @@ import * as setupGradle from '../setup-gradle'
import * as gradle from '../execution/gradle'
import * as dependencyGraph from '../dependency-graph'
import {BuildScanConfig, CacheConfig, DependencyGraphConfig, GradleExecutionConfig} from '../input-params'
import {saveDeprecationState} from '../deprecation-collector'
/**
* The main entry point for the action, called by Github Actions for the step.
@@ -22,6 +23,8 @@ export async function run(): Promise<void> {
config.getBuildRootDirectory(),
config.getArguments()
)
saveDeprecationState()
} catch (error) {
core.setFailed(String(error))
if (error instanceof Error && error.stack) {

View File

@@ -4,6 +4,7 @@ import * as dependencyGraph from '../dependency-graph'
import {CacheConfig, DependencyGraphConfig, SummaryConfig} from '../input-params'
import {PostActionJobFailure} from '../errors'
import {emitDeprecationWarnings, restoreDeprecationState} from '../deprecation-collector'
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
@@ -15,6 +16,9 @@ process.on('uncaughtException', e => handleFailure(e))
*/
export async function run(): Promise<void> {
try {
restoreDeprecationState()
emitDeprecationWarnings()
if (await setupGradle.complete(new CacheConfig(), new SummaryConfig())) {
// Only submit the dependency graphs once per job
await dependencyGraph.complete(new DependencyGraphConfig())