-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Expand file tree
/
Copy pathcomponent-security-validation.yml
More file actions
129 lines (109 loc) · 4.13 KB
/
Copy pathcomponent-security-validation.yml
File metadata and controls
129 lines (109 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
name: Component Security Validation
on:
pull_request:
paths:
- 'cli-tool/components/**/*.md'
- 'cli-tool/src/validation/**'
- '.github/workflows/component-security-validation.yml'
push:
branches:
- main
paths:
- 'cli-tool/components/**/*.md'
jobs:
security-audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for git metadata
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: cli-tool/package-lock.json
- name: Install dependencies
run: |
cd cli-tool
npm ci
- name: Run Security Audit
id: audit
run: |
cd cli-tool
npm run security-audit:ci
continue-on-error: false
- name: Generate JSON Report
if: always()
run: |
cd cli-tool
npm run security-audit:json
- name: Upload Security Report
if: always()
uses: actions/upload-artifact@v4
with:
name: security-audit-report
path: cli-tool/security-report.json
retention-days: 30
- name: Comment PR with Results
if: github.event_name == 'pull_request' && always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const reportPath = 'cli-tool/security-report.json';
if (!fs.existsSync(reportPath)) {
console.log('No security report found');
return;
}
const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
const passed = report.summary.passed;
const failed = report.summary.failed;
const warnings = report.summary.warnings;
const total = report.summary.total;
const status = failed === 0 ? '✅ PASSED' : '❌ FAILED';
const emoji = failed === 0 ? '🎉' : '⚠️';
let comment = `## ${emoji} Security Audit Report\n\n`;
comment += `**Status**: ${status}\n\n`;
comment += `### Summary\n`;
comment += `- **Total components**: ${total}\n`;
comment += `- ✅ **Passed**: ${passed}\n`;
comment += `- ❌ **Failed**: ${failed}\n`;
comment += `- ⚠️ **Warnings**: ${warnings}\n\n`;
if (failed > 0) {
comment += `### ❌ Failed Components\n\n`;
for (const component of report.components) {
if (!component.overall.valid) {
comment += `**${component.component.path}**\n`;
comment += `- Errors: ${component.overall.errorCount}\n`;
comment += `- Warnings: ${component.overall.warningCount}\n`;
comment += `- Score: ${component.overall.score}/100\n\n`;
// Show top errors
for (const [validator, result] of Object.entries(component.validators)) {
if (result.errors && result.errors.length > 0) {
comment += ` **${validator}**: ${result.errors.length} error(s)\n`;
for (const error of result.errors.slice(0, 2)) {
comment += ` - \`${error.code}\`: ${error.message}\n`;
}
}
}
comment += `\n`;
}
}
}
comment += `\n---\n`;
comment += `📊 View full report in [workflow artifacts](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`;
// Post comment
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
- name: Fail workflow if errors found
if: failure()
run: |
echo "::error::Security audit found critical issues"
exit 1