76 lines
2.8 KiB
JavaScript
76 lines
2.8 KiB
JavaScript
require('dotenv').config();
|
|
const { owner, repo, fccBaseUrl, prBaseUrl } = require('./constants');
|
|
const fs = require('fs');
|
|
const { octokitConfig, octokitAuth } = require('./octokitConfig');
|
|
const octokit = require('@octokit/rest')(octokitConfig);
|
|
const { paginate } = require('./paginate');
|
|
const { saveToFile, writeToFile } = './fileFunctions';
|
|
const fetch = require('node-fetch');
|
|
const { getStatuses } = require('./getStatuses');
|
|
|
|
octokit.authenticate(octokitAuth);
|
|
|
|
const findFailures = async (errorsToFind, maxPrs) => {
|
|
const methodProps = {
|
|
owner, repo,
|
|
state: 'open', base: 'master', sort: 'created',
|
|
direction: 'asc', page: 1, per_page: 100
|
|
};
|
|
if (maxPRs) {
|
|
maxPages = Math.ceil(maxPrs / 100); // limits
|
|
}
|
|
|
|
const allOpenPRs = await paginate(octokit.pullRequests.getAll, methodProps, octokit, maxPages);
|
|
|
|
const failedPRs = allOpenPRs.reduce(async (prevPromise, { number: pr, head: { sha: ref }) => {
|
|
const failed = await prevPromise;
|
|
const statuses = await getStatuses(octokit.repos.getStatuses, {owner, repo, ref});
|
|
if (statuses.length) {
|
|
const { state, target_url } = statuses[0]; // first element contain most recent status
|
|
const hasProblem = state === 'failure' || state === 'error';
|
|
if (hasProblem) {
|
|
let buildNum = Number(target_url.match(/\/builds\/(\d+)\?/i)[1]);
|
|
buildNum++; // full build log file is 1 # higher than buildNum (same as job number)
|
|
const travisLogUrl = `https://api.travis-ci.org/v3/job/${buildNum}/log.txt`;
|
|
errorsToFind.forEach(async ({ errorDesc, errorRegex }) => {
|
|
const response = await fetch(travisLogUrl)
|
|
const logText = await response.text();
|
|
if (errorRegex.test(logText)) {
|
|
failed.push({
|
|
errorDesc,
|
|
pr,
|
|
buildLog: buildNum
|
|
})
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return failed;
|
|
}, Promise.resolve([]));
|
|
|
|
return failedPRs;
|
|
};
|
|
|
|
/* Main Program */
|
|
const [ n, f, inputFile, outputFile, maxPRs ] = process.argv;
|
|
const inputFileMsg = 'Please specify an input file containing errors to find.\n';
|
|
const outputFileMsg = 'Please specify an output file to save the results of the search.\n';
|
|
const maxPRMsg = 'Please specify an integer from 1-4500 (inclusive) for the max # of PR to search.';
|
|
let errors = '';
|
|
if (!inputFile) { errors += inputFileMsg }
|
|
if (!outputFile) { errors += outputFileMsg }
|
|
if (!maxPRs || parseInt(maxPRs) < 1 || parseInt(maxPRs) > 4500) {
|
|
errors += maxPRMsg;
|
|
}
|
|
|
|
if (errors) { return console.log(errors) }
|
|
|
|
fs.readFile(inputFile, 'utf8', (err, errorsToFind) => {
|
|
if (err) { throw err }
|
|
findFailures(errorsToFind, maxPRs)
|
|
.then((failedPRs) => {
|
|
saveToFile(outputFile, JSON.stringify(failedPRs));
|
|
console.log(`# PRs matching specified error: ${failedPRs.length}`);
|
|
})
|
|
});
|