Allow flexible use of dependency-graph support

Adds a 'dependency-graph' parameter that has 4 options:
1. 'disabled': no dependency graph files generated (the default)
2. 'generate': dependency graph files will be generated and saved as artifacts.
3. 'generate-and-submit': dependency graph files will be generated, saved as artifacts,
   and submitted to the Dependency Submission API on job completion.
4. 'download-and-submit': any previously uploaded dependency graph artifacts will be downloaded
   and submitted to the Dependency Submission API.
This commit is contained in:
daz 2023-07-05 12:33:47 -06:00
parent 820b228f28
commit 063cc1c708
No known key found for this signature in database
5 changed files with 62 additions and 14 deletions

View file

@ -12,6 +12,7 @@
"import/no-namespace": "off", "import/no-namespace": "off",
"i18n-text/no-en": "off", "i18n-text/no-en": "off",
"no-unused-vars": "off", "no-unused-vars": "off",
"no-shadow": "off",
"sort-imports": "off", "sort-imports": "off",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}], "@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
@ -30,6 +31,7 @@
"@typescript-eslint/no-misused-new": "error", "@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error", "@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-shadow": "error",
"@typescript-eslint/no-unnecessary-qualifier": "error", "@typescript-eslint/no-unnecessary-qualifier": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error", "@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-useless-constructor": "error", "@typescript-eslint/no-useless-constructor": "error",

View file

@ -58,10 +58,10 @@ inputs:
required: false required: false
default: true default: true
generate-dependency-graph: dependency-graph:
description: When 'true', a dependency graph snapshot will be generated for Gradle builds. 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' and 'download-and-submit'.
required: false required: false
default: false default: 'disabled'
# EXPERIMENTAL & INTERNAL ACTION INPUTS # EXPERIMENTAL & INTERNAL ACTION INPUTS
# The following action properties allow fine-grained tweaking of the action caching behaviour. # The following action properties allow fine-grained tweaking of the action caching behaviour.
@ -80,6 +80,11 @@ inputs:
required: false required: false
default: false default: false
github-token:
description: The GitHub token used to authenticate when submitting via the Dependency Submission API.
default: ${{ github.token }}
required: false
outputs: outputs:
build-scan-url: build-scan-url:
description: Link to the build scan if any description: Link to the build scan if any

View file

