1+ name : Weekly CI Scheduler
2+
3+ on :
4+ schedule :
5+ - cron : ' 0 0 * * 1'
6+ workflow_dispatch :
7+ inputs :
8+ debug :
9+ description : ' Debug mode'
10+ required : false
11+ default : ' false'
12+
13+ env :
14+ TARGET_WORKFLOWS : ' ["RT-Thread BSP Static Build Check", "utest_auto_run"]'
15+ DISCUSSION_CATEGORY : " Github Action Exception Reports"
16+
17+ jobs :
18+ trigger-and-monitor :
19+ name : Trigger and Monitor CIs
20+ runs-on : ubuntu-latest
21+ outputs :
22+ failed_workflows : ${{ steps.collect-results.outputs.failed_workflows }}
23+ total_workflows : ${{ steps.collect-results.outputs.total_workflows }}
24+ has_results : ${{ steps.collect-results.outputs.has_results }}
25+
26+ steps :
27+ - name : Checkout repository
28+ uses : actions/checkout@v4
29+
30+ - name : Install Python dependencies
31+ run : |
32+ python -m pip install --upgrade pip
33+ pip install requests
34+
35+ - name : Record start time
36+ id : start-time
37+ run : |
38+ echo "start_time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
39+ echo "Start time: $(date -u +'%Y-%m-%dT%H:%M:%SZ')"
40+
41+ - name : Trigger CI workflows directly
42+ id : trigger-ci
43+ run : |
44+ python tools/ci/scheduled-ci-trigger/trigger_workflows_direct.py
45+ env :
46+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
47+ TARGET_WORKFLOWS : ${{ env.TARGET_WORKFLOWS }}
48+
49+ - name : Wait for workflows to appear
50+ id : wait-for-workflows
51+ run : |
52+ echo "Waiting for workflows to appear in API..."
53+ python tools/ci/scheduled-ci-trigger/wait_for_workflows.py "${{ steps.start-time.outputs.start_time }}"
54+ env :
55+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
56+ TARGET_WORKFLOWS : ${{ env.TARGET_WORKFLOWS }}
57+
58+ - name : Monitor CI workflows
59+ id : monitor-ci
60+ run : |
61+ python tools/ci/scheduled-ci-trigger/monitor_workflows.py "${{ steps.start-time.outputs.start_time }}"
62+ env :
63+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
64+ TARGET_WORKFLOWS : ${{ env.TARGET_WORKFLOWS }}
65+
66+ - name : Collect monitoring results
67+ id : collect-results
68+ run : |
69+ echo "Checking for monitoring results..."
70+ if [ -f "monitoring_results.json" ]; then
71+ echo "monitoring_results.json found"
72+ 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']))")
73+ TOTAL_COUNT=$(python -c "import json; data=json.load(open('monitoring_results.json')); print(len(data))")
74+ echo "failed_workflows=$FAILED_COUNT" >> $GITHUB_OUTPUT
75+ echo "total_workflows=$TOTAL_COUNT" >> $GITHUB_OUTPUT
76+ echo "has_results=true" >> $GITHUB_OUTPUT
77+ echo "Results: $FAILED_COUNT failed out of $TOTAL_COUNT total"
78+ else
79+ echo "monitoring_results.json not found"
80+ echo "failed_workflows=0" >> $GITHUB_OUTPUT
81+ echo "total_workflows=0" >> $GITHUB_OUTPUT
82+ echo "has_results=false" >> $GITHUB_OUTPUT
83+ fi
84+
85+ - name : Generate detailed report
86+ if : steps.collect-results.outputs.has_results == 'true' && steps.collect-results.outputs.failed_workflows != '0'
87+ id : generate-report
88+ run : |
89+ echo "Generating detailed report..."
90+ python tools/ci/scheduled-ci-trigger/generate_report.py
91+ echo "Report generation completed"
92+
93+ - name : Upload report artifact
94+ if : steps.collect-results.outputs.has_results == 'true' && steps.collect-results.outputs.failed_workflows != '0'
95+ uses : actions/upload-artifact@v4
96+ with :
97+ name : ci-failure-report
98+ path : |
99+ monitoring_results.json
100+ failure_details.md
101+ retention-days : 7
102+
103+ create-discussion :
104+ name : Create Discussion Report
105+ needs : trigger-and-monitor
106+ if : needs.trigger-and-monitor.outputs.has_results == 'true' && needs.trigger-and-monitor.outputs.failed_workflows != '0'
107+ runs-on : ubuntu-latest
108+
109+ steps :
110+ - name : Checkout repository
111+ uses : actions/checkout@v4
112+
113+ - name : Download report artifact
114+ uses : actions/download-artifact@v4
115+ with :
116+ name : ci-failure-report
117+
118+ - name : Create Discussion
119+ uses : actions/github-script@v6
120+ env :
121+ DISCUSSION_CATEGORY : ${{ env.DISCUSSION_CATEGORY }}
122+ with :
123+ script : |
124+ const fs = require('fs');
125+
126+ const reportPath = './failure_details.md';
127+
128+ let reportContent = fs.readFileSync(reportPath, 'utf8');
129+
130+ // 提取日期从第一行: # YYYYMMDD_ci_integration-failed-report
131+ const lines = reportContent.split('\n');
132+ const firstLine = lines[0].trim();
133+ const dateMatch = firstLine.match(/# (\d{8})_ci_integration-failed-report/);
134+
135+ if (!dateMatch) {
136+ console.error('Failed to extract date from first line:', firstLine);
137+ process.exit(1);
138+ }
139+
140+ const dateString = dateMatch[1];
141+ const discussionTitle = `${dateString}_ci_integration-failed-report`;
142+
143+ // === 关键修复:移除第一行(用于提取的隐藏行) ===
144+ reportContent = lines.slice(1).join('\n').trim();
145+
146+ // 获取仓库ID和分类ID
147+ const getRepoQuery = `
148+ query($owner: String!, $repo: String!) {
149+ repository(owner: $owner, name: $repo) {
150+ id
151+ discussionCategories(first: 20) {
152+ nodes {
153+ id
154+ name
155+ }
156+ }
157+ }
158+ }
159+ `;
160+
161+ const repoData = await github.graphql(getRepoQuery, {
162+ owner: context.repo.owner,
163+ repo: context.repo.repo
164+ });
165+
166+ const repositoryId = repoData.repository.id;
167+ const categories = repoData.repository.discussionCategories.nodes;
168+ const targetCategory = categories.find(cat => cat.name === process.env.DISCUSSION_CATEGORY);
169+
170+ if (!targetCategory) {
171+ console.error('Category not found:', process.env.DISCUSSION_CATEGORY);
172+ process.exit(1);
173+ }
174+
175+ const createDiscussionMutation = `
176+ mutation($repositoryId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
177+ createDiscussion(input: {
178+ repositoryId: $repositoryId
179+ categoryId: $categoryId
180+ title: $title
181+ body: $body
182+ }) {
183+ discussion {
184+ id
185+ title
186+ url
187+ }
188+ }
189+ }
190+ `;
191+
192+ const result = await github.graphql(createDiscussionMutation, {
193+ repositoryId: repositoryId,
194+ categoryId: targetCategory.id,
195+ title: discussionTitle,
196+ body: reportContent // 使用清理后的内容(无第一行)
197+ });
198+
199+ console.log('Discussion created successfully:', result.createDiscussion.discussion.url);
0 commit comments