@@ -97,40 +97,102 @@ export async function getOctokitForRepo(app, owner, repo) {
9797 throw new Error ( `Installation not found for repository ${ owner } /${ repo } ` ) ;
9898}
9999
100+ /**
101+ * This function is used to remove the "Pending CLA" label from the PRs of the user who has signed the CLA.
102+ * @param {Object } app - The Octokit app instance.
103+ * @param {Object } claSignatureInfo - The information about the CLA signature.
104+ * @example
105+ * const claSignatureInfo = {
106+ * referrer: "https://website.com/cla?org=rudderlabs&repo=rudder-server&prNumber=1234&username=githubUsername", // The URL of the page where the CLA was signed
107+ * username: "githubUsername" // The username of the user who signed the CLA,
108+ * }
109+ * await afterCLA(app, claSignatureInfo);
110+ */
100111export async function afterCLA ( app , claSignatureInfo ) {
101- if ( ! claSignatureInfo || ! claSignatureInfo . referrer ) return ;
102- const { org, repo, prNumber } = parseUrlQueryParams (
103- claSignatureInfo . referrer ,
104- ) ;
105- console . log (
106- `PR related to the CLA - owner: ${ org } , repo: ${ repo } , prNumber: ${ prNumber } ` ,
107- ) ;
108- if ( ! org || ! repo || ! prNumber ) {
109- console . log ( "Not enough info to find the related PR." ) ;
112+ const { org, username } = parseUrlQueryParams ( claSignatureInfo ?. referrer ) || { } ;
113+ const githubUsername = claSignatureInfo . username || username ;
114+
115+ if ( ! org || ! githubUsername ) {
116+ console . log ( "Not enough info to find the related PRs." ) ;
110117 return ;
111118 }
119+
120+ console . log ( `Processing CLA for ${ githubUsername ? `user: ${ githubUsername } ` : 'unknown user' } in org/account: ${ org } ` ) ;
121+
122+ try {
123+ for await ( const { installation } of app . eachInstallation . iterator ( ) ) {
124+ for await ( const { octokit, repository } of app . eachRepository . iterator ( {
125+ installationId : installation . id ,
126+ } ) ) {
127+ console . log ( `Processing repository: ${ repository . name } ` ) ;
128+
129+ // Check if the current repository belongs to the org
130+ if ( repository ?. owner ?. login ?. toLowerCase ( ) !== org ?. toLowerCase ( ) ) {
131+ console . log ( `Skipping ${ repository . name } as it doesn't belong to ${ org } ` ) ;
132+ continue ;
133+ }
134+
135+ // Get all open PRs for the user in this repository
136+ try {
137+ const prs = await octokit . paginate ( octokit . rest . pulls . list , {
138+ owner : org ,
139+ repo : repository . name ,
140+ state : 'open' ,
141+ creator : githubUsername
142+ } ) ;
143+ console . log ( `Found ${ prs . length } open PRs for ${ githubUsername } in ${ repository . name } :` , prs . map ( pr => pr . number ) . join ( ', ' ) ) ;
144+ for ( const pr of prs ) {
145+ await removePendingCLALabel ( octokit , org , repository . name , pr . number ) ;
146+ }
147+ } catch ( error ) {
148+ if ( error . status === 404 ) {
149+ console . log ( `Repository ${ org } /${ repository . name } not found or no access. Skipping.` ) ;
150+ } else {
151+ console . error ( `Error processing ${ org } /${ repository . name } :` , error . message ) ;
152+ }
153+ }
154+ }
155+ }
156+ } catch ( error ) {
157+ console . error ( "Error in afterCLA:" , error ) ;
158+ } finally {
159+ console . log ( "Completed post CLA verification tasks" ) ;
160+ }
161+ }
162+
163+ async function removePendingCLALabel ( octokit , owner , repo , issue_number ) {
112164 try {
113- let octokit = await getOctokitForRepo ( app , org , repo ) ;
165+ console . log ( `Removing label 'Pending CLA' from PR # ${ issue_number } in ${ owner } / ${ repo } ` ) ;
114166 await octokit . rest . issues . removeLabel ( {
115- owner : org ,
116- repo : repo ,
117- issue_number : prNumber ,
167+ owner,
168+ repo,
169+ issue_number,
118170 name : "Pending CLA" ,
119171 } ) ;
120- console . log ( "Label 'Pending CLA' removed successfully." ) ;
121- } catch ( error ) {
122- if ( error . response ) {
123- console . error (
124- `Error! Status: ${ error . response . status } . Message: ${ error . response . data . message } ` ,
125- ) ;
172+ console . log ( `Label 'Pending CLA' removed successfully from PR #${ issue_number } .` ) ;
173+ } catch ( labelError ) {
174+ if ( labelError . status === 404 ) {
175+ console . log ( `Label 'Pending CLA' not found on PR #${ issue_number } . Skipping.` ) ;
126176 } else {
127- console . error ( error ) ;
177+ console . error ( `Error removing label from PR # ${ issue_number } :` , labelError . message ) ;
128178 }
129- } finally {
130- console . log ( "Completed post CLA verification tasks" ) ;
131179 }
132180}
133181
182+ /**
183+ * This function is used to get the message string based on the name of the message template and the context.
184+ * @param {string } name - The name of the message template.
185+ * @param {Object } context - The context object containing variables for the message template.
186+ * @returns {string } - The message string.
187+ * @example
188+ * const context = {
189+ * org: "rudderlabs",
190+ * repo: "rudder-server",
191+ * pr_number: 1234,
192+ * username: "githubUsername"
193+ * }
194+ * const message = getMessage("ask-to-sign-cla", context);
195+ */
134196export function getMessage ( name , context ) {
135197 let message = "" ;
136198 switch ( name ) {
0 commit comments