Drupal themes often include JavaScript build tools and browser-side packages. Those dependencies need a separate security check because Composer cannot inspect the npm ecosystem.
The production audit
npm-audit:
runs-on: ubuntu-latest
defaults:
run:
working-directory: docroot/themes/custom/swift_devportal_9
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: "24"
cache: npm
cache-dependency-path: docroot/themes/custom/swift_devportal_9/package-lock.json
- run: npm ci --ignore-scripts
- name: Audit production npm dependencies
continue-on-error: true
run: npm audit --omit=dev --audit-level=high
npm ci installs the exact dependency graph in package-lock.json and fails when the manifest and lockfile disagree. --ignore-scripts prevents dependency lifecycle scripts from executing in CI.
The audit uses --omit=dev to focus on packages shipped to production. --audit-level=high sets the failing threshold to high and critical findings.
Reporting-only adoption
This job currently has continue-on-error: true. GitHub records findings without blocking every push while existing dependency debt is addressed. Once the baseline is clean, remove that setting so new high-severity findings become a required gate.
Avoid running npm audit fix --force automatically. Forced upgrades can cross major versions. Upgrade deliberately, rebuild the theme, test browser behavior, and commit both package.json and package-lock.json.