-
-
Notifications
You must be signed in to change notification settings - Fork 5.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
Add [Github] pull request state badge #1207
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,8 +120,104 @@ function mapGithubReleaseDate(camp, githubApiUrl, githubAuth) { | |
})); | ||
} | ||
|
||
function mapGithubPRState(camp, githubApiUrl, githubAuth){ | ||
camp.route(/^\/github\/pr-state\/([^/]+)\/([^/]+)\/([^/]+)\.(svg|png|gif|jpg|json)$/, | ||
cache((data, match, sendBadge, request) => { | ||
const [, owner, repo, number, format] = match; | ||
const apiUrl = `${githubApiUrl}/repos/${owner}/${repo}/pulls/${number}`; | ||
const badgeData = getBadgeData('pull request', data); | ||
|
||
if (badgeData.template === 'social') { | ||
badgeData.logo = getLogo('github', data); | ||
} | ||
|
||
githubAuth.request(request, apiUrl, {}, function (err, res, buffer) { | ||
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. You can use an arrow function here: |
||
if (err != null) { | ||
badgeData.text[1] = 'inaccessible'; | ||
sendBadge(format, badgeData); | ||
return; | ||
} | ||
|
||
//github return 404 if repo not found or no pr | ||
if(res.statusCode === 404) { | ||
badgeData.text[1] = 'no pr or repo not found'; | ||
sendBadge(format, badgeData); | ||
return; | ||
} | ||
|
||
try { | ||
const pr = JSON.parse(buffer); | ||
let colorscheme = ''; | ||
let status = ''; | ||
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. It would be clearer what's happening with these declarations |
||
|
||
const responseIsIssueLike = pr.hasOwnProperty('state') && | ||
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. How about calling it |
||
pr.hasOwnProperty('merged') && | ||
pr.hasOwnProperty('mergeable') && | ||
pr.hasOwnProperty('mergeable_state'); | ||
|
||
if(!responseIsIssueLike) { | ||
badgeData.text[1] = 'inaccessible'; | ||
sendBadge(format, badgeData); | ||
return; | ||
} | ||
|
||
if (pr.state === 'closed') { | ||
badgeData.text[1] = pr.merged ? 'merged' : 'closed'; | ||
badgeData.colorscheme = pr.merged ? 'purple' : 'closed'; | ||
sendBadge(format, badgeData); | ||
return; | ||
} | ||
|
||
if(pr.state !== 'open') { | ||
badgeData.text[1] = 'inaccessible'; | ||
sendBadge(format, badgeData); | ||
return; | ||
} | ||
|
||
switch (pr.mergeable_state) { | ||
case 'clean': | ||
status = 'mergeable'; | ||
break; | ||
case 'dirty': | ||
status = 'has conflicts'; | ||
break; | ||
case 'behind': | ||
status = 'needs rebase'; | ||
break; | ||
default: | ||
status = pr.mergeable_state; | ||
} | ||
|
||
switch (pr.mergeable) { | ||
case null: | ||
colorscheme = 'lightgrey'; | ||
break; | ||
case 'unstable': | ||
case 'behind': | ||
colorscheme = 'yellow'; | ||
break; | ||
case true: | ||
colorscheme = 'green'; | ||
break; | ||
default: | ||
colorscheme = 'red'; | ||
} | ||
|
||
badgeData.text[1] = status; | ||
badgeData.colorscheme = colorscheme; | ||
sendBadge(format, badgeData); | ||
} catch (e) { | ||
console.log(e); | ||
badgeData.text[1] = 'invalid'; | ||
sendBadge(format, badgeData); | ||
} | ||
}); | ||
})); | ||
} | ||
|
||
|
||
module.exports = { | ||
mapGithubCommitsSince, | ||
mapGithubReleaseDate | ||
mapGithubReleaseDate, | ||
mapGithubPRState | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,176 @@ t.create('GitHub closed issues raw') | |
value: Joi.string().regex(/^\w+\+?$/) | ||
})); | ||
|
||
// pull request state | ||
|
||
t.create('Pull request state, regular case') | ||
.get('/pr-state/badges/shields/578.json') | ||
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. Let's make this |
||
.expectJSONTypes(Joi.object().keys({ | ||
name: Joi.equal('pull request state'), | ||
value: Joi.equal('closed', 'merged', 'mergeable', 'has conflicts', 'need rebase') | ||
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. This will always be |
||
})); | ||
|
||
t.create('Pull request state, closed pull request') | ||
.get('/pr-state/badges/shields/578.json') | ||
.intercept(nock => | ||
nock('https://api.github.com') | ||
.get('/repos/badges/shields/pulls/578') | ||
.query(true) | ||
.reply(200, { | ||
mergeable: null, | ||
mergeable_state: 'unknown', | ||
merged: false, | ||
state: 'closed' | ||
}) | ||
) | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'closed' | ||
}); | ||
|
||
t.create('Pull request state, merged pull request') | ||
.get('/pr-state/badges/shields/578.json') | ||
.intercept(nock => | ||
nock('https://api.github.com') | ||
.get('/repos/badges/shields/pulls/578') | ||
.query(true) | ||
.reply(200, { | ||
mergeable: null, | ||
mergeable_state: 'unknown', | ||
merged: true, | ||
state: 'closed' | ||
}) | ||
) | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'merged' | ||
}); | ||
|
||
t.create('Pull request state, pull request with unknown state') | ||
.get('/pr-state/badges/shields/578.json') | ||
.intercept(nock => | ||
nock('https://api.github.com') | ||
.get('/repos/badges/shields/pulls/578') | ||
.query(true) | ||
.reply(200, { | ||
mergeable: null, | ||
mergeable_state: 'unknown', | ||
merged: false, | ||
state: 'open' | ||
}) | ||
) | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'unknown' | ||
}); | ||
|
||
t.create('Pull request state, mergeable pull request') | ||
.get('/pr-state/badges/shields/578.json') | ||
.intercept(nock => | ||
nock('https://api.github.com') | ||
.get('/repos/badges/shields/pulls/578') | ||
.query(true) | ||
.reply(200, { | ||
mergeable: true, | ||
mergeable_state: 'clean', | ||
merged: false, | ||
state: 'open' | ||
}) | ||
) | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'mergeable' | ||
}); | ||
|
||
t.create('Pull request state, pull request with conflicts') | ||
.get('/pr-state/badges/shields/578.json') | ||
.intercept(nock => | ||
nock('https://api.github.com') | ||
.get('/repos/badges/shields/pulls/578') | ||
.query(true) | ||
.reply(200, { | ||
mergeable: false, | ||
mergeable_state: 'dirty', | ||
merged: false, | ||
state: 'open' | ||
}) | ||
) | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'has conflicts' | ||
}); | ||
|
||
t.create('Pull request state, pull request that needs rebase') | ||
.get('/pr-state/badges/shields/578.json') | ||
.intercept(nock => | ||
nock('https://api.github.com') | ||
.get('/repos/badges/shields/pulls/578') | ||
.query(true) | ||
.reply(200, { | ||
mergeable: false, | ||
mergeable_state: 'behind', | ||
merged: false, | ||
state: 'open' | ||
}) | ||
) | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'need rebase' | ||
}); | ||
|
||
t.create('Pull request state, mergeable pull request but build unstable') | ||
.get('/pr-state/badges/shields/578.json') | ||
.intercept(nock => | ||
nock('https://api.github.com') | ||
.get('/repos/badges/shields/pulls/578') | ||
.query(true) | ||
.reply(200, { | ||
mergeable: true, | ||
mergeable_state: 'unstable', | ||
merged: false, | ||
state: 'open' | ||
}) | ||
) | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'unstable' | ||
}); | ||
|
||
t.create('Pull request state, valid response but not a Github issue') | ||
.get('/pr-state/badges/shields/-1.json') | ||
.expectJSONTypes(Joi.object().keys({ | ||
name: Joi.equal('pull request state'), | ||
value: Joi.equal('inaccessible') | ||
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. Since these are both literals you can simplify this to |
||
})); | ||
|
||
t.create('Pull request state, invalid response') | ||
.get('/pr-state/badges/shields/578.json') | ||
.intercept(nock => | ||
nock('https://api.github.com') | ||
.get('/repos/badges/shields/pulls/578') | ||
.query(true) | ||
.reply(200, 'This should be JSON') | ||
) | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'inaccessible' | ||
}); | ||
|
||
t.create('Pull request state, request error') | ||
.get('/pr-state/badges/shields/578.json') | ||
.networkOff() | ||
.expectJSON({ | ||
name: 'pull request state', | ||
value: 'inaccessible' | ||
}); | ||
|
||
t.create('GitHub pull request state') | ||
.get('/pr-state/badges/shields/6.json') | ||
.expectedJSONTypes(Joi.object().keys({ | ||
name: 'pull request', | ||
value: Joi.string().regex(/^\w+/) | ||
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. I'm not sure I understand the purpose of this test. Could you clarify? ^^ |
||
})); | ||
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. Could you get these tests passing? Otherwise they look good! |
||
|
||
t.create('GitHub open issues') | ||
.get('/issues/badges/shields.json') | ||
.expectJSONTypes(Joi.object().keys({ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1577,6 +1577,13 @@ <h3 id="miscellaneous">Miscellaneous</h3> | |
</td> | ||
<td><code>https://img.shields.io/github/issues-pr-closed/cdnjs/cdnjs.svg</code></td> | ||
</tr> | ||
<tr> | ||
<th data-keywords='GitHub pullrequest pr state merge mergeability' data-doc='githubDoc'> GitHub pull request state: </th> | ||
<td> | ||
<img src='/github/pr-state/badges/shields/6.svg' alt=''/></td> | ||
<td> | ||
<code>https://img.shields.io/github/pr-state/badges/shields/6.svg</code></td> | ||
</tr> | ||
<tr> | ||
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. After #1163
|
||
<th data-doc="githubDoc" data-keywords="GitHub issue label">GitHub issues by-label:</th> | ||
<td> | ||
|
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.
Is this github's merged purple? If we do add a named "purple" it probably should not be github's. You can hard-code it in the badge code instead.