From b09c7e669ad903a0a3f0dfec8bfbcc4714ef22c9 Mon Sep 17 00:00:00 2001 From: daz Date: Mon, 8 Apr 2024 17:27:59 -0600 Subject: [PATCH] Mark build-result files as processed to avoid double-dipping On long-lived machines, it's possible that the `.build-results` directory isn't cleared between invocations. This will result in the job summary including results from previous jobs. By marking each build-results file as 'processed', we can avoid this scenario. --- .github/workflows/demo-job-summary.yml | 4 +++ sources/src/build-results.ts | 35 +++++++++++++++++++++----- sources/src/setup-gradle.ts | 4 ++- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/.github/workflows/demo-job-summary.yml b/.github/workflows/demo-job-summary.yml index 0ff7ec7..f56c0f9 100644 --- a/.github/workflows/demo-job-summary.yml +++ b/.github/workflows/demo-job-summary.yml @@ -16,6 +16,10 @@ jobs: npm install npm run build working-directory: sources + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' - name: Setup Gradle uses: ./setup-gradle - name: Build kotlin-dsl project diff --git a/sources/src/build-results.ts b/sources/src/build-results.ts index 4af5204..2813bd5 100644 --- a/sources/src/build-results.ts +++ b/sources/src/build-results.ts @@ -13,15 +13,38 @@ export interface BuildResult { } export function loadBuildResults(): BuildResult[] { + return getUnprocessedResults().map(filePath => { + const content = fs.readFileSync(filePath, 'utf8') + return JSON.parse(content) as BuildResult + }) +} + +export function markBuildResultsProcessed(): void { + getUnprocessedResults().forEach(markProcessed) +} + +function getUnprocessedResults(): string[] { const buildResultsDir = path.resolve(process.env['RUNNER_TEMP']!, '.build-results') if (!fs.existsSync(buildResultsDir)) { return [] } - return fs.readdirSync(buildResultsDir).map(file => { - // Every file in the .build-results dir should be a BuildResults JSON - const filePath = path.join(buildResultsDir, file) - const content = fs.readFileSync(filePath, 'utf8') - return JSON.parse(content) as BuildResult - }) + return fs + .readdirSync(buildResultsDir) + .map(file => { + return path.resolve(buildResultsDir, file) + }) + .filter(filePath => { + return path.extname(filePath) === '.json' && !isProcessed(filePath) + }) +} + +function isProcessed(resultFile: string): boolean { + const markerFile = `${resultFile}.processed` + return fs.existsSync(markerFile) +} + +function markProcessed(resultFile: string): void { + const markerFile = `${resultFile}.processed` + fs.writeFileSync(markerFile, '') } diff --git a/sources/src/setup-gradle.ts b/sources/src/setup-gradle.ts index b138e56..af418ae 100644 --- a/sources/src/setup-gradle.ts +++ b/sources/src/setup-gradle.ts @@ -6,7 +6,7 @@ import * as caches from './caching/caches' import * as jobSummary from './job-summary' import * as buildScan from './build-scan' -import {loadBuildResults} from './build-results' +import {loadBuildResults, markBuildResultsProcessed} from './build-results' import {CacheListener, generateCachingReport} from './caching/cache-reporting' import {DaemonController} from './daemon-controller' import {BuildScanConfig, CacheConfig, SummaryConfig, getWorkspaceDirectory} from './input-params' @@ -63,6 +63,8 @@ export async function complete(cacheConfig: CacheConfig, summaryConfig: SummaryC const cachingReport = generateCachingReport(cacheListener) await jobSummary.generateJobSummary(buildResults, cachingReport, summaryConfig) + markBuildResultsProcessed() + core.info('Completed post-action step') return true