Weekly CI Scheduler #13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); |