rename: FuzzForge → SecPipe

Rename the entire project from FuzzForge to SecPipe:
- Python packages: fuzzforge_cli → secpipe_cli, fuzzforge_common → secpipe_common,
  fuzzforge_mcp → secpipe_mcp, fuzzforge_tests → secpipe_tests
- Directories: fuzzforge-cli → secpipe-cli, fuzzforge-common → secpipe-common,
  fuzzforge-mcp → secpipe-mcp, fuzzforge-tests → secpipe-tests
- Environment variables: FUZZFORGE_* → SECPIPE_*
- MCP server name: SecPipe MCP Server
- CI workflows, Makefile, Dockerfile, hub-config, NOTICE updated
- Fix mcp-server.yml to use uvicorn secpipe_mcp.application:app
This commit is contained in:
AFredefon
2026-04-09 04:10:46 +02:00
parent bbf864e88b
commit be009a4094
120 changed files with 866 additions and 800 deletions
+30
View File
@@ -0,0 +1,30 @@
PACKAGE=$(word 1, $(shell uv version))
VERSION=$(word 2, $(shell uv version))
SOURCES=./src
.PHONY: clean format mypy ruff version
clean:
@find . -type d \( \
-name '*.egg-info' \
-o -name '.mypy_cache' \
-o -name '.pytest_cache' \
-o -name '.ruff_cache' \
-o -name '__pycache__' \
\) -printf 'removing directory %p\n' -exec rm -rf {} +
cloc:
cloc $(SOURCES)
format:
uv run ruff format $(SOURCES)
mypy:
uv run mypy $(SOURCES)
ruff:
uv run ruff check --fix $(SOURCES)
version:
@echo '$(PACKAGE)@$(VERSION)'
+3
View File
@@ -0,0 +1,3 @@
# SecPipe Tests
Common test utilities and fixtures for SecPipe packages.
+12
View File
@@ -0,0 +1,12 @@
[mypy]
plugins = pydantic.mypy
strict = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_return_any = True
[mypy-boto3.*]
ignore_missing_imports = True
[mypy-testcontainers.*]
ignore_missing_imports = True
+23
View File
@@ -0,0 +1,23 @@
[project]
name = "secpipe-tests"
version = "0.0.1"
description = "Common test utilities and fixtures for SecPipe packages."
authors = []
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
"podman==5.6.0",
"pydantic>=2.12.4",
"pytest==9.0.2",
"secpipe-common==0.0.1",
]
[project.optional-dependencies]
lints = [
"bandit==1.8.6",
"mypy==1.18.2",
"ruff==0.14.4",
]
[tool.uv.sources]
secpipe-common = { workspace = true }
+16
View File
@@ -0,0 +1,16 @@
line-length = 120
[lint]
select = [ "ALL" ]
ignore = [
"COM812", # conflicts with the formatter
"D100", # ignoring missing docstrings in public modules
"D104", # ignoring missing docstrings in public packages
"D203", # conflicts with 'D211'
"D213", # conflicts with 'D212'
"TD002", # ignoring missing author in 'TODO' statements
"TD003", # ignoring missing issue link in 'TODO' statements
"PLR0913", # allowing functions with many arguments in tests (required for fixtures)
"PLR2004", # allowing comparisons using unamed numerical constants in tests
"S101", # allowing 'assert' statements in tests
]
@@ -0,0 +1,9 @@
"""Common test utilities and fixtures for SecPipe packages.
This package provides shared test utilities, fixtures, and helpers that can be
reused across multiple SecPipe packages to reduce code duplication and ensure
consistency in testing approaches.
"""
__all__ = []
@@ -0,0 +1,22 @@
"""Pytest configuration for shared fixtures.
This conftest.py makes fixtures available to any test that imports from
secpipe_tests. Test packages should add 'pytest_plugins = ["secpipe_tests.fixtures"]'
to their conftest.py to use these shared fixtures.
"""
# Import fixtures to make them available
from secpipe_tests.fixtures import (
minio_container,
random_module_execution_identifier,
random_project_identifier,
storage_configuration,
)
__all__ = [
"minio_container",
"random_module_execution_identifier",
"random_project_identifier",
"storage_configuration",
]
+144
View File
@@ -0,0 +1,144 @@
"""Common test fixtures for SecPipe packages.
Provides reusable fixtures for generating random identifiers and other
common test utilities shared across multiple SecPipe packages.
"""
import random
import string
from os import environ
from typing import TYPE_CHECKING
from uuid import uuid4, uuid7
import pytest
from secpipe_common.sandboxes.engines.podman.configuration import PodmanConfiguration
from podman import PodmanClient
from pydantic import UUID7
# Type aliases for identifiers
type SecPipeProjectIdentifier = UUID7
type SecPipeExecutionIdentifier = UUID7
# Constants for validation
SECPIPE_PROJECT_NAME_LENGTH_MIN: int = 3
SECPIPE_PROJECT_NAME_LENGTH_MAX: int = 64
SECPIPE_PROJECT_DESCRIPTION_LENGTH_MAX: int = 256
if TYPE_CHECKING:
from collections.abc import Callable, Generator
from pathlib import Path
def generate_random_string(
min_length: int,
max_length: int,
) -> str:
"""TODO."""
return "".join(random.choices(population=string.printable, k=random.randint(min_length, max_length))) # noqa: S311
# ===== Project Fixtures =====
@pytest.fixture
def random_project_name() -> Callable[[], str]:
"""Generate random project names."""
def inner() -> str:
return generate_random_string(
min_length=SECPIPE_PROJECT_NAME_LENGTH_MIN,
max_length=SECPIPE_PROJECT_NAME_LENGTH_MAX,
)
return inner
@pytest.fixture
def random_project_description() -> Callable[[], str]:
"""Generate random project descriptions."""
def inner() -> str:
return generate_random_string(
min_length=1,
max_length=SECPIPE_PROJECT_DESCRIPTION_LENGTH_MAX,
)
return inner
@pytest.fixture
def random_project_identifier() -> Callable[[], SecPipeProjectIdentifier]:
"""Generate random project identifiers.
Returns a callable that generates fresh UUID7 identifiers for each call.
This pattern allows generating multiple unique identifiers within a single test.
:return: Callable that generates project identifiers.
"""
def inner() -> SecPipeProjectIdentifier:
return uuid7()
return inner
@pytest.fixture
def random_execution_identifier() -> Callable[[], SecPipeExecutionIdentifier]:
"""Generate random execution identifiers.
Returns a callable that generates fresh UUID7 identifiers for each call.
This pattern allows generating multiple unique identifiers within a single test.
:return: Callable that generates execution identifiers.
"""
def inner() -> SecPipeExecutionIdentifier:
return uuid7()
return inner
@pytest.fixture
def podman_socket() -> str:
"""TODO."""
socket: str = environ.get("DOCKER_HOST", "")
return socket
@pytest.fixture
def podman_client(podman_socket: str) -> Generator[PodmanClient]:
"""TODO."""
with PodmanClient(base_url=podman_socket) as client:
yield client
@pytest.fixture
def podman_engine_configuration(podman_socket: str) -> PodmanConfiguration:
"""TODO."""
return PodmanConfiguration(socket=podman_socket)
DOCKERFILE: str = 'FROM docker.io/debian:trixie\nCMD ["/bin/sh"]'
@pytest.fixture
def path_to_oci(podman_client: PodmanClient, tmp_path: Path) -> Generator[Path]:
"""TODO."""
dockerfile: Path = tmp_path / "Dockerfile"
dockerfile.write_text(DOCKERFILE)
identifier = str(uuid4())
image, _ = podman_client.images.build(
path=tmp_path,
dockerfile=dockerfile.name,
tag=identifier,
)
path: Path = tmp_path / "image.oci"
with path.open(mode="wb") as file:
for chunk in image.save():
file.write(chunk)
podman_client.images.get(name=identifier).remove()
yield path
path.unlink(missing_ok=True)