unity-test-runner/src/model/results-check.js

114 lines
3.4 KiB
JavaScript
Raw Normal View History

import * as core from '@actions/core';
import * as github from '@actions/github';
import * as fs from 'fs';
import * as xmljs from 'xml-js';
import path from 'path';
import Handlebars from 'handlebars';
import ReportConverter from './report-converter';
import { RunMeta } from './ts/meta.ts';
class ResultsCheck {
static async publishResults(artifactsPath, githubToken) {
// Parse all reports
const runs = [];
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 ResultsCheck.parseReport(path.join(artifactsPath, filepath));
core.info(fileData.summary);
runs.push(fileData);
}),
);
// Prepare run summary
const runSummary = new RunMeta('Test Results');
runs.forEach(run => {
runSummary.total += run.total;
runSummary.passed += run.passed;
runSummary.skipped += run.skipped;
runSummary.failed += run.failed;
runSummary.duration += run.duration;
core.debug(`Run suites length ${run.suites.length}`);
run.suites.forEach(suite => {
runSummary.addTests(suite.tests);
});
});
// Log run summary
core.info('=================');
core.info('Analyze result:');
core.info(runSummary.summary);
// Create check
await ResultsCheck.createCheck(githubToken, runs, runSummary, runSummary.extractAnnotations());
}
static async parseReport(filepath) {
core.info(`Trying to open ${filepath}`);
const file = await fs.promises.readFile(filepath, 'utf8');
const report = xmljs.xml2js(file, { compact: true });
core.info(`File ${filepath} parsed...`);
return ReportConverter.convertReport(path.basename(filepath), report);
}
static async createCheck(githubToken, runs, runSummary, annotations) {
const pullRequest = github.context.payload.pull_request;
const headSha = (pullRequest && pullRequest.head.sha) || github.context.sha;
const summary = await ResultsCheck.renderSummary(runs);
const text = await ResultsCheck.renderText(runs);
const title = runSummary.summary;
core.info(`Posting results for ${headSha}`);
const createCheckRequest = {
...github.context.repo,
name: 'Test Results',
head_sha: headSha,
status: 'completed',
conclusion: 'neutral',
output: {
title,
summary,
text,
annotations: annotations.slice(0, 50),
},
};
const octokit = github.getOctokit(githubToken);
await octokit.checks.create(createCheckRequest);
}
static async renderSummary(runMetas) {
return ResultsCheck.render(`${__dirname}/../views/summary.hbs`, runMetas);
}
static async renderText(runMetas) {
return ResultsCheck.render(`${__dirname}/../views/text.hbs`, runMetas);
}
static async render(viewPath, runMetas) {
const source = await fs.promises.readFile(viewPath, 'utf8');
Handlebars.registerHelper('indent', ResultsCheck.indentHelper);
const template = Handlebars.compile(source);
return template(
{ runs: runMetas },
{
allowProtoMethodsByDefault: true,
allowProtoPropertiesByDefault: true,
},
);
}
static indentHelper(argument) {
return argument
.split('\n')
.map(s => ` ${s}`)
.join('\n');
}
}
export default ResultsCheck;