-
Notifications
You must be signed in to change notification settings - Fork 322
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
Use js to show status of gh issues and PR #1896
base: main
Are you sure you want to change the base?
Conversation
Can we add @isabela-pf to the repo (even only with read access) so that we can assign her to review ? |
I wonder if the tool that mystmd.org uses for GitHub hover cards could be repurposed here? @agoose77 or @stevejpurves any thoughts on that? Either way I think that updating the statuses is pretty nice 🙂 |
@Carreau there was a long-ish discussion before on whether this was a good idea, that ended in a stalemate: #1085 FWIW my views (one, two) on this haven't really changed since then. But there's enough new voices now that I could be outvoted! EDIT: I realize now that the two proposals are different; here you just want to add the icons, not convert the link into the full PR title. I'm OK with adding/coloring the icons. |
invitation sent! |
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.
EDIT: I realize now that the two proposals are different; here you just want to add the icons, not convert the link into the full PR title. I'm OK with adding/coloring the icons.
I'm glad you called this out, because I was going to double check on the same after reading preceding issues. Thank you!
And many thanks to @Carreau for posting the screen shot of the result! That also makes it much easier for me to be sure what I'm looking at.
I'm going to write my comments as a numbered list for (hopefully) easier reference, but they are not reliant on one another.
- The icon choice is good! I am glad to see them used in the same way as the GitHub reference discussed previously.
- The addition of icons also makes sense considering GitHub as a reference. Do the icons get announced as a part of the link or in the tooltip, or are they visual only?
- I think it was a good idea to map the status colors in the GitHub reference to the ones within the theme, and I think appropriate colors were chosen. However, in this situation, I do worry that they are close in value (light/darkness) and could be easily mixed up due to colorblindness, low or bright light situations, and any other situation where color is harder to discern. If the status is reiterated in the tooltip or in a text precursor to the
#xxxx
I think this is acceptable. If color is the only way to tell this status, I'd like to advise an additional way of communicating.
Please let me know if you have any questions for me! This is definitely on a good track, self-appointed "less than optimal design skills" or not.
Thanks for the links to #1085, I missed it. I think this is indeed much narrower in scope.
Currently those are just visual, we can change if we want.
I think that's my main question, I'm really not good ad design/color. If you think there are changes we need to do and you can come up with colors that work with PST that would help me. I've mostly use red/green/purple because I know that's what GitHub is doing. I don't want to bias the design process, but should the link be colors the same way as the icon, and should for example closed issues be strikethrough. I'm tempted to think no for strikethrough as most issue reference in documentation will be to merged PR and closed issues. |
I likely need to use font-awesome 6 instead of 5. |
or even octicons? I think a complete set for us would be:
font awesome has code-merge and code-pull-request and circle-check but its circle-dot doesn't really resemble the octicon equivalent. |
I'm happy to use octicon, I just wanted to avoid an extra dependnecy by default. |
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.
I'm weighing in one more time with more explicit approval on the design front in hopes that clarifies any lingering questions. In terms of what's been done so far, I find it matches GitHub's patterns of status icons and coloring, matches pydata-sphinx-theme's design system (uses color variables and relevant icons), and is mindful of dependencies that may mess with either of these patterns from a user experience/user interface perspective. That's all good to me!
I do think this is not a change that is needed to, for example, fix a bug or anything in the pydata-sphinx-theme, so if there is a choice to not move forward with this I also think that preserves a perfectly fine experience. But if it is wanted, this proof of concept seems like the right way to go about it from the design perspective.
We should be using FA 6 (this is the one we are vendoring with the theme). |
Also despite my earlier comment about octicons, I won't object to using FA6 equivalents --- we can always switch to octicons later if necessary. |
Sorry this was meant more at @Carreau since he is currently using FA 5 |
here's a screenshot of how this will look: IMO we're not there yet:
|
Nah, that is because the PR I linked to has been merged since then...
I did not figured out how to not underline it I'll have a look at the rest. |
<script type="module"> | ||
import { Octokit, App } from "https://esm.sh/octokit"; | ||
const octokit = new Octokit(); | ||
window.octokit = octokit; |
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 there a good reason to make the octokit instance global?
window.octokit = octokit; |
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.
Reviewing this PR has given me some ideas for how to roll it out. I am inspired by the approach that you have taken with some of your other work (for example, with same-name-different-URL links).
I think it would be good to start with just our own website first, the PST docs. To do this, I believe you need to move the JavaScript and CSS into external files and then add them to the Sphinx config:
html_css_files = ["custom.css", ("github-matches.css", {"rel": "preload"})]
html_js_files = ["pydata-icon.js", "custom-icon.js", ("github-matches.js", {"type": "module"})]
Note: using rel=preload and type=module should ensure that both files are loaded asynchronously. I believe this will cause a layout shift since you apply a CSS class that adds content (via a :before pseudo-element) after the page is rendered, but I think this shouldn't be too disruptive, since it's just an icon... but I'm not sure, which is another reason why it would be prudent to release this first only on the PST docs.
Another idea I had while reviewing this PR is that maybe this is one of those things that's better to put in the docs as a recipe rather than including it by default in the code. A recipe gives theme adopters something to follow if they wish to add this behavior to their own website, but frees us from the urgency of having to fix the code if something breaks. A recipe is also frees us from needing to get the implementation right for every site that uses PST, because a recipe can be adapted by implementers for the specific needs of each site individually.
What do you think?
</noscript> | ||
// Regular expression to match the desired GitHub issue URL pattern | ||
// the s in pulls/issues is technically wrong but we find it sometimes. | ||
const regex = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/(pull|issue)s?\/(\d+)$/; |
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.
optional trailing slash?
const regex = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/(pull|issue)s?\/(\d+)$/; | |
const regex = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/(pull|issue)s?\/(\d+)\/?$/; |
untested regexes make me nervous...
const githubIssueLinks = Array.prototype.filter.call(anchorTags, function(element) { | ||
return regex.test(element.href); | ||
}); |
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.
The way you've written it is not wrong, but here is a bit more modern way to write the same thing:
const githubIssueLinks = Array.prototype.filter.call(anchorTags, function(element) { | |
return regex.test(element.href); | |
}); | |
const githubIssueLinks = Array.prototype.filter.call(anchorTags, ({ href }) => regex.test(href)); |
// we can sometime be throttled, or just refused connection, | ||
// just do one request on root, and if not 200, just do nothing. | ||
const root_res = await octokit.request('GET /'); | ||
if (root_res.status == 200) { |
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.
how do you feel about turning this into an early return?
githubIssueLinks.map(async (atag) => { | ||
const match = atag.href.match(regex); | ||
if (match) { | ||
const [fullUrl, username, repo,pr, issueNumber] = match; |
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.
const [fullUrl, username, repo,pr, issueNumber] = match; | |
const [fullUrl, username, repo, pr, issueNumber] = match; |
</noscript> | ||
// Regular expression to match the desired GitHub issue URL pattern | ||
// the s in pulls/issues is technically wrong but we find it sometimes. | ||
const regex = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/(pull|issue)s?\/(\d+)$/; |
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.
non-capturing group?
const regex = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/(pull|issue)s?\/(\d+)$/; | |
const regex = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/(?:pull|issue)s?\/(\d+)$/; |
if (res.data.pull_request !== undefined){ | ||
console.debug('[PST] DEBUG: 4') | ||
pull_issue = 'pull'; | ||
state = res.data.pull_request.merged_at != null ? 'merged': res.data.state ; |
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.
could you comment this line? why can't we just set the variable to res.data.state
console.debug('[PST] DEBUG: 1') | ||
let pull_issue = 'unset'; | ||
console.debug('[PST] DEBUG: 2') | ||
let state = 'unset'; | ||
console.debug('[PST] DEBUG: 3') | ||
if (res.data.pull_request !== undefined){ | ||
console.debug('[PST] DEBUG: 4') | ||
pull_issue = 'pull'; | ||
state = res.data.pull_request.merged_at != null ? 'merged': res.data.state ; | ||
console.debug('[PST] DEBUG: 4b') | ||
} else { | ||
console.debug('[PST] DEBUG: 5') | ||
pull_issue = 'issue'; | ||
state = res.data.state; | ||
console.debug('[PST] DEBUG: 5b') | ||
} | ||
console.log('[PST] adding classes to', pull_issue, state); | ||
atag.classList.add(`pst-gh-${pull_issue}`) | ||
atag.classList.add(`pst-gh-${state}`) |
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.
I felt a bit misled by this code because of the initial value "unset," which made me think that these are the default values, but in fact these values get reset in the unconditional else-block to "issue" and res.data.state
. So I would rewrite it as:
console.debug('[PST] DEBUG: 1') | |
let pull_issue = 'unset'; | |
console.debug('[PST] DEBUG: 2') | |
let state = 'unset'; | |
console.debug('[PST] DEBUG: 3') | |
if (res.data.pull_request !== undefined){ | |
console.debug('[PST] DEBUG: 4') | |
pull_issue = 'pull'; | |
state = res.data.pull_request.merged_at != null ? 'merged': res.data.state ; | |
console.debug('[PST] DEBUG: 4b') | |
} else { | |
console.debug('[PST] DEBUG: 5') | |
pull_issue = 'issue'; | |
state = res.data.state; | |
console.debug('[PST] DEBUG: 5b') | |
} | |
console.log('[PST] adding classes to', pull_issue, state); | |
atag.classList.add(`pst-gh-${pull_issue}`) | |
atag.classList.add(`pst-gh-${state}`) | |
let issueType = 'issue'; | |
let state = res.data.state; | |
if (res.data.pull_request) { | |
issueType = 'pull'; | |
if (res.data.pull_request.merged_at) { | |
state = 'merged'; | |
} | |
} | |
atag.classList.add(`pst-gh-${issueType}`) | |
atag.classList.add(`pst-gh-${state}`) |
// we can sometime be throttled, or just refused connection, | ||
// just do one request on root, and if not 200, just do nothing. | ||
const root_res = await octokit.request('GET /'); | ||
if (root_res.status == 200) { |
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.
// we can sometime be throttled, or just refused connection, | |
// just do one request on root, and if not 200, just do nothing. | |
const root_res = await octokit.request('GET /'); | |
if (root_res.status == 200) { | |
// GitHub's API server may throttle us or refuse the connection, | |
// so make a request on root, and if not 200, just do nothing. | |
const rootResponse = await octokit.request('GET /'); | |
if (rootResponse.status == 200) |
//repo: 'REPO', | ||
//issue_number: 'ISSUE_NUMBER', | ||
headers: { | ||
'X-GitHub-Api-Version': '2024-09-30' |
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.
This line results in a 400 on the Read the Docs preview build, for example, on preview -community/topics/attribution:
"The version you specified in the "X-GitHub-API-Version" request header, "2024-09-30", is not a supported version. The following versions are currently supported: "2022-11-28" (most recent)."
See #1895.
Not that I heve the right skills and am good at desing, just show what could be done.
Need to be pulled into a separate JS file and properely desinged.