Skip to content

Commit edbc9d5

Browse files
committed
feat: add ncu-ci cigtm <jobid>
1 parent 158efdf commit edbc9d5

File tree

3 files changed

+140
-9
lines changed

3 files changed

+140
-9
lines changed

bin/ncu-ci

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@ const {
66
JobParser,
77
parseJobFromURL,
88
CI_TYPES_KEYS: {
9-
PR, COMMIT, BENCHMARK
9+
PR, COMMIT, BENCHMARK, CITGM
1010
}
1111
} = require('../lib/ci/ci_type_parser');
1212

1313
const {
14-
PRBuild, BenchmarkRun, CommitBuild, HealthBuild,
15-
listBuilds, FailureAggregator, jobCache
14+
PRBuild,
15+
BenchmarkRun,
16+
CommitBuild,
17+
CITGMBuild,
18+
HealthBuild,
19+
listBuilds,
20+
FailureAggregator,
21+
jobCache
1622
} = require('../lib/ci/ci_result_parser');
1723
const clipboardy = require('clipboardy');
1824
const { writeJson, writeFile } = require('../lib/file');
@@ -28,7 +34,8 @@ const commandKeys = [
2834
'walk',
2935
'url',
3036
'pr',
31-
'commit'
37+
'commit',
38+
'citgm'
3239
];
3340

