• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

oke-py / npm-audit-action / 14881417417

07 May 2025 10:44AM UTC coverage: 65.726% (-1.5%) from 67.194%
14881417417

Pull #257

github

web-flow
Merge 8af85fa7a into fa0968161
Pull Request #257: refactor(main): remove run() call as index.ts is now the entry point

28 of 38 branches covered (73.68%)

Branch coverage included in aggregate %.

135 of 210 relevant lines covered (64.29%)

3.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

48.84
/src/main.ts
1
import * as core from '@actions/core'
2✔
2
import * as github from '@actions/github'
2✔
3
import { Octokit } from '@octokit/rest'
2✔
4
import { Audit } from './audit.js'
2✔
5
import { IssueOption } from './interface.js'
6
import * as issue from './issue.js'
2✔
7
import * as pr from './pr.js'
2✔
8
import * as workdir from './workdir.js'
2✔
9

10
export async function run(): Promise<void> {
8✔
11
  try {
8✔
12
    // move to working directory
13
    const workingDirectory = core.getInput('working_directory')
8✔
14
    if (workingDirectory) {
8!
15
      // Remove trailing slash if present
16
      const normalizedWorkingDirectory = workingDirectory.endsWith('/')
×
17
        ? workingDirectory.slice(0, -1)
×
18
        : workingDirectory
×
19

20
      if (!workdir.isValid(normalizedWorkingDirectory)) {
×
21
        throw new Error('Invalid input: working_directory')
×
22
      }
×
23

24
      try {
×
25
        // Try to change directory
26
        process.chdir(normalizedWorkingDirectory)
×
27
        core.info(
×
28
          `Successfully changed directory to: ${normalizedWorkingDirectory}`
×
29
        )
×
30
      } catch (error) {
×
31
        // If changing directory fails, log the error but continue
32
        core.warning(
×
33
          `Failed to change directory to: ${normalizedWorkingDirectory}`
×
34
        )
×
35
        core.warning(
×
36
          `Error: ${error instanceof Error ? error.message : String(error)}`
×
37
        )
×
38
        core.warning('Continuing with current directory')
×
39
      }
×
40
    }
×
41
    core.info(`Current working directory: ${process.cwd()}`)
8✔
42

43
    // get audit-level
44
    const auditLevel = core.getInput('audit_level', { required: true })
8✔
45
    if (
8✔
46
      !['critical', 'high', 'moderate', 'low', 'info', 'none'].includes(
8✔
47
        auditLevel
8✔
48
      )
8✔
49
    ) {
8!
50
      throw new Error('Invalid input: audit_level')
×
51
    }
×
52

53
    const productionFlag = core.getInput('production_flag', { required: false })
8✔
54
    if (!['true', 'false'].includes(productionFlag)) {
8!
55
      throw new Error('Invalid input: production_flag')
×
56
    }
×
57

58
    const jsonFlag = core.getInput('json_flag', { required: false })
8✔
59
    if (!['true', 'false'].includes(jsonFlag)) {
8!
60
      throw new Error('Invalid input: json_flag')
×
61
    }
×
62

63
    // run `npm audit`
64
    const audit = new Audit()
8✔
65
    audit.run(auditLevel, productionFlag, jsonFlag)
8✔
66
    core.info(audit.stdout)
8✔
67
    core.setOutput('npm_audit', audit.stdout)
8✔
68

69
    if (audit.foundVulnerability()) {
8✔
70
      // vulnerabilities are found
71

72
      // get GitHub information
73
      const ctx = JSON.parse(core.getInput('github_context'))
6✔
74
      const token: string = core.getInput('github_token', { required: true })
6✔
75
      const octokit = new Octokit({
6✔
76
        auth: token
6✔
77
      })
6✔
78

79
      if (ctx.event_name === 'pull_request') {
6✔
80
        const createPRComments = core.getInput('create_pr_comments')
4✔
81
        if (!['true', 'false'].includes(createPRComments)) {
4!
82
          throw new Error('Invalid input: create_pr_comments')
×
83
        }
×
84

85
        if (createPRComments === 'true') {
4✔
86
          await pr.createComment(
2✔
87
            octokit,
2✔
88
            github.context.repo.owner,
2✔
89
            github.context.repo.repo,
2✔
90
            ctx.event.number,
2✔
91
            audit.strippedStdout()
2✔
92
          )
2✔
93
        }
2✔
94
        core.setFailed('This repo has some vulnerabilities')
4✔
95
        return
4✔
96
      } else {
6✔
97
        core.debug('open an issue')
2✔
98
        const createIssues = core.getInput('create_issues')
2✔
99
        if (!['true', 'false'].includes(createIssues)) {
2!
100
          throw new Error('Invalid input: create_issues')
×
101
        }
×
102

103
        if (createIssues === 'false') {
2✔
104
          core.setFailed('This repo has some vulnerabilities')
2✔
105
          return
2✔
106
        }
2!
107

108
        // remove control characters and create a code block
109
        const issueBody = audit.strippedStdout()
×
110
        const option: IssueOption = issue.getIssueOption(issueBody)
×
111

112
        const existingIssueNumber =
×
113
          core.getInput('dedupe_issues') === 'true'
×
114
            ? await issue.getExistingIssueNumber(
×
115
                octokit.issues.listForRepo,
×
116
                github.context.repo
×
117
              )
×
118
            : null
×
119

120
        if (existingIssueNumber !== null) {
2!
121
          const { data: createdComment } = await octokit.issues.createComment({
×
122
            ...github.context.repo,
×
123
            issue_number: existingIssueNumber,
×
124
            body: option.body
×
125
          })
×
126
          core.debug(`comment ${createdComment.url}`)
×
127
        } else {
×
128
          const { data: createdIssue } = await octokit.issues.create({
×
129
            ...github.context.repo,
×
130
            ...option
×
131
          })
×
132
          core.debug(`#${createdIssue.number}`)
×
133
        }
×
134
        core.setFailed('This repo has some vulnerabilities')
×
135
      }
×
136
    }
6✔
137
  } catch (e: unknown) {
8!
138
    core.setFailed((e as Error)?.message ?? 'Unknown error occurred')
×
139
  }
×
140
}
8✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc