Skip to content

refactor(llm): unify agent tool loop + built-in provider presets #589

refactor(llm): unify agent tool loop + built-in provider presets

refactor(llm): unify agent tool loop + built-in provider presets #589

Workflow file for this run

# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
name: Pull requests Check
on:
pull_request:
branches: [ "master" ]
push:
branches: [ "dev" ]
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- name: Clear NuGet cache
run: dotnet nuget locals all --clear
- name: Restore dependencies
run: dotnet restore --force --no-cache
- name: Build
run: dotnet build --no-restore --configuration Release
- name: Check code formatting
if: matrix.os == 'windows-latest' && false
run: dotnet format --verify-no-changes
- name: Run security analysis
if: matrix.os == 'windows-latest'
run: dotnet list package --vulnerable --include-transitive
- name: Test
run: dotnet test --no-build --verbosity normal --configuration Release --filter "Category!=Performance" --collect:"XPlat Code Coverage" --logger "trx;LogFileName=test-results.trx"
- name: Upload coverage to Codecov
if: matrix.os == 'windows-latest'
uses: codecov/codecov-action@v5
with:
file: ./**/TestResults/**/*.xml
flags: pr-check
name: pr-${{ github.event.number }}-${{ matrix.os }}
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.os }}
path: |
**/TestResults/**/*.trx
**/TestResults/**/*.xml
if-no-files-found: error
report:
needs: build
runs-on: ubuntu-latest
if: always() && github.event_name == 'pull_request'
permissions:
actions: read
contents: read
issues: write
pull-requests: write
steps:
- name: Generate PR report
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const owner = context.repo.owner;
const repo = context.repo.repo;
const runId = context.runId;
const { data: jobsResponse } = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: runId,
per_page: 100
});
const { data: artifactsResponse } = await github.rest.actions.listWorkflowRunArtifacts({
owner,
repo,
run_id: runId,
per_page: 100
});
const artifactNames = new Set((artifactsResponse.artifacts || []).map(artifact => artifact.name));
const jobs = jobsResponse.jobs || [];
function findJob(osName) {
return jobs.find(job => job.name === `build (${osName})`);
}
function formatPlatformRow(label, osName) {
const job = findJob(osName);
if (!job) {
return `| ${label} | Unknown | No matching job found |`;
}
const testStep = (job.steps || []).find(step => step.name === 'Test');
const buildStep = (job.steps || []).find(step => step.name === 'Build');
const uploadStep = (job.steps || []).find(step => step.name === 'Upload test results');
const artifactName = `test-results-${osName}`;
const hasArtifact = artifactNames.has(artifactName);
const jobLink = job.html_url;
if (job.conclusion === 'success') {
let detail = 'Build and test passed';
if (testStep?.conclusion === 'success' && hasArtifact) {
detail = 'Tests passed, artifacts uploaded';
} else if (testStep?.conclusion === 'success') {
detail = 'Tests passed, no artifacts detected';
}
return `| ${label} | Passed | [${detail}](${jobLink}) |`;
}
if (testStep?.conclusion === 'failure') {
return `| ${label} | Failed | [Test step failed](${jobLink}) |`;
}
if (buildStep?.conclusion === 'failure') {
return `| ${label} | Failed | [Build step failed](${jobLink}) |`;
}
if (uploadStep?.conclusion === 'failure') {
return `| ${label} | Error | [Artifact upload failed](${jobLink}) |`;
}
if (job.conclusion === 'cancelled') {
return `| ${label} | Cancelled | [Job was cancelled](${jobLink}) |`;
}
if (job.status !== 'completed') {
return `| ${label} | Running | [Job still in progress](${jobLink}) |`;
}
return `| ${label} | Error | [Conclusion: ${job.conclusion || 'unknown'}](${jobLink}) |`;
}
const reportLines = [
'# PR Check Report',
'',
'## Summary',
`- **PR**: #${context.payload.pull_request.number}`,
`- **Branch**: ${context.payload.pull_request.head.ref} <- ${context.payload.pull_request.base.ref}`,
`- **Event**: ${context.eventName}`,
`- **Commit**: ${context.sha}`,
'',
'## Test Results',
'| Platform | Status | Details |',
'|------|------|------|',
formatPlatformRow('Ubuntu', 'ubuntu-latest'),
formatPlatformRow('Windows', 'windows-latest'),
'',
'## Code Quality',
'- Code formatting check',
'- Security vulnerability scan',
'- Dependency analysis',
'- Code coverage collection',
'',
'## Test Artifacts',
`- Test results artifacts count: ${artifactNames.size}`,
'- Code coverage uploaded to Codecov',
'',
'## Links',
`- [PR Page](${context.payload.pull_request.html_url})`,
`- [Actions Logs](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId})`,
'',
'---',
'*This report is auto-generated by GitHub Actions*'
];
fs.writeFileSync('pr-report.md', `${reportLines.join('\n')}\n`, 'utf8');
- name: Publish report summary
if: always()
run: cat pr-report.md >> "$GITHUB_STEP_SUMMARY"
- name: Find existing comment
if: always() && github.actor != 'dependabot[bot]' && github.event.pull_request.head.repo.full_name == github.repository
uses: actions/github-script@v7
id: find-comment
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('PR Check Report')
);
return botComment?.id;
- name: Create or update comment
if: always() && github.actor != 'dependabot[bot]' && github.event.pull_request.head.repo.full_name == github.repository
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const reportPath = './pr-report.md';
const report = fs.readFileSync(reportPath, 'utf8');
const commentId = '${{ steps.find-comment.outputs.result }}';
if (commentId) {
await github.rest.issues.updateComment({
comment_id: commentId,
owner: context.repo.owner,
repo: context.repo.repo,
body: report
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: report
});
}