mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-26 04:01:17 -04:00
This PR has the following items: 1. Introduces a couple of fixes to the sweeper script from issues right before the move to the mono repo. These were related to moving labeler out of the root of the sweeper folder and placing into the pr-tasks sub-folder. 2. Combined two scripts which were being used to update the data manually on Glitch (pr-relations.glitch.me). The new one-off script (get-pr-relations-data.js) downloads the current data.json and then pulls down applicable Github data which updates the data.json and automatically uploads it back to the Glitch server. 3. In an effort to use the same log file across all current one-off scripts and sweeper.js, the ProcessLog class was modified, so now every log created has the same JSON structure as is uploaded to the Glitch server. This removed a lot of redundant code across 3 files. 4. During a pair-coding session with @honmanyau, we tweaked the UI for the Dashboard app to give it a more consistent look across all views. 5. Based on feedback from a couple of the moderators using the new Dashboard app, the PR title was added along with some other styling. 6. Added some environment variables for running dashboard-api and dashboard-client in a development mode. 7. Added a sample_data.json file as a starter file, so someone does not have to do a full data pull to get things up and running. 8. Modified Pareto view to only display files with 2 or more PRs to speed up the report.
120 lines
4.0 KiB
JavaScript
120 lines
4.0 KiB
JavaScript
/*
|
|
This is a one-off script to run on all open PRs to add
|
|
a comment and "status: needs update" label to any PR with guide articles which
|
|
have frontmatter issues.
|
|
*/
|
|
|
|
require('dotenv').config({ path: '../.env' });
|
|
const fetch = require('node-fetch');
|
|
|
|
const { owner, repo, octokitConfig, octokitAuth } = require('../constants');
|
|
|
|
const octokit = require('@octokit/rest')(octokitConfig);
|
|
|
|
const { getPRs, getUserInput } = require('../get-prs');
|
|
const { addLabels, addComment } = require('../pr-tasks');
|
|
const { rateLimiter, savePrData, ProcessingLog } = require('../utils');
|
|
const { frontmatterCheck } = require('../validation/guide-folder-checks/frontmatter-check');
|
|
const { createErrorMsg } = require('../validation/guide-folder-checks/create-error-msg');
|
|
|
|
const allowedLangDirNames = [
|
|
"arabic",
|
|
"chinese",
|
|
"english",
|
|
"portuguese",
|
|
"russian",
|
|
"spanish"
|
|
];
|
|
|
|
octokit.authenticate(octokitAuth);
|
|
|
|
const log = new ProcessingLog('all-frontmatter-checks');
|
|
|
|
const labeler = async (number, prFiles, currentLabels, guideFolderErrorsComment) => {
|
|
const labelsToAdd = {}; // holds potential labels to add based on file path
|
|
if (guideFolderErrorsComment) {
|
|
labelsToAdd['status: needs update'] = 1;
|
|
}
|
|
const existingLabels = currentLabels.map(({ name }) => name);
|
|
|
|
/* this next section only adds needed labels which are NOT currently on the PR. */
|
|
const newLabels = Object.keys(labelsToAdd).filter(label => !existingLabels.includes(label));
|
|
if (newLabels.length) {
|
|
if (process.env.PRODUCTION_RUN === 'true') {
|
|
addLabels(number, newLabels);
|
|
}
|
|
await rateLimiter(+process.env.RATELIMIT_INTERVAL | 1500);
|
|
}
|
|
return newLabels;
|
|
};
|
|
|
|
const checkPath = (fullPath, fileContent) => {
|
|
let errorMsgs = [];
|
|
const remaining = fullPath.split("/");
|
|
const isTranslation = allowedLangDirNames.includes(remaining[1]) && remaining[1] !== 'english';
|
|
const frontMatterErrMsgs = frontmatterCheck(fullPath, isTranslation, fileContent);
|
|
return errorMsgs.concat(frontMatterErrMsgs);
|
|
};
|
|
|
|
const guideFolderChecks = async (number, prFiles, user) => {
|
|
let prErrors = [];
|
|
for (let { filename: fullPath, raw_url: fileUrl } of prFiles) {
|
|
let newErrors;
|
|
if (/^guide\//.test(fullPath)) {
|
|
const response = await fetch(fileUrl);
|
|
const fileContent = await response.text();
|
|
newErrors = checkPath(fullPath, fileContent);
|
|
}
|
|
if (newErrors) {
|
|
prErrors = prErrors.concat(newErrors);
|
|
}
|
|
}
|
|
|
|
if (prErrors.length) {
|
|
const comment = createErrorMsg(prErrors, user)
|
|
if (process.env.PRODUCTION_RUN === 'true') {
|
|
const result = await addComment(number, comment);
|
|
}
|
|
await rateLimiter(+process.env.RATELIMIT_INTERVAL | 1500);
|
|
return comment;
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
(async () => {
|
|
const { totalPRs, firstPR, lastPR } = await getUserInput();
|
|
// log.setFirstLast({ firstPR, lastPR });
|
|
console.log(firstPR, lastPR);
|
|
const prPropsToGet = ['number', 'labels', 'user'];
|
|
const { openPRs } = await getPRs(totalPRs, firstPR, lastPR, prPropsToGet);
|
|
|
|
if (openPRs.length) {
|
|
savePrData(openPRs, firstPR, lastPR);
|
|
log.start();
|
|
console.log('Starting frontmatter checks process...');
|
|
for (let count in openPRs) {
|
|
let { number, labels: currentLabels, user: { login: username } } = openPRs[count];
|
|
const { data: prFiles } = await octokit.pullRequests.listFiles({ owner, repo, number });
|
|
|
|
const guideFolderErrorsComment = await guideFolderChecks(number, prFiles, username);
|
|
const commentLogVal = guideFolderErrorsComment ? guideFolderErrorsComment : 'none';
|
|
|
|
const labelsAdded = await labeler(number, prFiles, currentLabels, guideFolderErrorsComment);
|
|
const labelLogVal = labelsAdded.length ? labelsAdded : 'none added';
|
|
|
|
log.add(number, { number, comment: commentLogVal, labels: labelLogVal });
|
|
await rateLimiter(+process.env.RATELIMIT_INTERVAL | 1500);
|
|
}
|
|
}
|
|
})()
|
|
.then(() => {
|
|
log.finish();
|
|
console.log('Successfully completed frontmatter checks');
|
|
})
|
|
.catch(err => {
|
|
log.finish();
|
|
console.log(err)
|
|
})
|