From 894898f84c4ac0a89f24bf7bee6c381eb0e67f51 Mon Sep 17 00:00:00 2001 From: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com> Date: Sat, 12 Sep 2026 01:16:17 +0530 Subject: [PATCH] ci: welcome first-time contributors after merge (#7397) * ci: welcome first-time contributors after merge * ci: welcome first-time contributors after merge * ci: support fork contributor welcome comments * ci: minimize contributor welcome permissions --- .../workflows/first-contributor-welcome.yml | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 .github/workflows/first-contributor-welcome.yml diff --git a/.github/workflows/first-contributor-welcome.yml b/.github/workflows/first-contributor-welcome.yml new file mode 100644 index 000000000..69c153db8 --- /dev/null +++ b/.github/workflows/first-contributor-welcome.yml @@ -0,0 +1,88 @@ +name: Welcome First-Time Contributors + +on: + pull_request_target: + types: [closed] + +permissions: + contents: read + issues: write + +jobs: + welcome: + # Match the first-time contributor definition used by ftc-require-issue. + if: > + github.event.pull_request.merged == true && + github.event.pull_request.user.type != 'Bot' && + !contains(fromJSON('["MEMBER","OWNER","COLLABORATOR","CONTRIBUTOR"]'), + github.event.pull_request.author_association) + runs-on: ubuntu-latest + steps: + - name: Thank first-time contributors + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + const pullRequest = context.payload.pull_request; + const owner = context.repo.owner; + const repo = context.repo.repo; + const marker = ""; + + const existingComments = await github.paginate( + github.rest.issues.listComments, + { + owner, + repo, + issue_number: pullRequest.number, + per_page: 100, + }, + ); + if (existingComments.some((comment) => comment.body?.includes(marker))) { + core.info("Welcome comment already exists; skipping duplicate."); + return; + } + + const prUrl = pullRequest.html_url; + const shareText = [ + "I just made my first contribution to @crewAIInc!", + "", + "Excited to help build the future of AI agents with CrewAI.", + "", + prUrl, + "", + "#OpenSource #AI #CrewAI", + ].join("\n"); + const xShareUrl = `https://x.com/intent/post?text=${encodeURIComponent(shareText)}`; + const linkedInShareUrl = `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(prUrl)}`; + + const body = [ + marker, + "", + `## Thanks for your first contribution to CrewAI, @${pullRequest.user.login}!`, + "", + "We really appreciate the time and care you put into this PR. Your work is now part of CrewAI — welcome to the contributor community.", + "", + "Want to share your contribution? Totally optional:", + "", + `[Share on X](${xShareUrl}) · [Share the PR on LinkedIn](${linkedInShareUrl})`, + "", + "If the links don't work, feel free to copy and personalize this:", + "", + "```text", + "I just made my first contribution to @crewAIInc!", + "", + "Excited to help build the future of AI agents with CrewAI.", + "", + prUrl, + "", + "#OpenSource #AI #CrewAI", + "```", + "", + "If you share, we'd love to see it — tag **@crewAIInc** on X and **CrewAI** on LinkedIn.", + ].join("\n"); + + await github.rest.issues.createComment({ + owner, + repo, + issue_number: pullRequest.number, + body, + });