From 1ee89c0dbc0c70c7575d0f0a4e130258feb93933 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Tue, 25 Aug 2026 10:27:07 +0200 Subject: [PATCH 1/3] tools: welcome first-time contributors Add contribution guidance and an advisory AgentScan warning for first-time pull request authors. Signed-off-by: Filip Skokan --- .github/workflows/first-time-contributor.yml | 117 +++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 .github/workflows/first-time-contributor.yml diff --git a/.github/workflows/first-time-contributor.yml b/.github/workflows/first-time-contributor.yml new file mode 100644 index 000000000000..c1cdae726e54 --- /dev/null +++ b/.github/workflows/first-time-contributor.yml @@ -0,0 +1,117 @@ +name: Welcome first-time contributors + +on: + pull_request_target: + types: [opened] + +permissions: {} + +jobs: + agentscan: + if: >- + github.repository == 'nodejs/node' && + (github.event.pull_request.author_association == 'FIRST_TIMER' || + github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR') + runs-on: ubuntu-slim + permissions: + contents: read + outputs: + scan_outcome: ${{ steps.agentscan.outcome }} + classification: ${{ steps.agentscan.outputs.classification }} + community_flagged: ${{ steps.agentscan.outputs['community-flagged'] }} + steps: + - name: Scan contributor activity + id: agentscan + # The welcome should still be posted if this advisory scan fails. + continue-on-error: true + uses: MatteoGabriele/agentscan-action@98202262c925c508d4c1424b1dfbe17ee35b0c02 # v2.4.0 + with: + github-token: ${{ github.token }} + mode: silent + scan-pull-requests: true + scan-issues: false + auto-close: false + honeypot: false + + comment: + needs: agentscan + runs-on: ubuntu-slim + permissions: + pull-requests: write + steps: + - name: Welcome first-time contributor + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + AGENTSCAN_OUTCOME: ${{ needs.agentscan.outputs.scan_outcome }} + AGENTSCAN_CLASSIFICATION: ${{ needs.agentscan.outputs.classification }} + AGENTSCAN_COMMUNITY_FLAGGED: ${{ needs.agentscan.outputs.community_flagged }} + with: + github-token: ${{ github.token }} + script: | + const marker = ''; + const author = context.payload.pull_request.user.login; + const body = [ + marker, + '', + 'Welcome to Node.js, and thank you for your first contribution!', + '', + 'Before review, please take a moment to read:', + '', + '* the [guide for first-time contributors](https://github.com/nodejs/node/blob/HEAD/doc/contributing/first-contributions.md)', + '* the [contribution and automation policies](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md)', + '* the [pull request guide](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md)', + '* the [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md)', + '* the [Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md)', + '', + 'Please make sure every commit is [signed off](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#step-4-commit). For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal.', + ]; + + const classification = process.env.AGENTSCAN_CLASSIFICATION; + // AgentScan also marks insufficient-data results as flagged, so use + // the specific classifications that warrant a maintainer caution. + const shouldCaution = process.env.AGENTSCAN_OUTCOME === 'success' && + (process.env.AGENTSCAN_COMMUNITY_FLAGGED === 'true' || + classification === 'mixed' || classification === 'automation'); + + if (shouldCaution) { + const profile = `https://agentscan.tools/user/${encodeURIComponent(author)}`; + body.push( + '', + '> [!CAUTION]', + '> **Maintainer note:** AgentScan found account activity patterns that may be consistent with automation.', + '> This is a heuristic, not proof that this pull request was opened by an agent or violates policy.', + '> AI-assisted contributions are permitted, but automated tooling must not open pull requests without', + '> advance approval, and contributors must personally understand, test, verify, and take responsibility', + '> for every submitted change. Review the [AgentScan analysis](' + profile + '),', + '> [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md), and', + '> [automation policy](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md#automation-and-bots)', + '> before acting.', + ); + } + + const { owner, repo } = context.repo; + const issue_number = context.payload.pull_request.number; + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number, + per_page: 100, + }); + const existing = comments.find((comment) => + comment.user?.login === 'github-actions[bot]' && + comment.body?.includes(marker)); + const comment = { owner, repo, body: body.join('\n') }; + + if (existing) { + await github.rest.issues.updateComment({ + ...comment, + comment_id: existing.id, + }); + core.info(`Updated guidance comment on pull request #${issue_number}`); + } else { + await github.rest.issues.createComment({ + ...comment, + issue_number, + }); + core.info(`Created guidance comment on pull request #${issue_number}`); + } From 699b75c8d213d9f2f26369d0a76caa94dc0ceb45 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Tue, 25 Aug 2026 17:48:01 +0200 Subject: [PATCH 2/3] fixup! tools: welcome first-time contributors --- .github/workflows/first-time-contributor.yml | 106 +++++++------------ 1 file changed, 39 insertions(+), 67 deletions(-) diff --git a/.github/workflows/first-time-contributor.yml b/.github/workflows/first-time-contributor.yml index c1cdae726e54..7d329e77843f 100644 --- a/.github/workflows/first-time-contributor.yml +++ b/.github/workflows/first-time-contributor.yml @@ -9,6 +9,7 @@ permissions: {} jobs: agentscan: if: >- + github.run_attempt == 1 && github.repository == 'nodejs/node' && (github.event.pull_request.author_association == 'FIRST_TIMER' || github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR') @@ -40,78 +41,49 @@ jobs: pull-requests: write steps: - name: Welcome first-time contributor - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NUMBER: ${{ github.event.pull_request.number }} AGENTSCAN_OUTCOME: ${{ needs.agentscan.outputs.scan_outcome }} AGENTSCAN_CLASSIFICATION: ${{ needs.agentscan.outputs.classification }} AGENTSCAN_COMMUNITY_FLAGGED: ${{ needs.agentscan.outputs.community_flagged }} - with: - github-token: ${{ github.token }} - script: | - const marker = ''; - const author = context.payload.pull_request.user.login; - const body = [ - marker, - '', - 'Welcome to Node.js, and thank you for your first contribution!', - '', - 'Before review, please take a moment to read:', - '', - '* the [guide for first-time contributors](https://github.com/nodejs/node/blob/HEAD/doc/contributing/first-contributions.md)', - '* the [contribution and automation policies](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md)', - '* the [pull request guide](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md)', - '* the [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md)', - '* the [Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md)', - '', - 'Please make sure every commit is [signed off](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#step-4-commit). For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal.', - ]; + WELCOME_MESSAGE: | + Welcome to Node.js, and thank you for your first contribution! - const classification = process.env.AGENTSCAN_CLASSIFICATION; - // AgentScan also marks insufficient-data results as flagged, so use - // the specific classifications that warrant a maintainer caution. - const shouldCaution = process.env.AGENTSCAN_OUTCOME === 'success' && - (process.env.AGENTSCAN_COMMUNITY_FLAGGED === 'true' || - classification === 'mixed' || classification === 'automation'); + Before review, please take a moment to read: - if (shouldCaution) { - const profile = `https://agentscan.tools/user/${encodeURIComponent(author)}`; - body.push( - '', - '> [!CAUTION]', - '> **Maintainer note:** AgentScan found account activity patterns that may be consistent with automation.', - '> This is a heuristic, not proof that this pull request was opened by an agent or violates policy.', - '> AI-assisted contributions are permitted, but automated tooling must not open pull requests without', - '> advance approval, and contributors must personally understand, test, verify, and take responsibility', - '> for every submitted change. Review the [AgentScan analysis](' + profile + '),', - '> [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md), and', - '> [automation policy](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md#automation-and-bots)', - '> before acting.', - ); - } + * the [guide for first-time contributors](https://github.com/nodejs/node/blob/HEAD/doc/contributing/first-contributions.md) + * the [contribution and automation policies](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md) + * the [pull request guide](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md) + * the [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md) + * the [Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md) - const { owner, repo } = context.repo; - const issue_number = context.payload.pull_request.number; - const comments = await github.paginate(github.rest.issues.listComments, { - owner, - repo, - issue_number, - per_page: 100, - }); - const existing = comments.find((comment) => - comment.user?.login === 'github-actions[bot]' && - comment.body?.includes(marker)); - const comment = { owner, repo, body: body.join('\n') }; + Please make sure every commit is [signed off](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#step-4-commit). For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal. + CAUTION_MESSAGE: | + > [!CAUTION] + > **Maintainer note:** AgentScan found account activity patterns that may be consistent with automation. + > This is a heuristic, not proof that this pull request was opened by an agent or violates policy. + > AI-assisted contributions are permitted, but automated tooling must not open pull requests without + > advance approval, and contributors must personally understand, test, verify, and take responsibility + > for every submitted change. Review the [AgentScan analysis](https://agentscan.tools/user/${{ github.event.pull_request.user.login }}), + > [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md), and + > [automation policy](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md#automation-and-bots) + > before acting. + run: | + add_caution=false + if [[ "$AGENTSCAN_OUTCOME" == "success" ]]; then + case "$AGENTSCAN_CLASSIFICATION" in + mixed|automation) + add_caution=true + ;; + esac + if [[ "$AGENTSCAN_COMMUNITY_FLAGGED" == "true" ]]; then + add_caution=true + fi + fi - if (existing) { - await github.rest.issues.updateComment({ - ...comment, - comment_id: existing.id, - }); - core.info(`Updated guidance comment on pull request #${issue_number}`); - } else { - await github.rest.issues.createComment({ - ...comment, - issue_number, - }); - core.info(`Created guidance comment on pull request #${issue_number}`); - } + if [[ "$add_caution" == "true" ]]; then + printf '%s\n\n%s\n' "$WELCOME_MESSAGE" "$CAUTION_MESSAGE" + else + printf '%s\n' "$WELCOME_MESSAGE" + fi | gh pr comment "$NUMBER" --repo "$GITHUB_REPOSITORY" --body-file - From 43f53ef4f96f0d4d4994285b65a4a1ffb2a5d2ab Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Tue, 25 Aug 2026 18:46:17 +0200 Subject: [PATCH 3/3] fixup! tools: welcome first-time contributors --- .github/workflows/first-time-contributor.yml | 42 ++++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/.github/workflows/first-time-contributor.yml b/.github/workflows/first-time-contributor.yml index 7d329e77843f..0a81a4ac2c3b 100644 --- a/.github/workflows/first-time-contributor.yml +++ b/.github/workflows/first-time-contributor.yml @@ -47,28 +47,36 @@ jobs: AGENTSCAN_OUTCOME: ${{ needs.agentscan.outputs.scan_outcome }} AGENTSCAN_CLASSIFICATION: ${{ needs.agentscan.outputs.classification }} AGENTSCAN_COMMUNITY_FLAGGED: ${{ needs.agentscan.outputs.community_flagged }} - WELCOME_MESSAGE: | - Welcome to Node.js, and thank you for your first contribution! + WELCOME_MESSAGE: >2- + Welcome to Node.js, and thank you for your first contribution! Before review, please take a moment to read: - * the [guide for first-time contributors](https://github.com/nodejs/node/blob/HEAD/doc/contributing/first-contributions.md) - * the [contribution and automation policies](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md) - * the [pull request guide](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md) - * the [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md) - * the [Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md) + * the [guide for first-time contributors](https://github.com/nodejs/node/blob/HEAD/doc/contributing/first-contributions.md) + * the [contribution and automation policies](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md) + * the [pull request guide](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md) + * the [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md) + * the [Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md) - Please make sure every commit is [signed off](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#step-4-commit). For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal. - CAUTION_MESSAGE: | + Please make sure every commit is + [signed off](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#step-4-commit). + For a first pull request, GitHub Actions require collaborator + approval and Jenkins CI must be started by a collaborator or triager, + so an initial wait is normal. + CAUTION_MESSAGE: >- > [!CAUTION] - > **Maintainer note:** AgentScan found account activity patterns that may be consistent with automation. - > This is a heuristic, not proof that this pull request was opened by an agent or violates policy. - > AI-assisted contributions are permitted, but automated tooling must not open pull requests without - > advance approval, and contributors must personally understand, test, verify, and take responsibility - > for every submitted change. Review the [AgentScan analysis](https://agentscan.tools/user/${{ github.event.pull_request.user.login }}), - > [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md), and - > [automation policy](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md#automation-and-bots) - > before acting. + + > AgentScan found account activity patterns that may be consistent with + automation. This is a heuristic, not proof that this pull request was + opened by an agent or violates policy. AI-assisted contributions are + permitted, but automated tooling must not open pull requests without + advance approval, and contributors must personally understand, test, + verify, and take responsibility for every submitted change. See the + [AgentScan analysis](https://agentscan.tools/user/${{ github.event.pull_request.user.login }}), + [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md), + and + [automation policy](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md#automation-and-bots) + for additional context. run: | add_caution=false if [[ "$AGENTSCAN_OUTCOME" == "success" ]]; then