Skip to content
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

fix(edge-case): fetching associatedPRs on 100+ context.commits in success lifecycle #892

Merged
merged 12 commits into from
Aug 15, 2024
Merged
77 changes: 69 additions & 8 deletions lib/success.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,44 @@ export default async function success(pluginConfig, context, { Octokit }) {
const releaseInfos = releases.filter((release) => Boolean(release.name));
const shas = commits.map(({ hash }) => hash);

const { repository } = await octokit.graphql(
buildAssociatedPRsQuery(shas),
{ owner, repo },
);
const associatedPRs = Object.values(repository).map(
(item) => item.associatedPullRequests.nodes,
);
const associatedPRs = [];

// Split commit shas into chunks of 100 shas
const chunkSize = 100;
const shasChunks = [];
for (let i = 0; i < shas.length; i += chunkSize) {
const chunk = shas.slice(i, i + chunkSize);
shasChunks.push(chunk);
}
for (const chunk of shasChunks) {
const { repository } = await octokit.graphql(
buildAssociatedPRsQuery(chunk),
{ owner, repo },
);
const responseAssociatedPRs = Object.values(repository).map(
(item) => item.associatedPullRequests,
);
for (const { nodes, pageInfo } of responseAssociatedPRs) {
associatedPRs.push(nodes);
if (pageInfo.hasNextPage) {
let cursor = pageInfo.endCursor;
let hasNextPage = true;
while (hasNextPage) {
const { repository } = await octokit.graphql(
loadSingleCommitAssociatedPRs,
{ owner, repo, sha: response.commit.oid, cursor },
);
const { associatedPullRequests } = repository.commit;
associatedPRs.push(associatedPullRequests.nodes);
if (associatedPullRequests.pageInfo.hasNextPage) {
cursor = associatedPullRequests.pageInfo.endCursor;
} else {
hasNextPage = false;
}
}
}
}
}

const uniqueAssociatedPRs = uniqBy(flatten(associatedPRs), "number");

Expand Down Expand Up @@ -252,15 +283,20 @@ export default async function success(pluginConfig, context, { Octokit }) {
* @param {Array<string>} shas
* @returns {string}
*/
export function buildAssociatedPRsQuery(shas) {
function buildAssociatedPRsQuery(shas) {
return `#graphql
query getAssociatedPRs($owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
${shas
.map((sha) => {
return `commit${sha.slice(0, 6)}: object(oid: "${sha}") {
...on Commit {
oid
associatedPullRequests(first: 100) {
pageInfo {
endCursor
hasNextPage
}
nodes {
url
number
Expand All @@ -275,3 +311,28 @@ export function buildAssociatedPRsQuery(shas) {
}
`;
}

/**
* GraphQL Query to fetch additional associatedPR for commits that has more than 100 associatedPRs
*/
const loadSingleCommitAssociatedPRs = `#graphql
query getCommitAssociatedPRs($owner: String!, $repo: String!, $sha: String!, $cursor: String) {
repository(owner: $owner, name: $repo) {
commit: object(oid: $sha) {
...on Commit {
associatedPullRequests(after: $cursor, first: 100) {
pageInfo {
endCursor
hasNextPage
}
nodes {
url
number
body
}
}
}
}
}
}
`;
15 changes: 15 additions & 0 deletions test/integration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,12 @@ test("Comment and add labels on PR included in the releases", async (t) => {
data: {
repository: {
commit123: {
oid: "123",
associatedPullRequests: {
pageInfo: {
endCursor: "NI",
hasNextPage: false,
},
nodes: [prs[0]],
},
},
Expand Down Expand Up @@ -674,7 +679,12 @@ test("Verify, release and notify success", async (t) => {
data: {
repository: {
commit123: {
oid: "123",
associatedPullRequests: {
pageInfo: {
endCursor: "NI",
hasNextPage: false,
},
nodes: [prs[0]],
},
},
Expand Down Expand Up @@ -828,7 +838,12 @@ test("Verify, update release and notify success", async (t) => {
data: {
repository: {
commit123: {
oid: "123",
associatedPullRequests: {
pageInfo: {
endCursor: "NI",
hasNextPage: false,
},
nodes: [prs[0]],
},
},
Expand Down
Loading