Skip to content
Merged
Show file tree
Hide file tree
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
118 changes: 60 additions & 58 deletions .github/workflows/pr-issue-sync.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
name: Sync PR data from Linked Issues
name: PR Issue Sync

on:
pull_request_target:
types: [opened, edited, synchronize]
workflow_dispatch: {} # manual trigger only (disables automatic runs)

jobs:
sync-metadata:
Expand All @@ -28,66 +27,69 @@ jobs:
}
core.setOutput("issues", JSON.stringify(matches));

- name: Post or Update data Comment
if: steps.extract.outputs.issues && steps.extract.outputs.issues != '[]'
- name: Sync metadata
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issues = JSON.parse(`${{ steps.extract.outputs.issues }}`);
const prNumber = context.payload.pull_request.number;

let combinedLabels = [];
let combinedAssignees = [];
let combinedMilestones = [];

for (const number of issues) {
const data = ${{ fromJSON(format('{{\"issues\":{0},\"pr\":{1}}}', steps.extract.outputs.issues, github.event.pull_request.number)) }};
const prNumber = data.pr;
const issueNumbers = data.issues || [];

if (issueNumbers.length === 0) {
console.log("No linked issues found");
return;
}

for (const issueNumber of issueNumbers) {
try {
const issue = await github.rest.issues.get({
...context.repo,
issue_number: number
// Fetch issue
const { data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: parseInt(issueNumber)
});

combinedLabels.push(...issue.data.labels.map(l => l.name));
combinedAssignees.push(...issue.data.assignees.map(a => a.login));
if (issue.data.milestone) combinedMilestones.push(issue.data.milestone.title);

} catch (err) {
console.log(`Could not fetch issue #${number}: ${err.message}`);

console.log(`Syncing metadata from Issue #${issueNumber} to PR #${prNumber}`);

// --- Sync Labels ---
const issueLabels = issue.labels.map(l => l.name);
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
const currentPRLabels = pr.labels.map(l => l.name);
const combinedLabels = Array.from(new Set([...currentPRLabels, ...issueLabels]));

await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: combinedLabels
});
console.log(`Labels applied: ${combinedLabels.join(', ')}`);

// --- Sync Milestone ---
if (issue.milestone) {
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
milestone: issue.milestone.number
});
console.log(`Milestone synced: ${issue.milestone.title}`);
}

// --- Optionally: Add a comment on PR ---
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: `✅ Synchronized metadata from Issue #${issueNumber}:\nLabels: ${issueLabels.join(', ')}\nMilestone: ${issue.milestone ? issue.milestone.title : 'None'}`
});

} catch (error) {
console.error(`Error syncing issue #${issueNumber} to PR #${prNumber}:`, error.message);
}
}

// Deduplicate
combinedLabels = [...new Set(combinedLabels)];
combinedAssignees = [...new Set(combinedAssignees)];
combinedMilestones = [...new Set(combinedMilestones)];

const commentBody =
`### Synced data from Linked Issues\n\n` +
`**Labels:**\n${combinedLabels.length ? combinedLabels.map(l => `- ${l}`).join("\n") : "- None"}\n\n` +
`**Assignees:**\n${combinedAssignees.length ? combinedAssignees.map(a => `- ${a}`).join("\n") : "- None"}\n\n` +
`**Milestones:**\n${combinedMilestones.length ? combinedMilestones.map(m => `- ${m}`).join("\n") : "- None"}\n`;

// Get existing comments
const comments = await github.rest.issues.listComments({
...context.repo,
issue_number: prNumber
});

// Find existing workflow comment
const existingComment = comments.data.find(c => c.body.includes("### Synced data from Linked Issues"));

if (existingComment) {
await github.rest.issues.updateComment({
...context.repo,
comment_id: existingComment.id,
body: commentBody
});
} else {
// Create new comment
await github.rest.issues.createComment({
...context.repo,
issue_number: prNumber,
body: commentBody
});
}
58 changes: 58 additions & 0 deletions src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -1517,3 +1517,61 @@ a {
.theme-doc-breadcrumbs a.breadcrumbs__link > svg.breadcrumbHomeIcon_YNFT {
display: inline-block;
}

/* Fix difficulty and topic pill backgrounds in light/dark mode */
[data-theme='light'] .rounded.bg-gray-100,
[data-theme='light'] .rounded-full.bg-green-100,
[data-theme='light'] .rounded-full.bg-yellow-100,
[data-theme='light'] .rounded-full.bg-red-100,
[data-theme='light'] .rounded-full.bg-blue-100 {
background-color: var(--ifm-color-emphasis-100) !important;
}

[data-theme='light'] .rounded-full.bg-green-100 {
background-color: #dcfce7 !important; /* green-100 */
}

[data-theme='light'] .rounded-full.bg-yellow-100 {
background-color: #fef9c3 !important; /* yellow-100 */
}

[data-theme='light'] .rounded-full.bg-red-100 {
background-color: #fee2e2 !important; /* red-100 */
}

[data-theme='light'] .rounded-full.bg-blue-100 {
background-color: #dbeafe !important; /* blue-100 */
}

[data-theme='light'] .rounded.bg-gray-100 {
background-color: #f3f4f6 !important; /* gray-100 */
}

/* Dark mode overrides */
[data-theme='dark'] .rounded.dark\:bg-gray-700,
[data-theme='dark'] .rounded-full.dark\:bg-green-900,
[data-theme='dark'] .rounded-full.dark\:bg-yellow-900,
[data-theme='dark'] .rounded-full.dark\:bg-red-900,
[data-theme='dark'] .rounded-full.dark\:bg-blue-900 {
opacity: 1 !important;
}

[data-theme='dark'] .rounded-full.dark\:bg-green-900 {
background-color: #14532d !important; /* green-900 */
}

[data-theme='dark'] .rounded-full.dark\:bg-yellow-900 {
background-color: #713f12 !important; /* yellow-900 */
}

[data-theme='dark'] .rounded-full.dark\:bg-red-900 {
background-color: #7f1d1d !important; /* red-900 */
}

[data-theme='dark'] .rounded-full.dark\:bg-blue-900 {
background-color: #1e3a8a !important; /* blue-900 */
}

[data-theme='dark'] .rounded.dark\:bg-gray-700 {
background-color: #374151 !important; /* gray-700 */
}
Loading