diff --git a/lib/action.mjs b/lib/action.mjs index 6380f33..20a7e12 100644 --- a/lib/action.mjs +++ b/lib/action.mjs @@ -88,7 +88,7 @@ fragment PR on PullRequest { baseRef { name } headRef { name } } -`,Zb=[],Xb=[];switch(process.env.GITHUB_EVENT_NAME){case"push":case"workflow_dispatch":await uW();break;case"pull_request":case"pull_request_target":await lW();break;default:throw new Error(`Event ${process.env.GITHUB_EVENT_NAME} is not supported. Only push, workflow_dispatch, pull_request, and pull_request_target are supported.`)}LA.default.setOutput("updated-prs",Zb.join(","));LA.default.setOutput("conflicted-prs",Xb.join(","));async function uW(){Ei.isString.assert(process.env.GITHUB_EVENT_PATH);let{ref:e,repository:A}=JSON.parse(await Hb.readFile(process.env.GITHUB_EVENT_PATH)),t="refs/heads/";if(!e.startsWith(t))return;let r=e.slice(t.length),s={repo:A.name,owner:A.owner.name??A.owner.login};await Cu(5e3);let o=`repo:${s.owner}/${s.repo} is:open is:pr base:${r}`;for await(let n of IW({search:o}))await Bu(s,n)}async function lW(){Ei.isString.assert(process.env.GITHUB_EVENT_PATH);let{action:e,number:A,repository:t}=JSON.parse(await Hb.readFile(process.env.GITHUB_EVENT_PATH)),r={repo:t.name,owner:t.owner.name??t.owner.login};(e==="opened"||e==="synchronize")&&await Cu(5e3);let s=await Kb({...r,number:A});await Bu(r,s)}async function Bu(e,A){switch(A.mergeable){case"CONFLICTING":await BW(e,A);break;case"MERGEABLE":{let t=[hW(e,A),QW(e,A)];await Promise.all(t);break}case"UNKNOWN":{console.info(`[PR ${A.number}] Conflict state is not yet known. Retrying.`),await Cu(1e3);let t=await Kb({...e,number:A.number});await Bu(e,t);break}}}function gi(e,A){return e.labels.nodes.some(t=>A.includes(t.name))}async function QW(e,A){if(!aW)return;if(cW&&!A.autoMergeRequest){console.info(`[${A.number}] Auto-merge is not enabled, skipping update.`);return}if(uu.length>0&&!gi(A,uu)){console.info(`[${A.number}] Does not any of the labels (${uu}), skipping update.`);return}if(lu.length>0&&gi(A,lu)){console.info(`[${A.number}] Has one of the excluded (${lu}), skipping update.`);return}if(EW.includes(zb(A.author))){console.info(`[${A.number}] Was created by an excluded author, skipping update.`);return}if(!$b(A,gW)){console.info(`[${A.number}] Not in the expected ready state, skipping update.`);return}if(await CW(e,A)&&(Zb.push(A.number),console.info(`[${A.number}] \u2705 Updating branch.`),!ci))return oW.rest.pulls.updateBranch({...e,pull_number:A.number})}async function CW(e,A){return(await Ot.graphql(` +`,Zb=[],Xb=[];switch(process.env.GITHUB_EVENT_NAME){case"push":case"workflow_dispatch":await uW();break;case"pull_request":case"pull_request_target":await lW();break;default:throw new Error(`Event ${process.env.GITHUB_EVENT_NAME} is not supported. Only push, workflow_dispatch, pull_request, and pull_request_target are supported.`)}LA.default.setOutput("updated-prs",Zb.join(","));LA.default.setOutput("conflicted-prs",Xb.join(","));async function uW(){Ei.isString.assert(process.env.GITHUB_EVENT_PATH);let{ref:e,repository:A}=JSON.parse(await Hb.readFile(process.env.GITHUB_EVENT_PATH)),t="refs/heads/";if(!e.startsWith(t))return;let r=e.slice(t.length),s={repo:A.name,owner:A.owner.name??A.owner.login};await Cu(1e4);let o=`repo:${s.owner}/${s.repo} is:open is:pr base:${r}`;for await(let n of IW({search:o}))console.info(`Handling PRs ${n.map(i=>i.number).join(", ")}`),await Promise.all(n.map(async i=>Bu(s,i)))}async function lW(){Ei.isString.assert(process.env.GITHUB_EVENT_PATH);let{action:e,number:A,repository:t}=JSON.parse(await Hb.readFile(process.env.GITHUB_EVENT_PATH)),r={repo:t.name,owner:t.owner.name??t.owner.login};(e==="opened"||e==="synchronize")&&await Cu(5e3);let s=await Kb({...r,number:A});await Bu(r,s)}async function Bu(e,A){switch(A.mergeable){case"CONFLICTING":await BW(e,A);break;case"MERGEABLE":{let t=[hW(e,A),QW(e,A)];await Promise.all(t);break}case"UNKNOWN":{console.info(`[PR ${A.number}] Conflict state is not yet known. Retrying.`),await Cu(1e3);let t=await Kb({...e,number:A.number});await Bu(e,t);break}}}function gi(e,A){return e.labels.nodes.some(t=>A.includes(t.name))}async function QW(e,A){if(!aW)return;if(cW&&!A.autoMergeRequest){console.info(`[${A.number}] Auto-merge is not enabled, skipping update.`);return}if(uu.length>0&&!gi(A,uu)){console.info(`[${A.number}] Does not any of the labels (${uu}), skipping update.`);return}if(lu.length>0&&gi(A,lu)){console.info(`[${A.number}] Has one of the excluded (${lu}), skipping update.`);return}if(EW.includes(zb(A.author))){console.info(`[${A.number}] Was created by an excluded author, skipping update.`);return}if(!$b(A,gW)){console.info(`[${A.number}] Not in the expected ready state, skipping update.`);return}if(await CW(e,A)&&(Zb.push(A.number),console.info(`[${A.number}] \u2705 Updating branch.`),!ci))return oW.rest.pulls.updateBranch({...e,pull_number:A.number})}async function CW(e,A){return(await Ot.graphql(` query ($owner: String!, $repository:String!, $baseRef:String!, $headRef:String!) { repository(owner:$owner, name: $repository) { ref(qualifiedName: $baseRef) { @@ -126,7 +126,7 @@ fragment PR on PullRequest { } } } - `,{...e,cursor:A});for(let r of t.search.nodes)yield r;if(!t.search.pageInfo.hasNextPage)break;A=t.search.pageInfo.endCursor}}function zb(e){return e.__typename==="Bot"?`app/${e.login}`:e.login}function $b(e,A){switch(A){case"all":return!0;case"draft":return e.isDraft;case"ready_for_review":return!e.isDraft}}function eD(e){return $b(e,nW)?gu.length>0&&!gi(e,gu)?(console.info(`[${e.number}] Does not any of the labels (${gu}), skipping conflict handling.`),!1):Eu.length>0&&gi(e,Eu)?(console.info(`[${e.number}] Has one of the excluded (${Eu}), skipping conflict handling.`),!1):iW.includes(zb(e.author))?(console.info(`[${e.number}] Was created by an excluded author, skipping conflict handling.`),!1):!0:(console.info(`[${e.number}] Not in the expected ready state, skipping conflict handling.`),!1)} + `,{...e,cursor:A});if(yield t.search.nodes,!t.search.pageInfo.hasNextPage)break;A=t.search.pageInfo.endCursor}}function zb(e){return e.__typename==="Bot"?`app/${e.login}`:e.login}function $b(e,A){switch(A){case"all":return!0;case"draft":return e.isDraft;case"ready_for_review":return!e.isDraft}}function eD(e){return $b(e,nW)?gu.length>0&&!gi(e,gu)?(console.info(`[${e.number}] Does not any of the labels (${gu}), skipping conflict handling.`),!1):Eu.length>0&&gi(e,Eu)?(console.info(`[${e.number}] Has one of the excluded (${Eu}), skipping conflict handling.`),!1):iW.includes(zb(e.author))?(console.info(`[${e.number}] Was created by an excluded author, skipping conflict handling.`),!1):!0:(console.info(`[${e.number}] Not in the expected ready state, skipping conflict handling.`),!1)} /*! Bundled license information: undici/lib/fetch/body.js: diff --git a/src/action.ts b/src/action.ts index 8202394..79468a8 100644 --- a/src/action.ts +++ b/src/action.ts @@ -141,13 +141,15 @@ async function processPushEvent() { /** * Conflict state is not computed instantaneously. - * This gives GitHub 5 seconds to compute it. + * This gives GitHub 10 seconds to compute it. */ - await setTimeout(5000); + await setTimeout(10_000); const search = `repo:${repositoryId.owner}/${repositoryId.repo} is:open is:pr base:${targetBranch}`; for await (const pullRequest of iteratePullRequests({ search })) { - await processPr(repositoryId, pullRequest); + console.info(`Handling PRs ${pullRequest.map(pr => pr.number).join(', ')}`); + + await Promise.all(pullRequest.map(async pr => processPr(repositoryId, pr))); } } @@ -442,9 +444,7 @@ async function* iteratePullRequests(params: { search: string }) { }, ); - for (const pullRequest of response.search.nodes) { - yield pullRequest; - } + yield response.search.nodes; if (!response.search.pageInfo.hasNextPage) { break;