Skip to content

Commit 4a6d8d0

Browse files
committed
chore(release): release vue3-extended-multiselect v3.0.1
1 parent 4c0ce69 commit 4a6d8d0

15 files changed

+268
-155
lines changed

.github/workflows/audit.yml

Lines changed: 215 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,31 @@ jobs:
2525
- name: Install dependencies
2626
run: npm ci
2727

28-
- name: Audit dependencies
28+
- name: Run security audit
2929
id: audit
3030
run: |
31-
AUDIT_OUTPUT=$(npm audit --audit-level=moderate --json 2>/dev/null || true)
31+
set +e
32+
npm audit --audit-level=moderate --json > audit_results.json 2>audit_error.log
33+
AUDIT_EXIT_CODE=$?
34+
35+
if [ $AUDIT_EXIT_CODE -eq 1 ]; then
36+
echo "Vulnerabilities found (exit code 1)"
37+
echo "has_vulnerabilities=true" >> $GITHUB_OUTPUT
38+
elif [ $AUDIT_EXIT_CODE -ne 0 ]; then
39+
echo "Audit failed with exit code: $AUDIT_EXIT_CODE"
40+
echo '{"error": "audit_failed", "exit_code": '$AUDIT_EXIT_CODE'}' > audit_results.json
41+
echo "has_vulnerabilities=false" >> $GITHUB_OUTPUT
42+
echo "audit_failed=true" >> $GITHUB_OUTPUT
43+
else
44+
echo "No vulnerabilities found"
45+
echo "has_vulnerabilities=false" >> $GITHUB_OUTPUT
46+
fi
47+
48+
AUDIT_OUTPUT=$(cat audit_results.json)
3249
echo "audit_output<<EOF" >> $GITHUB_OUTPUT
3350
echo "$AUDIT_OUTPUT" >> $GITHUB_OUTPUT
3451
echo "EOF" >> $GITHUB_OUTPUT
3552
36-
npm audit --audit-level=moderate || echo "::warning::npm audit found vulnerabilities"
37-
3853
- name: Upload audit report
3954
if: always()
4055
uses: actions/upload-artifact@v4
@@ -43,129 +58,215 @@ jobs:
4358
path: |
4459
package-lock.json
4560
package.json
61+
audit_results.json
62+
audit_error.log
4663
retention-days: 7
4764

