1+ name : Daily Package Validation Report
2+
3+ on :
4+ schedule :
5+ # Run daily at midnight UTC
6+ - cron : ' 0 0 * * *'
7+ workflow_dispatch : # Allow manual triggering for testing
8+ push :
9+ branches : [ fix-test-imports ] # Temporary: for testing only
10+
11+ jobs :
12+ validate-packages :
13+ name : Generate Package Validation Report
14+ runs-on : ubuntu-latest
15+
16+ steps :
17+ - name : Checkout code
18+ uses : actions/checkout@v4.1.7
19+
20+ - name : Setup pnpm
21+ uses : pnpm/action-setup@v4.0.0
22+ with :
23+ version : 9.14.2
24+
25+ - name : Setup Node.js
26+ uses : actions/setup-node@v4.0.3
27+ with :
28+ node-version : 18
29+ cache : ' pnpm'
30+
31+ - name : Install dependencies
32+ run : pnpm install -r --no-frozen-lockfile
33+
34+ - name : Compile TypeScript
35+ run : pnpm run build
36+
37+ - name : Run Package Validation Report
38+ id : validation
39+ run : |
40+ node scripts/generate-package-report.js --verbose --report-only --output=validation-report.json > validation-report.txt 2>&1
41+ echo "validation_exit_code=$?" >> $GITHUB_OUTPUT
42+ continue-on-error : true
43+
44+ - name : Upload Validation Report
45+ uses : actions/upload-artifact@v4
46+ with :
47+ name : package-validation-report-${{ github.run_number }}
48+ path : |
49+ validation-report.txt
50+ validation-report.json
51+ retention-days : 30
52+
53+ - name : Check for failures
54+ id : check_failures
55+ run : |
56+ if [ -f "validation-report.json" ]; then
57+ FAILED_COUNT=$(node -e "
58+ const fs = require('fs');
59+ try {
60+ const report = JSON.parse(fs.readFileSync('validation-report.json', 'utf8'));
61+ console.log(report.summary.failed || 0);
62+ } catch {
63+ console.log(0);
64+ }
65+ ")
66+ echo "failed_count=$FAILED_COUNT" >> $GITHUB_OUTPUT
67+ else
68+ echo "failed_count=0" >> $GITHUB_OUTPUT
69+ fi
70+
71+ - name : Create Issue on Failures
72+ if : steps.check_failures.outputs.failed_count != '0'
73+ uses : actions/github-script@v7
74+ with :
75+ script : |
76+ const fs = require('fs');
77+
78+ // Read JSON report for structured data
79+ let reportData = null;
80+ let failedCount = 0;
81+ let summaryText = '';
82+
83+ try {
84+ const jsonReport = fs.readFileSync('validation-report.json', 'utf8');
85+ reportData = JSON.parse(jsonReport);
86+ failedCount = reportData.summary.failed;
87+ summaryText = `
88+ 📊 **Summary:**
89+ - Total Components: ${reportData.summary.total}
90+ - ✅ Validated: ${reportData.summary.validated}
91+ - ❌ Failed: ${reportData.summary.failed}
92+ - ⏭️ Skipped: ${reportData.summary.skipped}
93+ - 📈 Publishable: ${reportData.summary.publishable}
94+ - 📉 Failure Rate: ${reportData.summary.failureRate}%
95+ `;
96+ } catch (error) {
97+ // Fallback to text report
98+ const report = fs.readFileSync('validation-report.txt', 'utf8');
99+ const failedPackages = report.match(/❌.*FAILED:/g) || [];
100+ failedCount = failedPackages.length;
101+ summaryText = `Failed to parse JSON report. Found ${failedCount} failures in text report.`;
102+ }
103+
104+ if (failedCount > 0) {
105+ // Generate failed packages list
106+ let failedPackagesList = '';
107+ if (reportData && reportData.failed) {
108+ const topFailures = reportData.failed.slice(0, 10);
109+ failedPackagesList = topFailures.map(pkg =>
110+ `- **${pkg.packageName}** (${pkg.app}): ${pkg.failures.map(f => f.check).join(', ')}`
111+ ).join('\n');
112+ if (reportData.failed.length > 10) {
113+ failedPackagesList += `\n- ... and ${reportData.failed.length - 10} more packages`;
114+ }
115+ } else {
116+ failedPackagesList = 'See full report for details.';
117+ }
118+
119+ const issueBody = `
120+ # 📦 Daily Package Validation Report - ${new Date().toDateString()}
121+
122+ ${summaryText}
123+
124+ ## 🔗 Links
125+ - **Workflow Run**: [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
126+ - **Download Reports**: Check the workflow artifacts for detailed JSON and text reports
127+
128+ ## ❌ Failed Packages
129+ ${failedPackagesList}
130+
131+ ## Full Report
132+ The complete validation report is available as an artifact in the workflow run.
133+
134+ ## Next Steps
135+ 1. Review the failed packages listed above
136+ 2. Check the full validation report artifact
137+ 3. Fix import/dependency issues in failing packages
138+ 4. Consider updating the validation criteria if needed
139+
140+ ---
141+ *This issue was automatically created by the daily package validation workflow.*
142+ `;
143+
144+ // Check if there's already an open issue for today
145+ const { data: issues } = await github.rest.issues.listForRepo({
146+ owner: context.repo.owner,
147+ repo: context.repo.repo,
148+ labels: ['package-validation', 'automated'],
149+ state: 'open'
150+ });
151+
152+ const today = new Date().toDateString();
153+ const existingIssue = issues.find(issue =>
154+ issue.title.includes(today) &&
155+ issue.title.includes('Package Validation Report')
156+ );
157+
158+ if (existingIssue) {
159+ // Update existing issue
160+ await github.rest.issues.createComment({
161+ owner: context.repo.owner,
162+ repo: context.repo.repo,
163+ issue_number: existingIssue.number,
164+ body: `## Updated Report - Run #${{ github.run_number }}
165+
166+ ${issueBody}`
167+ });
168+ } else {
169+ // Create new issue
170+ await github.rest.issues.create({
171+ owner: context.repo.owner,
172+ repo: context.repo.repo,
173+ title: `📦 Package Validation Report - ${today} - ${failedCount} failures`,
174+ body: issueBody,
175+ labels: ['package-validation', 'automated', 'bug']
176+ });
177+ }
178+ }
179+
180+ - name : Post Success Summary
181+ if : steps.validation.outputs.validation_exit_code == '0'
182+ run : |
183+ echo "🎉 All packages validated successfully!"
184+ echo "Daily validation completed with no issues."
0 commit comments