diff --git a/release-script/.gitignore b/release-script/.gitignore index 51e1838..b233e43 100644 --- a/release-script/.gitignore +++ b/release-script/.gitignore @@ -2,3 +2,4 @@ config.js package-lock.json npm-debug.log node_modules/ +.idea/ diff --git a/release-script/config.template.js b/release-script/config.template.js index c4f1eee..b424cd5 100644 --- a/release-script/config.template.js +++ b/release-script/config.template.js @@ -5,7 +5,7 @@ module.exports = { githubPassword: 'password', // Directory of TEAMMATES project - teammatesDir: '../teammates', + teammatesDir: '../../teammates', // Milestone number in GitHub, e.g. for V6.0.0 (https://github.com/TEAMMATES/teammates/milestone/254) => milestone number 254 milestone: 254, diff --git a/release-script/milestone-api.js b/release-script/milestone-api.js index 1c18b28..0561db1 100644 --- a/release-script/milestone-api.js +++ b/release-script/milestone-api.js @@ -1,8 +1,8 @@ const request = require('request'); -const { githubUsername, milestone } = require('./config'); +const { githubUsername, githubPassword, milestone } = require('./config'); -if (!githubUsername || !milestone) { - console.log('Milestone API could not proceed. Please specify a milestone and your GitHub username for authentication.'); +if (!githubUsername || !githubPassword || !milestone) { + console.log('Milestone API could not proceed. Please specify a milestone and your GitHub username & password for authentication.'); process.exit(); } @@ -13,6 +13,7 @@ function createRequestObject(uri) { uri, headers: { 'User-Agent': githubUsername, + Authorization: `Basic ${Buffer.from(`${githubUsername}:${githubPassword}`).toString('base64')}`, }, }; } diff --git a/release-script/pre-release.js b/release-script/pre-release.js index ecdc5bc..857e47b 100644 --- a/release-script/pre-release.js +++ b/release-script/pre-release.js @@ -8,6 +8,7 @@ const rl = require('readline-sync'); const { EOL: eol } = require('os'); const { teammatesDir } = require('./config'); const { getMilestoneInfo } = require('./milestone-api'); +const { getDisplayNameOfUser } = require('./user-api'); const developersJsonDir = './src/main/webapp/data/developers.json'; @@ -139,27 +140,53 @@ function checkPrMetadata() { }); } +function syncContributorsName(contributors, index, onComplete) { + if (contributors.length === index) { + onComplete(); + return; + } + const currentContributor = contributors[index]; + if (!currentContributor.username) { + syncContributorsName(contributors, index + 1, onComplete); + } + + getDisplayNameOfUser(currentContributor.username, (name) => { + if (name) { + currentContributor.name = name; + } + // try not to exceed the rate limit of API + setTimeout(() => { + syncContributorsName(contributors, index + 1, onComplete); + }, 200); + }); +} + function checkAndUpdateDevelopersJson() { prsInMilestone.forEach(pr => checkUsername(pr.user.login)); if (newContributors.length) { - Object.keys(newContributors).forEach(i => allDevs.contributors.push({ name: '', username: newContributors[i] })); - fs.writeFile(developersJsonDir, JSON.stringify(allDevs, null, 2) + eol, 'UTF-8', () => { - function capitalize(str) { - return str.charAt(0).toUpperCase() + str.slice(1); - } + const newContributorsDetail = []; + Object.keys(newContributors).forEach(i => newContributorsDetail.push({ username: newContributors[i] })); + syncContributorsName(newContributorsDetail, 0, () => { + allDevs.contributors.push(...newContributorsDetail); + + fs.writeFile(developersJsonDir, JSON.stringify(allDevs, null, 2) + eol, 'UTF-8', () => { + function capitalize(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + } - console.log('The execution is now paused and the username of new contributors have been temporarily added.'); - console.log('Enter the real names of the new contributors manually, then press enter on the console to continue.'); - rl.question(); + console.log('Please proofread the real names of newly added contributors. ' + + 'Their real names may not be entered correctly on GitHub.'); + rl.question(); - allDevs = JSON.parse(fs.readFileSync(developersJsonDir, 'UTF-8')); - allDevs.contributors.sort((a, b) => { - const aName = a.name || capitalize(a.username); - const bName = b.name || capitalize(b.username); - return aName > bName ? 1 : -1; - }); + allDevs = JSON.parse(fs.readFileSync(developersJsonDir, 'UTF-8')); + allDevs.contributors.sort((a, b) => { + const aName = a.name || capitalize(a.username); + const bName = b.name || capitalize(b.username); + return aName > bName ? 1 : -1; + }); - updateDevelopersJson(); + updateDevelopersJson(); + }); }); } else if (needUpdate) { updateDevelopersJson(); diff --git a/release-script/user-api.js b/release-script/user-api.js new file mode 100644 index 0000000..b861f67 --- /dev/null +++ b/release-script/user-api.js @@ -0,0 +1,35 @@ +const request = require('request'); +const { githubUsername, githubPassword } = require('./config'); + +if (!githubUsername || !githubPassword) { + console.log('User API could not proceed. Please specify your GitHub username & password for authentication.'); + process.exit(); +} + +function createRequestObject(uri) { + return { + uri, + headers: { + 'User-Agent': githubUsername, + Authorization: `Basic ${Buffer.from(`${githubUsername}:${githubPassword}`).toString('base64')}`, + }, + }; +} + +function getDisplayNameOfUser(username, callback) { + const uri = createRequestObject(`https://api.github.com/users/${username}`); + request(uri, (error, response, body) => { + if (response.statusCode !== 200) { + console.log(`Error ${response.statusCode} when getting displayed name of user ${username}:`); + console.log(response.statusMessage); + return callback(undefined); + } + + const userInfo = JSON.parse(body); + return callback(userInfo.name); + }); +} + +module.exports = { + getDisplayNameOfUser, +};