3441
// eslint-disable-next-line no-unused-vars
@@ -118,6 +125,18 @@ const argv = yargs
118125
},
119126
handler
120127
})
128+
.command({
129+
command: 'citgm <jobid>',
130+
desc: 'Show results of a citgm-smoker CI job',
131+
builder: (yargs) => {
132+
yargs
133+
.positional('jobid', {
134+
describe: 'id of the job',
135+
type: 'number'
136+
});
137+
},
138+
handler
139+
})
121140
.demandCommand(1, 'must provide a valid command')
122141
.option('copy', {
123142
default: false,
@@ -144,7 +163,8 @@ const argv = yargs
144163
const commandToType = {
145164
commit: COMMIT,
146165
pr: PR,
147-
benchmark: BENCHMARK
166+
benchmark: BENCHMARK,
167+
citgm: CITGM
148168
};
149169

150170
class CICommand {
@@ -188,6 +208,9 @@ class CICommand {
188208
case COMMIT:
189209
build = new CommitBuild(cli, request, job.jobid);
190210
break;
211+
case CITGM:
212+
build = new CITGMBuild(cli, request, job.jobid);
213+
break;
191214
case BENCHMARK:
192215
build = new BenchmarkRun(cli, request, job.jobid);
193216
break;
@@ -208,8 +231,7 @@ class CICommand {
208231
}
209232
}
210233

211-
async aggregate() { // noop
212-
}
234+
async aggregate() {} // noop
213235

214236
async serialize() {
215237
const { argv, cli } = this;
@@ -357,6 +379,7 @@ async function main(command, argv) {
357379
}
358380
case 'pr':
359381
case 'commit':
382+
case 'citgm':
360383
case 'benchmark': {
361384
commandHandler = new JobCommand(cli, request, argv, command);
362385
break;

docs/ncu-ci.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Commands:
2121
ncu-ci commit <jobid> Show results of a node-test-commit CI job
2222
ncu-ci benchmark <jobid> Show results of a benchmark-node-micro-benchmarks CI
2323
job
24+
ncu-ci citgm <jobid> Show results of a citgm-smoker job
2425
2526
Options:
2627
--version Show version number [boolean]

lib/ci/ci_result_parser.js

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,25 @@ const PR_TREE =
5050
const COMMIT_TREE =
5151
`result,url,number,${ACTION_TREE},${CHANGE_TREE},builtOn,` +
5252
`subBuilds[${BUILD_FIELDS}]`;
53+
const CITGM_MAIN_TREE =
54+
`result,url,number,${ACTION_TREE},${CHANGE_TREE},builtOn`;
55+
5356
// com.tikal.jenkins.plugins.multijob.MultiJobBuild
5457
const FANNED_TREE =
5558
`result,url,number,subBuilds[phaseName,${BUILD_FIELDS}]`;
59+
5660
// hudson.matrix.MatrixBuild
5761
const BUILD_TREE = 'result,runs[url,number,result],builtOn';
5862
const LINTER_TREE = 'result,url,number,builtOn';
5963
const CAUSE_TREE = 'upstreamBuild,upstreamProject,shortDescription,_class';
6064
const RUN_TREE = `actions[causes[${CAUSE_TREE}]],builtOn`;
6165

66+
// hudson.tasks.test.MatrixTestResult
67+
68+
const RESULT_TREE = 'result[suites[cases[name,status]]]';
69+
const CITGM_REPORT_TREE =
70+
`failCount,skipCount,totalCount,childReports[child[url],${RESULT_TREE}]`;
71+
6272
function getPath(url) {
6373
return url.replace(`https://${CI_DOMAIN}/`, '').replace('api/json', '');
6474
}
@@ -133,13 +143,13 @@ class Job {
133143
async getAPIData() {
134144
const { cli, request, path } = this;
135145
const url = this.apiUrl;
136-
cli.updateSpinner(`Querying API of ${path}`);
146+
cli.updateSpinner(`Querying API for ${path}`);
137147
return request.json(url);
138148
}
139149

140150
async getConsoleText() {
141151
const { cli, request, path } = this;
142-
cli.updateSpinner(`Querying console text of ${path}`);
152+
cli.updateSpinner(`Querying console text for ${path}`);
143153
const data = await request.text(this.consoleUrl);
144154
return data.replace(/\r/g, '');
145155
}
@@ -740,6 +750,102 @@ class PRBuild extends TestBuild {
740750
}
741751
}
742752

753+
class CITGMBuild extends TestBuild {
754+
constructor(cli, request, id) {
755+
const path = `job/citgm-smoker/${id}/`;
756+
const tree = CITGM_MAIN_TREE;
757+
758+
super(cli, request, path, tree);
759+
760+
this.id = id;
761+
}
762+
763+
async getResults() {
764+
let headerData;
765+
try {
766+
headerData = await this.getBuildData();
767+
} catch (err) {
768+
this.failures = [
769+
new NCUFailure({ url: this.apiUrl }, err.message)
770+
];
771+
return this.failures;
772+
}
773+
const { result } = headerData;
774+
775+
this.setBuildData(headerData);
776+
777+
this.updateAPIVariables();
778+
779+
let resultData;
780+
try {
781+
resultData = await this.getBuildData();
782+
} catch (err) {
783+
this.failures = [
784+
new NCUFailure({ url: this.apiUrl }, err.message)
785+
];
786+
return this.failures;
787+
}
788+
789+
const { childReports } = resultData;
790+
791+
this.results = this.parseResults(childReports);
792+
793+
return { result };
794+
}
795+
796+
parseResults(data) {
797+
const results = { passes: [], failures: [], skips: [], fixes: [] };
798+
data.forEach(platform => {
799+
const cases = flatten(platform.result.suites[0].cases);
800+
const nodeName = getNodeName(platform.child.url);
801+
802+
const passedModules = cases.filter(c => c.status === 'PASSED');
803+
results.passes.push({ [nodeName]: passedModules });
804+
805+
const failedModules = cases.filter(c => c.status === 'FAILED');
806+
results.failures.push({ [nodeName]: failedModules });
807+
808+
const skippedModules = cases.filter(c => c.status === 'SKIPPED');
809+
results.skips.push({ [nodeName]: skippedModules });
810+
811+
const fixedModules = cases.filter(c => c.status === 'FIXED');
812+
results.fixes.push({ [nodeName]: fixedModules });
813+
});
814+
return results;
815+
}
816+
817+
displayBuilds() {
818+
const { cli, results } = this;
819+
820+
cli.separator('Failures');
821+
for (const failure of results.failures) {
822+
const platform = Object.keys(failure)[0];
823+
const modules = failure[platform].map(f => f.name);
824+
825+
cli.table(platform, `${modules.length} Failures`, 25);
826+
cli.write('\n');
827+
cli.table(' '.repeat(11), modules.join('\n' + ' '.repeat(11)));
828+
cli.write('\n\n');
829+
}
830+
831+
// TODO(codebytere): how to display other builds?
832+
}
833+
834+
updateAPIVariables() {
835+
this.tree = CITGM_REPORT_TREE;
836+
this.path = `job/citgm-smoker/${this.id}/testReport/`;
837+
}
838+
839+
display() {
840+
this.displayHeader();
841+
this.displayBuilds();
842+
}
843+
844+
formatAsMarkdown() {
845+
// TODO(codebytere): implement.
846+
}
847+
}
848+
743849
function filterBuild(builds, type) {
744850
return builds
745851
.filter(build => build.result === type)
@@ -1034,6 +1140,7 @@ module.exports = {
10341140
PRBuild,
10351141
BenchmarkRun,
10361142
CommitBuild,
1143+
CITGMBuild,
10371144
HealthBuild,
10381145
jobCache,
10391146
parseJobFromURL,

0 commit comments

Comments
 (0)