From ab5044b8d53a8d47418f0c158a0f258358eb44cc Mon Sep 17 00:00:00 2001 From: Anshuman Jadiya Date: Thu, 13 Nov 2025 20:05:17 +0530 Subject: [PATCH 1/2] Add auto-reply workflow for issues and PRs --- .github/workflows/auto-reply.yml | 129 +++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 .github/workflows/auto-reply.yml diff --git a/.github/workflows/auto-reply.yml b/.github/workflows/auto-reply.yml new file mode 100644 index 0000000..8da6c2a --- /dev/null +++ b/.github/workflows/auto-reply.yml @@ -0,0 +1,129 @@ +name: 🤖 Auto Reply to Issues & PRs + +on: + issues: + types: [opened, reopened] + pull_request_target: + types: [opened, reopened, synchronize] + +permissions: + issues: write + pull-requests: write + +jobs: + auto-comment: + runs-on: ubuntu-latest + steps: + - name: 🧠 Auto Comment + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const repo = { owner: "git-goods", repo: "gitanimals" }; + + async function commentExists(issue_number, messageSnippet) { + const comments = await github.rest.issues.listComments({ + owner: repo.owner, + repo: repo.repo, + issue_number + }); + return comments.data.some(c => c.body.includes(messageSnippet)); + } + + async function addReaction(issue_number, reaction) { + try { + await github.rest.reactions.createForIssue({ + owner: repo.owner, + repo: repo.repo, + issue_number, + content: reaction + }); + } catch (err) { + core.info("Could not add reaction: " + err.message); + } + } + + async function addLabels(issue_number, labels) { + try { + await github.rest.issues.addLabels({ + owner: repo.owner, + repo: repo.repo, + issue_number, + labels + }); + } catch (err) { + core.info("Could not add labels: " + err.message); + } + } + + // === Handle Pull Requests === + if (context.payload.pull_request) { + const pr = context.payload.pull_request; + const prNumber = pr.number; + const user = pr.user?.login || 'contributor'; + const eventType = context.payload.action; + + // ✅ Only run on "opened" event — skip reopened/synchronize + if (eventType !== "opened") { + core.info(`Skipping PR #${prNumber} since event is '${eventType}'`); + return; + } + + const message = `🚀 Hi @${user}! + +Thank you for contributing to **gitanimals** under the **git-goods** organization. A maintainer will review your PR shortly. 🎉 + +### Please ensure: +- You’ve read the README.md, CONTRIBUTING.md, and CODE_OF_CONDUCT.md.😊`; + + const gif = "![TrustTheProcess](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExbWtoOWpsMnozdXd0MmJxejhiNGwwdjltY3dyNW80NHg2Ym01YTdlMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/mPKa6OI5oRsmextwBq/giphy.gif)"; + + if (!(await commentExists(prNumber, "Thank you for contributing to **gitanimals**"))) { + await github.rest.issues.createComment({ + owner: repo.owner, + repo: repo.repo, + issue_number: prNumber, + body: message + "\n\n" + gif + }); + await addReaction(prNumber, "rocket"); + } else { + core.info(`Comment already exists for PR #${prNumber}, skipping.`); + } + + const headRepoFull = pr.head?.repo?.full_name || ''; + const baseFull = `${repo.owner}/${repo.repo}`; + const isFork = headRepoFull.toLowerCase() !== baseFull.toLowerCase(); + const labels = ["needs-review"]; + if (isFork) labels.push("from-fork"); + + await addLabels(prNumber, labels); + return; + } + + // === Handle Issues === + if (context.payload.issue) { + const issue = context.payload.issue; + const issueNumber = issue.number; + const user = issue.user?.login || 'contributor'; + + const message = `👋 Hi @${user}! + +Thanks for opening an issue in **gitanimals** (git-goods org). We’ll review it soon — please ensure reproduction steps and logs are included.`; + + if (!(await commentExists(issueNumber, "Thanks for opening an issue in **gitanimals**"))) { + await github.rest.issues.createComment({ + owner: repo.owner, + repo: repo.repo, + issue_number: issueNumber, + body: message + }); + await addReaction(issueNumber, "tada"); + } else { + core.info(`Comment already exists for Issue #${issueNumber}, skipping.`); + } + + await addLabels(issueNumber, ["triage", "needs-info"]); + return; + } + + core.info("No issue or pull_request payload found. Nothing to do."); From 890ea0084d4282023f90b1538ae7b645ae5f3956 Mon Sep 17 00:00:00 2001 From: Anshuman Jadiya Date: Thu, 13 Nov 2025 20:13:14 +0530 Subject: [PATCH 2/2] Fix YAML syntax in auto-reply workflow Updated YAML syntax for auto-reply workflow to use double quotes for strings. --- .github/workflows/auto-reply.yml | 35 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/.github/workflows/auto-reply.yml b/.github/workflows/auto-reply.yml index 8da6c2a..8d44bd6 100644 --- a/.github/workflows/auto-reply.yml +++ b/.github/workflows/auto-reply.yml @@ -1,4 +1,4 @@ -name: 🤖 Auto Reply to Issues & PRs +name: "🤖 Auto Reply to Issues & PRs" on: issues: @@ -14,7 +14,7 @@ jobs: auto-comment: runs-on: ubuntu-latest steps: - - name: 🧠 Auto Comment + - name: "🧠 Auto Comment" uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} @@ -60,7 +60,7 @@ jobs: if (context.payload.pull_request) { const pr = context.payload.pull_request; const prNumber = pr.number; - const user = pr.user?.login || 'contributor'; + const user = pr.user?.login || "contributor"; const eventType = context.payload.action; // ✅ Only run on "opened" event — skip reopened/synchronize @@ -69,12 +69,14 @@ jobs: return; } - const message = `🚀 Hi @${user}! - -Thank you for contributing to **gitanimals** under the **git-goods** organization. A maintainer will review your PR shortly. 🎉 - -### Please ensure: -- You’ve read the README.md, CONTRIBUTING.md, and CODE_OF_CONDUCT.md.😊`; + const message = [ + `🚀 Hi @${user}!`, + ``, + `Thank you for contributing to **gitanimals** under the **git-goods** organization. A maintainer will review your PR shortly. 🎉`, + ``, + `### Please ensure:`, + `- You’ve read the README.md, CONTRIBUTING.md, and CODE_OF_CONDUCT.md.`, + ].join("\n"); const gif = "![TrustTheProcess](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExbWtoOWpsMnozdXd0MmJxejhiNGwwdjltY3dyNW80NHg2Ym01YTdlMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/mPKa6OI5oRsmextwBq/giphy.gif)"; @@ -90,7 +92,7 @@ Thank you for contributing to **gitanimals** under the **git-goods** organizatio core.info(`Comment already exists for PR #${prNumber}, skipping.`); } - const headRepoFull = pr.head?.repo?.full_name || ''; + const headRepoFull = pr.head?.repo?.full_name || ""; const baseFull = `${repo.owner}/${repo.repo}`; const isFork = headRepoFull.toLowerCase() !== baseFull.toLowerCase(); const labels = ["needs-review"]; @@ -104,11 +106,14 @@ Thank you for contributing to **gitanimals** under the **git-goods** organizatio if (context.payload.issue) { const issue = context.payload.issue; const issueNumber = issue.number; - const user = issue.user?.login || 'contributor'; - - const message = `👋 Hi @${user}! - -Thanks for opening an issue in **gitanimals** (git-goods org). We’ll review it soon — please ensure reproduction steps and logs are included.`; + const user = issue.user?.login || "contributor"; + + const message = [ + `👋 Hi @${user}!`, + ``, + `Thanks for opening an issue in **gitanimals** (git-goods org).`, + `We’ll review it soon — please ensure that the PR is meaningful.` + ].join("\n"); if (!(await commentExists(issueNumber, "Thanks for opening an issue in **gitanimals**"))) { await github.rest.issues.createComment({