-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Project Management: Prompt user to link GitHub account to WordPress.o…
…rg profile (#21221) * Project Management Automation: Add getAssociatedPullRequest utility * Project Management Automation: Add First-Time Contributor label on push * Project Management Automation: Include as dependency in root package * Project Management Automation: Prompt user to link GitHub account to profile * Project Management Automation: Update documentation for first contribution prompt * Project Management Automation: Check for single commit of author * Project Management Automation: Fetch profile by https HEAD * Project Management Automation: Fix hostname to use hostname * Project Management Automation: Add hasWordPressProfile tests * Project Management Automation: Add request User-Agent header * Project Management Automation: Update contributor prompt text * Project Management Automation: Rename addFirstTimeContributorLabel to firstTimeContributor * Project Management Automation: Expand function comment to include new behavior * Project Management Automation: Expand CHANGELOG to include rename
- Loading branch information
Showing
15 changed files
with
544 additions
and
136 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
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
50 changes: 0 additions & 50 deletions
50
packages/project-management-automation/lib/add-first-time-contributor-label.js
This file was deleted.
Oops, something went wrong.
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
113 changes: 113 additions & 0 deletions
113
packages/project-management-automation/lib/first-time-contributor.js
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 |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
const debug = require( './debug' ); | ||
const getAssociatedPullRequest = require( './get-associated-pull-request' ); | ||
const hasWordPressProfile = require( './has-wordpress-profile' ); | ||
|
||
/** @typedef {import('@actions/github').GitHub} GitHub */ | ||
/** @typedef {import('@octokit/webhooks').WebhookPayloadPush} WebhookPayloadPush */ | ||
/** @typedef {import('./get-associated-pull-request').WebhookPayloadPushCommit} WebhookPayloadPushCommit */ | ||
|
||
/** | ||
* Message of comment prompting contributor to link their GitHub account from | ||
* their WordPress.org profile for props credit. | ||
* | ||
* @type {string} | ||
*/ | ||
const ACCOUNT_LINK_PROMPT = | ||
"Congratulations on your first merged pull request! We'd like to credit " + | ||
'you for your contribution in the post announcing the next WordPress ' + | ||
"release, but we can't find a WordPress.org profile associated with your " + | ||
'GitHub account. When you have a moment, visit the following URL and ' + | ||
'click "link your GitHub account" under "GitHub Username" to link your ' + | ||
'accounts:\n\nhttps://profiles.wordpress.org/me/profile/edit/\n\nAnd if ' + | ||
"you don't have a WordPress.org account, you can create one on this page:" + | ||
'\n\nhttps://login.wordpress.org/register\n\nKudos!'; | ||
|
||
/** | ||
* Adds the 'First Time Contributor' label to PRs merged on behalf of | ||
* contributors that have not yet made a commit, and prompts the user to link | ||
* their GitHub account to their WordPress.org profile if neccessary for props | ||
* credit. | ||
* | ||
* @param {WebhookPayloadPush} payload Push event payload. | ||
* @param {GitHub} octokit Initialized Octokit REST client. | ||
*/ | ||
async function firstTimeContributor( payload, octokit ) { | ||
if ( payload.ref !== 'refs/heads/master' ) { | ||
debug( 'first-time-contributor: Commit is not to `master`. Aborting' ); | ||
return; | ||
} | ||
|
||
const commit = | ||
/** @type {WebhookPayloadPushCommit} */ ( payload.commits[ 0 ] ); | ||
const pullRequest = getAssociatedPullRequest( commit ); | ||
if ( ! pullRequest ) { | ||
debug( | ||
'first-time-contributor: Cannot determine pull request associated with commit. Aborting' | ||
); | ||
return; | ||
} | ||
|
||
const repo = payload.repository.name; | ||
const owner = payload.repository.owner.login; | ||
const author = commit.author.username; | ||
debug( | ||
`first-time-contributor: Searching for commits in ${ owner }/${ repo } by @${ author }` | ||
); | ||
|
||
const { data: commits } = await octokit.repos.listCommits( { | ||
owner, | ||
repo, | ||
author, | ||
} ); | ||
|
||
if ( commits.length > 1 ) { | ||
debug( | ||
`first-time-contributor: Not the first commit for author. Aborting` | ||
); | ||
return; | ||
} | ||
|
||
debug( | ||
`first-time-contributor: Adding 'First Time Contributor' label to issue #${ pullRequest }` | ||
); | ||
|
||
await octokit.issues.addLabels( { | ||
owner, | ||
repo, | ||
issue_number: pullRequest, | ||
labels: [ 'First-time Contributor' ], | ||
} ); | ||
|
||
debug( | ||
`first-time-contributor: Checking for WordPress username associated with @${ author }` | ||
); | ||
|
||
let hasProfile; | ||
try { | ||
hasProfile = await hasWordPressProfile( author ); | ||
} catch ( error ) { | ||
debug( | ||
`first-time-contributor: Error retrieving from profile API:\n\n${ error.toString() }` | ||
); | ||
return; | ||
} | ||
|
||
if ( hasProfile ) { | ||
debug( | ||
`first-time-contributor: User already known. No need to prompt for account link!` | ||
); | ||
return; | ||
} | ||
|
||
await octokit.issues.createComment( { | ||
owner, | ||
repo, | ||
issue_number: pullRequest, | ||
body: ACCOUNT_LINK_PROMPT, | ||
} ); | ||
} | ||
|
||
module.exports = firstTimeContributor; |
39 changes: 39 additions & 0 deletions
39
packages/project-management-automation/lib/get-associated-pull-request.js
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 |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* @typedef WebhookPayloadPushCommitAuthor | ||
* | ||
* @property {string} name Author name. | ||
* @property {string} email Author email. | ||
* @property {string} username Author username. | ||
*/ | ||
|
||
/** | ||
* Minimal type detail of GitHub Push webhook event payload, for lack of their | ||
* own. | ||
* | ||
* TODO: If GitHub improves this on their own webhook payload types, this type | ||
* should no longer be necessary. | ||
* | ||
* @typedef {Record<string,*>} WebhookPayloadPushCommit | ||
* | ||
* @property {string} message Commit message. | ||
* @property {WebhookPayloadPushCommitAuthor} author Commit author. | ||
* | ||
* @see https://developer.github.com/v3/activity/events/types/#pushevent | ||
*/ | ||
|
||
/** | ||
* Given a commit object, returns a promise resolving with the pull request | ||
* number associated with the commit, or null if an associated pull request | ||
* cannot be determined. | ||
* | ||
* @param {WebhookPayloadPushCommit} commit Commit object. | ||
* | ||
* @return {number?} Pull request number, or null if it cannot be | ||
* determined. | ||
*/ | ||
function getAssociatedPullRequest( commit ) { | ||
const match = commit.message.match( /\(#(\d+)\)$/m ); | ||
return match && Number( match[ 1 ] ); | ||
} | ||
|
||
module.exports = getAssociatedPullRequest; |
46 changes: 46 additions & 0 deletions
46
packages/project-management-automation/lib/has-wordpress-profile.js
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 |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
const { request } = require( 'https' ); | ||
|
||
/** | ||
* Endpoint hostname for WordPress.org profile lookup by GitHub username. | ||
* | ||
* @type {string} | ||
*/ | ||
const BASE_PROFILE_LOOKUP_API_HOSTNAME = 'profiles.wordpress.org'; | ||
|
||
/** | ||
* Base path for WordPress.org profile lookup by GitHub username. | ||
* | ||
* @type {string} | ||
*/ | ||
const BASE_PROFILE_LOOKUP_API_BASE_PATH = '/wp-json/wporg-github/v1/lookup/'; | ||
|
||
/** | ||
* Returns a promise resolving to a boolean indicating if the given GitHub | ||
* username can be associated with a WordPress.org profile. | ||
* | ||
* @param {string} githubUsername GitHub username. | ||
* | ||
* @return {Promise<boolean>} Promise resolving to whether WordPress profile is | ||
* known. | ||
*/ | ||
async function hasWordPressProfile( githubUsername ) { | ||
return new Promise( ( resolve, reject ) => { | ||
const options = { | ||
hostname: BASE_PROFILE_LOOKUP_API_HOSTNAME, | ||
path: BASE_PROFILE_LOOKUP_API_BASE_PATH + githubUsername, | ||
method: 'HEAD', | ||
headers: { | ||
'User-Agent': 'Gutenberg/project-management-automation', | ||
}, | ||
}; | ||
|
||
request( options, ( res ) => resolve( res.statusCode === 200 ) ) | ||
.on( 'error', ( error ) => reject( error ) ) | ||
.end(); | ||
} ); | ||
} | ||
|
||
module.exports = hasWordPressProfile; |
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
Oops, something went wrong.