mirror of
https://github.com/gradle/gradle-build-action
synced 2024-11-27 12:02:15 +00:00
Add dependency-graph-continue-on-failure
input param
- Translate to env var for init-script support - Use when deciding whether to log or rethrow errors - Add a custom error type to trigger failure in post action
This commit is contained in:
parent
369fcc54d8
commit
a01f794d92
8 changed files with 70 additions and 16 deletions
|
@ -20,8 +20,6 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
unsupported-gradle-version-failure:
|
unsupported-gradle-version-failure:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -32,6 +30,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
gradle-version: 7.0.1
|
gradle-version: 7.0.1
|
||||||
dependency-graph: generate
|
dependency-graph: generate
|
||||||
|
dependency-graph-continue-on-failure: false
|
||||||
- name: Run with unsupported Gradle version
|
- name: Run with unsupported Gradle version
|
||||||
working-directory: .github/workflow-samples/groovy-dsl
|
working-directory: .github/workflow-samples/groovy-dsl
|
||||||
run: |
|
run: |
|
||||||
|
@ -42,8 +41,6 @@ jobs:
|
||||||
|
|
||||||
unsupported-gradle-version-warning:
|
unsupported-gradle-version-warning:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -54,11 +51,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
gradle-version: 7.0.1
|
gradle-version: 7.0.1
|
||||||
dependency-graph: generate
|
dependency-graph: generate
|
||||||
- name: Run with unsupported Gradle version
|
dependency-graph-continue-on-failure: true
|
||||||
working-directory: .github/workflow-samples/groovy-dsl
|
|
||||||
run: |
|
|
||||||
gradle help
|
|
||||||
|
|
||||||
- name: Run with unsupported Gradle version
|
- name: Run with unsupported Gradle version
|
||||||
working-directory: .github/workflow-samples/groovy-dsl
|
working-directory: .github/workflow-samples/groovy-dsl
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -73,6 +73,11 @@ inputs:
|
||||||
required: false
|
required: false
|
||||||
default: 'disabled'
|
default: 'disabled'
|
||||||
|
|
||||||
|
dependency-graph-continue-on-failure:
|
||||||
|
description: When 'false' a failure to generate or submit a dependency graph will fail the Step or Job. When 'true' a warning will be emitted but no failure will result.
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
|
||||||
artifact-retention-days:
|
artifact-retention-days:
|
||||||
description: Specifies the number of days to retain any artifacts generated by the action. If not set, the default retention settings for the repository will apply.
|
description: Specifies the number of days to retain any artifacts generated by the action. If not set, the default retention settings for the repository will apply.
|
||||||
required: false
|
required: false
|
||||||
|
|
|
@ -10,7 +10,13 @@ import * as path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
|
||||||
import * as layout from './repository-layout'
|
import * as layout from './repository-layout'
|
||||||
import {DependencyGraphOption, getJobMatrix, getArtifactRetentionDays} from './input-params'
|
import {PostActionJobFailure} from './errors'
|
||||||
|
import {
|
||||||
|
DependencyGraphOption,
|
||||||
|
getDependencyGraphContinueOnFailure,
|
||||||
|
getJobMatrix,
|
||||||
|
getArtifactRetentionDays
|
||||||
|
} from './input-params'
|
||||||
|
|
||||||
const DEPENDENCY_GRAPH_PREFIX = 'dependency-graph_'
|
const DEPENDENCY_GRAPH_PREFIX = 'dependency-graph_'
|
||||||
|
|
||||||
|
@ -26,6 +32,7 @@ export async function setup(option: DependencyGraphOption): Promise<void> {
|
||||||
|
|
||||||
core.info('Enabling dependency graph generation')
|
core.info('Enabling dependency graph generation')
|
||||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_ENABLED', 'true')
|
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_ENABLED', 'true')
|
||||||
|
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_CONTINUE_ON_FAILURE', getDependencyGraphContinueOnFailure())
|
||||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR', getJobCorrelator())
|
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR', getJobCorrelator())
|
||||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_JOB_ID', github.context.runId)
|
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_JOB_ID', github.context.runId)
|
||||||
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_REF', github.context.ref)
|
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_REF', github.context.ref)
|
||||||
|
@ -51,7 +58,7 @@ export async function complete(option: DependencyGraphOption): Promise<void> {
|
||||||
await uploadDependencyGraphs(await findGeneratedDependencyGraphFiles())
|
await uploadDependencyGraphs(await findGeneratedDependencyGraphFiles())
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
core.warning(`Failed to ${option} dependency graph. Will continue. ${String(e)}`)
|
warnOrFail(option, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +85,7 @@ async function downloadAndSubmitDependencyGraphs(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await submitDependencyGraphs(await downloadDependencyGraphs())
|
await submitDependencyGraphs(await downloadDependencyGraphs())
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
core.warning(`Download and submit dependency graph failed. Will continue. ${String(e)}`)
|
warnOrFail(DependencyGraphOption.DownloadAndSubmit, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +95,7 @@ async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise<v
|
||||||
await submitDependencyGraphFile(jsonFile)
|
await submitDependencyGraphFile(jsonFile)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof RequestError) {
|
if (error instanceof RequestError) {
|
||||||
core.warning(buildWarningMessage(jsonFile, error))
|
throw new Error(translateErrorMessage(jsonFile, error))
|
||||||
} else {
|
} else {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -96,9 +103,9 @@ async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise<v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildWarningMessage(jsonFile: string, error: RequestError): string {
|
function translateErrorMessage(jsonFile: string, error: RequestError): string {
|
||||||
const relativeJsonFile = getRelativePathFromWorkspace(jsonFile)
|
const relativeJsonFile = getRelativePathFromWorkspace(jsonFile)
|
||||||
const mainWarning = `Failed to submit dependency graph ${relativeJsonFile}.\n${String(error)}`
|
const mainWarning = `Dependency submission failed for ${relativeJsonFile}.\n${String(error)}`
|
||||||
if (error.message === 'Resource not accessible by integration') {
|
if (error.message === 'Resource not accessible by integration') {
|
||||||
return `${mainWarning}
|
return `${mainWarning}
|
||||||
Please ensure that the 'contents: write' permission is available for the workflow job.
|
Please ensure that the 'contents: write' permission is available for the workflow job.
|
||||||
|
@ -160,6 +167,14 @@ async function findDependencyGraphFiles(dir: string): Promise<string[]> {
|
||||||
return graphFiles
|
return graphFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function warnOrFail(option: String, error: unknown): void {
|
||||||
|
if (!getDependencyGraphContinueOnFailure()) {
|
||||||
|
throw new PostActionJobFailure(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
core.warning(`Failed to ${option} dependency graph. Will continue.\n${String(error)}`)
|
||||||
|
}
|
||||||
|
|
||||||
function getOctokit(): InstanceType<typeof GitHub> {
|
function getOctokit(): InstanceType<typeof GitHub> {
|
||||||
return github.getOctokit(getGithubToken())
|
return github.getOctokit(getGithubToken())
|
||||||
}
|
}
|
||||||
|
|
11
src/errors.ts
Normal file
11
src/errors.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export class PostActionJobFailure extends Error {
|
||||||
|
constructor(error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
super(error.message)
|
||||||
|
this.name = error.name
|
||||||
|
this.stack = error.stack
|
||||||
|
} else {
|
||||||
|
super(String(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -107,6 +107,10 @@ export function getDependencyGraphOption(): DependencyGraphOption {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDependencyGraphContinueOnFailure(): boolean {
|
||||||
|
return getBooleanInput('dependency-graph-continue-on-failure', true)
|
||||||
|
}
|
||||||
|
|
||||||
export function getArtifactRetentionDays(): number {
|
export function getArtifactRetentionDays(): number {
|
||||||
const val = core.getInput('artifact-retention-days')
|
const val = core.getInput('artifact-retention-days')
|
||||||
return parseNumericInput('artifact-retention-days', val, 0)
|
return parseNumericInput('artifact-retention-days', val, 0)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as setupGradle from './setup-gradle'
|
import * as setupGradle from './setup-gradle'
|
||||||
|
import {PostActionJobFailure} from './errors'
|
||||||
|
|
||||||
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
// 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
|
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
|
||||||
|
@ -13,6 +14,11 @@ export async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await setupGradle.complete()
|
await setupGradle.complete()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error instanceof PostActionJobFailure) {
|
||||||
|
core.setFailed(String(error))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
handleFailure(error)
|
handleFailure(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@ if (getVariable('GITHUB_DEPENDENCY_GRAPH_ENABLED') != "true") {
|
||||||
def gradleVersion = GradleVersion.current().baseVersion
|
def gradleVersion = GradleVersion.current().baseVersion
|
||||||
if (gradleVersion < GradleVersion.version("5.2") ||
|
if (gradleVersion < GradleVersion.version("5.2") ||
|
||||||
(gradleVersion >= GradleVersion.version("7.0") && gradleVersion < GradleVersion.version("7.1"))) {
|
(gradleVersion >= GradleVersion.version("7.0") && gradleVersion < GradleVersion.version("7.1"))) {
|
||||||
|
if (getVariable('GITHUB_DEPENDENCY_GRAPH_CONTINUE_ON_FAILURE') != "true") {
|
||||||
|
throw new GradleException("Dependency Graph is not supported for ${gradleVersion}. No dependency snapshot will be generated.")
|
||||||
|
}
|
||||||
println "::warning::Dependency Graph is not supported for ${gradleVersion}. No dependency snapshot will be generated."
|
println "::warning::Dependency Graph is not supported for ${gradleVersion}. No dependency snapshot will be generated."
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,23 @@ class TestDependencyGraph extends BaseInitScriptTest {
|
||||||
|
|
||||||
then:
|
then:
|
||||||
assert !reportsDir.exists()
|
assert !reportsDir.exists()
|
||||||
assert result.output.contains("::warning::Dependency Graph is not supported")
|
assert result.output.contains("::warning::Dependency Graph is not supported for ${testGradleVersion}")
|
||||||
|
|
||||||
|
where:
|
||||||
|
testGradleVersion << NO_DEPENDENCY_GRAPH_VERSIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
def "fails build when enabled for older Gradle versions if continue-on-failure is false"() {
|
||||||
|
assumeTrue testGradleVersion.compatibleWithCurrentJvm
|
||||||
|
|
||||||
|
when:
|
||||||
|
def vars = envVars
|
||||||
|
vars.put('GITHUB_DEPENDENCY_GRAPH_CONTINUE_ON_FAILURE', 'false')
|
||||||
|
def result = runAndFail(['help'], initScript, testGradleVersion.gradleVersion, [], vars)
|
||||||
|
|
||||||
|
then:
|
||||||
|
assert !reportsDir.exists()
|
||||||
|
assert result.output.contains("Dependency Graph is not supported for ${testGradleVersion}")
|
||||||
|
|
||||||
where:
|
where:
|
||||||
testGradleVersion << NO_DEPENDENCY_GRAPH_VERSIONS
|
testGradleVersion << NO_DEPENDENCY_GRAPH_VERSIONS
|
||||||
|
@ -114,6 +130,7 @@ class TestDependencyGraph extends BaseInitScriptTest {
|
||||||
def getEnvVars() {
|
def getEnvVars() {
|
||||||
return [
|
return [
|
||||||
GITHUB_DEPENDENCY_GRAPH_ENABLED: "true",
|
GITHUB_DEPENDENCY_GRAPH_ENABLED: "true",
|
||||||
|
GITHUB_DEPENDENCY_GRAPH_CONTINUE_ON_FAILURE: "true",
|
||||||
GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR: "CORRELATOR",
|
GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR: "CORRELATOR",
|
||||||
GITHUB_DEPENDENCY_GRAPH_JOB_ID: "1",
|
GITHUB_DEPENDENCY_GRAPH_JOB_ID: "1",
|
||||||
GITHUB_DEPENDENCY_GRAPH_REF: "main",
|
GITHUB_DEPENDENCY_GRAPH_REF: "main",
|
||||||
|
|
Loading…
Reference in a new issue