Contributing scan-action

Scan Action

Developer guidelines when contributing to scan-action

Getting started

In order to test and develop in the scan-action repo you will need the following dependencies installed:

  • Node.js (>= 20.11.0)
  • npm
  • Docker

Initial setup

Run once after cloning to install dependencies and development tools:

npm install

This command installs all dependencies and sets up Husky git hooks that automatically format code and rebuild the distribution files before commits.

Useful commands

Common commands for ongoing development:

  • npm run build - Bundle with ncc and normalize line endings
  • npm run lint - Check code with ESLint
  • npm run prettier - Auto-format code with Prettier
  • npm test - Complete test suite (lint + install Grype + build + run tests)
  • npm run run-tests - Run Jest tests only
  • npm run test:update-snapshots - Update test expectations (lint + install Grype + run tests with snapshot updates)
  • npm run audit - Run security audit on production dependencies
  • npm run update-deps - Update dependencies with npm-check-updates

Testing

Tests require Grype to be installed locally and a Docker registry for integration tests. Set up your test environment:

Install Grype locally:

npm run install-and-update-grype

Start local Docker registry:

docker run -d -p 5000:5000 --name registry registry:2

Tests automatically disable Grype database auto-update and validation to ensure consistent test results.

CI environment:

The GitHub Actions test workflow automatically:

  • Starts a Docker registry service on port 5000
  • Tests on Ubuntu, Windows, and macOS
  • Validates across multiple configurations (image/path/sbom sources, output formats)

Test types

The scan-action uses Jest for testing with several categories:

  • Unit tests (e.g., tests/action.test.js, tests/grype_command.test.js): Test individual functions in isolation by mocking GitHub Actions context and external dependencies.

  • Integration tests: Execute the full action workflow with real Grype invocations. These tests validate end-to-end functionality including downloading Grype, running scans, and generating output files.

  • SARIF validation tests (tests/sarif_output.test.js): Validate SARIF report structure and content using the @microsoft/jest-sarif library to ensure consistent output format and compliance with the SARIF specification.

  • Distribution tests (tests/dist.test.js): Verify that the committed dist/ directory is up-to-date with the source code.

Test fixtures:

The tests/fixtures/ directory contains sample projects and files for testing:

  • npm-project/ - Sample npm project for directory scanning
  • yarn-project/ - Sample yarn project for directory scanning
  • test_sbom.spdx.json - Sample SBOM file for SBOM scanning tests

SARIF output testing

The SARIF output tests validate report structure using the @microsoft/jest-sarif library. Tests normalize dynamic values (versions, fully qualified names) before validation to ensure consistent results across test runs.

The tests validate that:

  • Generated SARIF reports are valid according to the SARIF specification
  • Expected vulnerabilities are detected in test fixtures
  • Output structure remains consistent across runs

If you need to update test expectations, run:

npm run test:update-snapshots

Development workflow

Pre-commit hooks

The scan-action uses Husky to run automated checks before each commit:

  1. Code formatting - lint-staged runs Prettier on staged JavaScript files
  2. Distribution rebuild - Runs npm run precommit to rebuild dist/ directory
  3. Auto-staging - Automatically stages updated dist/ files

The hook is defined in .husky/pre-commit and ensures that distribution files are always synchronized with source code.

Code organization

The scan-action has a straightforward single-file architecture:

Main action (action.yml):

  • Entry point: index.js
  • Compiled to: dist/index.js
  • Downloads Grype, runs vulnerability scans, generates reports

Download Grype sub-action (download-grype/action.yml):

  • Entry point: Reuses dist/index.js with run: "download-grype" input
  • Provides standalone Grype download and caching
  • Returns cmd output with path to Grype binary

Key functions in index.js:

  • downloadGrype() - Downloads Grype using install script
  • downloadGrypeWindowsWorkaround() - Windows-specific download logic
  • installGrype() - Installs and caches Grype binary
  • sourceInput() - Validates mutually exclusive inputs (image/path/sbom)
  • run() - Main action execution flow
  • Command construction and output handling

GitHub Actions specifics

Debugging Actions

Enable detailed debug logging by setting a repository secret:

  1. Go to your repository Settings → Secrets and variables → Actions
  2. Add a new secret: ACTIONS_STEP_DEBUG = true

This enables debug logging from the @actions/toolkit libraries used throughout the action.

See the GitHub documentation for more details.

Testing Actions locally

CI validation:

The repository includes comprehensive CI workflows in .github/workflows/test.yml that:

  • Test on Ubuntu, Windows, and macOS
  • Validate distribution files are up-to-date
  • Test scanning images, directories, and SBOM files
  • Verify all output formats (SARIF, JSON, CycloneDX, table)
  • Test download-grype sub-action

Manual testing:

Test changes in your own workflows using the repository name and branch:

- uses: <your-username>/scan-action@<your-branch>
  with:
    image: "alpine:latest"

Or test locally using act if you have it installed.

Action runtime

The scan-action uses the Node.js 20 runtime (runs.using: node20 in action.yml). This runtime is provided by GitHub Actions and doesn’t require separate installation in workflows.

Next Steps

Understanding the Codebase

Contributing Your Work

Finding Work

Getting Help

Last modified November 26, 2025: allow local too invocation (d20d613)