Skip to content

Commit f72c464

Browse files
[feat] Enhanced RFC discussion integration with auto-sync
Improves RFC discussions with full proposal content, author info, and automatic synchronization when PRs are updated. Includes fork compatibility using pull_request_target workflows. Key features: - Rich discussion creation with embedded RFC content - Auto-sync on PR updates via GraphQL mutations - Better formatting and metadata display - Maintains compatibility with fork contributions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 22a5bed commit f72c464

File tree

3 files changed

+245
-3
lines changed

3 files changed

+245
-3
lines changed

.github/workflows/rfc-discussion.yml

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ jobs:
3434
core.info('Found markdown file: ' + mdFile.filename);
3535
core.setOutput('filename', mdFile.filename);
3636
37+
- name: Get RFC Content
38+
id: get-rfc-content
39+
uses: actions/github-script@v7
40+
with:
41+
script: |
42+
const mdFile = '${{ steps.changed-files.outputs.filename }}';
43+
const { data: fileContent } = await github.rest.repos.getContent({
44+
owner: context.repo.owner,
45+
repo: context.repo.repo,
46+
path: mdFile,
47+
ref: context.payload.pull_request.head.sha
48+
});
49+
50+
const content = Buffer.from(fileContent.content, 'base64').toString('utf8');
51+
core.setOutput('content', content);
52+
3753
- name: Create a new GitHub Discussion
3854
id: create-discussion
3955
uses: abirismyname/[email protected]
@@ -42,11 +58,28 @@ jobs:
4258
with:
4359
title: "RFC Discussion: ${{ github.event.pull_request.title }}"
4460
body: |
45-
This is the discussion thread for RFC PR #${{ github.event.pull_request.number }}.
61+
# RFC Discussion: ${{ github.event.pull_request.title }}
62+
63+
**Author:** @${{ github.event.pull_request.user.login }} | **Status:** 🟡 Under Review
64+
65+
## 📋 Quick Links
66+
- 🔧 [Source PR #${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})
67+
- 📝 [View Changes](${{ github.event.pull_request.html_url }}/files)
68+
- 📖 [Rendered Proposal](https://github.com/${{ github.repository }}/blob/${{ github.event.pull_request.head.ref }}/${{ steps.changed-files.outputs.filename }})
69+
70+
---
71+
72+
## 📄 Current Proposal
73+
74+
> **Last Updated:** ${{ github.event.pull_request.updated_at }}
75+
> **Commit:** [`${{ github.event.pull_request.head.sha }}`](${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }})
4676
47-
Please provide feedback and discuss the RFC here rather than in the PR comments.
77+
<!-- RFC_CONTENT_START -->
78+
${{ steps.get-rfc-content.outputs.content }}
79+
<!-- RFC_CONTENT_END -->
4880
49-
PR Link: ${{ github.event.pull_request.html_url }}
81+
---
82+
**💬 Discussion Guidelines:** Share feedback, concerns, and suggestions below. Use reply threads to keep conversations organized.
5083
repository-id: "R_kgDONlIMAA"
5184
category-id: "DIC_kwDONlIMAM4Cl3Tj"
5285

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
name: Sync RFC Discussion
2+
3+
on:
4+
pull_request_target:
5+
types: [synchronize]
6+
paths:
7+
- 'rfcs/**.md'
8+
9+
jobs:
10+
sync-discussion:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
discussions: write
14+
pull-requests: read
15+
16+
steps:
17+
- name: Get Changed Files
18+
id: changed-files
19+
uses: actions/github-script@v7
20+
with:
21+
script: |
22+
const { data: files } = await github.rest.pulls.listFiles({
23+
owner: context.repo.owner,
24+
repo: context.repo.repo,
25+
pull_number: context.issue.number
26+
});
27+
28+
const mdFile = files.find(file => file.filename.startsWith('rfcs/') && file.filename.endsWith('.md'));
29+
if (!mdFile) {
30+
core.info('No RFC markdown file found, skipping sync');
31+
return;
32+
}
33+
core.setOutput('filename', mdFile.filename);
34+
35+
- name: Get RFC Content
36+
id: get-rfc-content
37+
if: steps.changed-files.outputs.filename
38+
uses: actions/github-script@v7
39+
with:
40+
script: |
41+
const mdFile = '${{ steps.changed-files.outputs.filename }}';
42+
const { data: fileContent } = await github.rest.repos.getContent({
43+
owner: context.repo.owner,
44+
repo: context.repo.repo,
45+
path: mdFile,
46+
ref: context.payload.pull_request.head.sha
47+
});
48+
49+
const content = Buffer.from(fileContent.content, 'base64').toString('utf8');
50+
core.setOutput('content', content);
51+
52+
- name: Find Discussion
53+
id: find-discussion
54+
if: steps.changed-files.outputs.filename
55+
uses: actions/github-script@v7
56+
with:
57+
script: |
58+
const query = `
59+
query($owner: String!, $repo: String!, $searchTerm: String!) {
60+
repository(owner: $owner, name: $repo) {
61+
discussions(first: 50, orderBy: {field: CREATED_AT, direction: DESC}) {
62+
nodes {
63+
id
64+
title
65+
body
66+
}
67+
}
68+
}
69+
}
70+
`;
71+
72+
const variables = {
73+
owner: context.repo.owner,
74+
repo: context.repo.repo,
75+
searchTerm: `RFC Discussion: ${context.payload.pull_request.title}`
76+
};
77+
78+
const result = await github.graphql(query, variables);
79+
const discussion = result.repository.discussions.nodes.find(d =>
80+
d.title === `RFC Discussion: ${context.payload.pull_request.title}`
81+
);
82+
83+
if (discussion) {
84+
core.setOutput('discussion_id', discussion.id);
85+
core.info(`Found discussion: ${discussion.id}`);
86+
} else {
87+
core.info('Discussion not found');
88+
}
89+
90+
- name: Update Discussion Content
91+
if: steps.find-discussion.outputs.discussion_id && steps.changed-files.outputs.filename
92+
uses: actions/github-script@v7
93+
with:
94+
script: |
95+
const discussionId = '${{ steps.find-discussion.outputs.discussion_id }}';
96+
const rfcContent = `${{ steps.get-rfc-content.outputs.content }}`;
97+
const mdFile = '${{ steps.changed-files.outputs.filename }}';
98+
99+
const newBody = `# RFC Discussion: ${{ github.event.pull_request.title }}
100+
101+
**Author:** @${{ github.event.pull_request.user.login }} | **Status:** 🟡 Under Review
102+
103+
## 📋 Quick Links
104+
- 🔧 [Source PR #${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})
105+
- 📝 [View Changes](${{ github.event.pull_request.html_url }}/files)
106+
- 📖 [Rendered Proposal](https://github.com/${{ github.repository }}/blob/${{ github.event.pull_request.head.ref }}/${mdFile})
107+
108+
---
109+
110+
## 📄 Current Proposal
111+
112+
> **Last Updated:** ${{ github.event.pull_request.updated_at }}
113+
> **Commit:** [\`${{ github.event.pull_request.head.sha }}\`](${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }})
114+
115+
<!-- RFC_CONTENT_START -->
116+
${rfcContent}
117+
<!-- RFC_CONTENT_END -->
118+
119+
---
120+
**💬 Discussion Guidelines:** Share feedback, concerns, and suggestions below. Use reply threads to keep conversations organized.`;
121+
122+
const mutation = `
123+
mutation($discussionId: ID!, $body: String!) {
124+
updateDiscussion(input: {
125+
discussionId: $discussionId,
126+
body: $body
127+
}) {
128+
discussion {
129+
id
130+
title
131+
}
132+
}
133+
}
134+
`;
135+
136+
const variables = {
137+
discussionId: discussionId,
138+
body: newBody
139+
};
140+
141+
try {
142+
const result = await github.graphql(mutation, variables);
143+
core.info(`Successfully updated discussion: ${result.updateDiscussion.discussion.id}`);
144+
} catch (error) {
145+
core.setFailed(`Failed to update discussion: ${error.message}`);
146+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# RFC: Test Enhanced Discussion Integration
2+
3+
- Start Date: 2025-01-06
4+
- Target Major Version: (1.x)
5+
- Reference Issues: N/A - Testing workflow
6+
- Implementation PR: (leave this empty)
7+
8+
## Summary
9+
10+
This is a test RFC to verify the enhanced discussion integration workflow. It includes automatic discussion creation with full proposal content and sync capabilities.
11+
12+
## Basic example
13+
14+
```javascript
15+
// This is just test content to verify the workflow
16+
console.log("Enhanced discussion workflow test");
17+
```
18+
19+
## Motivation
20+
21+
We want to ensure that:
22+
1. RFC discussions are created with full proposal content
23+
2. Discussion content is automatically synced when PRs are updated
24+
3. The workflow works correctly with forks
25+
4. Users get a better experience with rich, formatted discussions
26+
27+
## Detailed design
28+
29+
The enhanced workflow includes:
30+
31+
- **Rich Discussion Creation**: Discussions now include the full RFC content, author information, and useful links
32+
- **Automatic Sync**: When RFCs are updated via PR commits, the discussion content automatically updates
33+
- **Better Formatting**: Discussions use proper markdown formatting with sections and metadata
34+
- **Fork Compatibility**: Uses `pull_request_target` to work with fork contributions
35+
36+
### Technical Implementation
37+
38+
1. Enhanced creation workflow extracts RFC content from PR
39+
2. Sync workflow monitors for PR updates and refreshes discussion content
40+
3. GraphQL mutations update existing discussions
41+
4. Proper permissions ensure fork compatibility
42+
43+
## Drawbacks
44+
45+
- Slightly more complex workflow configuration
46+
- Requires GraphQL API usage for discussion updates
47+
- May generate more GitHub API calls
48+
49+
## Alternatives
50+
51+
- Keep the simple discussion format
52+
- Use manual discussion updates
53+
- Rely on PR comments instead of discussions
54+
55+
## Adoption strategy
56+
57+
This is a workflow enhancement that doesn't affect end users directly. RFC authors will benefit from richer discussions automatically.
58+
59+
## Unresolved questions
60+
61+
- Should we add even more metadata to discussions?
62+
- How should we handle very large RFC files?
63+
- Should we include diff information in sync updates?

0 commit comments

Comments
 (0)