Skip to content

Commit

Permalink
ncu-ci: command to start CI for PRs
Browse files Browse the repository at this point in the history
  • Loading branch information
mmarchini committed Jul 9, 2020
1 parent 158efdf commit aa762dd
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
76 changes: 76 additions & 0 deletions bin/ncu-ci
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ const {
PRBuild, BenchmarkRun, CommitBuild, HealthBuild,
listBuilds, FailureAggregator, jobCache
} = require('../lib/ci/ci_result_parser');
const {
RunPRJob
} = require('../lib/ci/run_ci');
const clipboardy = require('clipboardy');
const { writeJson, writeFile } = require('../lib/file');
const { getMergedConfig } = require('../lib/config');

const { runPromise } = require('../lib/run');
const auth = require('../lib/auth');
Expand Down Expand Up @@ -70,6 +74,26 @@ const argv = yargs
},
handler
})
.command({
command: 'run <prid>',
desc: 'Run CI for given PR',
builder: (yargs) => {
yargs
.positional('prid', {
describe: 'ID of the PR',
type: 'number'
})
.option('owner', {
default: '',
describe: 'GitHub repository owner'
})
.option('repo', {
default: '',
describe: 'GitHub repository name'
});
},
handler
})
.command({
command: 'url <url>',
desc: 'Automatically detect CI type and show results',
Expand Down Expand Up @@ -147,6 +171,54 @@ const commandToType = {
benchmark: BENCHMARK
};

class RunPRJobCommand {
constructor(cli, request, argv) {
this.cli = cli;
this.request = request;
this.dir = process.cwd();
this.argv = argv;
this.config = getMergedConfig(this.dir);
}

get owner() {
return this.argv.owner || this.config.owner;
}

get repo() {
return this.argv.repo || this.config.repo;
}

get prid() {
return this.argv.prid;
}

async start() {
const {
cli, request, prid, repo, owner
} = this;
let validArgs = true;
if (!repo) {
validArgs = false;
cli.error('GitHub repository is missing, please set it via ncu-config ' +
'or pass it via the --repo option');
}
if (!owner) {
cli.error('GitHub owner is missing, please set it via ncu-config ' +
'or pass it via the --owner option');
validArgs = false;
}
if (!validArgs) {
this.cli.setExitCode(1);
return;
}
const jobRunner = new RunPRJob(cli, request, owner, repo, prid);
if (!jobRunner.start()) {
this.cli.setExitCode(1);
process.exitCode = 1;
}
}
}

class CICommand {
constructor(cli, request, argv) {
this.cli = cli;
Expand Down Expand Up @@ -343,6 +415,10 @@ async function main(command, argv) {
let commandHandler;
// Prepare queue.
switch (command) {
case 'run': {
const jobRunner = new RunPRJobCommand(cli, request, argv);
return jobRunner.start();
}
case 'rate': {
commandHandler = new RateCommand(cli, request, argv);
break;
Expand Down
78 changes: 78 additions & 0 deletions lib/ci/run_ci.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use strict';

const FormData = require('form-data');

const {
CI_DOMAIN,
CI_TYPES,
CI_TYPES_KEYS
} = require('./ci_type_parser');

const CI_CRUMB_URL = `https://${CI_DOMAIN}/crumbIssuer/api/json`;
const CI_PR_NAME = CI_TYPES.get(CI_TYPES_KEYS.PR).jobName;
const CI_PR_URL = `https://${CI_DOMAIN}/job/${CI_PR_NAME}/build`;

class RunPRJob {
constructor(cli, request, owner, repo, prid) {
this.cli = cli;
this.request = request;
this.owner = owner;
this.repo = repo;
this.prid = prid;
}

async getCrumb() {
try {
const { crumb } = await this.request.json(CI_CRUMB_URL);
return crumb;
} catch (e) {
return false;
}
}

get payload() {
const payload = new FormData();
payload.append('json', JSON.stringify({
parameter: [
{ name: 'CERTIFY_SAFE', value: 'on' },
{ name: 'TARGET_GITHUB_ORG', value: this.owner },
{ name: 'TARGET_REPO_NAME', value: this.repo },
{ name: 'PR_ID', value: this.prid },
{ name: 'REBASE_ONTO', value: '<pr base branch>' },
{ name: 'DESCRIPTION_SETTER_DESCRIPTION', value: '' }
]
}));
return payload;
}

async start() {
const { cli } = this;
cli.startSpinner('Validating Jenkins credentials');
const crumb = await this.getCrumb();

if (crumb === false) {
cli.stopSpinner('Jenkins credentials invalid',
this.cli.SPINNER_STATUS.FAILED);
return false;
}
cli.stopSpinner('Jenkins credentials valid');

try {
cli.startSpinner('Starting PR CI job');
await this.request.text(CI_PR_URL, {
method: 'POST',
headers: {
'Jenkins-Crumb': crumb
},
body: this.payload
});
cli.stopSpinner('PR CI job successfully started');
} catch (err) {
cli.stopSpinner('Failed to start CI', this.cli.SPINNER_STATUS.FAILED);
return false;
}
return true;
}
}

module.exports = { RunPRJob };
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"core-validate-commit": "^3.13.1",
"execa": "^4.0.1",
"figures": "^3.2.0",
"form-data": "^3.0.0",
"fs-extra": "^9.0.0",
"ghauth": "^4.0.0",
"inquirer": "^7.1.0",
Expand Down

0 comments on commit aa762dd

Please sign in to comment.