diff options
| author | Yuqiang Wang <[email protected]> | 2025-10-30 09:19:36 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-10-30 09:19:36 +0800 |
| commit | ba509f92c2ab00cbf5a53ec89e1ad35e1eb70614 (patch) | |
| tree | 8bf3a68e324a771b7189172c58da9da86994266a /.github | |
| parent | 666fa243f28811ee017b4d771e0744d2d8e79f44 (diff) | |
[ci]: Introduce a regular inspection mechanism for abnormal CI reports (#10852)
Diffstat (limited to '.github')
| -rw-r--r-- | .github/workflows/bsp_buildings.yml | 9 | ||||
| -rw-r--r-- | .github/workflows/scheduled-ci-trigger.yml | 200 | ||||
| -rw-r--r-- | .github/workflows/utest_auto_run.yml | 7 |
3 files changed, 213 insertions, 3 deletions
diff --git a/.github/workflows/bsp_buildings.yml b/.github/workflows/bsp_buildings.yml index 0ef5fb6185..47647aaff1 100644 --- a/.github/workflows/bsp_buildings.yml +++ b/.github/workflows/bsp_buildings.yml @@ -13,9 +13,6 @@ name: RT-Thread BSP Static Build Check # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the RT-Thread organization master branch on: - # Runs at 16:00 UTC (BeiJing 00:00) every day - schedule: - - cron: '0 16 * * *' push: branches: - master @@ -46,6 +43,12 @@ on: types: - online-pkgs-static-building-trigger-event workflow_dispatch: + inputs: + trigger_type: + description: '触发类型' + required: false + default: 'manual' + type: string concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/.github/workflows/scheduled-ci-trigger.yml b/.github/workflows/scheduled-ci-trigger.yml new file mode 100644 index 0000000000..6616570ff9 --- /dev/null +++ b/.github/workflows/scheduled-ci-trigger.yml @@ -0,0 +1,200 @@ +name: Weekly CI Scheduler + +on: + # Runs at 08:00 Beijing time every day + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + inputs: + debug: + description: 'Debug mode' + required: false + default: 'false' + +env: + TARGET_WORKFLOWS: '["RT-Thread BSP Static Build Check", "utest_auto_run"]' + DISCUSSION_CATEGORY: "Github Action Exception Reports" + +jobs: + trigger-and-monitor: + name: Trigger and Monitor CIs + runs-on: ubuntu-latest + outputs: + failed_workflows: ${{ steps.collect-results.outputs.failed_workflows }} + total_workflows: ${{ steps.collect-results.outputs.total_workflows }} + has_results: ${{ steps.collect-results.outputs.has_results }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install requests + + - name: Record start time + id: start-time + run: | + echo "start_time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + echo "Start time: $(date -u +'%Y-%m-%dT%H:%M:%SZ')" + + - name: Trigger CI workflows directly + id: trigger-ci + run: | + python tools/ci/scheduled-ci-trigger/trigger_workflows_direct.py + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TARGET_WORKFLOWS: ${{ env.TARGET_WORKFLOWS }} + + - name: Wait for workflows to appear + id: wait-for-workflows + run: | + echo "Waiting for workflows to appear in API..." + python tools/ci/scheduled-ci-trigger/wait_for_workflows.py "${{ steps.start-time.outputs.start_time }}" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TARGET_WORKFLOWS: ${{ env.TARGET_WORKFLOWS }} + + - name: Monitor CI workflows + id: monitor-ci + run: | + python tools/ci/scheduled-ci-trigger/monitor_workflows.py "${{ steps.start-time.outputs.start_time }}" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TARGET_WORKFLOWS: ${{ env.TARGET_WORKFLOWS }} + + - name: Collect monitoring results + id: collect-results + run: | + echo "Checking for monitoring results..." + if [ -f "monitoring_results.json" ]; then + echo "monitoring_results.json found" + FAILED_COUNT=$(python -c "import json; data=json.load(open('monitoring_results.json')); print(len([w for w in data if w.get('conclusion') == 'failure']))") + TOTAL_COUNT=$(python -c "import json; data=json.load(open('monitoring_results.json')); print(len(data))") + echo "failed_workflows=$FAILED_COUNT" >> $GITHUB_OUTPUT + echo "total_workflows=$TOTAL_COUNT" >> $GITHUB_OUTPUT + echo "has_results=true" >> $GITHUB_OUTPUT + echo "Results: $FAILED_COUNT failed out of $TOTAL_COUNT total" + else + echo "monitoring_results.json not found" + echo "failed_workflows=0" >> $GITHUB_OUTPUT + echo "total_workflows=0" >> $GITHUB_OUTPUT + echo "has_results=false" >> $GITHUB_OUTPUT + fi + + - name: Generate detailed report + if: steps.collect-results.outputs.has_results == 'true' && steps.collect-results.outputs.failed_workflows != '0' + id: generate-report + run: | + echo "Generating detailed report..." + python tools/ci/scheduled-ci-trigger/generate_report.py + echo "Report generation completed" + + - name: Upload report artifact + if: steps.collect-results.outputs.has_results == 'true' && steps.collect-results.outputs.failed_workflows != '0' + uses: actions/upload-artifact@v4 + with: + name: ci-failure-report + path: | + monitoring_results.json + failure_details.md + retention-days: 7 + + create-discussion: + name: Create Discussion Report + needs: trigger-and-monitor + if: needs.trigger-and-monitor.outputs.has_results == 'true' && needs.trigger-and-monitor.outputs.failed_workflows != '0' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download report artifact + uses: actions/download-artifact@v4 + with: + name: ci-failure-report + + - name: Create Discussion + uses: actions/github-script@v6 + env: + DISCUSSION_CATEGORY: ${{ env.DISCUSSION_CATEGORY }} + with: + script: | + const fs = require('fs'); + + const reportPath = './failure_details.md'; + + let reportContent = fs.readFileSync(reportPath, 'utf8'); + + // 提取日期从第一行: # YYYYMMDD_ci_integration-failed-report + const lines = reportContent.split('\n'); + const firstLine = lines[0].trim(); + const dateMatch = firstLine.match(/# (\d{8})_ci_integration-failed-report/); + + if (!dateMatch) { + console.error('Failed to extract date from first line:', firstLine); + process.exit(1); + } + + const dateString = dateMatch[1]; + const discussionTitle = `${dateString}_ci_integration-failed-report`; + + // === 关键修复:移除第一行(用于提取的隐藏行) === + reportContent = lines.slice(1).join('\n').trim(); + + // 获取仓库ID和分类ID + const getRepoQuery = ` + query($owner: String!, $repo: String!) { + repository(owner: $owner, name: $repo) { + id + discussionCategories(first: 20) { + nodes { + id + name + } + } + } + } + `; + + const repoData = await github.graphql(getRepoQuery, { + owner: context.repo.owner, + repo: context.repo.repo + }); + + const repositoryId = repoData.repository.id; + const categories = repoData.repository.discussionCategories.nodes; + const targetCategory = categories.find(cat => cat.name === process.env.DISCUSSION_CATEGORY); + + if (!targetCategory) { + console.error('Category not found:', process.env.DISCUSSION_CATEGORY); + process.exit(1); + } + + const createDiscussionMutation = ` + mutation($repositoryId: ID!, $categoryId: ID!, $title: String!, $body: String!) { + createDiscussion(input: { + repositoryId: $repositoryId + categoryId: $categoryId + title: $title + body: $body + }) { + discussion { + id + title + url + } + } + } + `; + + const result = await github.graphql(createDiscussionMutation, { + repositoryId: repositoryId, + categoryId: targetCategory.id, + title: discussionTitle, + body: reportContent // 使用清理后的内容(无第一行) + }); + + console.log('Discussion created successfully:', result.createDiscussion.discussion.url);
\ No newline at end of file diff --git a/.github/workflows/utest_auto_run.yml b/.github/workflows/utest_auto_run.yml index a4303ab826..824caffcba 100644 --- a/.github/workflows/utest_auto_run.yml +++ b/.github/workflows/utest_auto_run.yml @@ -18,6 +18,13 @@ on: - documentation/** - '**/README.md' - '**/README_zh.md' + workflow_dispatch: + inputs: + trigger_type: + description: '触发类型' + required: false + default: 'manual' + type: string concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} |
