Developer’s Guide
Developing VulnScout
Requirements
Docker or Podman (rootless or with your user in the
dockergroup)Node.js 22 (via NVM) is required to develop the frontend without issues. Installation guide: nvm
nvm install 22
nvm use 22
Project Structure
Directory |
Purpose |
|---|---|
|
Python/Flask backend (controllers, models, routes, helpers) |
|
React + TypeScript frontend (Vite, Tailwind CSS) |
|
Backend unit, integration, end-to-end and webapp tests |
|
Frontend unit tests (Jest + Testing Library) |
|
Alembic database migrations |
|
Local cache, outputs and example input files |
Modify the Backend
The backend is a Flask application located in src/. When running in dev mode the local src/ directory is mounted into the container, so any change is picked up immediately without rebuilding the image.
Start the container in dev mode:
./vulnscout --dev start
Or start with inputs and the web UI in one step:
./vulnscout --dev --serve \
--add-spdx /path/to/sbom.spdx.json \
--add-cve-check /path/to/cve-check.json
Flask will run with --debug when DEV_MODE=true is set in the container, enabling auto-reload on Python file changes.
Database changes
When editing the database schema, it is necessary to generate migrations. We use Alembic for that.
Instead of manually writing the migration code, we can take advantage of the auto-generation feature of Alembic. For this, run the backend in dev mode and run the following:
docker exec vulnscout \
flask --app src.bin.webapp db migrate -m "your migration title"
Modify the Frontend
By default, the frontend/ directory is not mounted into the container. To get hot-reload for frontend changes, run VulnScout in dev mode — this starts the backend container and a Vite dev server on the host side:
./vulnscout --dev start
Or combined with a serve command that also loads input files:
./vulnscout --dev --serve \
--add-spdx /path/to/sbom.spdx.json \
--add-cve-check /path/to/cve-check.json
The Vite dev server reads VITE_API_URL from frontend/.env (created automatically from the config, default: http://localhost:7275) to proxy API requests to the backend container.
If node_modules are not yet installed, the script will run npm install automatically.
Note: Dev mode requires
npmto be available on the host. Use NVM 22 to ensure compatibility.
Testing the Project
We use CQFD to run testing tools in a container.
Quick Setup with CQFD
Step 1: Setup CQFD and Docker/Podman
Install Docker: https://docs.docker.com/engine/install/
Or install Podman: https://podman.io/docs/installation
If using Docker, make sure it runs without requiring sudo. To do so, add your user to the docker group:
sudo groupadd docker
sudo usermod -aG docker $USER
Log out and log back in to apply the changes.
Install CQFD:
git clone https://github.com/savoirfairelinux/cqfd.git
cd cqfd
sudo make install
For more information, visit the CQFD GitHub repository.
Step 2: Initialise CQFD for this Project
Once installed, initialise the container image:
cqfd init
Note: This only needs to be done once, unless the container definition (
.cqfd/docker/Dockerfile) is modified.
Step 3: Run Tests with CQFD
To run all tests using CQFD, execute the following command:
cqfd
You can also run the tests separately:
cqfd -b test_backend
cqfd -b test_frontend
cqfd -b test_ci
Running Tests Locally (without CQFD)
Backend
Activate the virtual environment and install dev dependencies first:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements/dev.txt
Then run the tests:
# All unit tests
pytest tests/unit_tests/
# All webapp (API) tests
pytest tests/webapp_tests/
# All tests with coverage report in terminal
pytest --cov=src tests/
# All tests with HTML coverage report
pytest --cov-report html --cov=src tests/
# Type checking
mypy --config-file tests/tox.ini
Frontend
cd frontend
npm install
npm run test # unit tests
npm run coverage # tests + coverage report
npm run lint # ESLint
npm run build # production build check
Setting a Custom Version
The container version is set at build time via the VULNSCOUT_VERSION Docker build argument (defined in the Dockerfile).
It is baked into the image as both an environment variable (ENV VULNSCOUT_VERSION) and the OCI label org.opencontainers.image.version.
To build the image with a custom version:
docker build --build-arg VULNSCOUT_VERSION=v1.2.3 -t vulnscout:v1.2.3 .
The version is then available at runtime:
Inside the container: via the
VULNSCOUT_VERSIONenvironment variable (used by the Flask/api/versionendpoint andentrypoint.sh --version).From the host: via
docker inspecton the image label (used by./vulnscout --version).
Note: The
ci/release_tag.shscript automates version bumps by updating theARG VULNSCOUT_VERSIONline in theDockerfilealong with other version references.
Testing the Docker Image
You can test the Docker image using the provided tests Makefile.
To build and test the Docker image, run:
make -C tests docker_build docker_test docker_clean
Optionally set a custom tag:
export BUILD_TAG="my-local-test"
make -C tests docker_build docker_test docker_clean
Code Quality and Linting
Python Backend (Flask)
Task |
Command |
|---|---|
Linter |
|
Type checking |
|
Unit tests |
|
Coverage (terminal) |
|
Coverage (HTML) |
|
Frontend (React + TypeScript)
Task |
Command |
|---|---|
Dev server |
|
Build |
|
Unit tests |
|
Linter |
|
Coverage report |
|
Bash Scripts (vulnscout and entrypoint.sh)
Task |
Command |
|---|---|
Linter |
|
Note: Running
make -C tests testwill execute all linters and tests. Ifpre-commitis installed,flake8will also run on every commit. With CQFD, usecqfd -b testto run the full suite.
Pre-commit Hook
We use pre-commit to automatically run flake8 before every commit.
To enable it:
pip install pre-commit
pre-commit install
This helps enforce code quality and consistency across all contributions.
Building the Documentation
Full documentation is available in the doc/ directory as a Sphinx project.
Local Build
Install the required Python packages:
pip install sphinx myst-parser sphinx-rtd-theme
Then build the HTML documentation:
make -C doc html
The generated pages are in doc/build/html/. Open doc/build/html/index.html in your browser.
Building with CQFD
If you use CQFD, you can build the documentation inside the CQFD container:
cqfd -b documentation
The generated documentation will be available in doc/build/html/ on the host.
Release Process
VulnScout follows a semantic versioning strategy with development versions between releases.
Version Numbering Strategy
The versioning workflow follows these steps:
Current stable version:
v0.9.1(example - keep for now)Before creating a release tag: Bump version to
v0.10First PR after release: Bump version to
v0.10-devFeature PRs: Continue development with
-devsuffixRepeat the cycle