From f72c4649c6299a0be781110ad993391c2ff69933 Mon Sep 17 00:00:00 2001 From: bymyself Date: Sun, 1 Jun 2025 16:33:19 -0700 Subject: [PATCH 1/4] [feat] Enhanced RFC discussion integration with auto-sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .github/workflows/rfc-discussion.yml | 39 +++++- .github/workflows/sync-rfc-discussion.yml | 146 ++++++++++++++++++++++ rfcs/0004-test-enhanced-discussions.md | 63 ++++++++++ 3 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/sync-rfc-discussion.yml create mode 100644 rfcs/0004-test-enhanced-discussions.md diff --git a/.github/workflows/rfc-discussion.yml b/.github/workflows/rfc-discussion.yml index 11af50c..8fad1e1 100644 --- a/.github/workflows/rfc-discussion.yml +++ b/.github/workflows/rfc-discussion.yml @@ -34,6 +34,22 @@ jobs: core.info('Found markdown file: ' + mdFile.filename); core.setOutput('filename', mdFile.filename); + - name: Get RFC Content + id: get-rfc-content + uses: actions/github-script@v7 + with: + script: | + const mdFile = '${{ steps.changed-files.outputs.filename }}'; + const { data: fileContent } = await github.rest.repos.getContent({ + owner: context.repo.owner, + repo: context.repo.repo, + path: mdFile, + ref: context.payload.pull_request.head.sha + }); + + const content = Buffer.from(fileContent.content, 'base64').toString('utf8'); + core.setOutput('content', content); + - name: Create a new GitHub Discussion id: create-discussion uses: abirismyname/create-discussion@v1.x @@ -42,11 +58,28 @@ jobs: with: title: "RFC Discussion: ${{ github.event.pull_request.title }}" body: | - This is the discussion thread for RFC PR #${{ github.event.pull_request.number }}. + # RFC Discussion: ${{ github.event.pull_request.title }} + + **Author:** @${{ github.event.pull_request.user.login }} | **Status:** 🟡 Under Review + + ## 📋 Quick Links + - 🔧 [Source PR #${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }}) + - 📝 [View Changes](${{ github.event.pull_request.html_url }}/files) + - 📖 [Rendered Proposal](https://github.com/${{ github.repository }}/blob/${{ github.event.pull_request.head.ref }}/${{ steps.changed-files.outputs.filename }}) + + --- + + ## 📄 Current Proposal + + > **Last Updated:** ${{ github.event.pull_request.updated_at }} + > **Commit:** [`${{ github.event.pull_request.head.sha }}`](${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }}) - Please provide feedback and discuss the RFC here rather than in the PR comments. + + ${{ steps.get-rfc-content.outputs.content }} + - PR Link: ${{ github.event.pull_request.html_url }} + --- + **💬 Discussion Guidelines:** Share feedback, concerns, and suggestions below. Use reply threads to keep conversations organized. repository-id: "R_kgDONlIMAA" category-id: "DIC_kwDONlIMAM4Cl3Tj" diff --git a/.github/workflows/sync-rfc-discussion.yml b/.github/workflows/sync-rfc-discussion.yml new file mode 100644 index 0000000..ed60b77 --- /dev/null +++ b/.github/workflows/sync-rfc-discussion.yml @@ -0,0 +1,146 @@ +name: Sync RFC Discussion + +on: + pull_request_target: + types: [synchronize] + paths: + - 'rfcs/**.md' + +jobs: + sync-discussion: + runs-on: ubuntu-latest + permissions: + discussions: write + pull-requests: read + + steps: + - name: Get Changed Files + id: changed-files + uses: actions/github-script@v7 + with: + script: | + const { data: files } = await github.rest.pulls.listFiles({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + + const mdFile = files.find(file => file.filename.startsWith('rfcs/') && file.filename.endsWith('.md')); + if (!mdFile) { + core.info('No RFC markdown file found, skipping sync'); + return; + } + core.setOutput('filename', mdFile.filename); + + - name: Get RFC Content + id: get-rfc-content + if: steps.changed-files.outputs.filename + uses: actions/github-script@v7 + with: + script: | + const mdFile = '${{ steps.changed-files.outputs.filename }}'; + const { data: fileContent } = await github.rest.repos.getContent({ + owner: context.repo.owner, + repo: context.repo.repo, + path: mdFile, + ref: context.payload.pull_request.head.sha + }); + + const content = Buffer.from(fileContent.content, 'base64').toString('utf8'); + core.setOutput('content', content); + + - name: Find Discussion + id: find-discussion + if: steps.changed-files.outputs.filename + uses: actions/github-script@v7 + with: + script: | + const query = ` + query($owner: String!, $repo: String!, $searchTerm: String!) { + repository(owner: $owner, name: $repo) { + discussions(first: 50, orderBy: {field: CREATED_AT, direction: DESC}) { + nodes { + id + title + body + } + } + } + } + `; + + const variables = { + owner: context.repo.owner, + repo: context.repo.repo, + searchTerm: `RFC Discussion: ${context.payload.pull_request.title}` + }; + + const result = await github.graphql(query, variables); + const discussion = result.repository.discussions.nodes.find(d => + d.title === `RFC Discussion: ${context.payload.pull_request.title}` + ); + + if (discussion) { + core.setOutput('discussion_id', discussion.id); + core.info(`Found discussion: ${discussion.id}`); + } else { + core.info('Discussion not found'); + } + + - name: Update Discussion Content + if: steps.find-discussion.outputs.discussion_id && steps.changed-files.outputs.filename + uses: actions/github-script@v7 + with: + script: | + const discussionId = '${{ steps.find-discussion.outputs.discussion_id }}'; + const rfcContent = `${{ steps.get-rfc-content.outputs.content }}`; + const mdFile = '${{ steps.changed-files.outputs.filename }}'; + + const newBody = `# RFC Discussion: ${{ github.event.pull_request.title }} + +**Author:** @${{ github.event.pull_request.user.login }} | **Status:** 🟡 Under Review + +## 📋 Quick Links +- 🔧 [Source PR #${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }}) +- 📝 [View Changes](${{ github.event.pull_request.html_url }}/files) +- 📖 [Rendered Proposal](https://github.com/${{ github.repository }}/blob/${{ github.event.pull_request.head.ref }}/${mdFile}) + +--- + +## 📄 Current Proposal + +> **Last Updated:** ${{ github.event.pull_request.updated_at }} +> **Commit:** [\`${{ github.event.pull_request.head.sha }}\`](${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }}) + + +${rfcContent} + + +--- +**💬 Discussion Guidelines:** Share feedback, concerns, and suggestions below. Use reply threads to keep conversations organized.`; + + const mutation = ` + mutation($discussionId: ID!, $body: String!) { + updateDiscussion(input: { + discussionId: $discussionId, + body: $body + }) { + discussion { + id + title + } + } + } + `; + + const variables = { + discussionId: discussionId, + body: newBody + }; + + try { + const result = await github.graphql(mutation, variables); + core.info(`Successfully updated discussion: ${result.updateDiscussion.discussion.id}`); + } catch (error) { + core.setFailed(`Failed to update discussion: ${error.message}`); + } \ No newline at end of file diff --git a/rfcs/0004-test-enhanced-discussions.md b/rfcs/0004-test-enhanced-discussions.md new file mode 100644 index 0000000..1b3205b --- /dev/null +++ b/rfcs/0004-test-enhanced-discussions.md @@ -0,0 +1,63 @@ +# RFC: Test Enhanced Discussion Integration + +- Start Date: 2025-01-06 +- Target Major Version: (1.x) +- Reference Issues: N/A - Testing workflow +- Implementation PR: (leave this empty) + +## Summary + +This is a test RFC to verify the enhanced discussion integration workflow. It includes automatic discussion creation with full proposal content and sync capabilities. + +## Basic example + +```javascript +// This is just test content to verify the workflow +console.log("Enhanced discussion workflow test"); +``` + +## Motivation + +We want to ensure that: +1. RFC discussions are created with full proposal content +2. Discussion content is automatically synced when PRs are updated +3. The workflow works correctly with forks +4. Users get a better experience with rich, formatted discussions + +## Detailed design + +The enhanced workflow includes: + +- **Rich Discussion Creation**: Discussions now include the full RFC content, author information, and useful links +- **Automatic Sync**: When RFCs are updated via PR commits, the discussion content automatically updates +- **Better Formatting**: Discussions use proper markdown formatting with sections and metadata +- **Fork Compatibility**: Uses `pull_request_target` to work with fork contributions + +### Technical Implementation + +1. Enhanced creation workflow extracts RFC content from PR +2. Sync workflow monitors for PR updates and refreshes discussion content +3. GraphQL mutations update existing discussions +4. Proper permissions ensure fork compatibility + +## Drawbacks + +- Slightly more complex workflow configuration +- Requires GraphQL API usage for discussion updates +- May generate more GitHub API calls + +## Alternatives + +- Keep the simple discussion format +- Use manual discussion updates +- Rely on PR comments instead of discussions + +## Adoption strategy + +This is a workflow enhancement that doesn't affect end users directly. RFC authors will benefit from richer discussions automatically. + +## Unresolved questions + +- Should we add even more metadata to discussions? +- How should we handle very large RFC files? +- Should we include diff information in sync updates? \ No newline at end of file From c8e8367b776b767bf0ff0e07f2d457d71f5730ed Mon Sep 17 00:00:00 2001 From: bymyself Date: Sun, 1 Jun 2025 17:04:50 -0700 Subject: [PATCH 2/4] [fix] YAML syntax error in sync workflow Fixed template literal escaping in GitHub Actions script --- .github/workflows/sync-rfc-discussion.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync-rfc-discussion.yml b/.github/workflows/sync-rfc-discussion.yml index ed60b77..1f5f655 100644 --- a/.github/workflows/sync-rfc-discussion.yml +++ b/.github/workflows/sync-rfc-discussion.yml @@ -93,7 +93,7 @@ jobs: with: script: | const discussionId = '${{ steps.find-discussion.outputs.discussion_id }}'; - const rfcContent = `${{ steps.get-rfc-content.outputs.content }}`; + const rfcContent = '${{ steps.get-rfc-content.outputs.content }}'; const mdFile = '${{ steps.changed-files.outputs.filename }}'; const newBody = `# RFC Discussion: ${{ github.event.pull_request.title }} From 6d7537e31b3636e4e07e4bffabb93a9e5c1c1bc2 Mon Sep 17 00:00:00 2001 From: bymyself Date: Sun, 1 Jun 2025 18:42:17 -0700 Subject: [PATCH 3/4] [fix] Complete rewrite of sync workflow to fix YAML syntax Rebuilt the workflow to avoid GitHub Actions expression conflicts within template literals --- .github/workflows/sync-rfc-discussion.yml | 62 ++++++++++++++--------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/.github/workflows/sync-rfc-discussion.yml b/.github/workflows/sync-rfc-discussion.yml index 1f5f655..62e2dca 100644 --- a/.github/workflows/sync-rfc-discussion.yml +++ b/.github/workflows/sync-rfc-discussion.yml @@ -56,7 +56,7 @@ jobs: with: script: | const query = ` - query($owner: String!, $repo: String!, $searchTerm: String!) { + query($owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { discussions(first: 50, orderBy: {field: CREATED_AT, direction: DESC}) { nodes { @@ -71,8 +71,7 @@ jobs: const variables = { owner: context.repo.owner, - repo: context.repo.repo, - searchTerm: `RFC Discussion: ${context.payload.pull_request.title}` + repo: context.repo.repo }; const result = await github.graphql(query, variables); @@ -96,28 +95,41 @@ jobs: const rfcContent = '${{ steps.get-rfc-content.outputs.content }}'; const mdFile = '${{ steps.changed-files.outputs.filename }}'; - const newBody = `# RFC Discussion: ${{ github.event.pull_request.title }} - -**Author:** @${{ github.event.pull_request.user.login }} | **Status:** 🟡 Under Review - -## 📋 Quick Links -- 🔧 [Source PR #${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }}) -- 📝 [View Changes](${{ github.event.pull_request.html_url }}/files) -- 📖 [Rendered Proposal](https://github.com/${{ github.repository }}/blob/${{ github.event.pull_request.head.ref }}/${mdFile}) - ---- - -## 📄 Current Proposal - -> **Last Updated:** ${{ github.event.pull_request.updated_at }} -> **Commit:** [\`${{ github.event.pull_request.head.sha }}\`](${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }}) - - -${rfcContent} - - ---- -**💬 Discussion Guidelines:** Share feedback, concerns, and suggestions below. Use reply threads to keep conversations organized.`; + // Build the body content parts + const title = `# RFC Discussion: ${{ github.event.pull_request.title }}`; + const author = `**Author:** @${{ github.event.pull_request.user.login }} | **Status:** 🟡 Under Review`; + const links = `## 📋 Quick Links + - 🔧 [Source PR #${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }}) + - 📝 [View Changes](${{ github.event.pull_request.html_url }}/files) + - 📖 [Rendered Proposal](https://github.com/${{ github.repository }}/blob/${{ github.event.pull_request.head.ref }}/${mdFile})`; + + const proposalHeader = `## 📄 Current Proposal`; + const metadata = `> **Last Updated:** ${{ github.event.pull_request.updated_at }} + > **Commit:** [\`${{ github.event.pull_request.head.sha }}\`](${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }})`; + + const guidelines = `**💬 Discussion Guidelines:** Share feedback, concerns, and suggestions below. Use reply threads to keep conversations organized.`; + + // Combine all parts + const newBody = [ + title, + '', + author, + '', + links, + '', + '---', + '', + proposalHeader, + '', + metadata, + '', + '', + rfcContent, + '', + '', + '---', + guidelines + ].join('\n'); const mutation = ` mutation($discussionId: ID!, $body: String!) { From 62f675addea15bd336ace258109dcdc5c290ddf8 Mon Sep 17 00:00:00 2001 From: bymyself Date: Sun, 1 Jun 2025 21:10:30 -0700 Subject: [PATCH 4/4] [cleanup] Remove test RFC document for workflow testing Will create proper test on separate branch after workflow merge --- rfcs/0004-test-enhanced-discussions.md | 63 -------------------------- 1 file changed, 63 deletions(-) delete mode 100644 rfcs/0004-test-enhanced-discussions.md diff --git a/rfcs/0004-test-enhanced-discussions.md b/rfcs/0004-test-enhanced-discussions.md deleted file mode 100644 index 1b3205b..0000000 --- a/rfcs/0004-test-enhanced-discussions.md +++ /dev/null @@ -1,63 +0,0 @@ -# RFC: Test Enhanced Discussion Integration - -- Start Date: 2025-01-06 -- Target Major Version: (1.x) -- Reference Issues: N/A - Testing workflow -- Implementation PR: (leave this empty) - -## Summary - -This is a test RFC to verify the enhanced discussion integration workflow. It includes automatic discussion creation with full proposal content and sync capabilities. - -## Basic example - -```javascript -// This is just test content to verify the workflow -console.log("Enhanced discussion workflow test"); -``` - -## Motivation - -We want to ensure that: -1. RFC discussions are created with full proposal content -2. Discussion content is automatically synced when PRs are updated -3. The workflow works correctly with forks -4. Users get a better experience with rich, formatted discussions - -## Detailed design - -The enhanced workflow includes: - -- **Rich Discussion Creation**: Discussions now include the full RFC content, author information, and useful links -- **Automatic Sync**: When RFCs are updated via PR commits, the discussion content automatically updates -- **Better Formatting**: Discussions use proper markdown formatting with sections and metadata -- **Fork Compatibility**: Uses `pull_request_target` to work with fork contributions - -### Technical Implementation - -1. Enhanced creation workflow extracts RFC content from PR -2. Sync workflow monitors for PR updates and refreshes discussion content -3. GraphQL mutations update existing discussions -4. Proper permissions ensure fork compatibility - -## Drawbacks - -- Slightly more complex workflow configuration -- Requires GraphQL API usage for discussion updates -- May generate more GitHub API calls - -## Alternatives - -- Keep the simple discussion format -- Use manual discussion updates -- Rely on PR comments instead of discussions - -## Adoption strategy - -This is a workflow enhancement that doesn't affect end users directly. RFC authors will benefit from richer discussions automatically. - -## Unresolved questions - -- Should we add even more metadata to discussions? -- How should we handle very large RFC files? -- Should we include diff information in sync updates? \ No newline at end of file