Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING: Require Node 18, support ESM and CJS #319

Merged
merged 12 commits into from
Dec 10, 2023
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
test/yarn-berry.cjs
dist
coverage
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"mocha": true
},
"parserOptions": {
"ecmaVersion": 2019
"ecmaVersion": 2021
},
"extends": [
"eslint:recommended",
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: ["16", "18", "20"]
node: ["18", "20", "21"]
name: Build and test with Node ${{ matrix.node }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm run build
# Have audit-ci run audit-ci to audit itself :)
- run: node ./dist/bin.js --config ./audit-ci.jsonc
- run: npm test
- run: npm run coverage
- run: npm run lint
- run: npm run format -- --check
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/npmpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ jobs:
test-and-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "16"
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm run build
- run: npm test
- run: npm run coverage
- run: npm run lint
- run: npm publish
env:
Expand Down
14 changes: 0 additions & 14 deletions .mocharc.json

This file was deleted.

1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
test/yarn-berry.cjs
coverage
**/pnpm-lock.yaml
**/*-output.json
**/.pnp.cjs
26 changes: 0 additions & 26 deletions .travis.yml

This file was deleted.

29 changes: 14 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# audit-ci

[![npm version](https://badge.fury.io/js/audit-ci.svg)](https://badge.fury.io/js/audit-ci)
[![Build Status](https://app.travis-ci.com/IBM/audit-ci.svg?branch=main)](https://app.travis-ci.com/github/IBM/audit-ci)
[![CircleCI](https://circleci.com/gh/IBM/audit-ci/tree/main.svg?style=svg)](https://circleci.com/gh/IBM/audit-ci/tree/main)
[![GitHub CI](https://github.com/IBM/audit-ci/actions/workflows/build.yml/badge.svg)](https://github.com/IBM/audit-ci/actions/workflows/build.yml)
[![CodeQL](https://github.com/IBM/audit-ci/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/IBM/audit-ci/actions/workflows/codeql-analysis.yml)
Expand All @@ -14,7 +13,7 @@ threshold while ignoring allowlisted advisories.

## Requirements

- Node >=12.9.0 (Yarn Berry requires Node >=12.13.0)
- Node >=16
- _(Optional)_ Yarn ^1.12.3 || Yarn >=2.4.0
- _(Optional)_ PNPM >=4.3.0

Expand All @@ -28,9 +27,9 @@ _(Recommended)_ Install `audit-ci` during your CI environment using `npx`, `yarn

```sh
# Use the option for your project's package manager, pinning to a major version to avoid breaking changes
npx audit-ci@^6 --config ./audit-ci.jsonc
yarn dlx audit-ci@^6 --config ./audit-ci.jsonc
pnpm dlx audit-ci@^6 --config ./audit-ci.jsonc
npx audit-ci@^7 --config ./audit-ci.jsonc
yarn dlx audit-ci@^7 --config ./audit-ci.jsonc
pnpm dlx audit-ci@^7 --config ./audit-ci.jsonc
```

Alternatively, `audit-ci` can be installed as a devDependency.
Expand Down Expand Up @@ -197,7 +196,7 @@ You can also use an object notation ([NSPRecord](#nsprecord-fields)) in which yo
steps:
- uses: actions/checkout@v2
- name: Audit for vulnerabilities
run: npx audit-ci@^6 --config ./audit-ci.jsonc
run: npx audit-ci@^7 --config ./audit-ci.jsonc
```

_(Recommended)_ Run `audit-ci` immediately after checking out the git repository to reduce the risk of executing a `postinstall` script from a compromised NPM package.
Expand All @@ -223,7 +222,7 @@ steps:
# command: if [[ ! -z $CIRCLE_PULL_REQUEST ]] ; then npx audit-ci --config ./audit-ci.jsonc ; fi
- run:
name: run-audit-ci
command: npx audit-ci@^6 --config ./audit-ci.jsonc
command: npx audit-ci@^7 --config ./audit-ci.jsonc
- run:
name: install-npm
command: "npm install --no-audit"
Expand All @@ -237,14 +236,14 @@ Auditing only on PR builds is [recommended](#qa)
scripts:
# This script should be the first that runs to reduce the risk of
# executing a script from a compromised NPM package.
- if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then npx audit-ci@^6 --config ./audit-ci.jsonc; fi
- if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then npx audit-ci@^7 --config ./audit-ci.jsonc; fi
```

For `Travis-CI` not using PR builds:

```yml
scripts:
- npx audit-ci@^6 --config ./audit-ci.jsonc
- npx audit-ci@^7 --config ./audit-ci.jsonc
```

## Options
Expand Down Expand Up @@ -349,7 +348,7 @@ With a `JSON5` config file:
Or, with the CLI with `yarn dlx`:

```sh
yarn dlx audit-ci@^6 -l -a "GHSA-38f5-ghc2-fcmv" lodash base64url --show-found false
yarn dlx audit-ci@^7 -l -a "GHSA-38f5-ghc2-fcmv" lodash base64url --show-found false
```

### Prevents build with critical vulnerabilities showing the full report
Expand All @@ -367,7 +366,7 @@ With a `JSONC` config file:
Or, with the CLI with `pnpm dlx`:

```sh
pnpm dlx audit-ci@^6 --critical --report-type full
pnpm dlx audit-ci@^7 --critical --report-type full
```

### Continues build regardless of vulnerabilities, but show the summary report
Expand All @@ -384,7 +383,7 @@ With a `JSONC` config file:
Or, with the CLI:

```sh
npx audit-ci@^6 --report-type summary
npx audit-ci@^7 --report-type summary
```

### Pass additional args to Yarn Berry to exclude a certain package from audit
Expand All @@ -401,7 +400,7 @@ With a `JSONC` config file, in a project on Yarn Berry v3.3.0 or later:
Or, with the CLI:

```sh
npx audit-ci@^6 --extra-args '\--exclude' example
npx audit-ci@^7 --extra-args '\--exclude' example
```

### Example config file and different directory usage
Expand All @@ -428,7 +427,7 @@ npx audit-ci@^6 --extra-args '\--exclude' example
```

```sh
npx audit-ci@^6 --directory test/npm-config-file --config test/npm-config-file/audit-ci.jsonc
npx audit-ci@^7 --directory test/npm-config-file --config test/npm-config-file/audit-ci.jsonc
```

#### test/pnpm-config-file/audit-ci.json5
Expand All @@ -449,7 +448,7 @@ npx audit-ci@^6 --directory test/npm-config-file --config test/npm-config-file/a
```

```sh
npx audit-ci@^6 --directory test/pnpm-config-file --config test/pnpm-config-file/audit-ci.json5
npx audit-ci@^7 --directory test/pnpm-config-file --config test/pnpm-config-file/audit-ci.json5
```

## Codemod
Expand Down
2 changes: 1 addition & 1 deletion docs/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* This file generates the `schema.json` file. */

import { type NSPRecord } from "../lib/nsp-record";
import { type NSPRecord } from "../lib/nsp-record.js";

export interface Schema {
/** @default https://github.com/IBM/audit-ci/raw/main/docs/schema.json */
Expand Down
12 changes: 6 additions & 6 deletions lib/allowlist.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { GitHubAdvisoryId } from "audit-types";
import { isGitHubAdvisoryId } from "./common";
import { isGitHubAdvisoryId } from "./common.js";
import {
type NSPContent,
type NSPRecord,
type GitHubNSPRecord,
getAllowlistId,
isNSPRecordActive,
} from "./nsp-record";
} from "./nsp-record.js";

export type AllowlistRecord = string | NSPRecord;

Expand All @@ -24,7 +24,7 @@ const DEFAULT_NSP_CONTENT: Readonly<NSPContent> = {
* @returns Normalized NSPRecord object.
*/
export function normalizeAllowlistRecord(
recordOrId: AllowlistRecord
recordOrId: AllowlistRecord,
): NSPRecord {
return typeof recordOrId === "string"
? {
Expand All @@ -40,7 +40,7 @@ export function normalizeAllowlistRecord(
* @returns An array of NSPRecords with duplicates removed.
*/
export function dedupeAllowlistRecords(
recordsOrIds: AllowlistRecord[]
recordsOrIds: AllowlistRecord[],
): NSPRecord[] {
const map = new Map<string, NSPRecord>();
for (const recordOrId of recordsOrIds) {
Expand Down Expand Up @@ -78,7 +78,7 @@ class Allowlist {
for (const allowlist of input) {
if (typeof allowlist === "number") {
throw new TypeError(
"Unsupported number as allowlist. Perform codemod to update config to use GitHub advisory as identifiers: https://github.com/quinnturner/audit-ci-codemod with `npx @quinnturner/audit-ci-codemod`. See also: https://github.com/IBM/audit-ci/pull/217"
"Unsupported number as allowlist. Perform codemod to update config to use GitHub advisory as identifiers: https://github.com/quinnturner/audit-ci-codemod with `npx @quinnturner/audit-ci-codemod`. See also: https://github.com/IBM/audit-ci/pull/217",
);
}

Expand Down Expand Up @@ -106,7 +106,7 @@ class Allowlist {
}

static mapConfigToAllowlist(
config: Readonly<{ allowlist: AllowlistRecord[] }>
config: Readonly<{ allowlist: AllowlistRecord[] }>,
) {
const { allowlist } = config;
const deduplicatedAllowlist = dedupeAllowlistRecords(allowlist || []);
Expand Down
6 changes: 3 additions & 3 deletions lib/audit-ci.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import audit from "./audit";
import { green, red } from "./colors";
import { runYargs } from "./config";
import audit from "./audit.js";
import { green, red } from "./colors.js";
import { runYargs } from "./config.js";

/**
* Runs the audit-ci CLI.
Expand Down
41 changes: 24 additions & 17 deletions lib/audit.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { yellow } from "./colors";
import { ReportConfig } from "./common";
import type { AuditCiFullConfig } from "./config";
import type { Summary } from "./model";
import * as npmAuditer from "./npm-auditer";
import * as pnpmAuditer from "./pnpm-auditer";
import * as yarnAuditer from "./yarn-auditer";
import { yellow } from "./colors.js";
import { ReportConfig } from "./common.js";
import type { AuditCiFullConfig } from "./config.js";
import type { Summary } from "./model.js";
import * as npmAuditer from "./npm-auditer.js";
import * as pnpmAuditer from "./pnpm-auditer.js";
import * as yarnAuditer from "./yarn-auditer.js";

const PARTIAL_RETRY_ERROR_MSG = {
// The three ENOAUDIT error messages for NPM are:
Expand All @@ -19,23 +19,27 @@ const PARTIAL_RETRY_ERROR_MSG = {
} as const;

function getAuditor(
packageManager: "npm" | "yarn" | "pnpm"
packageManager: "npm" | "yarn" | "pnpm",
): typeof yarnAuditer | typeof npmAuditer | typeof pnpmAuditer {
switch (packageManager) {
case "yarn":
case "yarn": {
return yarnAuditer;
case "npm":
}
case "npm": {
return npmAuditer;
case "pnpm":
}
case "pnpm": {
return pnpmAuditer;
default:
}
default: {
throw new Error(`Invalid package manager: ${packageManager}`);
}
}
}

async function audit(
config: AuditCiFullConfig,
reporter?: (summary: Summary, config: ReportConfig) => Summary
reporter?: (summary: Summary, config: ReportConfig) => Summary,
) {
const {
"pass-enoaudit": passENoAudit,
Expand All @@ -49,12 +53,15 @@ async function audit(
try {
const result = await auditor.auditWithFullConfig(config, reporter);
return result;
} catch (error: any) {
const message = error.message || error;
} catch (error: unknown) {
const message =
error && typeof error === "object" && "message" in error
? error.message
: error;
const isRetryableMessage =
typeof message === "string" &&
PARTIAL_RETRY_ERROR_MSG[packageManager].some((retryErrorMessage) =>
message.includes(retryErrorMessage)
message.includes(retryErrorMessage),
);
const shouldRetry = attempt < maxRetryCount && isRetryableMessage;
if (shouldRetry) {
Expand All @@ -67,7 +74,7 @@ async function audit(
if (shouldPassWithoutAuditing) {
console.warn(
yellow,
`ACTION RECOMMENDED: An audit could not performed due to ${maxRetryCount} audits that resulted in ENOAUDIT. Perform an audit manually and verify that no significant vulnerabilities exist before merging.`
`ACTION RECOMMENDED: An audit could not performed due to ${maxRetryCount} audits that resulted in ENOAUDIT. Perform an audit manually and verify that no significant vulnerabilities exist before merging.`,
);
return;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/bin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env node
import { runAuditCi } from "./audit-ci";
import { runAuditCi } from "./audit-ci.js";

// eslint-disable-next-line unicorn/prefer-top-level-await
runAuditCi().catch((error) => {
console.error(error);
process.exit(1);
Expand Down
Loading