Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 153 additions & 1 deletion .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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]

jobs:
label:
Expand All @@ -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 = /\bSPARK-\d+\b/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`;
}
}
commentBody += '---\n*This comment was automatically generated by GitHub Actions*';
// Check if there's an existing comment from this action
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: commentBody
});
console.log('Updated existing comment');
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: commentBody
});
console.log('Created new comment');
}