Pagination on reactionGroups in the GitHub GraphQL API - github

I’m trying to extract the username of all the users that have reacted to an issue (and how they reacted) with the GitHub GraphQL API. I’ve only been able to extract a maximum of 11 users per reaction group per query, and I haven’t found a way to successfully paginate the queries - the same users are returned each time.
Here’s an example of my query using an issue with many reactions:
{
repository(owner: "mapbox", name: "mapbox-gl-js") {
issue(number: 3184) {
reactionGroups {
content
reactors(first: 30) {
totalCount
pageInfo {
hasNextPage
endCursor
}
edges {
node {
... on User {
login
}
}
}
}
}
}
}
}
For THUMBS_UP reactions this correctly returns totalCount: 77. However, there are only 11 usernames returned (not the 30 requested). The value of hasNextPage in pageInfo is false, and using the returned cursor value or modifying the reactors query to last:30 instead of first:30 has no impact on which 11 users are returned.
Is there a way I can modify my query to get this working (I’m new to GraphQL) or is this a current limitation of the API? Thanks!
(I've also asked this on the GitHub community forums, but no reply yet - see here)

Related

Retrieve ALL Github issues of a specific Project using the GraphQL API

I've been trying to retrieve all GitHub issues of a specific project using their GraphQL API.
The problem that i have is that i need to specify in the items a first or last param it doesn't work. Although by specifying one of these params i get only a partition of the issues.
I thought that i could get the first 100, then use pagination and get the other 100 etc until the response is an empty list. From what i read, i cannot find a parameter in the items that defines a page.
What are your thoughts on this? Is there a workaround?
Thanks a lot for your time.
This query seems to work fine and gives page info under items,
query{
organization(login: "microsoft") {
projectV2(number: 559) {
title
items(first: 100) {
pageInfo {
endCursor
hasNextPage
}
}
}
}
}
Output,
{
"data": {
"organization": {
"projectV2": {
"title": "Azure TRE - Engineering",
"items": {
"pageInfo": {
"endCursor": "Njc",
"hasNextPage": false
}
}
}
}
}
}
Tested the query using,
GitHub Explorer

Filter Github issues closed by a user

Is there way to filter the issues closed by a user.
Referred the below link, but didn't help.
https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests
You could list repository issues, filtering by state: closed.
The answer includes a closed_by field that you can use to filter the result set.
Another approach, using GitHub GraphQL, is possible en though the Issue object does not have a ClosedEvent field which actually has the Actor field with the user details.
GitHub support suggests in that thread
query commits{
repository(owner: "rohit-smpx", name:"inno"){
issues(first: 10, states:CLOSED){
nodes{
number
title
timelineItems(itemTypes:CLOSED_EVENT, last: 1){
nodes{
__typename
...on ClosedEvent{
actor{
login
}
createdAt
}
}
}
}
}
}
}

Why am I able to bypass pagination when I call the same field twice (with different queries) in GitHub's GraphQL API

I noticed something I don't understand while trying to get the number of open issues per repository for a user.
When I use the following query I am asked to perform pagination (as expected) -
query {
user(login:"armsp"){
repositories{
nodes{
name
issues(states: OPEN){
totalCount
}
}
}
}
}
The error message after running the above -
{
"data": {
"user": null
},
"errors": [
{
"type": "MISSING_PAGINATION_BOUNDARIES",
"path": [
"user",
"repositories"
],
"locations": [
{
"line": 54,
"column": 5
}
],
"message": "You must provide a `first` or `last` value to properly paginate the `repositories` connection."
}
]
}
However when I do the following I actually get all the results which doesn't make any sense to me -
query {
user(login:"armsp"){
repositories{
totalCount
}
repositories{
nodes{
name
issues(states: OPEN){
totalCount
}
}
}
}
}
Shouldn't I be asked for pagination in the second query too ?
TLDR; This appears to be a bug. There's no way to bypass the limit applied when fetching a list of resources.
Limiting responses like this is a common feature of public APIs -- if the response could include thousands or millions of results, it'll tie up a lot of server resources to fulfill it all at once. Allowing users to make those sort of queries is both costly and a potential security risk.
Github's intent appears to be to always limit the amount of results when fetching a list of resources. This isn't well documented on the GraphQL side, but matches the behavior of their REST API:
Requests that return multiple items will be paginated to 30 items by default. You can specify further pages with the ?page parameter. For some resources, you can also set a custom page size up to 100 with the ?per_page parameter.
For connections, it looks like the check for the first or last parameter is only ran whenever the nodes field is present in the selection set. This makes sense, since this is ultimately the field we want to limit -- requesting other fields like totalDiskUsage or totalDiskUsage, even without a limit argument, is harmless with the regard to above concerns.
Things get funky when you consider how GraphQL handles selection sets with selections that have the same name. Without getting into the nitty gritty details, GraphQL will let you request the same field multiple times. If the field in question has a selection set, it will effectively merge the selection sets into a single one. So
query {
user(login:"armsp") {
repositories {
totalCount
}
repositories {
totalDiskUsage
}
}
}
becomes and is equivalent to
query {
user(login:"armsp") {
repositories {
totalCount
totalDiskUsage
}
}
}
Side note: The above does not hold true if you explicitly give one of the fields an alias since then the two fields have different response names.
All that to say, technically this query:
query {
user(login:"armsp"){
repositories{
totalCount
}
repositories{
nodes{
name
issues(states: OPEN){
totalCount
}
}
}
}
}
should also blow up with the same MISSING_PAGINATION_BOUNDARIES error. The fact that it doesn't means the selection set merging is somehow borking the check that's in place. This is clearly a bug. However, even while this appears to "work", it still doesn't get around whatever limits Github has applies at the storage layer -- you will always get at most 100 results even when exploiting the above bug.

Get latest release without prerelease in GraphQL

I'm migrating my connection with GitHub REST API to GraphQL API and I'm confused about getting latest release.
When I use this endpoint bellow to get latest release with REST API it will never return Draft releases or prereleases.
/repos/:owner/:repo/releases/latest
But, when I do the same with GraphQL API I can't filter that, using the query bellow I get the latest release but if it is and prerelease I'll have to query again to find another one.
{
InovaFarmaApi: repository(owner: "precisaosistemas", name: "inovafarma-api") {
...releaseData
}
}
fragment releaseData on Repository {
releases (last: 2) {
nodes {
isPrerelease
}
}
}
Can I filter for only release and not Draft releases or prereleases?
It doesn't look like it.
The GitHub developer documentation has a complete listing of all GraphQL object types, their fields, and their associated parameters. A Repository in particular documents its releases field; that has the Relay connection parameters and an ordering, but the only supported ReleaseOrderField values are CREATED_AT and NAME.
That means you need to repeat calls to page through the releases until you find one that meets your criteria.
query GetRelease($owner: String!, $name: String!, $cursor: String) {
repository(owner: $owner, name: $name) {
releases(before: $cursor,
last: 1,
orderBy: {field: CREATED_AT, order: DESC}) {
pageInfo { hasPreviousPage, startCursor }
nodes {
isPrerelease
...OtherReleaseData
}
}
}
}
If you hit a release where isPrerelease is true (which you don't want), and hasPreviousPage is also true, re-run the query passing the previous startCursor value as the cursor argument.

How to get info about specific user using github graphQL?

How can I get info about specific user or specific repo using github GraphQL? I've try this query:
{
search (query: "torvalds", type: USER, first: 1){
edges {
node {
}
}
}
}
but autocomplete for node show only __typename which return string "User".
DEMO
search returns a SearchResultItem, which is an interface. In order to access fields on it, you need to use a fragment on a concrete type like so:
{
search (query: "torvalds", type: USER, first: 1){
edges {
node {
... on User {
login
}
}
}
}
}
I made a short video tour of GitHub's GraphQL API which you might find useful: https://youtu.be/6xO87LlijoQ
EDIT: If you're just looking for a user or org and know the exact name, #stubailo's answer is actually better. You'll still need to use a fragment for most fields, but you'll get just one result of type RepositoryOwner.
The best way to get information about a specific user is to use the repositoryOwner query, like so:
{
repositoryOwner(login: "stubailo") {
login
... on User {
bio
}
}
}
Search is good too, but if you know the name of a user or organization, it's more direct to use the query above.