Copilot commented on code in PR #53633:
URL: https://github.com/apache/spark/pull/53633#discussion_r2650417202


##########
.github/workflows/labeler.yml:
##########
@@ -24,7 +24,9 @@
 # See also 
https://github.community/t/specify-check-suite-when-creating-a-checkrun/118380/10
 
 name: "On pull requests"
-on: pull_request_target
+on:
+  pull_request_target:
+    types: [opened, edited, reopened]

Review Comment:
   The workflow will trigger on every edit to a pull request, even if the edit 
doesn't involve the title. This could lead to unnecessary workflow runs and API 
calls to JIRA when only the PR description or other metadata is changed. 
Consider adding a condition to check if the title has actually changed before 
running the JIRA validation logic.



##########
.github/workflows/labeler.yml:
##########
@@ -38,3 +40,153 @@ jobs:
       with:
         repo-token: "${{ secrets.GITHUB_TOKEN }}"
         sync-labels: true
+
+  jira-info:
+    name: Comment JIRA information
+    runs-on: ubuntu-latest
+    permissions:
+      pull-requests: write
+    steps:
+    - name: Extract JIRA IDs and comment
+      uses: actions/github-script@v7
+      with:
+        github-token: ${{ secrets.GITHUB_TOKEN }}
+        script: |
+          const prTitle = context.payload.pull_request.title;
+          const prNumber = context.payload.pull_request.number;
+
+          // Extract JIRA IDs from PR title
+          const jiraIdRegex = /SPARK-\d+/g;
+          const jiraIds = prTitle.match(jiraIdRegex);
+
+          // If no JIRA IDs found, check for [MINOR] tag
+          if (!jiraIds || jiraIds.length === 0) {
+            const minorRegex = /^\[MINOR\]/i;
+            if (minorRegex.test(prTitle)) {
+              console.log('PR title has [MINOR] tag, skipping');
+              return;
+            }
+
+            // Post reminder comment
+            const reminderComment = `## ⚠️ Pull Request Title 
Validation\n\nThis pull request title does not contain a JIRA issue 
ID.\n\nPlease update the title to either:\n- Include a JIRA ID: \`[SPARK-12345] 
Your description\`\n- Mark as minor change: \`[MINOR] Your description\`\n\nFor 
minor changes that don't require a JIRA ticket (e.g., typo fixes), please 
prefix the title with \`[MINOR]\`.\n\n---\n*This comment was automatically 
generated by GitHub Actions*`;
+
+            const comments = await github.rest.issues.listComments({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: prNumber
+            });
+
+            const botComment = comments.data.find(comment =>
+              comment.user.type === 'Bot' &&
+              (comment.body.includes('## JIRA Issue Information') || 
comment.body.includes('## ⚠️ Pull Request Title Validation'))
+            );
+
+            if (botComment) {
+              await github.rest.issues.updateComment({
+                owner: context.repo.owner,
+                repo: context.repo.repo,
+                comment_id: botComment.id,
+                body: reminderComment
+              });
+              console.log('Updated reminder comment');
+            } else {
+              await github.rest.issues.createComment({
+                owner: context.repo.owner,
+                repo: context.repo.repo,
+                issue_number: prNumber,
+                body: reminderComment
+              });
+              console.log('Created reminder comment');
+            }
+            return;
+          }
+
+          // Remove duplicates
+          const uniqueJiraIds = [...new Set(jiraIds)];
+          console.log(`Found JIRA IDs: ${uniqueJiraIds.join(', ')}`);
+
+          // Fetch JIRA information for each ID
+          const jiraBaseUrl = 'https://issues.apache.org/jira';
+          const jiraInfos = [];
+
+          for (const jiraId of uniqueJiraIds) {
+            try {
+              const response = await 
fetch(`${jiraBaseUrl}/rest/api/2/issue/${jiraId}`);
+
+              if (!response.ok) {
+                jiraInfos.push({
+                  id: jiraId,
+                  type: 'Unknown',
+                  error: `Failed to fetch (HTTP ${response.status})`
+                });
+                continue;
+              }
+
+              const data = await response.json();
+              const fields = data.fields;
+
+              jiraInfos.push({
+                id: jiraId,
+                type: fields.issuetype?.name || 'Unknown',
+                summary: fields.summary || 'N/A',
+                assignee: fields.assignee ? fields.assignee.displayName : 
'None',
+                status: fields.status ? fields.status.name : 'Unknown',
+                affected: fields.versions ? fields.versions.map(v => v.name) : 
[]
+              });
+            } catch (error) {
+              console.error(`Error fetching ${jiraId}:`, error);
+              jiraInfos.push({
+                id: jiraId,
+                type: 'Unknown',
+                error: error.message
+              });
+            }
+          }
+
+          // Format comment
+          let commentBody = '## JIRA Issue Information\n\n';
+
+          for (const info of jiraInfos) {
+            if (info.error) {
+              commentBody += `=== ${info.type} ${info.id} ===\n`;
+              commentBody += `Error: ${info.error}\n\n`;
+            } else {
+              commentBody += `=== ${info.type} ${info.id} ===\n`;
+              commentBody += `Summary ${info.summary}\n`;
+              commentBody += `Assignee ${info.assignee}\n`;
+              commentBody += `Status ${info.status}\n`;
+              commentBody += `Affected ${JSON.stringify(info.affected)}\n\n`;

Review Comment:
   The comment body formatting is missing colons after field labels, which 
makes the output less readable. Each field label (Summary, Assignee, Status, 
Affected) should be followed by a colon to clearly separate the label from its 
value.
   ```suggestion
                 commentBody += `Summary: ${info.summary}\n`;
                 commentBody += `Assignee: ${info.assignee}\n`;
                 commentBody += `Status: ${info.status}\n`;
                 commentBody += `Affected: 
${JSON.stringify(info.affected)}\n\n`;
   ```



##########
.github/workflows/labeler.yml:
##########
@@ -38,3 +40,153 @@ jobs:
       with:
         repo-token: "${{ secrets.GITHUB_TOKEN }}"
         sync-labels: true
+
+  jira-info:
+    name: Comment JIRA information
+    runs-on: ubuntu-latest
+    permissions:
+      pull-requests: write
+    steps:
+    - name: Extract JIRA IDs and comment
+      uses: actions/github-script@v7
+      with:
+        github-token: ${{ secrets.GITHUB_TOKEN }}
+        script: |
+          const prTitle = context.payload.pull_request.title;
+          const prNumber = context.payload.pull_request.number;
+
+          // Extract JIRA IDs from PR title
+          const jiraIdRegex = /SPARK-\d+/g;

Review Comment:
   The JIRA ID regex pattern does not enforce position or word boundaries, 
which means it will match JIRA IDs anywhere in the title, including in URLs or 
as part of larger strings. For example, "SPARK-12345678" would incorrectly 
match as "SPARK-12345". Consider using word boundaries (\b) to ensure the JIRA 
ID is properly delimited: /\bSPARK-\d+\b/g
   ```suggestion
             const jiraIdRegex = /\bSPARK-\d+\b/g;
   ```



##########
.github/workflows/labeler.yml:
##########
@@ -38,3 +40,153 @@ jobs:
       with:
         repo-token: "${{ secrets.GITHUB_TOKEN }}"
         sync-labels: true
+
+  jira-info:
+    name: Comment JIRA information
+    runs-on: ubuntu-latest
+    permissions:
+      pull-requests: write
+    steps:
+    - name: Extract JIRA IDs and comment
+      uses: actions/github-script@v7
+      with:
+        github-token: ${{ secrets.GITHUB_TOKEN }}
+        script: |
+          const prTitle = context.payload.pull_request.title;
+          const prNumber = context.payload.pull_request.number;
+
+          // Extract JIRA IDs from PR title
+          const jiraIdRegex = /SPARK-\d+/g;
+          const jiraIds = prTitle.match(jiraIdRegex);
+
+          // If no JIRA IDs found, check for [MINOR] tag
+          if (!jiraIds || jiraIds.length === 0) {
+            const minorRegex = /^\[MINOR\]/i;
+            if (minorRegex.test(prTitle)) {
+              console.log('PR title has [MINOR] tag, skipping');
+              return;
+            }
+
+            // Post reminder comment
+            const reminderComment = `## ⚠️ Pull Request Title 
Validation\n\nThis pull request title does not contain a JIRA issue 
ID.\n\nPlease update the title to either:\n- Include a JIRA ID: \`[SPARK-12345] 
Your description\`\n- Mark as minor change: \`[MINOR] Your description\`\n\nFor 
minor changes that don't require a JIRA ticket (e.g., typo fixes), please 
prefix the title with \`[MINOR]\`.\n\n---\n*This comment was automatically 
generated by GitHub Actions*`;
+
+            const comments = await github.rest.issues.listComments({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              issue_number: prNumber
+            });
+
+            const botComment = comments.data.find(comment =>
+              comment.user.type === 'Bot' &&
+              (comment.body.includes('## JIRA Issue Information') || 
comment.body.includes('## ⚠️ Pull Request Title Validation'))
+            );
+
+            if (botComment) {
+              await github.rest.issues.updateComment({
+                owner: context.repo.owner,
+                repo: context.repo.repo,
+                comment_id: botComment.id,
+                body: reminderComment
+              });
+              console.log('Updated reminder comment');
+            } else {
+              await github.rest.issues.createComment({
+                owner: context.repo.owner,
+                repo: context.repo.repo,
+                issue_number: prNumber,
+                body: reminderComment
+              });
+              console.log('Created reminder comment');
+            }
+            return;
+          }
+
+          // Remove duplicates
+          const uniqueJiraIds = [...new Set(jiraIds)];
+          console.log(`Found JIRA IDs: ${uniqueJiraIds.join(', ')}`);
+
+          // Fetch JIRA information for each ID
+          const jiraBaseUrl = 'https://issues.apache.org/jira';
+          const jiraInfos = [];
+
+          for (const jiraId of uniqueJiraIds) {
+            try {
+              const response = await 
fetch(`${jiraBaseUrl}/rest/api/2/issue/${jiraId}`);
+
+              if (!response.ok) {
+                jiraInfos.push({
+                  id: jiraId,
+                  type: 'Unknown',
+                  error: `Failed to fetch (HTTP ${response.status})`
+                });
+                continue;
+              }
+
+              const data = await response.json();
+              const fields = data.fields;
+
+              jiraInfos.push({
+                id: jiraId,
+                type: fields.issuetype?.name || 'Unknown',
+                summary: fields.summary || 'N/A',
+                assignee: fields.assignee ? fields.assignee.displayName : 
'None',
+                status: fields.status ? fields.status.name : 'Unknown',
+                affected: fields.versions ? fields.versions.map(v => v.name) : 
[]
+              });
+            } catch (error) {
+              console.error(`Error fetching ${jiraId}:`, error);
+              jiraInfos.push({
+                id: jiraId,
+                type: 'Unknown',
+                error: error.message
+              });
+            }
+          }
+
+          // Format comment
+          let commentBody = '## JIRA Issue Information\n\n';
+
+          for (const info of jiraInfos) {
+            if (info.error) {
+              commentBody += `=== ${info.type} ${info.id} ===\n`;
+              commentBody += `Error: ${info.error}\n\n`;

Review Comment:
   The error message format is inconsistent with the success message format. In 
the error case (line 152), there's a space and "===" separator, but the error 
message doesn't include the same structured fields (Summary, Assignee, Status, 
Affected) as the success case. Consider providing a more consistent format or 
adding a link to the JIRA issue URL for manual verification when the API call 
fails.
   ```suggestion
                 commentBody += `Summary Error while fetching issue details\n`;
                 commentBody += `Assignee N/A\n`;
                 commentBody += `Status Unknown\n`;
                 commentBody += `Affected []\n`;
                 commentBody += `Error ${info.error}\n`;
                 commentBody += `URL ${jiraBaseUrl}/browse/${info.id}\n\n`;
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to