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
No known key found for this signature in database
7 changed files with 194 additions and 1 deletions

View file

@ -0,0 +1,95 @@
# Deprecation upgrade guide
As these actions evolve, certain inputs, behaviour and usages are deprecated for removal.
Deprecated functionality will be fully supported during the current major release, and will be
removed in the next major release.
Users will receive a deprecation warning when they rely on deprecated functionality,
prompting them to update their workflows.
## Deprecated in v3.x
### Using the action to execute Gradle via the `arguments` parameter is deprecated
The core functionality of the `setup-gradle` (and `gradle-build-action`) actions is to configure your
Gradle environment for GitHub Actions. Once the action has run, any subsequent Gradle executions will
benefit from caching, reporting and other features of the action.
Using the `arguments` parameter to execute Gradle directly is not necessary to benefit from this action.
This input is deprecated, and will be removed in the `v4` major release of the action.
To convert your workflows, replace any steps using the `arguments` parameter with 2 steps: one to `setup-gradle` and another that runs your Gradle build.
For example, if your workflow looks like this:
```
steps:
- name: Assemble the project
uses: gradle/actions/setup-gradle@v3
with:
arguments: 'assemble'
- name: Run the tests
uses: gradle/actions/setup-gradle@v3
with:
arguments: 'test'
```
Then replace this with a single call to `setup-gradle` together with separate `run` steps to execute your build.
```
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Assemble the project
run: ./gradlew assemble
- name: Run the tests
run: ./gradlew test
```
Using the action in this way gives you more control over how Gradle is executed, while still giving you
all of the benefits of the `setup-gradle` action.
The `arguments` parameter is scheduled to be removed in `setup-gradle@v4`.
Note: if you are using the `gradle-build-action`, [see here](#the-gradle-build-action-has-been-replaced-by-the-setup-gradle-action) for more details on how to migrate.
### The `gradle-build-action` has been replaced by the `setup-gradle` action
The `gradle-build-action` action has evolved, so that the core functionality is now to configure the
Gradle environment for GitHub Actions. For clarity and consistency with other action (eg `setup-java`, `setup-node`), the `gradle-build-action` has been replaced by the `setup-gradle` action.
As of `v3.x`, the `setup-gradle` and `gradle-build-action` actions are functionally identical,
and are released with the same versions.
To convert your workflows, simply replace:
```
uses: gradle/gradle-build-action@v3
```
with
```
uses: gradle/actions/setup-gradle@v3
```
### The `build-scan-terms-of-service` input parameters have been renamed
With recent releases of the `com.gradle.develocity` plugin, key input parameters have been renamed.
- `build-scan-terms-of-service-url` is now `build-scan-terms-of-use-url`
- `build-scan-terms-of-service-agree` is now `build-scan-terms-of-use-agree`
The standard URL for the terms of use has also changed to https://gradle.com/help/legal-terms-of-use
To convert your workflows, change:
```
build-scan-publish: true
build-scan-terms-of-service-url: "https://gradle.com/terms-of-service"
build-scan-terms-of-service-agree: "yes"
```
to this:
```
build-scan-publish: true
build-scan-terms-of-use-url: "https://gradle.com/help/legal-terms-of-use"
build-scan-terms-of-use-agree: "yes"
```
These deprecated build-scan parameters are scheduled to be removed in `setup-gradle@v4` and `dependency-submission@v4`.

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())