mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-06 00:45:22 +08:00
Some checks failed
ToolsCI / Tools (push) Has been cancelled
pkgs_test / change (push) Has been cancelled
utest_auto_run / A9 :components/dfs.cfg (push) Has been cancelled
utest_auto_run / A9 :components/lwip.cfg (push) Has been cancelled
utest_auto_run / A9 :components/netdev.cfg (push) Has been cancelled
utest_auto_run / A9 :components/sal.cfg (push) Has been cancelled
utest_auto_run / A9 :cpp11/cpp11.cfg (push) Has been cancelled
utest_auto_run / AARCH64-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / A9-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / RISCV-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / XUANTIE-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / AARCH64 :default.cfg (push) Has been cancelled
utest_auto_run / A9 :default.cfg (push) Has been cancelled
utest_auto_run / A9-smp :default.cfg (push) Has been cancelled
utest_auto_run / RISCV :default.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/atomic_c11.cfg (push) Has been cancelled
utest_auto_run / RISCV :kernel/atomic_c11.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/ipc.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/kernel_basic.cfg (push) Has been cancelled
utest_auto_run / A9 :kernel/mem.cfg (push) Has been cancelled
utest_auto_run / post-ci-status (push) Has been cancelled
304 lines
11 KiB
YAML
304 lines
11 KiB
YAML
#
|
|
# Copyright (c) 2025, RT-Thread Development Team
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Change Logs:
|
|
# Date Author Notes
|
|
# 2025-10-27 GitHub Copilot Post CI results to PR comments
|
|
|
|
name: CI Results Comment
|
|
|
|
# on:
|
|
# workflow_run:
|
|
# workflows:
|
|
# - "RT-Thread BSP Static Build Check"
|
|
# - "Static code analysis"
|
|
# - "Check File Format and License"
|
|
# - "utest_auto_run"
|
|
# - "ToolsCI"
|
|
# - "pkgs_test"
|
|
# types:
|
|
# - completed
|
|
|
|
permissions:
|
|
pull-requests: write
|
|
issues: write
|
|
actions: read
|
|
checks: read
|
|
|
|
jobs:
|
|
comment-ci-results:
|
|
runs-on: ubuntu-22.04
|
|
if: github.event.workflow_run.event == 'pull_request' && github.repository_owner == 'RT-Thread'
|
|
steps:
|
|
- name: Get PR number
|
|
id: get-pr
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
// Get PR number from workflow_run
|
|
const prNumber = context.payload.workflow_run.pull_requests[0]?.number;
|
|
if (!prNumber) {
|
|
console.log('No PR found in workflow_run');
|
|
// Fallback: search for PR by branch
|
|
const pulls = await github.rest.pulls.list({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
state: 'open',
|
|
head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`
|
|
});
|
|
|
|
if (pulls.data.length === 0) {
|
|
console.log('No open PR found for this branch');
|
|
return null;
|
|
}
|
|
|
|
const pr = pulls.data[0];
|
|
console.log(`Found PR #${pr.number}`);
|
|
return pr.number;
|
|
}
|
|
|
|
console.log(`Found PR #${prNumber}`);
|
|
return prNumber;
|
|
|
|
- name: Get workflow run details
|
|
if: steps.get-pr.outputs.result != 'null'
|
|
id: workflow-details
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const prNumber = ${{ steps.get-pr.outputs.result }};
|
|
if (!prNumber) {
|
|
return { success: false, message: 'No PR found' };
|
|
}
|
|
|
|
// Get all workflow runs for this PR
|
|
const workflowRuns = await github.rest.actions.listWorkflowRunsForRepo({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
event: 'pull_request',
|
|
per_page: 100
|
|
});
|
|
|
|
// Filter runs for this specific PR
|
|
const prRuns = workflowRuns.data.workflow_runs.filter(run => {
|
|
return run.pull_requests.some(pr => pr.number === prNumber);
|
|
});
|
|
|
|
// Get the latest run for each workflow
|
|
const workflowMap = new Map();
|
|
for (const run of prRuns) {
|
|
const existing = workflowMap.get(run.name);
|
|
if (!existing || new Date(run.created_at) > new Date(existing.created_at)) {
|
|
workflowMap.set(run.name, run);
|
|
}
|
|
}
|
|
|
|
// Prepare results summary
|
|
const results = [];
|
|
for (const [name, run] of workflowMap) {
|
|
let status = '🟡';
|
|
let statusText = 'In Progress';
|
|
|
|
if (run.status === 'completed') {
|
|
if (run.conclusion === 'success') {
|
|
status = '✅';
|
|
statusText = 'Success';
|
|
} else if (run.conclusion === 'failure') {
|
|
status = '❌';
|
|
statusText = 'Failure';
|
|
} else if (run.conclusion === 'cancelled') {
|
|
status = '⏭️';
|
|
statusText = 'Cancelled';
|
|
} else if (run.conclusion === 'skipped') {
|
|
status = '⏭️';
|
|
statusText = 'Skipped';
|
|
}
|
|
} else if (run.status === 'queued') {
|
|
status = '🟠';
|
|
statusText = 'Queued';
|
|
}
|
|
|
|
results.push({
|
|
name: name,
|
|
status: status,
|
|
statusText: statusText,
|
|
url: run.html_url,
|
|
conclusion: run.conclusion,
|
|
runId: run.id
|
|
});
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
results: results,
|
|
prNumber: prNumber
|
|
};
|
|
|
|
- name: Get job details
|
|
if: steps.get-pr.outputs.result != 'null'
|
|
id: job-details
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const workflowDetails = ${{ steps.workflow-details.outputs.result }};
|
|
if (!workflowDetails || !workflowDetails.success) {
|
|
return { jobs: [] };
|
|
}
|
|
|
|
const allJobs = [];
|
|
|
|
for (const result of workflowDetails.results) {
|
|
try {
|
|
const jobs = await github.rest.actions.listJobsForWorkflowRun({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
run_id: result.runId,
|
|
per_page: 100
|
|
});
|
|
|
|
for (const job of jobs.data.jobs) {
|
|
let jobStatus = '⌛';
|
|
if (job.status === 'completed') {
|
|
if (job.conclusion === 'success') {
|
|
jobStatus = '✅';
|
|
} else if (job.conclusion === 'failure') {
|
|
jobStatus = '❌';
|
|
} else if (job.conclusion === 'skipped') {
|
|
jobStatus = '⏭️';
|
|
}
|
|
} else if (job.status === 'in_progress') {
|
|
jobStatus = '🔄';
|
|
} else if (job.status === 'queued') {
|
|
jobStatus = '🟠';
|
|
}
|
|
|
|
allJobs.push({
|
|
workflow: result.name,
|
|
name: job.name,
|
|
status: jobStatus,
|
|
conclusion: job.conclusion || job.status,
|
|
url: job.html_url
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.log(`Error getting jobs for workflow ${result.name}: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
return { jobs: allJobs };
|
|
|
|
- name: Post or update comment
|
|
if: steps.get-pr.outputs.result != 'null'
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const prNumber = ${{ steps.get-pr.outputs.result }};
|
|
const workflowDetails = ${{ steps.workflow-details.outputs.result }};
|
|
const jobDetails = ${{ steps.job-details.outputs.result }};
|
|
|
|
if (!workflowDetails || !workflowDetails.success) {
|
|
console.log('No workflow details available');
|
|
return;
|
|
}
|
|
|
|
// Prepare comment body
|
|
const now = new Date();
|
|
const timestamp = now.toISOString();
|
|
const results = workflowDetails.results;
|
|
const jobs = jobDetails.jobs || [];
|
|
|
|
let commentBody = '<!-- CI Results Comment -->\n';
|
|
commentBody += '## 🤖 CI Test Results\n\n';
|
|
commentBody += `**Last Updated:** ${timestamp}\n\n`;
|
|
commentBody += '### Test Spec & Results:\n\n';
|
|
commentBody += '✅ Success | ❌ Failure | 🟠 Queued | 🟡 Progress | ⏭️ Skipped | ⚠️ Quarantine\n\n';
|
|
|
|
// Group jobs by workflow
|
|
const jobsByWorkflow = new Map();
|
|
for (const job of jobs) {
|
|
if (!jobsByWorkflow.has(job.workflow)) {
|
|
jobsByWorkflow.set(job.workflow, []);
|
|
}
|
|
jobsByWorkflow.get(job.workflow).push(job);
|
|
}
|
|
|
|
// Calculate overall statistics
|
|
let totalSuccess = 0;
|
|
let totalFailure = 0;
|
|
let totalQueued = 0;
|
|
let totalProgress = 0;
|
|
let totalSkipped = 0;
|
|
|
|
for (const result of results) {
|
|
if (result.conclusion === 'success') totalSuccess++;
|
|
else if (result.conclusion === 'failure') totalFailure++;
|
|
else if (result.statusText === 'Queued') totalQueued++;
|
|
else if (result.statusText === 'In Progress') totalProgress++;
|
|
else if (result.conclusion === 'skipped' || result.conclusion === 'cancelled') totalSkipped++;
|
|
}
|
|
|
|
// Summary line
|
|
commentBody += '#### Overall Summary\n\n';
|
|
commentBody += `- ✅ **Success:** ${totalSuccess}\n`;
|
|
commentBody += `- ❌ **Failure:** ${totalFailure}\n`;
|
|
commentBody += `- 🟠 **Queued:** ${totalQueued}\n`;
|
|
commentBody += `- 🟡 **In Progress:** ${totalProgress}\n`;
|
|
commentBody += `- ⏭️ **Skipped:** ${totalSkipped}\n\n`;
|
|
|
|
commentBody += '---\n\n';
|
|
commentBody += '### Detailed Results\n\n';
|
|
|
|
// Build detailed results
|
|
for (const result of results) {
|
|
commentBody += `<details>\n`;
|
|
commentBody += `<summary>${result.status} <strong>${result.name}</strong> - ${result.statusText}</summary>\n\n`;
|
|
commentBody += `**Workflow:** [${result.name}](${result.url})\n\n`;
|
|
|
|
// Show jobs for this workflow
|
|
const workflowJobs = jobsByWorkflow.get(result.name) || [];
|
|
if (workflowJobs.length > 0) {
|
|
commentBody += '**Jobs:**\n\n';
|
|
for (const job of workflowJobs) {
|
|
commentBody += `- ${job.status} [${job.name}](${job.url})\n`;
|
|
}
|
|
}
|
|
commentBody += '\n</details>\n\n';
|
|
}
|
|
|
|
commentBody += '\n---\n';
|
|
commentBody += '*🤖 This comment is automatically generated and updated by the CI system.*\n';
|
|
|
|
// Check if comment already exists
|
|
const comments = await github.rest.issues.listComments({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: prNumber
|
|
});
|
|
|
|
const existingComment = comments.data.find(comment =>
|
|
comment.user.login === 'github-actions[bot]' &&
|
|
comment.body.includes('<!-- CI Results Comment -->')
|
|
);
|
|
|
|
if (existingComment) {
|
|
// Update existing comment
|
|
await github.rest.issues.updateComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
comment_id: existingComment.id,
|
|
body: commentBody
|
|
});
|
|
console.log(`Updated comment ${existingComment.id} on PR #${prNumber}`);
|
|
} else {
|
|
// Create new comment
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: prNumber,
|
|
body: commentBody
|
|
});
|
|
console.log(`Created new comment on PR #${prNumber}`);
|
|
}
|