diff --git a/.github/workflows/integ-test-dependency-submission-failures.yml b/.github/workflows/integ-test-dependency-submission-failures.yml index 536ba28c..de6dd1c4 100644 --- a/.github/workflows/integ-test-dependency-submission-failures.yml +++ b/.github/workflows/integ-test-dependency-submission-failures.yml @@ -1,4 +1,4 @@ -name: Test dependency graph +name: Test dependency submission failures on: workflow_call: diff --git a/.github/workflows/integ-test-dependency-submission.yml b/.github/workflows/integ-test-dependency-submission.yml index 6b9fe008..57a0a4ff 100644 --- a/.github/workflows/integ-test-dependency-submission.yml +++ b/.github/workflows/integ-test-dependency-submission.yml @@ -1,4 +1,4 @@ -name: Test dependency graph +name: Test dependency submission on: workflow_call: @@ -245,3 +245,79 @@ jobs: uses: ./dependency-submission with: build-root-directory: .github/workflow-samples/groovy-dsl + + custom-report-dir-submit: + strategy: + fail-fast: false + 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 + + - name: Generate dependency graph + id: dependency-graph + uses: ./dependency-submission + with: + dependency-graph: generate-and-submit + build-root-directory: .github/workflow-samples/groovy-dsl + env: + DEPENDENCY_GRAPH_REPORT_DIR: '${{ github.workspace }}/custom/report-dir' + - name: Check generated dependency graphs + shell: bash + run: | + echo "report file: ${{ steps.dependency-graph.outputs.dependency-graph-file }}" + + if [ ! -e "${{ steps.dependency-graph.outputs.dependency-graph-file }}" ]; then + echo "Did not find dependency graph file" + exit 1 + fi + + if [ -z "$(ls -A "${{ github.workspace }}/custom/report-dir")" ]; then + echo "No dependency graph files found in custom directory" + exit 1 + fi + + custom-report-dir-upload: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + - name: Initialize integ-test + uses: ./.github/actions/init-integ-test + + - name: Generate and upload dependency graph + id: dependency-graph + uses: ./dependency-submission + with: + dependency-graph: generate-and-upload + build-root-directory: .github/workflow-samples/groovy-dsl + env: + DEPENDENCY_GRAPH_REPORT_DIR: '${{ github.workspace }}/custom/report-dir' + + custom-report-dir-download-and-submit: + needs: custom-report-dir-upload + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + - name: Initialize integ-test + uses: ./.github/actions/init-integ-test + + - name: Download and submit dependency graph + uses: ./dependency-submission + with: + dependency-graph: download-and-submit + build-root-directory: .github/workflow-samples/groovy-dsl + env: + DEPENDENCY_GRAPH_REPORT_DIR: '${{ github.workspace }}/custom/report-dir' + - name: Check downloaded dependency graph + shell: bash + run: | + if [ -z "$(ls -A "${{ github.workspace }}/custom/report-dir")" ]; then + echo "No dependency graph files found in custom directory" + exit 1 + fi diff --git a/sources/src/configuration.ts b/sources/src/configuration.ts index f59cfbf7..9eb22915 100644 --- a/sources/src/configuration.ts +++ b/sources/src/configuration.ts @@ -45,6 +45,10 @@ export class DependencyGraphConfig { return DependencyGraphConfig.constructJobCorrelator(github.context.workflow, github.context.job, getJobMatrix()) } + getReportDirectory(): string { + return path.resolve(getWorkspaceDirectory(), 'dependency-graph-reports') + } + static constructJobCorrelator(workflow: string, jobId: string, matrixJson: string): string { const matrixString = this.describeMatrix(matrixJson) const label = matrixString ? `${workflow}-${jobId}-${matrixString}` : `${workflow}-${jobId}` diff --git a/sources/src/dependency-graph.ts b/sources/src/dependency-graph.ts index a12fb130..480fc3ef 100644 --- a/sources/src/dependency-graph.ts +++ b/sources/src/dependency-graph.ts @@ -34,10 +34,7 @@ export async function setup(config: DependencyGraphConfig): Promise { maybeExportVariable('GITHUB_DEPENDENCY_GRAPH_REF', github.context.ref) maybeExportVariable('GITHUB_DEPENDENCY_GRAPH_SHA', getShaFromContext()) maybeExportVariable('GITHUB_DEPENDENCY_GRAPH_WORKSPACE', getWorkspaceDirectory()) - maybeExportVariable( - 'DEPENDENCY_GRAPH_REPORT_DIR', - path.resolve(getWorkspaceDirectory(), 'dependency-graph-reports') - ) + maybeExportVariable('DEPENDENCY_GRAPH_REPORT_DIR', config.getReportDirectory()) // To clear the dependency graph, we generate an empty graph by excluding all projects and configurations if (option === DependencyGraphOption.Clear) { @@ -62,22 +59,22 @@ export async function complete(config: DependencyGraphConfig): Promise { return case DependencyGraphOption.GenerateAndSubmit: case DependencyGraphOption.Clear: // Submit the empty dependency graph - await submitDependencyGraphs(await findGeneratedDependencyGraphFiles()) + await submitDependencyGraphs(await findDependencyGraphFiles()) return case DependencyGraphOption.GenerateAndUpload: - await uploadDependencyGraphs(await findGeneratedDependencyGraphFiles(), config) + await uploadDependencyGraphs(await findDependencyGraphFiles(), config) } } catch (e) { warnOrFail(config, option, e) } } -async function findGeneratedDependencyGraphFiles(): Promise { - const workspaceDirectory = getWorkspaceDirectory() - return await findDependencyGraphFiles(workspaceDirectory) -} - async function uploadDependencyGraphs(dependencyGraphFiles: string[], config: DependencyGraphConfig): Promise { + if (dependencyGraphFiles.length === 0) { + core.info('No dependency graph files found to upload.') + return + } + if (isRunningInActEnvironment()) { core.info('Dependency graph upload not supported in the ACT environment.') core.info(`Would upload: ${dependencyGraphFiles.join(', ')}`) @@ -111,6 +108,11 @@ async function downloadAndSubmitDependencyGraphs(config: DependencyGraphConfig): } async function submitDependencyGraphs(dependencyGraphFiles: string[]): Promise { + if (dependencyGraphFiles.length === 0) { + core.info('No dependency graph files found to submit.') + return + } + if (isRunningInActEnvironment()) { core.info('Dependency graph submit not supported in the ACT environment.') core.info(`Would submit: ${dependencyGraphFiles.join(', ')}`) @@ -156,8 +158,6 @@ async function submitDependencyGraphFile(jsonFile: string): Promise { } async function downloadDependencyGraphs(): Promise { - const workspaceDirectory = getWorkspaceDirectory() - const findBy = github.context.payload.workflow_run ? { token: getGithubToken(), @@ -168,34 +168,37 @@ async function downloadDependencyGraphs(): Promise { : undefined const artifactClient = new DefaultArtifactClient() - const downloadPath = path.resolve(workspaceDirectory, 'dependency-graph') const dependencyGraphArtifacts = ( await artifactClient.listArtifacts({ latest: true, findBy }) - ).artifacts.filter(candidate => candidate.name.startsWith(DEPENDENCY_GRAPH_PREFIX)) + ).artifacts.filter(artifact => artifact.name.startsWith(DEPENDENCY_GRAPH_PREFIX)) for (const artifact of dependencyGraphArtifacts) { const downloadedArtifact = await artifactClient.downloadArtifact(artifact.id, { - path: downloadPath, findBy }) core.info(`Downloading dependency-graph artifact ${artifact.name} to ${downloadedArtifact.downloadPath}`) } - return findDependencyGraphFiles(downloadPath) + return findDependencyGraphFiles() } -async function findDependencyGraphFiles(dir: string): Promise { - const globber = await glob.create(`${dir}/dependency-graph-reports/*.json`) +async function findDependencyGraphFiles(): Promise { + const globber = await glob.create(`${getReportDirectory()}/**/*.json`) const allFiles = await globber.glob() const unprocessedFiles = allFiles.filter(file => !isProcessed(file)) unprocessedFiles.forEach(markProcessed) + core.info(`Found dependency graph files: ${unprocessedFiles.join(', ')}`) return unprocessedFiles } +function getReportDirectory(): string { + return process.env.DEPENDENCY_GRAPH_REPORT_DIR! +} + function isProcessed(dependencyGraphFile: string): boolean { const markerFile = `${dependencyGraphFile}.processed` return fs.existsSync(markerFile)