@ -10,12 +10,16 @@ import fs from 'fs'
import * as execution from './execution' import * as execution from './execution'
import * as layout from './repository-layout' import * as layout from './repository-layout'
import * as params from './input-params' import {DependencyGraphOption, getJobMatrix} from './input-params'
const DEPENDENCY_GRAPH_ARTIFACT = 'dependency-graph' const DEPENDENCY_GRAPH_ARTIFACT = 'dependency-graph'
export function prepare(): void { export function setup(option: DependencyGraphOption): void {
core.info('Enabling dependency graph') if (option === DependencyGraphOption.Disabled || option === DependencyGraphOption.DownloadAndSubmit) {
return
}
core.info('Enabling dependency graph generation')
const jobCorrelator = getJobCorrelator() const jobCorrelator = getJobCorrelator()
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_ENABLED', 'true') core.exportVariable('GITHUB_DEPENDENCY_GRAPH_ENABLED', 'true')
core.exportVariable('GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR', jobCorrelator) core.exportVariable('GITHUB_DEPENDENCY_GRAPH_JOB_CORRELATOR', jobCorrelator)
@ -26,6 +30,21 @@ export function prepare(): void {
) )
} }
export async function complete(option: DependencyGraphOption): Promise<void> {
switch (option) {
case DependencyGraphOption.Disabled:
return
case DependencyGraphOption.Generate:
await uploadDependencyGraphs()
return
case DependencyGraphOption.GenerateAndSubmit:
await submitDependencyGraphs(await uploadDependencyGraphs())
return
case DependencyGraphOption.DownloadAndSubmit:
await downloadAndSubmitDependencyGraphs()
}
}
export async function generateDependencyGraph(executable: string | undefined): Promise<void> { export async function generateDependencyGraph(executable: string | undefined): Promise<void> {
const buildRootDirectory = layout.buildRootDirectory() const buildRootDirectory = layout.buildRootDirectory()
@ -34,7 +53,7 @@ export async function generateDependencyGraph(executable: string | undefined): P
await execution.executeGradleBuild(executable, buildRootDirectory, args) await execution.executeGradleBuild(executable, buildRootDirectory, args)
} }
export async function uploadDependencyGraphs(): Promise<void> { export async function uploadDependencyGraphs(): Promise<string[]> {
const workspaceDirectory = layout.workspaceDirectory() const workspaceDirectory = layout.workspaceDirectory()
const graphFiles = await findDependencyGraphFiles(workspaceDirectory) const graphFiles = await findDependencyGraphFiles(workspaceDirectory)
@ -43,6 +62,8 @@ export async function uploadDependencyGraphs(): Promise<void> {
const artifactClient = artifact.create() const artifactClient = artifact.create()
artifactClient.uploadArtifact(DEPENDENCY_GRAPH_ARTIFACT, graphFiles, workspaceDirectory) artifactClient.uploadArtifact(DEPENDENCY_GRAPH_ARTIFACT, graphFiles, workspaceDirectory)
return graphFiles
} }
export async function downloadAndSubmitDependencyGraphs(): Promise<void> { export async function downloadAndSubmitDependencyGraphs(): Promise<void> {
@ -140,7 +161,7 @@ function getRelativePathFromWorkspace(file: string): string {
} }
export function getJobCorrelator(): string { export function getJobCorrelator(): string {
return constructJobCorrelator(github.context.workflow, github.context.job, params.getJobMatrix()) return constructJobCorrelator(github.context.workflow, github.context.job, getJobMatrix())
} }
export function constructJobCorrelator(workflow: string, jobId: string, matrixJson: string): string { export function constructJobCorrelator(workflow: string, jobId: string, matrixJson: string): string {

View file

@ -67,6 +67,23 @@ export function isDependencyGraphEnabled(): boolean {
return getBooleanInput('generate-dependency-graph', true) return getBooleanInput('generate-dependency-graph', true)
} }
export function getDependencyGraphOption(): DependencyGraphOption {
const val = core.getInput('dependency-graph')
switch (val.toLowerCase().trim()) {
case 'disabled':
return DependencyGraphOption.Disabled
case 'generate':
return DependencyGraphOption.Generate
case 'generate-and-submit':
return DependencyGraphOption.GenerateAndSubmit
case 'download-and-submit':
return DependencyGraphOption.DownloadAndSubmit
}
throw TypeError(
`The value '${val} is not valid for 'dependency-graph. Valid values are: [disabled, generate-and-upload, generate-and-submit, download-and-submit]. The default value is 'disabled'.`
)
}
function getBooleanInput(paramName: string, paramDefault = false): boolean { function getBooleanInput(paramName: string, paramDefault = false): boolean {
const paramValue = core.getInput(paramName) const paramValue = core.getInput(paramName)
switch (paramValue.toLowerCase().trim()) { switch (paramValue.toLowerCase().trim()) {
@ -79,3 +96,10 @@ function getBooleanInput(paramName: string, paramDefault = false): boolean {
} }
throw TypeError(`The value '${paramValue} is not valid for '${paramName}. Valid values are: [true, false]`) throw TypeError(`The value '${paramValue} is not valid for '${paramName}. Valid values are: [true, false]`)
} }
export enum DependencyGraphOption {
Disabled,
Generate,
GenerateAndSubmit,
DownloadAndSubmit
}

View file

@ -38,9 +38,7 @@ export async function setup(): Promise<void> {
core.saveState(CACHE_LISTENER, cacheListener.stringify()) core.saveState(CACHE_LISTENER, cacheListener.stringify())
if (params.isDependencyGraphEnabled()) { dependencyGraph.setup(params.getDependencyGraphOption())
dependencyGraph.prepare()
}
} }
export async function complete(): Promise<void> { export async function complete(): Promise<void> {
@ -64,9 +62,7 @@ export async function complete(): Promise<void> {
logJobSummary(buildResults, cacheListener) logJobSummary(buildResults, cacheListener)
} }
if (params.isDependencyGraphEnabled()) { dependencyGraph.complete(params.getDependencyGraphOption())
dependencyGraph.uploadDependencyGraphs()
}
} }
async function determineGradleUserHome(): Promise<string> { async function determineGradleUserHome(): Promise<string> {