48-
- name: Create issue if vulnerable
49-
if: failure()
65+
- name: Process audit results
66+
id: process-results
67+
if: always() && steps.audit.outputs.audit_output
68+
run: |
69+
AUDIT_OUTPUT='${{ steps.audit.outputs.audit_output }}'
70+
71+
# Create a simple Node.js script to process the JSON
72+
cat > process_audit.js << 'EOF'
73+
try {
74+
const auditData = JSON.parse(process.argv[1]);
75+
76+
if (auditData.error) {
77+
console.log('::error::Audit failed: ' + auditData.error);
78+
process.exit(1);
79+
}
80+
81+
const vulnerabilities = auditData.metadata?.vulnerabilities || {};
82+
const total = vulnerabilities.total || 0;
83+
const critical = vulnerabilities.critical || 0;
84+
const high = vulnerabilities.high || 0;
85+
const moderate = vulnerabilities.moderate || 0;
86+
const low = vulnerabilities.low || 0;
87+
88+
console.log(`total=${total}`);
89+
console.log(`critical=${critical}`);
90+
console.log(`high=${high}`);
91+
console.log(`moderate=${moderate}`);
92+
console.log(`low=${low}`);
93+
94+
// Create a summary string
95+
const summary = `Critical: ${critical}, High: ${high}, Moderate: ${moderate}, Low: ${low}, Total: ${total}`;
96+
console.log(`summary=${summary}`);
97+
98+
if (total > 0) {
99+
console.log('::error::Vulnerabilities found: ' + summary);
100+
process.exit(1);
101+
}
102+
103+
} catch (error) {
104+
console.log('::error::Failed to parse audit results: ' + error.message);
105+
process.exit(1);
106+
}
107+
EOF
108+
109+
# Run the processing script and capture outputs
110+
node process_audit.js "$AUDIT_OUTPUT" >> $GITHUB_OUTPUT
111+
112+
- name: Create security issue
113+
if: |
114+
always() &&
115+
steps.audit.outputs.has_vulnerabilities == 'true' &&
116+
github.event_name != 'pull_request'
50117
uses: actions/github-script@v6
51118
with:
52119
github-token: ${{ secrets.GITHUB_TOKEN }}
53120
script: |
121+
const { owner, repo } = context.repo;
122+
const runId = context.runId;
123+
const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${runId}`;
124+
125+
const auditOutput = `${{ steps.audit.outputs.audit_output }}`;
126+
const summary = `${{ steps.process-results.outputs.summary }}`;
127+
128+
let vulnerabilityDetails = 'Unable to parse vulnerability details';
129+
let auditData = {};
130+
54131
try {
55-
const auditOutput = `${{ steps.audit.outputs.audit_output }}`;
56-
let auditData = {};
57-
let vulnerabilitySummary = 'Unable to parse audit details';
58-
59-
try {
60-
auditData = JSON.parse(auditOutput);
61-
if (auditData.metadata && auditData.metadata.vulnerabilities) {
62-
const vulns = auditData.metadata.vulnerabilities;
63-
vulnerabilitySummary = `Vulnerabilities found:
64-
- Critical: ${vulns.critical || 0}
65-
- High: ${vulns.high || 0}
66-
- Moderate: ${vulns.moderate || 0}
67-
- Low: ${vulns.low || 0}`;
68-
}
69-
} catch (parseError) {
70-
console.error('Failed to parse audit output:', parseError.message);
71-
vulnerabilitySummary = 'Failed to parse audit output. Check workflow artifacts for details.';
72-
}
73-
74-
let existingIssues;
75-
try {
76-
existingIssues = await github.rest.issues.listForRepo({
77-
owner: context.repo.owner,
78-
repo: context.repo.repo,
79-
labels: ['security', 'vulnerability'],
80-
state: 'open'
81-
});
82-
} catch (apiError) {
83-
console.error('Failed to fetch existing issues:', apiError.message);
84-
existingIssues = { data: [] };
85-
}
86-
87-
const existingIssue = existingIssues.data.find(issue =>
88-
issue.title.includes('Security vulnerabilities detected') ||
89-
issue.title.includes('🚨 Security vulnerabilities detected')
90-
);
91-
92-
if (existingIssue) {
93-
console.warn('Security issue already exists: #' + existingIssue.number);
94-
return;
95-
}
96-
97-
try {
98-
await github.rest.issues.create({
99-
owner: context.repo.owner,
100-
repo: context.repo.repo,
101-
title: '🚨 Security vulnerabilities detected in dependencies',
102-
body: `## Security Audit Report
103-
104-
npm audit found vulnerabilities that require attention.
105-
106-
**Vulnerability Summary:**
107-
\`\`\`
108-
${vulnerabilitySummary}
109-
\`\`\`
110-
111-
**Next Steps:**
112-
1. Run \`npm audit fix\` to attempt automatic fixes
113-
2. Review the full audit report in the workflow artifacts
114-
3. Update vulnerable dependencies manually if needed
115-
116-
**Workflow Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
117-
118-
*This issue was automatically generated by the security audit workflow.*`,
119-
labels: ['security', 'vulnerability', 'automated']
120-
});
121-
} catch (createError) {
122-
console.error('Failed to create security issue:', createError.message);
132+
auditData = JSON.parse(auditOutput);
133+
if (auditData.metadata && auditData.metadata.vulnerabilities) {
134+
const vulns = auditData.metadata.vulnerabilities;
135+
vulnerabilityDetails = `## Vulnerability Summary
136+
137+
| Severity | Count |
138+
|----------|-------|
139+
| 🔴 Critical | ${vulns.critical || 0} |
140+
| 🟠 High | ${vulns.high || 0} |
141+
| 🟡 Moderate | ${vulns.moderate || 0} |
142+
| 🔵 Low | ${vulns.low || 0} |
143+
| **Total** | **${vulns.total || 0}** |`;
123144
}
145+
} catch (parseError) {
146+
vulnerabilityDetails = `## Audit Results
147+
Unable to parse detailed vulnerability information. Check the workflow artifacts for complete details.`;
148+
}
149+
150+
// Check for existing open security issues
151+
const { data: existingIssues } = await github.rest.issues.listForRepo({
152+
owner,
153+
repo,
154+
labels: ['security-audit', 'dependencies'],
155+
state: 'open'
156+
});
157+
158+
const existingIssue = existingIssues.find(issue =>
159+
issue.title.includes('Security Audit: Vulnerabilities Detected') ||
160+
issue.title.includes('npm audit found vulnerabilities')
161+
);
162+
163+
if (existingIssue) {
164+
console.log(`Security issue already exists: #${existingIssue.number}`);
124165
125-
} catch (outerError) {
126-
console.error('Unexpected error in Create issue step:', outerError.message);
166+
// Update existing issue with latest results
167+
await github.rest.issues.update({
168+
owner,
169+
repo,
170+
issue_number: existingIssue.number,
171+
body: `## 🔒 Security Audit Update
172+
173+
${vulnerabilityDetails}
174+
175+
**Latest Scan Results:** ${summary}
176+
177+
**Workflow Run:** [View Run](${runUrl})
178+
**Last Updated:** ${new Date().toISOString()}
179+
180+
**Next Steps:**
181+
1. Run \`npm audit fix\` to attempt automatic fixes
182+
2. Run \`npm audit\` to review detailed findings
183+
3. Manually update dependencies if automatic fixes are insufficient
184+
4. Check the workflow artifacts for complete audit report
185+
186+
*This issue is automatically updated by the security audit workflow.*`
187+
});
188+
} else {
189+
// Create new issue
190+
await github.rest.issues.create({
191+
owner,
192+
repo,
193+
title: `🔒 Security Audit: Vulnerabilities Detected - ${new Date().toISOString().split('T')[0]}`,
194+
body: `## 🔒 Security Audit Report
195+
196+
${vulnerabilityDetails}
197+
198+
**Workflow Run:** [View Run](${runUrl})
199+
**Detected:** ${new Date().toISOString()}
200+
201+
**Recommended Actions:**
202+
1. Run \`npm audit fix\` to attempt automatic fixes
203+
2. Run \`npm audit\` to review detailed findings
204+
3. Manually update vulnerable dependencies if needed
205+
4. Check the workflow artifacts for complete audit report
206+
5. Close this issue once vulnerabilities are resolved
207+
208+
**Automated Commands:**
209+
\`\`\`bash
210+
# Try automatic fixes
211+
npm audit fix
212+
213+
# Review remaining issues
214+
npm audit
215+
\`\`\`
216+
217+
*This issue was automatically generated by the security audit workflow.*`,
218+
labels: ['security-audit', 'dependencies', 'automated']
219+
});
127220
}
128221
129-
- name: Comment on PR if vulnerable
130-
if: failure() && github.event_name == 'pull_request'
222+
- name: Comment on PR with vulnerabilities
223+
if: |
224+
always() &&
225+
steps.audit.outputs.has_vulnerabilities == 'true' &&
226+
github.event_name == 'pull_request'
131227
uses: actions/github-script@v6
132228
with:
133229
github-token: ${{ secrets.GITHUB_TOKEN }}
134230
script: |
135-
try {
136-
const auditOutput = `${{ steps.audit.outputs.audit_output }}`;
137-
let vulnerabilitySummary = '## 🔒 Security Audit Results\n\nSecurity vulnerabilities detected by npm audit. Please run `npm audit` to review and fix these issues before merging.';
138-
139-
try {
140-
const auditData = JSON.parse(auditOutput);
141-
if (auditData.metadata && auditData.metadata.vulnerabilities) {
142-
const vulns = auditData.metadata.vulnerabilities;
143-
vulnerabilitySummary = `## 🔒 Security Audit Results
144-
145-
Vulnerabilities found in this PR:
146-
- ⚠️ Critical: ${vulns.critical || 0}
147-
- 🔴 High: ${vulns.high || 0}
148-
- 🟡 Moderate: ${vulns.moderate || 0}
149-
- 🔵 Low: ${vulns.low || 0}
150-
151-
Please run \`npm audit\` to review and fix these issues before merging.`;
152-
}
153-
} catch (parseError) {
154-
console.error('Failed to parse audit output for PR comment:', parseError.message);
155-
vulnerabilitySummary = '## 🔒 Security Audit Results\n\nSecurity vulnerabilities detected. Please check the workflow artifacts for detailed audit results.';
156-
}
157-
158-
try {
159-
await github.rest.issues.createComment({
160-
owner: context.repo.owner,
161-
repo: context.repo.repo,
162-
issue_number: context.payload.pull_request.number,
163-
body: vulnerabilitySummary
164-
});
165-
} catch (commentError) {
166-
console.error('Failed to create PR comment:', commentError.message);
167-
}
168-
169-
} catch (outerError) {
170-
console.error('Unexpected error in PR comment step:', outerError.message);
231+
const summary = `${{ steps.process-results.outputs.summary }}`;
232+
const total = `${{ steps.process-results.outputs.total }}`;
233+
const critical = `${{ steps.process-results.outputs.critical }}`;
234+
const high = `${{ steps.process-results.outputs.high }}`;
235+
236+
let severityIcon = '⚠️';
237+
if (critical > 0 || high > 0) {
238+
severityIcon = '🚨';
171239
}
240+
241+
const commentBody = `## ${severityIcon} Security Audit Results
242+
243+
**Vulnerabilities detected in this PR:**
244+
${summary}
245+
246+
**Required Action:**
247+
Please address these security vulnerabilities before merging this pull request.
248+
249+
**Quick Fixes:**
250+
\`\`\`bash
251+
# Try automatic fixes
252+
npm audit fix
253+
254+
# If that doesn't resolve all issues, try with force
255+
npm audit fix --force
256+
\`\`\`
257+
258+
*Note: Be cautious with \`--force\` as it may introduce breaking changes.*`;
259+
260+
await github.rest.issues.createComment({
261+
owner: context.repo.owner,
262+
repo: context.repo.repo,
263+
issue_number: context.payload.pull_request.number,
264+
body: commentBody
265+
});
266+
267+
- name: Fail workflow if vulnerabilities found
268+
if: steps.audit.outputs.has_vulnerabilities == 'true'
269+
run: |
270+
echo "::error::Security vulnerabilities detected! Check the created issue or PR comment for details."
271+
echo "Summary: ${{ steps.process-results.outputs.summary }}"
272+
exit 1

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Patch notes
22

3-
Current `vue3-extended-multiselect` version: **2.3.11**
3+
Current `vue3-extended-multiselect` version: **3.0.1**
44

55
---
66

@@ -544,7 +544,6 @@ Adding descriptive comments for some types in typings.
544544
- Added coverage configuration for unit testing.
545545
- Added banner with package information to all output variants.
546546
- Added enhanced null checking mechanism to pre-selected options.
547-
- Changed rollup output format and added UMD output variant.
548547
- Changed main documentation and documentation for contributors.
549548
- Changed package keywords.
550549
- Changed Node.js platform version and added a treshold for the node platform versions.
@@ -554,3 +553,9 @@ Adding descriptive comments for some types in typings.
554553
- Removed "publish" workflow in favor of the new "release" workflow for automatically creating Github tags and releases.
555554
- Removed explicit installation of "core-js" dependency.
556555
- Removed unnecessary "iconFilter" prop in ExtendedMultiselectLoader component.
556+
557+
### 3.0.1
558+
559+
- Changed security audit workflow with proper vulnerability handling.
560+
- Fixed a bug with layout shifting when using the optional "dropdownDisabled" prop together with the optional "iconSize" prop.
561+
- Fixed runtime errors in UMD file output variant by reconfiguring the "babel" plugin for rollup.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# vue3-extended-multiselect v3.0.0
1+
# vue3-extended-multiselect v3.0.1
22

33
---
44

0 commit comments

Comments
 (0)