agent-scan workflow (nuxt/nuxt)
The agent-scan workflow from nuxt/nuxt, explained and optimized by Latchkey.
A
CI health: A - excellent
Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the agent-scan workflow from the nuxt/nuxt repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
workflow (.yml)
name: agent-scan
on:
# zizmor: ignore[dangerous-triggers] - DO NOT add action/checkout in this workflow as it use pull_request_target
pull_request_target:
types:
- opened
- reopened
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@c7d61446e7aece6bdd3edcee4558bbfc0392615e # v2.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
mode: 'labels'
trusted-author-associations: 'owner, member'
- 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 # v9.0.0
with:
script: |
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-assisted contribution guidelines')
)
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 as a potential contribution without a human behind it. We welcome the thoughtful use of AI tools when contributing to Nuxt, but ask all contributors to follow [two core principles](https://roe.dev/blog/using-ai-in-open-source):",
'',
'1. **Never let an LLM speak for you** - all comments, issues, and PR descriptions should be written in your own words, reflecting your own understanding.',
'2. **Never let an LLM think for you** - only submit contributions you fully understand and can explain.',
'',
'Please review our [AI-assisted contribution guidelines](https://nuxt.com/docs/community/contribution#ai-assisted-contributions) and update this contribution if needed.',
'',
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)'],
])
await core.summary.write()
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: agent-scan on: # zizmor: ignore[dangerous-triggers] - DO NOT add action/checkout in this workflow as it use pull_request_target pull_request_target: types: - opened - reopened concurrency: group: agent-scan-${{ github.event.pull_request.number }} cancel-in-progress: true permissions: issues: write pull-requests: write jobs: agentscan: timeout-minutes: 30 runs-on: latchkey-small steps: - name: AgentScan id: agentscan uses: MatteoGabriele/agentscan-action@c7d61446e7aece6bdd3edcee4558bbfc0392615e # v2.0.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} mode: 'labels' trusted-author-associations: 'owner, member' - 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 # v9.0.0 with: script: | 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-assisted contribution guidelines') ) 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 as a potential contribution without a human behind it. We welcome the thoughtful use of AI tools when contributing to Nuxt, but ask all contributors to follow [two core principles](https://roe.dev/blog/using-ai-in-open-source):", '', '1. **Never let an LLM speak for you** - all comments, issues, and PR descriptions should be written in your own words, reflecting your own understanding.', '2. **Never let an LLM think for you** - only submit contributions you fully understand and can explain.', '', 'Please review our [AI-assisted contribution guidelines](https://nuxt.com/docs/community/contribution#ai-assisted-contributions) and update this contribution if needed.', '', 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)'], ]) await core.summary.write()
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Add a job timeout so a hung step cannot burn hours of runner time.
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.