-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: Centralize Author/Team Mapping for Commit Tracking #25986
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
c8bd440
.
benjisclowder 4be4690
debug authur mapping parsing
chloeYue 7737396
add.
benjisclowder 87d4bf7
lint fix
benjisclowder abf0810
.
benjisclowder 782fad7
.
benjisclowder 3e7b674
improve
chloeYue f080167
improve format
chloeYue File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ const octokit = new Octokit({ | |
/** | ||
* This script is used to filter and group commits by teams based on unique commit messages. | ||
* It takes two branches as input and generates a CSV file with the commit message, author,PR link, team,release tag and commit hash | ||
* The teams and their members are defined in the 'authorTeams' object. | ||
* The teams and their members are defined in the 'teams.json' file. | ||
* | ||
* Command to run the script: node development/generate-rc-commits.js origin/branchA origin/branchB | ||
* | ||
|
@@ -19,96 +19,24 @@ const octokit = new Octokit({ | |
* Output: the generated commits will be in a file named 'commits.csv'. | ||
*/ | ||
|
||
// JSON mapping authors to teams | ||
const authorTeams = { | ||
Accounts: [ | ||
'Owen Craston', | ||
'Gustavo Antunes', | ||
'Monte Lai', | ||
'Daniel Rocha', | ||
'Howard Braham', | ||
'Kate Johnson', | ||
'Xiaoming Wang', | ||
'Charly Chevalier', | ||
'Mike B', | ||
], | ||
'Wallet UX': ['David Walsh', 'Nidhi Kumari', 'Jony Bursztyn'], | ||
'Extension Platform': [ | ||
'chloeYue', | ||
'Chloe Gao', | ||
'danjm', | ||
'Danica Shen', | ||
'Brad Decker', | ||
'hjetpoluru', | ||
'Harika Jetpoluru', | ||
'Marina Boboc', | ||
'Gauthier Petetin', | ||
'Dan Miller', | ||
'Dan J Miller', | ||
'David Murdoch', | ||
'Niranjana Binoy', | ||
'Victor Thomas', | ||
'vthomas13', | ||
'seaona', | ||
'Norbert Elter', | ||
], | ||
'Wallet API': ['tmashuang', 'jiexi', 'BelfordZ', 'Shane'], | ||
Confirmations: [ | ||
'Pedro Figueiredo', | ||
'Sylva Elendu', | ||
'Olusegun Akintayo', | ||
'Jyoti Puri', | ||
'Ariella Vu', | ||
'OGPoyraz', | ||
'vinistevam', | ||
'Matthew Walsh', | ||
'cryptotavares', | ||
'Vinicius Stevam', | ||
'Derek Brans', | ||
'sleepytanya', | ||
'Priya', | ||
], | ||
'Design Systems': [ | ||
'georgewrmarshall', | ||
'Garrett Bear', | ||
'George Marshall', | ||
'Devin', | ||
], | ||
Snaps: [ | ||
'David Drazic', | ||
'hmalik88', | ||
'Montoya', | ||
'Mrtenz', | ||
'Frederik Bolding', | ||
'Bowen Sanders', | ||
'Guillaume Roux', | ||
'Hassan Malik', | ||
'Maarten Zuidhoorn', | ||
'Jonathan Ferreira', | ||
], | ||
Assets: ['salimtb', 'sahar-fehri', 'Brian Bergeron'], | ||
Linea: ['VGau', 'Victorien Gauch'], | ||
lavamoat: ['weizman', 'legobeat', 'kumavis', 'LeoTM'], | ||
'Wallet Framework': [ | ||
'Michele Esposito', | ||
'Elliot Winkler', | ||
'Gudahtt', | ||
'Jongsun Suh', | ||
'Mark Stacey', | ||
], | ||
MMI: [ | ||
'António Regadas', | ||
'Albert Olivé', | ||
'Ramon AC', | ||
'Shane T', | ||
'Bernardo Garces Chapero', | ||
], | ||
Swaps: ['Daniel', 'Davide Brocchetto', 'Nicolas Ferro', 'infiniteflower'], | ||
Devex: ['Thomas Huang', 'Alex Donesky', 'jiexi', 'Zachary Belford'], | ||
Notifications: ['Prithpal-Sooriya', 'Matteo Scurati', 'Prithpal Sooriya'], | ||
Bridging: ['Bilal', 'micaelae', 'Ethan Wessel'], | ||
Ramps: ['George Weiler'], | ||
}; | ||
// Function to fetch author teams mapping file from teams.json | ||
async function fetchAuthorTeamsFile() { | ||
try { | ||
const { data } = await octokit.request( | ||
'GET /repos/{owner}/{repo}/contents/{path}', | ||
{ | ||
owner: 'MetaMask', | ||
repo: 'MetaMask-planning', | ||
path: 'teams.json', | ||
}, | ||
); | ||
const content = Buffer.from(data.content, 'base64').toString('utf-8'); | ||
return JSON.parse(content); // Assuming the file is in JSON format | ||
} catch (error) { | ||
console.error('Error fetching author teams mapping file:', error); | ||
return {}; | ||
} | ||
} | ||
|
||
// Function to get PR labels | ||
async function getPRLabels(owner, repo, prNumber) { | ||
|
@@ -129,18 +57,26 @@ async function getPRLabels(owner, repo, prNumber) { | |
} | ||
} | ||
|
||
// Function to get the team for a given author | ||
function getTeamForAuthor(authorName) { | ||
for (const [team, authors] of Object.entries(authorTeams)) { | ||
if (authors.includes(authorName)) { | ||
return team; | ||
} | ||
// Function to get the GitHub username for a given commit hash | ||
async function getGitHubUsername(commitHash) { | ||
try { | ||
const { data } = await octokit.request( | ||
'GET /repos/{owner}/{repo}/commits/{ref}', | ||
{ | ||
owner: 'MetaMask', | ||
repo: 'metamask-extension', | ||
ref: commitHash, | ||
}, | ||
); | ||
return data.author ? data.author.login : null; | ||
} catch (error) { | ||
console.error('Error fetching GitHub username:', error); | ||
return null; | ||
} | ||
return 'Other/Unknown'; // Default team for unknown authors | ||
} | ||
|
||
// Function to filter commits based on unique commit messages and group by teams | ||
async function filterCommitsByTeam(branchA, branchB) { | ||
async function filterCommitsByTeam(branchA, branchB, authorTeams) { | ||
try { | ||
const git = simpleGit(); | ||
|
||
|
@@ -157,17 +93,27 @@ async function filterCommitsByTeam(branchA, branchB) { | |
const log = await git.log(logOptions); | ||
const seenMessages = new Set(); | ||
const commitsByTeam = {}; | ||
let processedCommits = 0; | ||
|
||
const MAX_COMMITS = 500; // Limit the number of commits to process | ||
|
||
console.log('Generation of the CSV file "commits.csv" is in progress...'); | ||
|
||
for (const commit of log.all) { | ||
const { author, message, hash } = commit; | ||
if (commitsByTeam.length >= MAX_COMMITS) { | ||
if (processedCommits >= MAX_COMMITS) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tested and found the current |
||
break; | ||
} | ||
|
||
const team = getTeamForAuthor(author); | ||
const { author, message, hash } = commit; | ||
const githubUsername = await getGitHubUsername(hash); | ||
let team = authorTeams[githubUsername] || 'Other/Unknown'; | ||
|
||
// Format the team label | ||
team = team | ||
.replace(/^team-/u, '') // Remove the "team-" prefix | ||
.split('-') // Split the string into an array of words | ||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1)) // Capitalize the first letter of each word | ||
.join(' '); // Join the words back into a string with spaces | ||
|
||
// Extract PR number from the commit message using regex | ||
const prMatch = message.match(/\(#(\d+)\)/u); | ||
|
@@ -206,9 +152,9 @@ async function filterCommitsByTeam(branchA, branchB) { | |
releaseLabel, | ||
hash: hash.substring(0, 10), | ||
}); | ||
processedCommits += 1; | ||
} | ||
} | ||
|
||
return commitsByTeam; | ||
} catch (error) { | ||
console.error(error); | ||
|
@@ -233,7 +179,7 @@ function formatAsCSV(commitsByTeam) { | |
}); | ||
} | ||
csvContent.unshift( | ||
'Commit Message,Author,PR Link,Team,Release Label, Commit Hash', | ||
'Commit Message,Author,PR Link,Team,Release Label,Commit Hash', | ||
); | ||
|
||
return csvContent; | ||
|
@@ -250,7 +196,14 @@ async function main() { | |
const branchA = args[0]; | ||
const branchB = args[1]; | ||
|
||
const commitsByTeam = await filterCommitsByTeam(branchA, branchB); | ||
// Fetch author teams mapping from the teams.json file | ||
const authorTeams = await fetchAuthorTeamsFile(); | ||
|
||
const commitsByTeam = await filterCommitsByTeam( | ||
branchA, | ||
branchB, | ||
authorTeams, | ||
); | ||
|
||
if (Object.keys(commitsByTeam).length === 0) { | ||
console.log('No unique commits found.'); | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the teams.json file, the PR author's username (handle) is used, so we need to retrieve the username instead of the author's name from the commit log.