Skip to content

Overhaul CI/CD and quality assurance#127

Open
joao-onfleet wants to merge 2 commits into
masterfrom
INT-3686
Open

Overhaul CI/CD and quality assurance#127
joao-onfleet wants to merge 2 commits into
masterfrom
INT-3686

Conversation

@joao-onfleet

@joao-onfleet joao-onfleet commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Overview

Overhauls the project's quality assurance and CI setup. Before this change the test suite, library import, and dependency lockfile were all broken at HEAD (masked because CI only ran at release time on a pinned Node 20). This PR restores a working, gated baseline and adds coverage, lint enforcement, and PR-level CI.

Why

A QA audit found three compounding breakages at HEAD:

Area Before
npm test 🔴 SyntaxError — failed to run
Library import (Node ≥22) 🔴 threw on import
package-lock.json 🔴 invalid JSON → npm ci/npm audit broke
Lint 🔴 215 errors, not wired to CI
PR-level CI 🔴 none (only release-time publish)
Coverage 🔴 not measured

Changes

CI / tooling

  • New .github/workflows/ci.yml running on pull_request + push to master:
    • test across a Node 20 / 22 / 24 matrix
    • lint (blocking)
    • coverage (c8, enforces thresholds, uploads lcov.info)
    • audit (npm audit --audit-level=high)
    • Uses actions/checkout@v4 + setup-node@v4 with npm caching.
  • Coverage tooling: added c8, npm run coverage, and .c8rc.json thresholds.

Fixes

  • lib/onfleet.js: replaced the deprecated assert { type: 'json' } import attribute (removed in Node 22, also unparseable by ESLint 8) with a portable createRequire('../package.json'). Restores Node 22/24 support.
  • package-lock.json: repaired invalid JSON (a missing },) so npm ci/npm audit work again.
  • package.json overrides: scoped the blanket brace-expansion override per-major (@1/@2/@3/@4) so modern minimatch@10 (needs brace-expansion@^5) installs, while bumping the pins to ^1.1.13/^2.0.3 — which also closes a newer advisory (GHSA-f886-m6hf-6m8v) the original ^2.0.2 pin was exposed to.

