2021-02-27 18:13:19 +00:00
|
|
|
import * as core from '@actions/core';
|
|
|
|
|
import * as fs from 'fs';
|
2022-01-11 11:52:29 +00:00
|
|
|
import * as github from '@actions/github';
|
2021-02-27 18:13:19 +00:00
|
|
|
import Handlebars from 'handlebars';
|
|
|
|
|
import ResultsParser from './results-parser';
|
2022-01-11 11:52:29 +00:00
|
|
|
import { RunMeta } from './results-meta';
|
|
|
|
|
import path from 'path';
|
2021-02-27 18:13:19 +00:00
|
|
|
|
2022-01-11 11:52:29 +00:00
|
|
|
const ResultsCheck = {
|
|
|
|
|
async createCheck(artifactsPath, githubToken, checkName) {
|
2021-02-27 18:13:19 +00:00
|
|
|
// Validate input
|
2021-03-06 06:55:03 +00:00
|
|
|
if (!fs.existsSync(artifactsPath) || !githubToken || !checkName) {
|
2021-02-27 18:13:19 +00:00
|
|
|
throw new Error(
|
2021-02-28 06:44:56 +00:00
|
|
|
`Missing input! {"artifactsPath": "${artifactsPath}", "githubToken": "${githubToken}, "checkName": "${checkName}"`,
|
2021-02-27 18:13:19 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse all results files
|
2022-01-11 11:52:29 +00:00
|
|
|
const runs: RunMeta[] = [];
|
2021-02-27 18:13:19 +00:00
|
|
|
const files = fs.readdirSync(artifactsPath);
|
|
|
|
|
await Promise.all(
|
|
|
|
|
files.map(async filepath => {
|
|
|
|
|
if (!filepath.endsWith('.xml')) return;
|
|
|
|
|
core.info(`Processing file ${filepath}...`);
|
|
|
|
|
const fileData = await ResultsParser.parseResults(path.join(artifactsPath, filepath));
|
|
|
|
|
core.info(fileData.summary);
|
|
|
|
|
runs.push(fileData);
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Combine all results into a single run summary
|
|
|
|
|
const runSummary = new RunMeta(checkName);
|
2022-01-11 11:52:29 +00:00
|
|
|
for (const run of runs) {
|
2021-02-27 18:13:19 +00:00
|
|
|
runSummary.total += run.total;
|
|
|
|
|
runSummary.passed += run.passed;
|
|
|
|
|
runSummary.skipped += run.skipped;
|
|
|
|
|
runSummary.failed += run.failed;
|
|
|
|
|
runSummary.duration += run.duration;
|
2022-01-11 11:52:29 +00:00
|
|
|
for (const suite of run.suites) {
|
2021-02-27 18:13:19 +00:00
|
|
|
runSummary.addTests(suite.tests);
|
2022-01-11 11:52:29 +00:00
|
|
|
}
|
|
|
|
|
}
|
2021-02-27 18:13:19 +00:00
|
|
|
|
|
|
|
|
// Log
|
|
|
|
|
core.info('=================');
|
|
|
|
|
core.info('Analyze result:');
|
|
|
|
|
core.info(runSummary.summary);
|
|
|
|
|
|
2021-03-06 06:55:03 +00:00
|
|
|
// Format output
|
2021-02-27 18:13:19 +00:00
|
|
|
const title = runSummary.summary;
|
|
|
|
|
const summary = await ResultsCheck.renderSummary(runs);
|
2021-03-06 06:55:03 +00:00
|
|
|
core.debug(`Summary view: ${summary}`);
|
2021-02-27 18:13:19 +00:00
|
|
|
const details = await ResultsCheck.renderDetails(runs);
|
2021-03-06 06:55:03 +00:00
|
|
|
core.debug(`Details view: ${details}`);
|
2021-02-27 18:13:19 +00:00
|
|
|
const rawAnnotations = runSummary.extractAnnotations();
|
2021-03-06 06:55:03 +00:00
|
|
|
core.debug(`Raw annotations: ${rawAnnotations}`);
|
2021-02-27 18:13:19 +00:00
|
|
|
const annotations = rawAnnotations.map(rawAnnotation => {
|
|
|
|
|
const annotation = rawAnnotation;
|
|
|
|
|
annotation.path = rawAnnotation.path.replace('/github/workspace/', '');
|
|
|
|
|
return annotation;
|
|
|
|
|
});
|
2021-03-06 06:55:03 +00:00
|
|
|
core.debug(`Annotations: ${annotations}`);
|
|
|
|
|
const output = {
|
|
|
|
|
title,
|
|
|
|
|
summary,
|
|
|
|
|
text: details,
|
|
|
|
|
annotations: annotations.slice(0, 50),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Call GitHub API
|
|
|
|
|
await ResultsCheck.requestGitHubCheck(githubToken, checkName, output);
|
|
|
|
|
return runSummary.failed;
|
2022-01-11 11:52:29 +00:00
|
|
|
},
|
2021-03-06 06:55:03 +00:00
|
|
|
|
2022-01-11 11:52:29 +00:00
|
|
|
async requestGitHubCheck(githubToken, checkName, output) {
|
2021-03-06 06:55:03 +00:00
|
|
|
const pullRequest = github.context.payload.pull_request;
|
|
|
|
|
const headSha = (pullRequest && pullRequest.head.sha) || github.context.sha;
|
2021-02-27 18:13:19 +00:00
|
|
|
|
2022-12-24 22:45:38 +00:00
|
|
|
const maxLength = 65_534;
|
|
|
|
|
if (output.length > maxLength) {
|
|
|
|
|
core.warning(`Output too long (${output.length}) truncating to ${maxLength}`);
|
|
|
|
|
output = output.slice(0, maxLength);
|
2022-12-16 19:44:40 +00:00
|
|
|
}
|
|
|
|
|
|
2021-02-27 18:13:19 +00:00
|
|
|
core.info(`Posting results for ${headSha}`);
|
|
|
|
|
const createCheckRequest = {
|
|
|
|
|
...github.context.repo,
|
|
|
|
|
name: checkName,
|
|
|
|
|
head_sha: headSha,
|
|
|
|
|
status: 'completed',
|
|
|
|
|
conclusion: 'neutral',
|
2021-03-06 06:55:03 +00:00
|
|
|
output,
|
2021-02-27 18:13:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const octokit = github.getOctokit(githubToken);
|
2022-01-11 13:44:47 +00:00
|
|
|
await octokit.rest.checks.create(createCheckRequest);
|
2022-01-11 11:52:29 +00:00
|
|
|
},
|
2021-02-27 18:13:19 +00:00
|
|
|
|
2022-01-11 11:52:29 +00:00
|
|
|
async renderSummary(runMetas) {
|
2022-01-11 12:32:54 +00:00
|
|
|
return ResultsCheck.render(`${__dirname}/results-check-summary.hbs`, runMetas);
|
2022-01-11 11:52:29 +00:00
|
|
|
},
|
2021-02-27 18:13:19 +00:00
|
|
|
|
2022-01-11 11:52:29 +00:00
|
|
|
async renderDetails(runMetas) {
|
2022-01-11 12:32:54 +00:00
|
|
|
return ResultsCheck.render(`${__dirname}/results-check-details.hbs`, runMetas);
|
2022-01-11 11:52:29 +00:00
|
|
|
},
|
2021-02-27 18:13:19 +00:00
|
|
|
|
2022-01-11 11:52:29 +00:00
|
|
|
async render(viewPath, runMetas) {
|
2021-02-27 18:13:19 +00:00
|
|
|
Handlebars.registerHelper('indent', toIndent =>
|
|
|
|
|
toIndent
|
|
|
|
|
.split('\n')
|
|
|
|
|
.map(s => ` ${s.replace('/github/workspace/', '')}`)
|
|
|
|
|
.join('\n'),
|
|
|
|
|
);
|
|
|
|
|
const source = await fs.promises.readFile(viewPath, 'utf8');
|
|
|
|
|
const template = Handlebars.compile(source);
|
|
|
|
|
return template(
|
|
|
|
|
{ runs: runMetas },
|
|
|
|
|
{
|
|
|
|
|
allowProtoMethodsByDefault: true,
|
|
|
|
|
allowProtoPropertiesByDefault: true,
|
|
|
|
|
},
|
|
|
|
|
);
|
2022-01-11 11:52:29 +00:00
|
|
|
},
|
|
|
|
|
};
|
2021-02-27 18:13:19 +00:00
|
|
|
|
|
|
|
|
export default ResultsCheck;
|