mirror of
https://github.com/gradle/actions
synced 2024-12-03 14:52:18 +00:00
Generated graph is submitted immediately by dependency-submission action
While `setup-gradle` must wait until the end of job to submit all of the generated graphs, the `dependency-submission` action will not save/upload the generated graph immediately, in the same step where it is generated.
This commit is contained in:
parent
38a821729e
commit
90bf65c87c
7 changed files with 105 additions and 69 deletions
4
.github/workflows/ci-dependency-review.yml
vendored
4
.github/workflows/ci-dependency-review.yml
vendored
|
@ -16,5 +16,9 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
- name: 'Dependency Submission'
|
||||||
|
uses: ./dependency-submission
|
||||||
|
with:
|
||||||
|
build-root-directory: .github/workflow-samples/groovy-dsl
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v4
|
uses: actions/dependency-review-action@v4
|
||||||
|
|
|
@ -89,51 +89,72 @@ jobs:
|
||||||
with:
|
with:
|
||||||
build-root-directory: .github/workflow-samples/kotlin-dsl
|
build-root-directory: .github/workflow-samples/kotlin-dsl
|
||||||
|
|
||||||
# TODO - Test this scenario (and make it work)
|
multiple-builds:
|
||||||
# multiple-builds:
|
strategy:
|
||||||
# strategy:
|
matrix:
|
||||||
# matrix:
|
os: ${{fromJSON(inputs.runner-os)}}
|
||||||
# os: ${{fromJSON(inputs.runner-os)}}
|
runs-on: ${{ matrix.os }}
|
||||||
# runs-on: ${{ matrix.os }}
|
steps:
|
||||||
# steps:
|
- name: Checkout sources
|
||||||
# - name: Checkout sources
|
uses: actions/checkout@v4
|
||||||
# uses: actions/checkout@v4
|
- name: Initialize integ-test
|
||||||
# - name: Initialize integ-test
|
uses: ./.github/actions/init-integ-test
|
||||||
# uses: ./.github/actions/init-integ-test
|
|
||||||
|
- id: kotlin-dsl
|
||||||
|
uses: ./dependency-submission
|
||||||
|
with:
|
||||||
|
build-root-directory: .github/workflow-samples/kotlin-dsl
|
||||||
|
- id: groovy-dsl
|
||||||
|
uses: ./dependency-submission
|
||||||
|
with:
|
||||||
|
build-root-directory: .github/workflow-samples/groovy-dsl
|
||||||
|
- id: groovy-dsl-again
|
||||||
|
uses: ./dependency-submission
|
||||||
|
with:
|
||||||
|
build-root-directory: .github/workflow-samples/groovy-dsl
|
||||||
|
additional-arguments: --no-build-cache
|
||||||
|
- name: Check generated dependency graphs
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "kotlin-dsl report file: ${{ steps.kotlin-dsl.outputs.dependency-graph-file }}"
|
||||||
|
echo "groovy-dsl report file: ${{ steps.groovy-dsl.outputs.dependency-graph-file }}"
|
||||||
|
echo "groovy-dsl-again report file: ${{ steps.groovy-dsl-again.outputs.dependency-graph-file }}"
|
||||||
|
ls -l dependency-graph-reports
|
||||||
|
if [ ! -e "${{ steps.kotlin-dsl.outputs.dependency-graph-file }}" ]; then
|
||||||
|
echo "Did not find kotlin-dsl dependency graph file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -e "${{ steps.groovy-dsl.outputs.dependency-graph-file }}" ]; then
|
||||||
|
echo "Did not find groovy-dsl dependency graph file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -e "${{ steps.groovy-dsl-again.outputs.dependency-graph-file }}" ]; then
|
||||||
|
echo "Did not find groovy-dsl-again dependency graph file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
multiple-builds-upload:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: ${{fromJSON(inputs.runner-os)}}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Initialize integ-test
|
||||||
|
uses: ./.github/actions/init-integ-test
|
||||||
|
|
||||||
|
- id: kotlin-dsl
|
||||||
|
uses: ./dependency-submission
|
||||||
|
with:
|
||||||
|
dependency-graph: generate-and-upload
|
||||||
|
build-root-directory: .github/workflow-samples/kotlin-dsl
|
||||||
|
- id: groovy-dsl
|
||||||
|
uses: ./dependency-submission
|
||||||
|
with:
|
||||||
|
dependency-graph: generate-and-upload
|
||||||
|
build-root-directory: .github/workflow-samples/groovy-dsl
|
||||||
|
|
||||||
# - name: Setup Gradle for dependency-graph generate
|
|
||||||
# uses: ./setup-gradle
|
|
||||||
# with:
|
|
||||||
# dependency-graph: generate-and-submit
|
|
||||||
# - id: gradle-assemble
|
|
||||||
# run: ./gradlew assemble
|
|
||||||
# working-directory: .github/workflow-samples/groovy-dsl
|
|
||||||
# - id: gradle-build
|
|
||||||
# run: ./gradlew build
|
|
||||||
# working-directory: .github/workflow-samples/groovy-dsl
|
|
||||||
# - id: gradle-build-again
|
|
||||||
# run: ./gradlew build
|
|
||||||
# working-directory: .github/workflow-samples/groovy-dsl
|
|
||||||
# - name: Check generated dependency graphs
|
|
||||||
# shell: bash
|
|
||||||
# run: |
|
|
||||||
# echo "gradle-assemble report file: ${{ steps.gradle-assemble.outputs.dependency-graph-file }}"
|
|
||||||
# echo "gradle-build report file: ${{ steps.gradle-build.outputs.dependency-graph-file }}"
|
|
||||||
# echo "gradle-build-again report file: ${{ steps.gradle-build-again.outputs.dependency-graph-file }}"
|
|
||||||
# ls -l dependency-graph-reports
|
|
||||||
# if [ ! -e "${{ steps.gradle-assemble.outputs.dependency-graph-file }}" ]; then
|
|
||||||
# echo "Did not find gradle-assemble dependency graph file"
|
|
||||||
# exit 1
|
|
||||||
# fi
|
|
||||||
# if [ ! -e "${{ steps.gradle-build.outputs.dependency-graph-file }}" ]; then
|
|
||||||
# echo "Did not find gradle-build dependency graph files"
|
|
||||||
# exit 1
|
|
||||||
# fi
|
|
||||||
# if [ ! -e "${{ steps.gradle-build-again.outputs.dependency-graph-file }}" ]; then
|
|
||||||
# echo "Did not find gradle-build-again dependency graph files"
|
|
||||||
# exit 1
|
|
||||||
# fi
|
|
||||||
|
|
||||||
config-cache:
|
config-cache:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -154,7 +175,7 @@ jobs:
|
||||||
echo "Did not find config-cache-store dependency graph files"
|
echo "Did not find config-cache-store dependency graph files"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
rm ${{ steps.config-cache-store.outputs.dependency-graph-file }}
|
rm ${{ steps.config-cache-store.outputs.dependency-graph-file }}*
|
||||||
- id: config-cache-reuse
|
- id: config-cache-reuse
|
||||||
uses: ./dependency-submission
|
uses: ./dependency-submission
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -288,18 +288,11 @@ jobs:
|
||||||
|
|
||||||
- name: Generate and submit dependency graph
|
- name: Generate and submit dependency graph
|
||||||
uses: gradle/actions/dependency-submission@v3
|
uses: gradle/actions/dependency-submission@v3
|
||||||
|
|
||||||
dependency-review:
|
|
||||||
needs: dependency-submission
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Perform dependency review
|
- name: Perform dependency review
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that the `dependency-submission` action submits the dependency graph at the completion of the workflow Job.
|
|
||||||
For this reason, the `dependency-review-action` must be executed in a dependent job, and not as a subsequent step in the job that generates the dependency graph.
|
|
||||||
|
|
||||||
## Usage with pull requests from public forked repositories
|
## Usage with pull requests from public forked repositories
|
||||||
|
|
||||||
This `contents: write` permission is [not available for any workflow that is triggered by a pull request submitted from a public forked repository](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token).
|
This `contents: write` permission is [not available for any workflow that is triggered by a pull request submitted from a public forked repository](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token).
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
"no-shadow": "off",
|
"no-shadow": "off",
|
||||||
"sort-imports": "off",
|
"sort-imports": "off",
|
||||||
|
"github/array-foreach": "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"}],
|
||||||
"@typescript-eslint/no-require-imports": "error",
|
"@typescript-eslint/no-require-imports": "error",
|
||||||
|
|
|
@ -54,11 +54,6 @@ function maybeExportVariable(variableName: string, value: unknown): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function complete(config: DependencyGraphConfig): Promise<void> {
|
export async function complete(config: DependencyGraphConfig): Promise<void> {
|
||||||
if (isRunningInActEnvironment()) {
|
|
||||||
core.info('Dependency graph upload and submit not supported in the ACT environment.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const option = config.getDependencyGraphOption()
|
const option = config.getDependencyGraphOption()
|
||||||
try {
|
try {
|
||||||
switch (option) {
|
switch (option) {
|
||||||
|
@ -84,6 +79,12 @@ async function findGeneratedDependencyGraphFiles(): Promise<string[]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function uploadDependencyGraphs(dependencyGraphFiles: string[], config: DependencyGraphConfig): Promise<void> {
|
async function uploadDependencyGraphs(dependencyGraphFiles: string[], config: DependencyGraphConfig): Promise<void> {
|
||||||
|
if (isRunningInActEnvironment()) {
|
||||||
|
core.info('Dependency graph upload not supported in the ACT environment.')
|
||||||
|
core.info(`Would upload: ${dependencyGraphFiles.join(', ')}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const workspaceDirectory = layout.workspaceDirectory()
|
const workspaceDirectory = layout.workspaceDirectory()
|
||||||
|
|
||||||
const artifactClient = new DefaultArtifactClient()
|
const artifactClient = new DefaultArtifactClient()
|
||||||
|
@ -111,12 +112,18 @@ async function downloadAndSubmitDependencyGraphs(config: DependencyGraphConfig):
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise<void> {
|
async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise<void> {
|
||||||
for (const jsonFile of dependencyGraphFiles) {
|
if (isRunningInActEnvironment()) {
|
||||||
|
core.info('Dependency graph submit not supported in the ACT environment.')
|
||||||
|
core.info(`Would submit: ${dependencyGraphFiles.join(', ')}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const dependencyGraphFile of dependencyGraphFiles) {
|
||||||
try {
|
try {
|
||||||
await submitDependencyGraphFile(jsonFile)
|
await submitDependencyGraphFile(dependencyGraphFile)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof RequestError) {
|
if (error instanceof RequestError) {
|
||||||
throw new Error(translateErrorMessage(jsonFile, error))
|
throw new Error(translateErrorMessage(dependencyGraphFile, error))
|
||||||
} else {
|
} else {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -184,8 +191,20 @@ async function downloadDependencyGraphs(): Promise<string[]> {
|
||||||
|
|
||||||
async function findDependencyGraphFiles(dir: string): Promise<string[]> {
|
async function findDependencyGraphFiles(dir: string): Promise<string[]> {
|
||||||
const globber = await glob.create(`${dir}/dependency-graph-reports/*.json`)
|
const globber = await glob.create(`${dir}/dependency-graph-reports/*.json`)
|
||||||
const graphFiles = globber.glob()
|
const allFiles = await globber.glob()
|
||||||
return graphFiles
|
const unprocessedFiles = allFiles.filter(file => !isProcessed(file))
|
||||||
|
unprocessedFiles.forEach(markProcessed)
|
||||||
|
return unprocessedFiles
|
||||||
|
}
|
||||||
|
|
||||||
|
function isProcessed(dependencyGraphFile: string): boolean {
|
||||||
|
const markerFile = `${dependencyGraphFile}.processed`
|
||||||
|
return fs.existsSync(markerFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
function markProcessed(dependencyGraphFile: string): void {
|
||||||
|
const markerFile = `${dependencyGraphFile}.processed`
|
||||||
|
fs.writeFileSync(markerFile, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
function warnOrFail(config: DependencyGraphConfig, option: String, error: unknown): void {
|
function warnOrFail(config: DependencyGraphConfig, option: String, error: unknown): void {
|
||||||
|
|
|
@ -42,6 +42,8 @@ export async function run(): Promise<void> {
|
||||||
const args: string[] = parseArgsStringToArgv(executionArgs)
|
const args: string[] = parseArgsStringToArgv(executionArgs)
|
||||||
const buildRootDirectory = layout.buildRootDirectory()
|
const buildRootDirectory = layout.buildRootDirectory()
|
||||||
await execution.executeGradleBuild(executable, buildRootDirectory, args)
|
await execution.executeGradleBuild(executable, buildRootDirectory, args)
|
||||||
|
|
||||||
|
await dependencyGraph.complete(config)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(String(error))
|
core.setFailed(String(error))
|
||||||
if (error instanceof Error && error.stack) {
|
if (error instanceof Error && error.stack) {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
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 * as dependencyGraph from '../dependency-graph'
|
|
||||||
|
|
||||||
import {CacheConfig, DependencyGraphConfig, SummaryConfig} from '../input-params'
|
import {CacheConfig, SummaryConfig} from '../input-params'
|
||||||
import {PostActionJobFailure} from '../errors'
|
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
|
||||||
|
@ -15,10 +14,7 @@ process.on('uncaughtException', e => handleFailure(e))
|
||||||
*/
|
*/
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
if (await setupGradle.complete(new CacheConfig(), new SummaryConfig())) {
|
await setupGradle.complete(new CacheConfig(), new SummaryConfig())
|
||||||
// Only submit the dependency graphs once per job
|
|
||||||
await dependencyGraph.complete(new DependencyGraphConfig())
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof PostActionJobFailure) {
|
if (error instanceof PostActionJobFailure) {
|
||||||
core.setFailed(String(error))
|
core.setFailed(String(error))
|
||||||
|
|
Loading…
Reference in a new issue