0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-06-06 22:09:08 +02:00

ci(workflows): add AgentScan workflow to flag possible AI-assisted PRs (#37962)

This PR adds an automated AgentScan workflow to help detect and handle
pull requests that appear to be created or authored primarily by
automated agents.

- If a PR is classified as `automation` or community-flagged, the
workflow:
  - Adds the `possible bot` label,
- Posts a policy comment linking to the repository AI Contribution
Policy (`CONTRIBUTING.md#ai-contribution-policy`) and listing required
disclosures and checks,
- Optionally closes the PR if classification indicates an
automated/unwelcome submission.
This commit is contained in:
bircni 2026-06-05 23:33:40 +02:00 committed by GitHub
parent aa63d1583d
commit 3659b5acc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

113
.github/workflows/agent-scan.yml vendored Normal file
View File

@ -0,0 +1,113 @@
name: AgentScan
on:
# jobs only use pinned actions and never checkout code
pull_request_target: # zizmor: ignore[dangerous-triggers]
types: [opened, reopened, synchronize, edited]
concurrency:
group: agent-scan-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
issues: write
pull-requests: write
jobs:
agentscan:
runs-on: ubuntu-latest
steps:
- name: AgentScan
id: agentscan
uses: MatteoGabriele/agentscan-action@0a0c88109b5153dff2805f969f5060441efb7b65
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
skip-members: "dependabot[bot],renovate[bot], giteabot (backports)"
agent-scan-comment: false
- name: Handle flagged PR
if: contains(fromJSON('["automation","mixed"]'), steps.agentscan.outputs.classification) || steps.agentscan.outputs.community-flagged == 'true'
env:
CLASSIFICATION: ${{ steps.agentscan.outputs.classification }}
COMMUNITY_FLAGGED: ${{ steps.agentscan.outputs.community-flagged }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
with:
script: |
const core = require('@actions/core');
const prNumber = context.payload.pull_request.number;
const classification = process.env.CLASSIFICATION;
const communityFlagged = process.env.COMMUNITY_FLAGGED === 'true';
const shouldClose = classification === 'automation' || communityFlagged;
const issue = context.payload.pull_request;
const labels = issue.labels?.map(l => l.name) || [];
if (!labels.includes('possible bot')) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: ['possible bot'],
});
}
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
per_page: 100,
});
const alreadyCommented = comments.some(c => c.user.type === 'Bot' && c.body.includes('AI Contribution Policy'));
if (!alreadyCommented) {
const closingNote = shouldClose
? "We're closing this for now as the account looks automated. If we got that wrong, please just reopen the PR and we'll take another look."
: 'If this was flagged in error, we apologise! 😳 Just let us know. 🙏';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: [
"We've flagged this pull request as potentially AI-assisted.",
'',
'Gitea welcomes the thoughtful use of AI tools, but contributors must use them responsibly and clearly disclose any assistance. Please follow the AI Contribution Policy in `CONTRIBUTING.md` and update this PR accordingly:',
'',
'Maintainers may close PRs that do not disclose AI assistance, appear to be low-quality AI-generated content, or where the contributor cannot explain the changes.',
'',
'See: https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md#ai-contribution-policy',
'',
closingNote,
].join('\n'),
});
} else {
core.info('Possible-bot comment already exists - skipping comment.');
}
if (shouldClose && issue.state === 'open' && !alreadyCommented) {
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
state: 'closed',
title: '🚨 unwelcome pr from bot 🚨',
});
}
const actionTaken = [
'Added `possible bot` label',
alreadyCommented ? null : 'posted policy comment',
shouldClose && !alreadyCommented ? 'closed PR' : null,
].filter(Boolean).join(', ');
core.summary
.addHeading('AgentScan: Possible Bot Flag', 2)
.addTable([
[{ data: 'Property', header: true }, { data: 'Value', header: true }],
['Pull Request', `#${prNumber}`],
['Classification', classification],
['Community flagged', String(communityFlagged)],
['Action', actionTaken || 'No action (already handled)'],
])
.write();