socketsecurity 2.2.90__tar.gz → 2.2.91__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/workflows/version-check.yml +36 -9
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.hooks/sync_version.py +56 -7
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/PKG-INFO +33 -3
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/README.md +30 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/pyproject.toml +3 -3
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/__init__.py +1 -1
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/config.py +70 -0
- socketsecurity-2.2.91/socketsecurity/fossa_compat.py +459 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/output.py +107 -46
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/socketcli.py +46 -21
- socketsecurity-2.2.91/tests/fixtures/fossa/README.md +18 -0
- socketsecurity-2.2.91/tests/fixtures/fossa/fossa-analyze-empty.json +13 -0
- socketsecurity-2.2.91/tests/fixtures/fossa/fossa-analyze-populated.json +1275 -0
- socketsecurity-2.2.91/tests/fixtures/fossa/fossa-sbom-empty-deep.json +1 -0
- socketsecurity-2.2.91/tests/fixtures/fossa/fossa-sbom-populated.json +1 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_cli_config.py +47 -2
- socketsecurity-2.2.91/tests/unit/test_fossa_compat.py +470 -0
- socketsecurity-2.2.91/tests/unit/test_fossa_parity.py +106 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_output.py +265 -24
- socketsecurity-2.2.91/tests/unit/test_socketcli.py +134 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/uv.lock +2 -2
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/CODEOWNERS +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/PULL_REQUEST_TEMPLATE/bug-fix.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/PULL_REQUEST_TEMPLATE/improvement.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/workflows/docker-stable.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/workflows/e2e-test.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/workflows/pr-preview.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/workflows/python-tests.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/workflows/release.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.github/zizmor.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.gitignore +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.pre-commit-config.yaml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/.python-version +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/CHANGELOG.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/Dockerfile +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/LICENSE +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/Makefile +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/docs/ci-cd.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/docs/cli-reference.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/docs/development.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/docs/troubleshooting.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/examples/config/sarif-dashboard-parity.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/examples/config/sarif-dashboard-parity.toml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/examples/config/sarif-diff-ci-cd.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/examples/config/sarif-diff-ci-cd.toml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/examples/config/sarif-instance-detail.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/examples/config/sarif-instance-detail.toml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/instructions/gitlab-commit-status/uat.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/pytest.ini +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/scripts/build_container.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/scripts/build_container_flexible.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/scripts/deploy-test-docker.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/scripts/deploy-test-pypi.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/scripts/docker-entrypoint.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/scripts/run.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/session.md +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socket.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/__init__.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/alert_selection.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/classes.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/cli_client.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/exceptions.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/git_interface.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/helper/__init__.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/helper/socket_facts_loader.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/lazy_file_loader.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/logging.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/messages.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/resource_utils.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/scm/__init__.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/scm/base.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/scm/client.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/scm/github.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/scm/gitlab.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/scm_comments.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/socket_config.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/tools/reachability.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/core/utils.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/__init__.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/base.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/formatters/__init__.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/formatters/slack.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/jira.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/manager.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/slack.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/teams.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/socketsecurity/plugins/webhook.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/__init__.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/core/conftest.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/core/create_diff_input.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/core/test_diff_alerts.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/core/test_diff_generation.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/core/test_has_manifest_files.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/core/test_package_and_alerts.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/core/test_sdk_methods.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/core/test_supporting_methods.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/fullscans/create_response.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/fullscans/diff/stream_diff.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/fullscans/diff/stream_diff_full.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/fullscans/head_scan/metadata.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/fullscans/head_scan/stream_scan.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/fullscans/head_scan/stream_scan_full.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/fullscans/new_scan/metadata.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/fullscans/new_scan/stream_scan.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/repos/repo_info_error.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/repos/repo_info_no_head.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/repos/repo_info_success.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/data/settings/security-policy.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/e2e/fixtures/simple-npm/index.js +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/e2e/fixtures/simple-npm/package.json +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/e2e/fixtures/simple-pypi/requirements.txt +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/e2e/validate-gitlab.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/e2e/validate-json.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/e2e/validate-reachability.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/e2e/validate-sarif.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/e2e/validate-scan.sh +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/__init__.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_alert_selection.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_client.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_config.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_dependency_overview.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_disable_ignore.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_gitlab_auth.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_gitlab_auth_fallback.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_gitlab_commit_status.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_gitlab_format.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_ignore_telemetry_filtering.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/tests/unit/test_slack_plugin.py +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/workflows/bitbucket-pipelines.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/workflows/buildkite.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/workflows/github-actions.yml +0 -0
- {socketsecurity-2.2.90 → socketsecurity-2.2.91}/workflows/gitlab-ci.yml +0 -0
|
@@ -35,16 +35,43 @@ jobs:
|
|
|
35
35
|
MAIN_VERSION=$(git show origin/main:socketsecurity/__init__.py | grep -o "__version__.*" | awk '{print $3}' | tr -d "'")
|
|
36
36
|
echo "MAIN_VERSION=$MAIN_VERSION" >> $GITHUB_ENV
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
export PR_VERSION
|
|
39
|
+
export MAIN_VERSION
|
|
40
|
+
|
|
41
|
+
# Compare against both main and latest published PyPI release.
|
|
42
|
+
python3 <<'PY'
|
|
43
|
+
import json
|
|
44
|
+
import os
|
|
45
|
+
import urllib.request
|
|
40
46
|
from packaging import version
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
pr_ver = version.parse(os.environ["PR_VERSION"])
|
|
49
|
+
main_ver = version.parse(os.environ["MAIN_VERSION"])
|
|
50
|
+
|
|
51
|
+
with urllib.request.urlopen("https://pypi.org/pypi/socketsecurity/json") as response:
|
|
52
|
+
pypi_data = json.load(response)
|
|
53
|
+
|
|
54
|
+
published_versions = []
|
|
55
|
+
for raw in pypi_data.get("releases", {}).keys():
|
|
56
|
+
parsed = version.parse(raw)
|
|
57
|
+
if not parsed.is_prerelease and not parsed.is_devrelease:
|
|
58
|
+
published_versions.append(parsed)
|
|
59
|
+
|
|
60
|
+
pypi_ver = max(published_versions) if published_versions else version.parse("0.0.0")
|
|
61
|
+
required_floor = max(main_ver, pypi_ver)
|
|
62
|
+
|
|
63
|
+
if pr_ver <= required_floor:
|
|
64
|
+
print(
|
|
65
|
+
f"❌ Version must be greater than main and PyPI! "
|
|
66
|
+
f"Main: {main_ver}, PyPI: {pypi_ver}, PR: {pr_ver}"
|
|
67
|
+
)
|
|
68
|
+
raise SystemExit(1)
|
|
69
|
+
|
|
70
|
+
print(
|
|
71
|
+
f"✅ Version properly incremented. "
|
|
72
|
+
f"Main: {main_ver}, PyPI: {pypi_ver}, PR: {pr_ver}"
|
|
73
|
+
)
|
|
74
|
+
PY
|
|
48
75
|
|
|
49
76
|
- name: Require uv.lock update when pyproject changes
|
|
50
77
|
run: |
|
|
@@ -12,7 +12,9 @@ UV_LOCK_FILE = pathlib.Path("uv.lock")
|
|
|
12
12
|
|
|
13
13
|
VERSION_PATTERN = re.compile(r"__version__\s*=\s*['\"]([^'\"]+)['\"]")
|
|
14
14
|
PYPROJECT_PATTERN = re.compile(r'^version\s*=\s*".*"$', re.MULTILINE)
|
|
15
|
-
|
|
15
|
+
STABLE_VERSION_PATTERN = re.compile(r"^\d+\.\d+\.\d+$")
|
|
16
|
+
PYPI_PROD_API = "https://pypi.org/pypi/socketsecurity/json"
|
|
17
|
+
PYPI_TEST_API = "https://test.pypi.org/pypi/socketsecurity/json"
|
|
16
18
|
|
|
17
19
|
def read_version_from_init(path: pathlib.Path) -> str:
|
|
18
20
|
content = path.read_text()
|
|
@@ -39,17 +41,39 @@ def bump_patch_version(version: str) -> str:
|
|
|
39
41
|
parts[-1] = str(int(parts[-1]) + 1)
|
|
40
42
|
return ".".join(parts)
|
|
41
43
|
|
|
42
|
-
def
|
|
44
|
+
def parse_stable_version(version: str):
|
|
45
|
+
if not STABLE_VERSION_PATTERN.fullmatch(version):
|
|
46
|
+
return None
|
|
47
|
+
return tuple(int(part) for part in version.split("."))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def format_stable_version(version_parts) -> str:
|
|
51
|
+
return ".".join(str(part) for part in version_parts)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def fetch_existing_versions(api_url: str) -> set:
|
|
43
55
|
try:
|
|
44
|
-
with urllib.request.urlopen(
|
|
56
|
+
with urllib.request.urlopen(api_url) as response:
|
|
45
57
|
data = json.load(response)
|
|
46
58
|
return set(data.get("releases", {}).keys())
|
|
47
59
|
except Exception as e:
|
|
48
|
-
print(f"⚠️ Warning: Failed to fetch
|
|
60
|
+
print(f"⚠️ Warning: Failed to fetch versions from {api_url}: {e}")
|
|
49
61
|
return set()
|
|
50
62
|
|
|
63
|
+
|
|
64
|
+
def fetch_latest_stable_pypi_version():
|
|
65
|
+
versions = fetch_existing_versions(PYPI_PROD_API)
|
|
66
|
+
stable_versions = []
|
|
67
|
+
for ver in versions:
|
|
68
|
+
parsed = parse_stable_version(ver)
|
|
69
|
+
if parsed is not None:
|
|
70
|
+
stable_versions.append(parsed)
|
|
71
|
+
if not stable_versions:
|
|
72
|
+
return None
|
|
73
|
+
return max(stable_versions)
|
|
74
|
+
|
|
51
75
|
def find_next_available_dev_version(base_version: str) -> str:
|
|
52
|
-
existing_versions = fetch_existing_versions()
|
|
76
|
+
existing_versions = fetch_existing_versions(PYPI_TEST_API)
|
|
53
77
|
for i in range(1, 100):
|
|
54
78
|
candidate = f"{base_version}.dev{i}"
|
|
55
79
|
if candidate not in existing_versions:
|
|
@@ -57,6 +81,19 @@ def find_next_available_dev_version(base_version: str) -> str:
|
|
|
57
81
|
print("❌ Could not find available .devN slot after 100 attempts.")
|
|
58
82
|
sys.exit(1)
|
|
59
83
|
|
|
84
|
+
|
|
85
|
+
def find_next_stable_patch_version(current_version: str) -> str:
|
|
86
|
+
current_stable = current_version.split(".dev")[0] if ".dev" in current_version else current_version
|
|
87
|
+
current_parts = parse_stable_version(current_stable)
|
|
88
|
+
if current_parts is None:
|
|
89
|
+
print(f"❌ Unsupported version format for stable bump: {current_version}")
|
|
90
|
+
sys.exit(1)
|
|
91
|
+
|
|
92
|
+
latest_pypi_parts = fetch_latest_stable_pypi_version()
|
|
93
|
+
base_parts = max([current_parts, latest_pypi_parts] if latest_pypi_parts else [current_parts])
|
|
94
|
+
next_parts = (base_parts[0], base_parts[1], base_parts[2] + 1)
|
|
95
|
+
return format_stable_version(next_parts)
|
|
96
|
+
|
|
60
97
|
def inject_version(version: str):
|
|
61
98
|
print(f"🔁 Updating version to: {version}")
|
|
62
99
|
|
|
@@ -105,13 +142,25 @@ def main():
|
|
|
105
142
|
print(f"⚠️ Version was unchanged — auto-bumped. Please git add{lock_hint} + commit again.")
|
|
106
143
|
sys.exit(0)
|
|
107
144
|
else:
|
|
108
|
-
new_version =
|
|
145
|
+
new_version = find_next_stable_patch_version(current_version)
|
|
109
146
|
inject_version(new_version)
|
|
110
147
|
uv_lock_changed = run_uv_lock()
|
|
111
148
|
lock_hint = " and uv.lock" if uv_lock_changed else ""
|
|
112
|
-
print(f"⚠️ Version was unchanged — auto-bumped. Please git add{lock_hint} + commit again.")
|
|
149
|
+
print(f"⚠️ Version was unchanged — auto-bumped to {new_version}. Please git add{lock_hint} + commit again.")
|
|
113
150
|
sys.exit(1)
|
|
114
151
|
else:
|
|
152
|
+
if not dev_mode:
|
|
153
|
+
current_parts = parse_stable_version(current_version)
|
|
154
|
+
latest_pypi_parts = fetch_latest_stable_pypi_version()
|
|
155
|
+
if current_parts is not None and latest_pypi_parts is not None and current_parts <= latest_pypi_parts:
|
|
156
|
+
next_parts = (latest_pypi_parts[0], latest_pypi_parts[1], latest_pypi_parts[2] + 1)
|
|
157
|
+
new_version = format_stable_version(next_parts)
|
|
158
|
+
inject_version(new_version)
|
|
159
|
+
uv_lock_changed = run_uv_lock()
|
|
160
|
+
lock_hint = " and uv.lock" if uv_lock_changed else ""
|
|
161
|
+
print(f"⚠️ Version {current_version} is already published on PyPI — auto-bumped to {new_version}. Please git add{lock_hint} + commit again.")
|
|
162
|
+
sys.exit(1)
|
|
163
|
+
|
|
115
164
|
uv_lock_changed = run_uv_lock()
|
|
116
165
|
if uv_lock_changed:
|
|
117
166
|
print("⚠️ Version already bumped, but uv.lock was out of date and has been updated. Please git add uv.lock + commit again.")
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: socketsecurity
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.91
|
|
4
4
|
Summary: Socket Security CLI for CI/CD
|
|
5
|
-
Project-URL: Homepage, https://
|
|
5
|
+
Project-URL: Homepage, https://socket.dev
|
|
6
6
|
Author-email: Douglas Coburn <douglas@socket.dev>
|
|
7
7
|
Maintainer-email: Douglas Coburn <douglas@socket.dev>
|
|
8
8
|
License: MIT License
|
|
@@ -41,7 +41,7 @@ Requires-Dist: packaging
|
|
|
41
41
|
Requires-Dist: prettytable
|
|
42
42
|
Requires-Dist: python-dotenv
|
|
43
43
|
Requires-Dist: requests
|
|
44
|
-
Requires-Dist: socketdev<4.0.0,>=3.
|
|
44
|
+
Requires-Dist: socketdev<4.0.0,>=3.0.33
|
|
45
45
|
Provides-Extra: dev
|
|
46
46
|
Requires-Dist: hatch; extra == 'dev'
|
|
47
47
|
Requires-Dist: pre-commit; extra == 'dev'
|
|
@@ -142,6 +142,7 @@ socketcli \
|
|
|
142
142
|
| Use case | Recommended mode | Key flags |
|
|
143
143
|
|:--|:--|:--|
|
|
144
144
|
| Basic policy enforcement in CI | Diff-based policy check | `--strict-blocking` |
|
|
145
|
+
| Legal/compliance artifact generation | Legal preset | `--legal` |
|
|
145
146
|
| Reachable-focused SARIF for reporting | Full-scope grouped SARIF | `--reach --sarif-scope full --sarif-grouping alert --sarif-reachability reachable --sarif-file <path>` |
|
|
146
147
|
| Detailed reachability export for investigations | Full-scope instance SARIF | `--reach --sarif-scope full --sarif-grouping instance --sarif-reachability all --sarif-file <path>` |
|
|
147
148
|
| Net-new PR findings only | Diff-scope SARIF | `--reach --sarif-scope diff --sarif-reachability reachable --sarif-file <path>` |
|
|
@@ -192,6 +193,35 @@ Run:
|
|
|
192
193
|
socketcli --config .socketcli.toml --target-path .
|
|
193
194
|
```
|
|
194
195
|
|
|
196
|
+
Legal/compliance preset example:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
socketcli --legal --target-path .
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
This preset enables license generation and writes default artifacts unless you override them:
|
|
203
|
+
- `socket-report.json`
|
|
204
|
+
- `socket-summary.txt`
|
|
205
|
+
- `socket-report-link.txt`
|
|
206
|
+
- `socket-sbom.json`
|
|
207
|
+
- `socket-license.json`
|
|
208
|
+
|
|
209
|
+
FOSSA-compatibility shaped legal artifacts:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
socketcli --legal-format fossa --target-path .
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
This switches the JSON report and legal artifact payloads to FOSSA-style compatibility shapes:
|
|
216
|
+
- the analyze artifact becomes a `project` / `vulnerability` / `licensing` / `quality` report
|
|
217
|
+
- the SBOM artifact becomes a FOSSA-attribution-style payload with `copyrightsByLicense`, `deepDependencies`, `directDependencies`, `licenses`, and `project` keys
|
|
218
|
+
|
|
219
|
+
When `--legal-format fossa` is used without explicit output paths, the defaults are closer to the FOSSA pipeline contract:
|
|
220
|
+
- `fossa-analyze.json`
|
|
221
|
+
- `fossa-test.txt`
|
|
222
|
+
- `fossa-link.txt`
|
|
223
|
+
- `fossa-sbom.json`
|
|
224
|
+
|
|
195
225
|
Reference sample configs:
|
|
196
226
|
|
|
197
227
|
TOML:
|
|
@@ -84,6 +84,7 @@ socketcli \
|
|
|
84
84
|
| Use case | Recommended mode | Key flags |
|
|
85
85
|
|:--|:--|:--|
|
|
86
86
|
| Basic policy enforcement in CI | Diff-based policy check | `--strict-blocking` |
|
|
87
|
+
| Legal/compliance artifact generation | Legal preset | `--legal` |
|
|
87
88
|
| Reachable-focused SARIF for reporting | Full-scope grouped SARIF | `--reach --sarif-scope full --sarif-grouping alert --sarif-reachability reachable --sarif-file <path>` |
|
|
88
89
|
| Detailed reachability export for investigations | Full-scope instance SARIF | `--reach --sarif-scope full --sarif-grouping instance --sarif-reachability all --sarif-file <path>` |
|
|
89
90
|
| Net-new PR findings only | Diff-scope SARIF | `--reach --sarif-scope diff --sarif-reachability reachable --sarif-file <path>` |
|
|
@@ -134,6 +135,35 @@ Run:
|
|
|
134
135
|
socketcli --config .socketcli.toml --target-path .
|
|
135
136
|
```
|
|
136
137
|
|
|
138
|
+
Legal/compliance preset example:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
socketcli --legal --target-path .
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This preset enables license generation and writes default artifacts unless you override them:
|
|
145
|
+
- `socket-report.json`
|
|
146
|
+
- `socket-summary.txt`
|
|
147
|
+
- `socket-report-link.txt`
|
|
148
|
+
- `socket-sbom.json`
|
|
149
|
+
- `socket-license.json`
|
|
150
|
+
|
|
151
|
+
FOSSA-compatibility shaped legal artifacts:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
socketcli --legal-format fossa --target-path .
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
This switches the JSON report and legal artifact payloads to FOSSA-style compatibility shapes:
|
|
158
|
+
- the analyze artifact becomes a `project` / `vulnerability` / `licensing` / `quality` report
|
|
159
|
+
- the SBOM artifact becomes a FOSSA-attribution-style payload with `copyrightsByLicense`, `deepDependencies`, `directDependencies`, `licenses`, and `project` keys
|
|
160
|
+
|
|
161
|
+
When `--legal-format fossa` is used without explicit output paths, the defaults are closer to the FOSSA pipeline contract:
|
|
162
|
+
- `fossa-analyze.json`
|
|
163
|
+
- `fossa-test.txt`
|
|
164
|
+
- `fossa-link.txt`
|
|
165
|
+
- `fossa-sbom.json`
|
|
166
|
+
|
|
137
167
|
Reference sample configs:
|
|
138
168
|
|
|
139
169
|
TOML:
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "socketsecurity"
|
|
9
|
-
version = "2.2.
|
|
9
|
+
version = "2.2.91"
|
|
10
10
|
requires-python = ">= 3.11"
|
|
11
11
|
license = {"file" = "LICENSE"}
|
|
12
12
|
dependencies = [
|
|
@@ -16,7 +16,7 @@ dependencies = [
|
|
|
16
16
|
'GitPython',
|
|
17
17
|
'packaging',
|
|
18
18
|
'python-dotenv',
|
|
19
|
-
"socketdev>=3.
|
|
19
|
+
"socketdev>=3.0.33,<4.0.0",
|
|
20
20
|
"bs4>=0.0.2",
|
|
21
21
|
"markdown>=3.10",
|
|
22
22
|
]
|
|
@@ -57,7 +57,7 @@ socketcli = "socketsecurity.socketcli:cli"
|
|
|
57
57
|
socketclidev = "socketsecurity.socketcli:cli"
|
|
58
58
|
|
|
59
59
|
[project.urls]
|
|
60
|
-
Homepage = "https://
|
|
60
|
+
Homepage = "https://socket.dev"
|
|
61
61
|
|
|
62
62
|
[tool.coverage.run]
|
|
63
63
|
source = ["socketsecurity"]
|
|
@@ -79,6 +79,7 @@ class CliConfig:
|
|
|
79
79
|
enable_debug: bool = False
|
|
80
80
|
allow_unverified: bool = False
|
|
81
81
|
enable_json: bool = False
|
|
82
|
+
json_file: Optional[str] = None
|
|
82
83
|
enable_sarif: bool = False
|
|
83
84
|
sarif_file: Optional[str] = None
|
|
84
85
|
sarif_scope: str = "diff"
|
|
@@ -86,6 +87,8 @@ class CliConfig:
|
|
|
86
87
|
sarif_reachability: str = "all"
|
|
87
88
|
enable_gitlab_security: bool = False
|
|
88
89
|
gitlab_security_file: Optional[str] = None
|
|
90
|
+
summary_file: Optional[str] = None
|
|
91
|
+
report_link_file: Optional[str] = None
|
|
89
92
|
disable_overview: bool = False
|
|
90
93
|
disable_security_issue: bool = False
|
|
91
94
|
files: str = None
|
|
@@ -137,6 +140,8 @@ class CliConfig:
|
|
|
137
140
|
reach_continue_on_no_source_files: bool = False
|
|
138
141
|
max_purl_batch_size: int = 5000
|
|
139
142
|
enable_commit_status: bool = False
|
|
143
|
+
legal: bool = False
|
|
144
|
+
legal_format: str = "socket"
|
|
140
145
|
config_file: Optional[str] = None
|
|
141
146
|
|
|
142
147
|
@classmethod
|
|
@@ -194,6 +199,7 @@ class CliConfig:
|
|
|
194
199
|
'enable_diff': args.enable_diff,
|
|
195
200
|
'allow_unverified': args.allow_unverified,
|
|
196
201
|
'enable_json': args.enable_json,
|
|
202
|
+
'json_file': args.json_file,
|
|
197
203
|
'enable_sarif': args.enable_sarif,
|
|
198
204
|
'sarif_file': args.sarif_file,
|
|
199
205
|
'sarif_scope': args.sarif_scope,
|
|
@@ -201,6 +207,8 @@ class CliConfig:
|
|
|
201
207
|
'sarif_reachability': args.sarif_reachability,
|
|
202
208
|
'enable_gitlab_security': args.enable_gitlab_security,
|
|
203
209
|
'gitlab_security_file': args.gitlab_security_file,
|
|
210
|
+
'summary_file': args.summary_file,
|
|
211
|
+
'report_link_file': args.report_link_file,
|
|
204
212
|
'disable_overview': args.disable_overview,
|
|
205
213
|
'disable_security_issue': args.disable_security_issue,
|
|
206
214
|
'files': args.files,
|
|
@@ -246,9 +254,40 @@ class CliConfig:
|
|
|
246
254
|
'reach_continue_on_no_source_files': args.reach_continue_on_no_source_files,
|
|
247
255
|
'max_purl_batch_size': args.max_purl_batch_size,
|
|
248
256
|
'enable_commit_status': args.enable_commit_status,
|
|
257
|
+
'legal': args.legal or args.legal_format == "fossa",
|
|
258
|
+
'legal_format': args.legal_format,
|
|
249
259
|
'config_file': args.config_file,
|
|
250
260
|
'version': __version__
|
|
251
261
|
}
|
|
262
|
+
|
|
263
|
+
if config_args['legal']:
|
|
264
|
+
config_args['generate_license'] = True
|
|
265
|
+
if not config_args['json_file']:
|
|
266
|
+
config_args['json_file'] = "socket-report.json"
|
|
267
|
+
if not config_args['summary_file']:
|
|
268
|
+
config_args['summary_file'] = "socket-summary.txt"
|
|
269
|
+
if not config_args['report_link_file']:
|
|
270
|
+
config_args['report_link_file'] = "socket-report-link.txt"
|
|
271
|
+
if not config_args['sbom_file']:
|
|
272
|
+
config_args['sbom_file'] = "socket-sbom.json"
|
|
273
|
+
if config_args['license_file_name'] == "license_output.json":
|
|
274
|
+
config_args['license_file_name'] = "socket-license.json"
|
|
275
|
+
|
|
276
|
+
if config_args['legal_format'] == "fossa":
|
|
277
|
+
if not args.json_file:
|
|
278
|
+
config_args['json_file'] = "fossa-analyze.json"
|
|
279
|
+
if not args.summary_file:
|
|
280
|
+
config_args['summary_file'] = "fossa-test.txt"
|
|
281
|
+
if not args.report_link_file:
|
|
282
|
+
config_args['report_link_file'] = "fossa-link.txt"
|
|
283
|
+
if not args.license_file_name:
|
|
284
|
+
# argparse always provides a default, so this branch is defensive only
|
|
285
|
+
config_args['license_file_name'] = "fossa-sbom.json"
|
|
286
|
+
elif args.license_file_name == "license_output.json":
|
|
287
|
+
config_args['license_file_name'] = "fossa-sbom.json"
|
|
288
|
+
if not args.sbom_file:
|
|
289
|
+
# FOSSA's "SBOM" artifact is the attribution payload; suppress the extra Socket-only SBOM file by default.
|
|
290
|
+
config_args['sbom_file'] = None
|
|
252
291
|
excluded_ecosystems = config_args["excluded_ecosystems"]
|
|
253
292
|
if isinstance(excluded_ecosystems, list):
|
|
254
293
|
config_args["excluded_ecosystems"] = excluded_ecosystems
|
|
@@ -570,6 +609,12 @@ def create_argument_parser() -> argparse.ArgumentParser:
|
|
|
570
609
|
action="store_true",
|
|
571
610
|
help="Output in JSON format"
|
|
572
611
|
)
|
|
612
|
+
output_group.add_argument(
|
|
613
|
+
"--json-file",
|
|
614
|
+
dest="json_file",
|
|
615
|
+
metavar="<path>",
|
|
616
|
+
help="Output file path for JSON report"
|
|
617
|
+
)
|
|
573
618
|
output_group.add_argument(
|
|
574
619
|
"--enable-sarif",
|
|
575
620
|
dest="enable_sarif",
|
|
@@ -617,6 +662,18 @@ def create_argument_parser() -> argparse.ArgumentParser:
|
|
|
617
662
|
default="gl-dependency-scanning-report.json",
|
|
618
663
|
help="Output file path for GitLab Security report (default: gl-dependency-scanning-report.json)"
|
|
619
664
|
)
|
|
665
|
+
output_group.add_argument(
|
|
666
|
+
"--summary-file",
|
|
667
|
+
dest="summary_file",
|
|
668
|
+
metavar="<path>",
|
|
669
|
+
help="Output file path for a plain-text summary report"
|
|
670
|
+
)
|
|
671
|
+
output_group.add_argument(
|
|
672
|
+
"--report-link-file",
|
|
673
|
+
dest="report_link_file",
|
|
674
|
+
metavar="<path>",
|
|
675
|
+
help="Output file path for the Socket report link"
|
|
676
|
+
)
|
|
620
677
|
output_group.add_argument(
|
|
621
678
|
"--disable-overview",
|
|
622
679
|
dest="disable_overview",
|
|
@@ -750,6 +807,19 @@ def create_argument_parser() -> argparse.ArgumentParser:
|
|
|
750
807
|
action="store_true",
|
|
751
808
|
help="Disable SSL certificate verification for API requests"
|
|
752
809
|
)
|
|
810
|
+
advanced_group.add_argument(
|
|
811
|
+
"--legal",
|
|
812
|
+
dest="legal",
|
|
813
|
+
action="store_true",
|
|
814
|
+
help="Enable legal/compliance-friendly defaults and file outputs"
|
|
815
|
+
)
|
|
816
|
+
advanced_group.add_argument(
|
|
817
|
+
"--legal-format",
|
|
818
|
+
dest="legal_format",
|
|
819
|
+
choices=["socket", "fossa"],
|
|
820
|
+
default="socket",
|
|
821
|
+
help="Select the legal artifact format. 'socket' keeps Socket-native outputs; 'fossa' emits compatibility-shaped JSON artifacts."
|
|
822
|
+
)
|
|
753
823
|
config_group.add_argument(
|
|
754
824
|
"--include-module-folders",
|
|
755
825
|
dest="include_module_folders",
|