name: Close Discussion on PR Merge on: push: branches: - main permissions: contents: read discussions: write jobs: close-discussion: runs-on: runner-cluster-htl-set steps: - name: Checkout Repository uses: actions/checkout@v4 - name: Set Up Node.js uses: actions/setup-node@v4 with: node-version: "20" - name: Install Dependencies run: npm install zx @octokit/graphql - name: Close Discussion env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_SHA: ${{ github.sha }} GITHUB_REPOSITORY: ${{ github.repository }} run: | npx zx << 'EOF' import { graphql } from "@octokit/graphql"; (async function () { try { const token = process.env.GITHUB_TOKEN; const commitSha = process.env.GITHUB_SHA; const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/"); if (!token || !commitSha || !owner || !repo) { console.log("Missing required environment variables."); process.exit(1); } const graphqlWithAuth = graphql.defaults({ headers: { authorization: `Bearer ${token}` }, }); // Find PR from commit SHA const searchQuery = ` query($owner: String!, $repo: String!, $sha: GitObjectID!) { repository(owner: $owner, name: $repo) { object(oid: $sha) { ... on Commit { associatedPullRequests(first: 1) { nodes { number body } } } } } } `; const prResult = await graphqlWithAuth(searchQuery, { owner, repo, sha: commitSha, }); const pr = prResult.repository.object.associatedPullRequests.nodes[0]; if (!pr) { console.log("No PR found for this commit."); return; } const prNumber = pr.number; const prBody = pr.body; const match = prBody.match(/#(\d+)/); if (!match) { console.log("No discussion ID found in PR body."); return; } const discussionNumber = match[1]; console.log(`Extracted Discussion Number: ${discussionNumber}`); // Fetch GraphQL discussion ID const discussionQuery = ` query($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { discussion(number: $number) { id } } } `; // try { const discussionResponse = await graphqlWithAuth(discussionQuery, { owner, repo, number: parseInt(discussionNumber, 10), }); const discussionQLId = discussionResponse.repository.discussion.id; if (!discussionQLId) { console.log("Failed to fetch discussion GraphQL ID."); return; } } catch (error) { console.error("Discussion not found or error occurred while fetching discussion:", error); return; } // Post comment const commentMutation = ` mutation($discussionId: ID!, $body: String!) { addDiscussionComment(input: { discussionId: $discussionId, body: $body }) { comment { id body } } } `; const commentResponse = await graphqlWithAuth(commentMutation, { discussionId: discussionQLId, body: `Merged with PR #${prNumber}`, }); const commentId = commentResponse.addDiscussionComment.comment.id; if (!commentId) { console.log("Failed to post the comment."); return; } console.log(`Comment Posted Successfully! Comment ID: ${commentId}`); // Mark comment as answer const markAnswerMutation = ` mutation($id: ID!) { markDiscussionCommentAsAnswer(input: { id: $id }) { discussion { id title } } } `; await graphqlWithAuth(markAnswerMutation, { id: commentId }); console.log("Comment marked as answer successfully!"); } catch (error) { console.error("Error:", error); process.exit(1); } })(); EOF