-
-
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
Enhance status badge for PRs in [GithubIssueDetail] #3295
Conversation
There are some linter errors that I don't quite understand:
What if the API is using snake case? |
Trying to use this code: return this.constructor.render({
number,
mergedAt: json['merged_at'],
closedAt: json['closed_at'],
}) instead of matching the properties out directly. Hope the CI will be happy with that. |
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.
Thanks for this!
However, I'm not convinced this is the right approach to address #1719. As I mentioned on that thread, the code has changed a lot, and I think those changes make some alternative solutions worth considering first.
Ultimately the ask behind #1719 is for slightly enhanced rendering logic (the badge message and color) on the existing GH Issue Detail state badge when the referenced item is a PR. I think creating an entirely separate service class with an additional badge route has the potential to create confusion (see below) and adds duplicative code that will have to be maintained.
With the approach implemented here in this PR, we'd end up with two separate badge routes and service classes that functionally only differ in the badge message and coloring, but exposed via two entirely separate paths:
The current/existing route:
https://img.shields.io/github/issues/detail/state/badges/shields/3269.svg
And then we'd also have
https://img.shields.io/github/status/merge-status/badges/shields/3269.svg
I also think it would be a confusing user experience to have one badge route pattern (/github/issues/detail/...
) that would have to be used for all other GH detail badges (labels, author, title, comments, update, etc.) but if the target item is a PR then the user would have to use a different path
IMO we could probably address #1719 by tweaking the logic in GithubIssueDetail service for the respective transform
and render
functions
What I am thinking about is that the badge rendering logic is completely different and they're using different GitHub APIs. Several questions:
Yes, these questions are all present in the original issue, but my reason of adding a new badge is that I don't want to have 2 API requests in one badge and the logic is pretty different (because we're using different APIs!). |
No one is proposing making 2 sequential API calls. There's plenty of badge service implementations that use the values of route/query parameters to conditionally determine the URL call to make, the schema to use, how to transform the response, and how to render. Many such conditions are already handled within the existing service class. |
This is very very reasonable! I've got a plan in mind, please comment:
|
That's probably the approach I'd suggest as well. Below are some snippets from what I was mocking up locally, may be a useful reference: Update the state map: const stateMap = {
schema: Joi.object({
...commonSchemaFields,
state: Joi.string()
.allow('open', 'closed')
.required(),
merged_at: Joi.string().allow(null),
}).required(),
transform: ({ json }) => ({
state: json.state,
merged: json.merged_at !== null,
}),
render: ({ value, isPR, number }) => {
const state = value.state
const label = `${isPR ? 'pull request' : 'issue'} ${number}`
if (!isPR || state === 'open') {
return {
color: stateColor(state),
label,
message: state,
}
}
if (value.merged) {
return {
label,
message: 'merged',
color: 'blueviolet',
}
}
return {
label,
message: 'rejected',
color: 'red',
}
},
} the service class static get route() {
return {
base: 'github',
pattern:
':kind(issues|pulls)/detail/:which(state|title|author|label|comments|age|last-update)/:user/:repo/:number([0-9]+)',
}
} the service class example will need to have the ...
namedParams: {
kind: 'issues',
which: 'state',
user: 'badges',
repo: 'shields',
number: '979',
},
staticPreview: this.render({
which: 'state',
value: { state: 'closed' },
isPR: false,
number: '979',
}),
... and the service implementations for async fetch({ kind, which, user, repo, number }) {
return this._requestJson({
url: `/repos/${user}/${repo}/${kind}/${number}`,
schema: whichMap[which].schema,
errorMessages: errorMessagesFor('issue, pull request or repo not found'),
})
}
transform({ json, which, kind }) {
const value = whichMap[which].transform({ json, which })
const isPR = json.hasOwnProperty('pull_request') || kind === 'pulls'
return { value, isPR }
}
async handle({ kind, which, user, repo, number }) {
const json = await this.fetch({ kind, which, user, repo, number })
const { value, isPR } = this.transform({ json, which, kind })
return this.constructor.render({ which, value, isPR, number })
} And lastly, the |
There's a few tests that would need to be updated as well:
|
Done, please review. |
Excellent! I'll review here shortly |
Addressed all comments, rebased on master, please take a look. |
https://shields-staging.herokuapp.com/github/pulls/detail/state/badges/shields/3280.svg Looking good! |
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.
Nice!
I'm basically following other PRs -- I am not an expert on JS.
Please don't hesitate to spot any problems.
This PR addresses #1719