@@ -108,12 +108,103 @@ jobs:
108108 if : ${{ inputs.run_checks }}
109109 run : npm run types:check
110110
111- - name : Run npm audit
111+ - name : Run npm audit and create markdown report
112112 if : ${{ inputs.run_audit }}
113- uses : oke-py/npm-audit-action@v3
113+ id : npm-audit
114+ continue-on-error : true
115+ run : |
116+ cd "${{ inputs.working_directory }}"
117+
118+ # Run npm audit and capture text output
119+ AUDIT_OUTPUT=$(npm audit --audit-level=${{ inputs.audit_level }} 2>&1) || AUDIT_EXIT_CODE=$?
120+
121+ # Create markdown report file
122+ REPORT_FILE=$(mktemp)
123+
124+ # Check if vulnerabilities were found
125+ if echo "$AUDIT_OUTPUT" | grep -q "vulnerabilities"; then
126+ # Format as markdown
127+ {
128+ echo "## 📋 npm audit report"
129+ echo ""
130+ echo "\`\`\`"
131+ echo "$AUDIT_OUTPUT"
132+ echo "\`\`\`"
133+ echo ""
134+ echo "> To fix these issues, run: \`npm audit fix\` or \`npm audit fix --force\` (for breaking changes)"
135+ } > "$REPORT_FILE"
136+ else
137+ # No vulnerabilities found
138+ {
139+ echo "## ✅ npm audit report"
140+ echo ""
141+ echo "No vulnerabilities found."
142+ } > "$REPORT_FILE"
143+ AUDIT_EXIT_CODE=0
144+ fi
145+
146+ # Read the report
147+ MARKDOWN_REPORT=$(cat "$REPORT_FILE")
148+
149+ # Add to workflow summary
150+ cat "$REPORT_FILE" >> $GITHUB_STEP_SUMMARY
151+
152+ # Store for PR comment (using multiline output)
153+ {
154+ echo "markdown_report<<AUDIT_EOF"
155+ cat "$REPORT_FILE"
156+ echo "AUDIT_EOF"
157+ } >> $GITHUB_OUTPUT
158+
159+ # Cleanup
160+ rm -f "$REPORT_FILE"
161+
162+ # Set exit code based on audit result
163+ if [ -n "$AUDIT_EXIT_CODE" ] && [ "$AUDIT_EXIT_CODE" != "0" ]; then
164+ echo "has_vulnerabilities=true" >> $GITHUB_OUTPUT
165+ exit $AUDIT_EXIT_CODE
166+ else
167+ echo "has_vulnerabilities=false" >> $GITHUB_OUTPUT
168+ fi
169+
170+ - name : Create or update PR comment with audit results
171+ if : ${{ inputs.run_audit && github.event_name == 'pull_request' }}
172+ uses : actions/github-script@v7
114173 with :
115- audit_level : ${{ inputs.audit_level }}
116- github_token : ${{ secrets.GITHUB_TOKEN }}
117- create_issues : false
118- create_pr_comments : true
119- working_directory : ${{ inputs.working_directory }}
174+ github-token : ${{ secrets.GITHUB_TOKEN }}
175+ script : |
176+ const report = `${{ steps.npm-audit.outputs.markdown_report }}`;
177+
178+ // Check if comment already exists
179+ const comments = await github.rest.issues.listComments({
180+ owner: context.repo.owner,
181+ repo: context.repo.repo,
182+ issue_number: context.issue.number,
183+ });
184+
185+ const existingComment = comments.data.find(comment =>
186+ comment.user.type === 'Bot' &&
187+ comment.body.includes('npm audit report')
188+ );
189+
190+ if (existingComment) {
191+ // Update existing comment
192+ await github.rest.issues.updateComment({
193+ owner: context.repo.owner,
194+ repo: context.repo.repo,
195+ comment_id: existingComment.id,
196+ body: report
197+ });
198+ } else {
199+ // Only create new comment if there are vulnerabilities
200+ // (to avoid cluttering PRs with "no vulnerabilities" comments)
201+ const hasVulnerabilities = '${{ steps.npm-audit.outputs.has_vulnerabilities }}' === 'true';
202+ if (hasVulnerabilities) {
203+ await github.rest.issues.createComment({
204+ owner: context.repo.owner,
205+ repo: context.repo.repo,
206+ issue_number: context.issue.number,
207+ body: report
208+ });
209+ }
210+ }
0 commit comments