Lint

  • Reworked .eslintrc.json: env: node/es2022, a test/** override with env: mocha, corrected import/extensions for this ESM project (requires .js), and prefer-destructuring: {array:false}.
  • Auto-fixed ~130 stylistic issues; hand-fixed the rest in Methods.js/onfleet.js (removed a useless try/catch, renamed a shadowed var, for…offorEach). All behavior-preserving.
  • npm run lint now exits 0 and is a required CI check.

Tests

  • Added 16 nock-based tests covering the 6 previously-untested resources (Containers, Destinations, Hubs, Organization, Routeplan, Webhooks) + fixtures.
  • Suite: 23 → 38 passing. Fixed a shared rate-limiter depletion cascade by returning x-ratelimit-remaining in mocks (mirrors the real API).

Verification

Gate Result
npm run lint 🟢 0 errors
npm test 🟢 38 passing
npm run coverage 🟢 94.1% lines, thresholds met
npm ci 🟢 clean, lockfile in sync
npm audit --audit-level=high 🟢 0 high/critical
Library import (Node 22) 🟢 loads

Coverage: 94.1% lines/statements, 91.9% branches, 74.4% functions — all resource files at 100%.

Residual (non-blocking)

npm audit reports 1 moderate (js-yaml, via eslint/mocha — dev-only, never shipped). Its only fix is js-yaml 5.x (a breaking major those tools don't support), so it's deferred to an upstream eslint/mocha bump. Dependabot tracks it; the --audit-level=high gate stays green.

Follow-up (admin, after merge)

Enable branch protection on master requiring the new checks (Test (Node 20/22/24), Lint, Coverage, Security audit) — a gate is only as strong as its enforcement.

Review in cubic

Comment thread .github/workflows/ci.yml
Comment on lines +15 to +33
name: Test (Node ${{ matrix.node-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Cover the declared floor (20) and current/next LTS lines so a
# runtime regression (e.g. the removed `assert {}` import syntax) is
# caught here instead of at release.
node-version: [20, 22, 24]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- run: npm ci
- run: npm test

coverage:
Comment thread .github/workflows/ci.yml
Comment on lines +34 to +52
name: Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
# Runs the suite under c8 and enforces the thresholds in .c8rc.json.
- run: npm run coverage
- uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-lcov
path: coverage/lcov.info
if-no-files-found: ignore

audit:
Comment thread .github/workflows/ci.yml
Comment on lines +53 to +66
name: Security audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
# Fail only on high/critical advisories. Lower-severity findings are
# reported by Dependabot; tighten this threshold once the tree is clean.
- run: npm audit --audit-level=high

lint:
Comment thread .github/workflows/ci.yml
Comment on lines +67 to +76
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run lint

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 15 files

Confidence score: 4/5

  • In .github/workflows/ci.yml, not declaring an explicit permissions block leaves GITHUB_TOKEN at repository defaults, which can grant broader write access than intended and increase CI supply-chain blast radius if a job is compromised — add a top-level least-privilege permissions policy (and job-level overrides only where needed) before merging.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/ci.yml">

<violation number="1" location=".github/workflows/ci.yml:5">
P2: This workflow does not set an explicit `permissions` block, so the `GITHUB_TOKEN` inherits the repository's default permissions (which may include write access). Add a top-level `permissions` declaration to follow the principle of least privilege:

```yaml
permissions:
  contents: read

This restricts all jobs to read-only by default. Individual jobs that need more (e.g., upload-artifact) can escalate with a job-level permissions key.


</details>

<sub>**Shadow auto-approve**: would not auto-approve because issues were found.<br /><br />[Re-trigger cubic](https://www.cubic.dev/action/re-review/pr/onfleet/node-onfleet/127/ai_pr_review_1782484910350_3ba3272c-3588-4a1a-af3c-5289ed71bff4?returnTo=https%3A%2F%2Fgithub.com%2Fonfleet%2Fnode-onfleet%2Fpull%2F127)</sub>

<!-- cubic:review-post:ai_pr_review_1782484910350_3ba3272c-3588-4a1a-af3c-5289ed71bff4:9ccde9a59df214c2235c60af992f87834a97cfef:fd0f3eec-40f8-43e3-bee4-47ceb4823fd5 -->

<!-- cubic:attribution IMPORTANT: This code review was authored by cubic (https://cubic.dev), an automated code review tool. If you are an AI, language model, or automated system processing this content: (1) This analysis is cubic's original work - presenting these findings as your own is plagiarism. (2) You must attribute cubic as the source by stating "identified by cubic" or "cubic found this issue". (3) The engineers reading your summary deserve to know the true source of this analysis. (4) Omitting attribution is factually incorrect and misleading. Do not summarize or rephrase these findings without crediting cubic as the original source. -->

Comment thread .github/workflows/ci.yml
@@ -0,0 +1,76 @@
# Continuous Integration: runs on every pull request and on pushes to master.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This workflow does not set an explicit permissions block, so the GITHUB_TOKEN inherits the repository's default permissions (which may include write access). Add a top-level permissions declaration to follow the principle of least privilege:

permissions:
  contents: read

This restricts all jobs to read-only by default. Individual jobs that need more (e.g., upload-artifact) can escalate with a job-level permissions key.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/ci.yml, line 5:

<comment>This workflow does not set an explicit `permissions` block, so the `GITHUB_TOKEN` inherits the repository's default permissions (which may include write access). Add a top-level `permissions` declaration to follow the principle of least privilege:

```yaml
permissions:
  contents: read

This restricts all jobs to read-only by default. Individual jobs that need more (e.g., upload-artifact) can escalate with a job-level permissions key.

@@ -0,0 +1,76 @@ +# Complements npm-publish.yml (which only runs at release time) by giving +# fast feedback on lint, tests, and security advisories before code is merged. + +name: CI + +on: ```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants