Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: tweak patterns, improve markdown output #275

Merged
merged 2 commits into from
Aug 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions lib/ci/ci_failure_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,17 @@ const FAILURE_FILTERS = [{
}
}, {
filter(ctx, text) {
const pattern =
/Changes not staged for commit:[\s\S]+no changes added to commit/mg;
const matches = text.match(pattern);
if (!matches) {
return null;
}
return new GitFailure(ctx, matches[0]);
const patterns = [{
pattern:
/Changes not staged for commit:[\s\S]+no changes added to commit/mg,
context: { index: 0, contextBefore: 0, contextAfter: 0 }
}, {
pattern:
// eslint-disable-next-line max-len
/error: Your local changes to the following files[\s\S]+Failed to merge in the changes./g,
context: { index: 0, contextBefore: 0, contextAfter: 0 }
}];
return failureMatcher(GitFailure, patterns, ctx, text);
}
}, {
filter(ctx, text) {
Expand All @@ -174,6 +178,9 @@ const FAILURE_FILTERS = [{
}, {
filter(ctx, text) {
const patterns = [{
pattern: /bash: line /g,
context: { index: 0, contextBefore: 0, contextAfter: 1 }
}, {
pattern: /ERROR: .+/g,
// Pick the last one
context: { index: -1, contextBefore: 0, contextAfter: 5 }
Expand All @@ -197,9 +204,6 @@ const FAILURE_FILTERS = [{
}, {
filter(ctx, text) {
const patterns = [{
pattern: /bash: line /g,
context: { index: 0, contextBefore: 0, contextAfter: 1 }
}, {
pattern: /FATAL: .+/g,
context: { index: -1, contextBefore: 0, contextAfter: 5 }
}, {
Expand Down
56 changes: 42 additions & 14 deletions lib/ci/ci_result_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ const FAILURE = 'FAILURE';
const ABORTED = 'ABORTED';
const UNSTABLE = 'UNSTABLE';

const SEP_LENGTH = 120;

const TEST_PHASE = 'Binary Tests';
// com.tikal.jenkins.plugins.multijob.MultiJobBuild
const BUILD_FIELDS = 'builtOn,buildNumber,jobName,result,url';
Expand Down Expand Up @@ -247,7 +245,7 @@ class TestBuild extends Job {

displayHeader() {
const { cli, result, change } = this;
cli.separator('Summary', SEP_LENGTH);
cli.separator('Summary');
cli.table('Result', resultName(result));
cli.table('URL', this.jobUrl);
cli.table('Source', this.sourceURL);
Expand All @@ -259,7 +257,7 @@ class TestBuild extends Job {
displayFailure(failure) {
const { cli } = this;
const { url, reason } = failure;
cli.separator(getNodeName(url), SEP_LENGTH);
cli.separator(getNodeName(url));
cli.table('URL', url);
if (failure.type) {
cli.table('Type', failure.type);
Expand All @@ -284,7 +282,7 @@ class TestBuild extends Job {
for (const failure of failures) {
this.displayFailure(failure);
}
cli.separator('Other builds', SEP_LENGTH);
cli.separator('Other builds');
for (const aborted of builds.aborted) {
cli.table('Aborted', getUrl(aborted.url));
}
Expand Down Expand Up @@ -336,7 +334,14 @@ function getHighlight(f) {
.replace(
/'JNLP4-connect connection from .+?'/, 'JNLP4-connect connection from ...'
)
.replace(/FATAL: Could not checkout \w+/, 'FATAL: Could not checkout ...');
.replace(/FATAL: Could not checkout \w+/, 'FATAL: Could not checkout ...')
.replace(
/error: pathspec .+ did not match any file\(s\) known to git/,
'error: pathspec ... did not match any file(s) known to git')
.replace(
/failed: no workspace for .+/,
'failed: no workspace for ...'
);
}

function markdownRow(...args) {
Expand All @@ -347,6 +352,10 @@ function markdownRow(...args) {
return result + '|\n';
}

function getMachineUrl(name) {
return `[${name}](https://${CI_DOMAIN}/computer/${name}/)`;
}

class FailureAggregator {
constructor(cli, failures) {
this.cli = cli;
Expand Down Expand Up @@ -392,29 +401,48 @@ class FailureAggregator {
aggregates = this.aggregates = this.aggregate();
}

let output = '';
const last = parseJobFromURL(this.failures[0].upstream);
const first = parseJobFromURL(
this.failures[this.failures.length - 1].upstream
);
const jobName = CI_TYPES.get(first.type).jobName;
let output = 'Failures in ';
output += `[${jobName}/${first.jobid}](${first.link}) to `;
output += `[${jobName}/${last.jobid}](${last.link}) `;
output += `that failed more than 2 PRs\n`;
const todo = [];
for (const type of Object.keys(aggregates)) {
output += `\n### ${FAILURE_TYPES_NAME[type]}\n\n`;
for (const item of aggregates[type]) {
const { reason, type, prs, failures, machines } = item;
if (prs.length < 2) { continue; }
output += markdownRow('Reason', `\`${reason}\``);
todo.push(reason);
output += markdownRow('Reason', `<code>${reason}</code>`);
output += markdownRow('-', ':-');
output += markdownRow('Type', type);
const source = prs.map(f => f.source);
output += markdownRow(
'Failed PR', `${source.length} (${source.join(', ')})`
);
output += markdownRow('Appeared', machines.join(', '));
output += markdownRow(
'Appeared', machines.map(getMachineUrl).join(', ')
);
if (prs.length > 1) {
output += markdownRow('First CI', `${prs[0].upstream}`);
}
output += markdownRow('Last CI', `${prs[prs.length - 1].upstream}`);
output += '\n' + fold('Example', failures[0].reason) + '\n';
output += '\n-------\n\n';
output += '\n';
output += fold(
`<a href="${failures[0].url}">Example</a>`,
failures[0].reason
);
output += '\n\n-------\n\n';
}
}
return output;

output += '### Progress\n\n';
output += todo.map(i => `- \`${i}\``).join('\n');
return output + '\n';
}

display() {
Expand All @@ -440,7 +468,7 @@ class FailureAggregator {
cli.table('First CI', `${prs[0].upstream}`);
}
cli.table('Last CI', `${prs[prs.length - 1].upstream}`);
cli.log('\n' + chalk.bold('Example:') + '\n');
cli.log('\n' + chalk.bold('Example: ') + `${failures[0].url}\n`);
const example = failures[0].reason;
cli.log(example.length > 512 ? example.slice(0, 512) + '...' : example);
cli.separator();
Expand Down Expand Up @@ -802,7 +830,7 @@ class BenchmarkRun extends Job {
display() {
const { cli, results, significantResults } = this;
cli.log(results);
cli.separator('significant results', SEP_LENGTH);
cli.separator('significant results');
cli.log(significantResults);
}

Expand Down
4 changes: 2 additions & 2 deletions test/fixtures/jenkins/git-failure-2/expected.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
[{
"url": "https://ci.nodejs.org/job/node-test-commit-linuxone/nodes=rhel72-s390x/3915/console",
"builtOn": "test-linuxonecc-rhel72-s390x-3",
"reason": "Changes not staged for commit:\n19:15:57 # (use \"git add <file>...\" to update what will be committed)\n19:15:57 # (use \"git checkout -- <file>...\" to discard changes in working directory)\n19:15:57 #\n19:15:57 #\tmodified: deps/v8/third_party/jinja2/LICENSE\n19:15:57 #\n19:15:57 # Untracked files:\n19:15:57 # (use \"git add <file>...\" to include in what will be committed)\n19:15:57 #\n19:15:57 #\tbuild/\n19:15:57 no changes added to commit",
"highlight": 0,
"type": "GIT_FAILURE"
}
}]