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]
