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