socketsecurity 2.11.6__tar.gz → 2.11.10__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.
Files changed (175) hide show
  1. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/actions/setup-docker/action.yml +1 -1
  2. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/actions/setup-sfw/action.yml +1 -1
  3. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/dependency-audit.yml +1 -1
  4. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/dependency-review.yml +6 -6
  5. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/docker-stable.yml +1 -1
  6. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/e2e-test.yml +1 -1
  7. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/package-check.yml +2 -2
  8. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/pr-preview.yml +4 -4
  9. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/python-tests.yml +3 -3
  10. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/release.yml +46 -4
  11. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/workflows/version-check.yml +16 -0
  12. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/CHANGELOG.md +22 -0
  13. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/PKG-INFO +5 -5
  14. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/docs/cli-reference.md +1 -1
  15. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/pyproject.toml +5 -5
  16. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/__init__.py +1 -1
  17. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/__init__.py +17 -4
  18. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/tools/reachability.py +1 -1
  19. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_sdk_methods.py +68 -1
  20. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/uv.lock +57 -57
  21. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/CODEOWNERS +0 -0
  22. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/PULL_REQUEST_TEMPLATE/bug-fix.md +0 -0
  23. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
  24. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/PULL_REQUEST_TEMPLATE/improvement.md +0 -0
  25. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  26. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/actions/setup-hatch/action.yml +0 -0
  27. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/dependabot.yml +0 -0
  28. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.github/zizmor.yml +0 -0
  29. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.gitignore +0 -0
  30. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.hooks/sync_version.py +0 -0
  31. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.pre-commit-config.yaml +0 -0
  32. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/.python-version +0 -0
  33. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/CONTRIBUTING.md +0 -0
  34. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/Dockerfile +0 -0
  35. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/Dockerfile.preview +0 -0
  36. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/LICENSE +0 -0
  37. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/Makefile +0 -0
  38. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/README.md +0 -0
  39. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/benchmarks/manifest_discovery.py +0 -0
  40. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/docs/ci-cd.md +0 -0
  41. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/docs/development.md +0 -0
  42. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/docs/troubleshooting.md +0 -0
  43. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/examples/config/sarif-dashboard-parity.json +0 -0
  44. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/examples/config/sarif-dashboard-parity.toml +0 -0
  45. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/examples/config/sarif-diff-ci-cd.json +0 -0
  46. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/examples/config/sarif-diff-ci-cd.toml +0 -0
  47. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/examples/config/sarif-instance-detail.json +0 -0
  48. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/examples/config/sarif-instance-detail.toml +0 -0
  49. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/instructions/gitlab-commit-status/uat.md +0 -0
  50. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/pytest.ini +0 -0
  51. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/scripts/build_container.sh +0 -0
  52. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/scripts/build_container_flexible.sh +0 -0
  53. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/scripts/deploy-test-docker.sh +0 -0
  54. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/scripts/deploy-test-pypi.sh +0 -0
  55. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/scripts/docker-entrypoint.sh +0 -0
  56. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/scripts/run.sh +0 -0
  57. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/session.md +0 -0
  58. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socket.yml +0 -0
  59. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/config.py +0 -0
  60. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/alert_selection.py +0 -0
  61. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/classes.py +0 -0
  62. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/cli_client.py +0 -0
  63. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/cli_run.py +0 -0
  64. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/exceptions.py +0 -0
  65. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/git_interface.py +0 -0
  66. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/git_remote.py +0 -0
  67. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/helper/__init__.py +0 -0
  68. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/helper/socket_facts_loader.py +0 -0
  69. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/lazy_file_loader.py +0 -0
  70. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/log_uploader.py +0 -0
  71. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/logging.py +0 -0
  72. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/messages.py +0 -0
  73. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/pull_request.py +0 -0
  74. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/resource_utils.py +0 -0
  75. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/scm/__init__.py +0 -0
  76. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/scm/base.py +0 -0
  77. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/scm/client.py +0 -0
  78. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/scm/github.py +0 -0
  79. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/scm/gitlab.py +0 -0
  80. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/scm_comments.py +0 -0
  81. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/socket_config.py +0 -0
  82. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/streaming.py +0 -0
  83. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/tools/coana-cache.mjs +0 -0
  84. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/core/utils.py +0 -0
  85. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/fossa_compat.py +0 -0
  86. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/output.py +0 -0
  87. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/__init__.py +0 -0
  88. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/base.py +0 -0
  89. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/formatters/__init__.py +0 -0
  90. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/formatters/slack.py +0 -0
  91. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/jira.py +0 -0
  92. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/manager.py +0 -0
  93. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/slack.py +0 -0
  94. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/teams.py +0 -0
  95. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/plugins/webhook.py +0 -0
  96. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/socketsecurity/socketcli.py +0 -0
  97. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/__init__.py +0 -0
  98. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/conftest.py +0 -0
  99. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/create_diff_input.json +0 -0
  100. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_diff_alerts.py +0 -0
  101. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_diff_generation.py +0 -0
  102. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_diff_scan_polling.py +0 -0
  103. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_facts_compression.py +0 -0
  104. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_full_scan_outputs.py +0 -0
  105. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_has_manifest_files.py +0 -0
  106. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_invalid_facts_marker.py +0 -0
  107. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_package_and_alerts.py +0 -0
  108. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/core/test_supporting_methods.py +0 -0
  109. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/fullscans/create_response.json +0 -0
  110. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/fullscans/diff/stream_diff.json +0 -0
  111. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/fullscans/diff/stream_diff_full.json +0 -0
  112. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/fullscans/head_scan/metadata.json +0 -0
  113. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/fullscans/head_scan/stream_scan.json +0 -0
  114. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/fullscans/head_scan/stream_scan_full.json +0 -0
  115. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/fullscans/new_scan/metadata.json +0 -0
  116. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/fullscans/new_scan/stream_scan.json +0 -0
  117. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/repos/repo_info_error.json +0 -0
  118. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/repos/repo_info_no_head.json +0 -0
  119. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/repos/repo_info_success.json +0 -0
  120. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/data/settings/security-policy.json +0 -0
  121. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/fixtures/simple-npm/index.js +0 -0
  122. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/fixtures/simple-npm/package.json +0 -0
  123. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/fixtures/simple-pypi/requirements.txt +0 -0
  124. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/reach-facts-probe.sh +0 -0
  125. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/validate-gitlab.sh +0 -0
  126. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/validate-json.sh +0 -0
  127. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/validate-reachability.sh +0 -0
  128. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/validate-sarif.sh +0 -0
  129. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/e2e/validate-scan.sh +0 -0
  130. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/fixtures/fossa/README.md +0 -0
  131. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/fixtures/fossa/fossa-analyze-empty.json +0 -0
  132. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/fixtures/fossa/fossa-analyze-populated.json +0 -0
  133. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/fixtures/fossa/fossa-sbom-empty-deep.json +0 -0
  134. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/fixtures/fossa/fossa-sbom-populated.json +0 -0
  135. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/__init__.py +0 -0
  136. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_alert_selection.py +0 -0
  137. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_cli_config.py +0 -0
  138. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_cli_run.py +0 -0
  139. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_client.py +0 -0
  140. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_commit_message_truncation.py +0 -0
  141. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_config.py +0 -0
  142. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_dependency_overview.py +0 -0
  143. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_disable_ignore.py +0 -0
  144. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_exclude_paths.py +0 -0
  145. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_fossa_compat.py +0 -0
  146. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_fossa_parity.py +0 -0
  147. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_full_scan_retry.py +0 -0
  148. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_git_interface.py +0 -0
  149. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_git_remote.py +0 -0
  150. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_github_buildkite_config.py +0 -0
  151. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_gitlab_auth.py +0 -0
  152. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_gitlab_auth_fallback.py +0 -0
  153. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_gitlab_commit_status.py +0 -0
  154. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_gitlab_format.py +0 -0
  155. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_ignore_authorization.py +0 -0
  156. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_ignore_telemetry_filtering.py +0 -0
  157. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_include_dirs.py +0 -0
  158. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_log_uploader.py +0 -0
  159. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_manifest_discovery.py +0 -0
  160. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_messages.py +0 -0
  161. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_output.py +0 -0
  162. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_pr_comment_rendering.py +0 -0
  163. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_pull_request_context.py +0 -0
  164. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_reachability.py +0 -0
  165. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_scan_scope.py +0 -0
  166. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_slack_plugin.py +0 -0
  167. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_slack_severity_normalization.py +0 -0
  168. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_socketcli.py +0 -0
  169. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_streaming.py +0 -0
  170. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_summary_text.py +0 -0
  171. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/tests/unit/test_tier1_finalize.py +0 -0
  172. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/workflows/bitbucket-pipelines.yml +0 -0
  173. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/workflows/buildkite.yml +0 -0
  174. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/workflows/github-actions.yml +0 -0
  175. {socketsecurity-2.11.6 → socketsecurity-2.11.10}/workflows/gitlab-ci.yml +0 -0
@@ -22,7 +22,7 @@ runs:
22
22
  - uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0
23
23
  if: inputs.enable-qemu == 'true'
24
24
  - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
25
- - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
25
+ - uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
26
26
  with:
27
27
  username: ${{ inputs.dockerhub-username }}
28
28
  password: ${{ inputs.dockerhub-token }}
@@ -27,7 +27,7 @@ runs:
27
27
  using: "composite"
28
28
  steps:
29
29
  - if: ${{ inputs.python == 'true' || inputs.uv == 'true' }}
30
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
30
+ uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
31
31
  with:
32
32
  python-version: "3.12"
33
33
 
@@ -40,7 +40,7 @@ jobs:
40
40
  persist-credentials: false
41
41
 
42
42
  - name: 🐍 setup python
43
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
43
+ uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
44
44
  with:
45
45
  python-version: ${{ env.PYTHON_VERSION }}
46
46
 
@@ -150,7 +150,7 @@ jobs:
150
150
  echo "sha=${{ github.event.pull_request.head.sha }}"
151
151
  } > sfw-artifacts/context.txt
152
152
 
153
- - uses: ./.github/actions/setup-sfw
153
+ - uses: $/.github/actions/setup-sfw
154
154
  with:
155
155
  uv: "true"
156
156
  mode: firewall-free
@@ -241,7 +241,7 @@ jobs:
241
241
  echo "sha=${{ github.event.pull_request.head.sha }}"
242
242
  } > sfw-artifacts/context.txt
243
243
 
244
- - uses: ./.github/actions/setup-sfw
244
+ - uses: $/.github/actions/setup-sfw
245
245
  with:
246
246
  uv: "true"
247
247
  mode: firewall-enterprise
@@ -332,7 +332,7 @@ jobs:
332
332
  echo "sha=${{ github.event.pull_request.head.sha }}"
333
333
  } > sfw-artifacts/context.txt
334
334
 
335
- - uses: ./.github/actions/setup-sfw
335
+ - uses: $/.github/actions/setup-sfw
336
336
  with:
337
337
  node: "true"
338
338
  mode: firewall-free
@@ -393,7 +393,7 @@ jobs:
393
393
  echo "sha=${{ github.event.pull_request.head.sha }}"
394
394
  } > sfw-artifacts/context.txt
395
395
 
396
- - uses: ./.github/actions/setup-sfw
396
+ - uses: $/.github/actions/setup-sfw
397
397
  with:
398
398
  node: "true"
399
399
  mode: firewall-enterprise
@@ -454,7 +454,7 @@ jobs:
454
454
  echo "sha=${{ github.event.pull_request.head.sha }}"
455
455
  } > sfw-artifacts/context.txt
456
456
 
457
- - uses: ./.github/actions/setup-sfw
457
+ - uses: $/.github/actions/setup-sfw
458
458
  with:
459
459
  python: "true"
460
460
  mode: firewall-free
@@ -518,7 +518,7 @@ jobs:
518
518
  echo "sha=${{ github.event.pull_request.head.sha }}"
519
519
  } > sfw-artifacts/context.txt
520
520
 
521
- - uses: ./.github/actions/setup-sfw
521
+ - uses: $/.github/actions/setup-sfw
522
522
  with:
523
523
  python: "true"
524
524
  mode: firewall-enterprise
@@ -29,7 +29,7 @@ jobs:
29
29
  echo "Version ${INPUT_VERSION} found on PyPI - proceeding with release"
30
30
 
31
31
  - name: Set up Docker publishing
32
- uses: ./.github/actions/setup-docker
32
+ uses: $/.github/actions/setup-docker
33
33
  with:
34
34
  dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
35
35
  dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -80,7 +80,7 @@ jobs:
80
80
  fetch-depth: 0
81
81
  persist-credentials: false
82
82
 
83
- - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
83
+ - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
84
84
  with:
85
85
  python-version: '3.12'
86
86
 
@@ -23,12 +23,12 @@ jobs:
23
23
  fetch-depth: 1
24
24
  persist-credentials: false
25
25
 
26
- - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
26
+ - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
27
27
  with:
28
28
  python-version: "3.12"
29
29
 
30
30
  - name: Install build tooling
31
- uses: ./.github/actions/setup-hatch
31
+ uses: $/.github/actions/setup-hatch
32
32
 
33
33
  - name: Install distribution validator
34
34
  run: python -m pip install "twine>=4.0.0"
@@ -107,12 +107,12 @@ jobs:
107
107
  fetch-depth: 0
108
108
  persist-credentials: false
109
109
 
110
- - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
110
+ - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
111
111
  with:
112
112
  python-version: "3.12"
113
113
 
114
114
  - name: Install build tooling
115
- uses: ./.github/actions/setup-hatch
115
+ uses: $/.github/actions/setup-hatch
116
116
 
117
117
  - name: Install distribution validator
118
118
  run: python -m pip install "twine>=4.0.0"
@@ -179,7 +179,7 @@ jobs:
179
179
  path: dist
180
180
 
181
181
  - name: Publish to TestPyPI
182
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
182
+ uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
183
183
  with:
184
184
  repository-url: https://test.pypi.org/legacy/
185
185
  verbose: true
@@ -252,7 +252,7 @@ jobs:
252
252
  path: dist
253
253
 
254
254
  - name: Set up Docker publishing
255
- uses: ./.github/actions/setup-docker
255
+ uses: $/.github/actions/setup-docker
256
256
  with:
257
257
  # QEMU is required to build the arm64 layer on an amd64 runner.
258
258
  enable-qemu: "true"
@@ -36,7 +36,7 @@ jobs:
36
36
  fetch-depth: 1
37
37
  persist-credentials: false
38
38
  - name: 🐍 setup python
39
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
39
+ uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
40
40
  with:
41
41
  python-version: ${{ env.PYTHON_VERSION }}
42
42
  - name: 🛠️ install deps
@@ -68,7 +68,7 @@ jobs:
68
68
  fetch-depth: 1
69
69
  persist-credentials: false
70
70
  - name: 🐍 setup python
71
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
71
+ uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
72
72
  with:
73
73
  python-version: ${{ env.PYTHON_VERSION }}
74
74
  - name: 🛠️ install deps
@@ -88,7 +88,7 @@ jobs:
88
88
  fetch-depth: 1
89
89
  persist-credentials: false
90
90
  - name: 🐍 setup python
91
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
91
+ uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
92
92
  with:
93
93
  python-version: "3.10"
94
94
  - name: 🚫 verify install is rejected on unsupported python
@@ -9,17 +9,18 @@ jobs:
9
9
  permissions:
10
10
  id-token: write
11
11
  contents: read
12
+ issues: write
12
13
  steps:
13
14
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
14
15
  with:
15
16
  fetch-depth: 0
16
17
  persist-credentials: false
17
- - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
18
+ - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
18
19
  with:
19
20
  python-version: '3.13'
20
21
 
21
22
  - name: Install build tooling
22
- uses: ./.github/actions/setup-hatch
23
+ uses: $/.github/actions/setup-hatch
23
24
 
24
25
  - name: Get Version
25
26
  id: version
@@ -66,10 +67,10 @@ jobs:
66
67
 
67
68
  - name: Publish to PyPI
68
69
  if: steps.version_check.outputs.pypi_exists != 'true'
69
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
70
+ uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
70
71
 
71
72
  - name: Set up Docker publishing
72
- uses: ./.github/actions/setup-docker
73
+ uses: $/.github/actions/setup-docker
73
74
  with:
74
75
  dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
75
76
  dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -123,3 +124,44 @@ jobs:
123
124
  socketdev/cli:${{ env.VERSION }}
124
125
  build-args: |
125
126
  CLI_VERSION=${{ env.VERSION }}
127
+
128
+ # Releases are immutable, so a failed run leaves a published GitHub release whose
129
+ # tag can never be reused, with nothing on PyPI or Docker Hub behind it. A failed
130
+ # run only notifies whoever published the release, so raise it where the team
131
+ # will see it.
132
+ - name: Open an issue for the failed release
133
+ if: failure()
134
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
135
+ env:
136
+ VERSION: ${{ env.VERSION }}
137
+ with:
138
+ script: |
139
+ const release = context.payload.release;
140
+ const runUrl =
141
+ `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}` +
142
+ `/actions/runs/${context.runId}`;
143
+ const body = [
144
+ `@SocketDev/customer-engineering the release workflow for [${release.tag_name}](${release.html_url}) ` +
145
+ `(published by @${release.author.login}) failed: ${runUrl}`,
146
+ '',
147
+ `- Tag: \`${release.tag_name}\``,
148
+ `- Package version at that commit: \`${process.env.VERSION || 'unknown'}\``,
149
+ '',
150
+ 'Check the run for which step failed. If it failed before "Publish to PyPI", nothing reached PyPI or ' +
151
+ 'Docker Hub, but the GitHub release is immutable and its tag can never be reused.',
152
+ '',
153
+ 'Before publishing another release:',
154
+ '',
155
+ '1. Edit this release\'s notes to say it was not published and name the release that replaces it.',
156
+ '2. If the tag and the package version disagree, merge a PR that bumps the version to one with no ' +
157
+ 'existing tag (the Version Check workflow enforces this), then publish a release whose tag matches ' +
158
+ 'that version exactly. Do not pick the next tag number from the releases list.',
159
+ ].join('\n');
160
+
161
+ const created = await github.rest.issues.create({
162
+ owner: context.repo.owner,
163
+ repo: context.repo.repo,
164
+ title: `Release ${release.tag_name} failed`,
165
+ body,
166
+ });
167
+ core.error(`Release failed; opened #${created.data.number}`);
@@ -44,6 +44,7 @@ jobs:
44
44
  python3 <<'PY'
45
45
  import json
46
46
  import os
47
+ import subprocess
47
48
  import tomllib
48
49
  import urllib.request
49
50
  from packaging import version
@@ -96,6 +97,21 @@ jobs:
96
97
  )
97
98
  raise SystemExit(1)
98
99
 
100
+ # Releases are immutable: once a v<version> release is published, its tag can't
101
+ # be moved or reused, even when that release failed and nothing reached PyPI.
102
+ # PyPI alone misses that, so a burned tag would only surface when the release
103
+ # run fails after the merge.
104
+ tag = f"v{os.environ['PR_VERSION']}"
105
+ if subprocess.run(
106
+ ["git", "rev-parse", "--quiet", "--verify", f"refs/tags/{tag}"],
107
+ capture_output=True,
108
+ ).returncode == 0:
109
+ print(
110
+ f"❌ Tag {tag} already exists, so {pr_ver} can never be released "
111
+ f"(latest PyPI release: {pypi_ver}). Bump to a version with no tag."
112
+ )
113
+ raise SystemExit(1)
114
+
99
115
  if pr_ver < main_ver:
100
116
  print(
101
117
  f"❌ Version moves backwards: main is {main_ver}, PR is {pr_ver}."
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.11.10
4
+
5
+ Versions 2.11.7 through 2.11.9 were never published to PyPI or Docker Hub. The
6
+ GitHub releases tagged `v2.11.8` and `v2.11.9` have no packages behind them;
7
+ their changes ship here.
8
+
9
+ ### Fixed: report why a new repository couldn't be created
10
+
11
+ - When a repository isn't in Socket yet and the API token can't create it, the
12
+ CLI now logs the failure, the HTTP status, and on a 403 a hint about the
13
+ `repo:create` scope before exiting `2`. Previously it exited `2` right after
14
+ file discovery with nothing logged.
15
+ - After the CLI creates a missing repository, its logging is no longer silenced
16
+ for the rest of the run.
17
+
18
+ ### Changed: bump pinned Coana CLI to 15.14.0
19
+
20
+ - Bumped the pinned reachability engine (the Coana CLI) from `15.13.2` to
21
+ `15.14.0`. See the
22
+ [reachability analysis changelog](https://docs.socket.dev/docs/reachability-analysis-changelog)
23
+ for engine changes.
24
+
3
25
  ## 2.11.6
4
26
 
5
27
  ### Added: `--reach-disable-dependency-downloads`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: socketsecurity
3
- Version: 2.11.6
3
+ Version: 2.11.10
4
4
  Summary: Socket Security CLI for CI/CD
5
5
  Project-URL: Homepage, https://socket.dev
6
6
  Author-email: Douglas Coburn <douglas@socket.dev>
@@ -38,7 +38,7 @@ Requires-Dist: brotli==1.2.1; platform_python_implementation == 'CPython'
38
38
  Requires-Dist: brotlicffi==1.2.1.0; platform_python_implementation != 'CPython'
39
39
  Requires-Dist: certifi>=2026.10.19
40
40
  Requires-Dist: gitpython==3.2.1
41
- Requires-Dist: markdown==3.11.1
41
+ Requires-Dist: markdown==3.11.2
42
42
  Requires-Dist: mdutils==1.8.1
43
43
  Requires-Dist: packaging==26.3
44
44
  Requires-Dist: prettytable==3.18.0
@@ -48,13 +48,13 @@ Requires-Dist: socketdev==3.6.1
48
48
  Provides-Extra: dev
49
49
  Requires-Dist: hatch==1.18.1; extra == 'dev'
50
50
  Requires-Dist: pre-commit==4.7.0; extra == 'dev'
51
- Requires-Dist: ruff==0.17.1; extra == 'dev'
51
+ Requires-Dist: ruff==0.17.2; extra == 'dev'
52
52
  Requires-Dist: twine==7.0.0; extra == 'dev'
53
- Requires-Dist: uv==0.13.4; extra == 'dev'
53
+ Requires-Dist: uv==0.13.5; extra == 'dev'
54
54
  Provides-Extra: test
55
55
  Requires-Dist: pytest-asyncio==1.4.0; extra == 'test'
56
56
  Requires-Dist: pytest-cov==7.1.0; extra == 'test'
57
- Requires-Dist: pytest-mock==3.16.0; extra == 'test'
57
+ Requires-Dist: pytest-mock==3.17.0; extra == 'test'
58
58
  Requires-Dist: pytest-watch==4.2.0; extra == 'test'
59
59
  Requires-Dist: pytest==9.1.1; extra == 'test'
60
60
  Description-Content-Type: text/markdown
@@ -338,7 +338,7 @@ If you don't want to provide the Socket API Token every time then you can use th
338
338
  | Parameter | Required | Default | Description |
339
339
  |:---------------------------------|:---------|:--------|:---------------------------------------------------------------------------------------------------------------------------|
340
340
  | `--reach` | False | False | Enable reachability analysis to identify which vulnerable functions are actually called by your code. Creates a full application reachability scan (`scan_type=socket_tier1`). |
341
- | `--reach-version` | False | 15.13.2 | Version of the Coana CLI to use. Defaults to the pinned version that ships with this CLI release, so the engine only changes when you upgrade the Socket CLI. Pass `latest` to always use the newest published version (opt-in auto-update), or an explicit version (e.g. `1.2.3`) to pin it. |
341
+ | `--reach-version` | False | 15.14.0 | Version of the Coana CLI to use. Defaults to the pinned version that ships with this CLI release, so the engine only changes when you upgrade the Socket CLI. Pass `latest` to always use the newest published version (opt-in auto-update), or an explicit version (e.g. `1.2.3`) to pin it. |
342
342
  | `--reach-analysis-timeout` | False | 10m | Timeout for each reachability analysis run, e.g. `90s`, `10m` or `1h`. Omitted by default, so coana applies its own default (`10m`). Alias: `--reach-timeout` |
343
343
  | `--reach-analysis-memory-limit` | False | 8GB | Memory limit for each reachability analysis run, e.g. `512MB` or `8GB`. Omitted by default, so coana applies its own default (`8GB`). Alias: `--reach-memory-limit` |
344
344
  | `--reach-concurrency` | False | 1 | Control parallel analysis execution (must be >= 1). Omitted by default, so coana applies its own default. |
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "socketsecurity"
9
- version = "2.11.6"
9
+ version = "2.11.10"
10
10
  requires-python = ">= 3.11"
11
11
  license = {"file" = "LICENSE"}
12
12
  dependencies = [
@@ -18,7 +18,7 @@ dependencies = [
18
18
  "python-dotenv==1.2.4",
19
19
  "socketdev==3.6.1",
20
20
  "beautifulsoup4==4.15.0",
21
- "markdown==3.11.1",
21
+ "markdown==3.11.2",
22
22
  "brotli==1.2.1; platform_python_implementation == 'CPython'",
23
23
  "brotlicffi==1.2.1.0; platform_python_implementation != 'CPython'",
24
24
  # requests' CA bundle. A floor rather than an exact pin, so later trust-store
@@ -46,14 +46,14 @@ classifiers = [
46
46
  test = [
47
47
  "pytest==9.1.1",
48
48
  "pytest-cov==7.1.0",
49
- "pytest-mock==3.16.0",
49
+ "pytest-mock==3.17.0",
50
50
  "pytest-asyncio==1.4.0",
51
51
  "pytest-watch==4.2.0"
52
52
  ]
53
53
  dev = [
54
- "ruff==0.17.1",
54
+ "ruff==0.17.2",
55
55
  "twine==7.0.0", # for building
56
- "uv==0.13.4", # for dependency management
56
+ "uv==0.13.5", # for dependency management
57
57
  "pre-commit==4.7.0",
58
58
  "hatch==1.18.1"
59
59
  ]
@@ -1,3 +1,3 @@
1
1
  __author__ = 'socket.dev'
2
- __version__ = '2.11.6'
2
+ __version__ = '2.11.10'
3
3
  USER_AGENT = f'SocketPythonCLI/{__version__}'
@@ -20,7 +20,11 @@ if TYPE_CHECKING:
20
20
  from socketsecurity.config import CliConfig
21
21
  from git import Repo
22
22
  from socketdev import socketdev
23
- from socketdev.exceptions import APIFailure
23
+ from socketdev.exceptions import (
24
+ APIFailure,
25
+ APIInsufficientQuota,
26
+ APIOrganizationNotAllowed,
27
+ )
24
28
  from socketdev.fullscans import DiffArtifacts, FullScanParams, SocketArtifact
25
29
  from socketdev.org import Organization
26
30
  from socketdev.repos import RepositoryInfo
@@ -1505,8 +1509,11 @@ class Core:
1505
1509
  sdk_logger = logging_std.getLogger("socketdev")
1506
1510
  original_level = sdk_logger.level
1507
1511
  sdk_logger.setLevel(logging_std.CRITICAL)
1508
- response = self.sdk.repos.repo(self.config.org_slug, repo_slug, use_types=True)
1509
- sdk_logger.setLevel(original_level)
1512
+ try:
1513
+ response = self.sdk.repos.repo(self.config.org_slug, repo_slug, use_types=True)
1514
+ finally:
1515
+ # This module logs through "socketdev" too, so a failed lookup must not leave it muted.
1516
+ sdk_logger.setLevel(original_level)
1510
1517
  if not response.success:
1511
1518
  log.error(f"Failed to get repository: {response.status}")
1512
1519
  # log.error(response.message)
@@ -1530,7 +1537,13 @@ class Core:
1530
1537
  return response.data
1531
1538
 
1532
1539
  except APIFailure as e:
1533
- log.error(f"API failure while creating repository: {e}")
1540
+ status = f" (HTTP {e.status_code})" if e.status_code else ""
1541
+ # The SDK appends the request path and response headers after the first line,
1542
+ # and some subclasses carry no message at all.
1543
+ reason = str(e).split("\n", 1)[0] or type(e).__name__
1544
+ log.error(f"API failure while creating repository {repo_slug}{status}: {reason}")
1545
+ if e.status_code == 403 and not isinstance(e, (APIInsufficientQuota, APIOrganizationNotAllowed)):
1546
+ log.error("A 403 here usually means the API token is missing the repo:create scope.")
1534
1547
  sys.exit(2) # Exit here with code 2. Code 1 indicates a successfully-detected security issue.
1535
1548
 
1536
1549
  return response.data
@@ -22,7 +22,7 @@ log = logging.getLogger(__name__)
22
22
  # Pinned Coana CLI version. Bumped deliberately per Python CLI release so the
23
23
  # reachability engine version only changes through a standard pip upgrade (advance notice).
24
24
  # Pass --reach-version latest to opt into the newest published version instead.
25
- DEFAULT_COANA_CLI_VERSION: Final = "15.13.2"
25
+ DEFAULT_COANA_CLI_VERSION: Final = "15.14.0"
26
26
 
27
27
  # Vendored from coana-package-manager, where it is generated; the only code that may read or
28
28
  # write the cache Coana shares with the Socket CLIs. See "Launching Coana" in that repo's
@@ -1,5 +1,13 @@
1
+ import logging
2
+
1
3
  import pytest
2
- from socketdev.exceptions import APIFailure
4
+ from socketdev.exceptions import (
5
+ APIAccessDenied,
6
+ APIFailure,
7
+ APIInsufficientPermissions,
8
+ APIInsufficientQuota,
9
+ APIResourceNotFound,
10
+ )
3
11
  from socketdev.fullscans import FullScanParams, FullScanStreamResponse, ScanType
4
12
 
5
13
  from socketsecurity.config import CliConfig
@@ -44,6 +52,65 @@ def test_get_repo_info(core, mock_sdk_with_responses):
44
52
  assert repo_info.id == "f639d6c9-acc3-4d8a-9fb5-2090ad651c7e"
45
53
  assert repo_info.head_full_scan_id == "head"
46
54
 
55
+
56
+ def test_get_repo_info_logs_why_repo_creation_failed(core, mock_sdk_with_responses, caplog):
57
+ """A repo that isn't in Socket yet and can't be created exits 2 with the reason logged"""
58
+ mock_sdk_with_responses.repos.repo.side_effect = APIResourceNotFound(status_code=404)
59
+ # Mirrors the SDK, which appends the request path and response headers to the message
60
+ mock_sdk_with_responses.repos.post.side_effect = APIAccessDenied(
61
+ "Insufficient permissions\nPath: https://api.socket.dev/v0/orgs/test/repos\n\nHeaders:\nx-req: 1",
62
+ status_code=403,
63
+ )
64
+
65
+ with caplog.at_level(logging.INFO, logger="socketdev"), pytest.raises(SystemExit) as exit_info:
66
+ core.get_repo_info("new-repo")
67
+
68
+ assert exit_info.value.code == 2
69
+ messages = [record.getMessage() for record in caplog.records]
70
+ assert "Failed to get repository new-repo, attempting to create it" in messages
71
+ assert "API failure while creating repository new-repo (HTTP 403): Insufficient permissions" in messages
72
+ assert any("repo:create" in message for message in messages)
73
+
74
+
75
+ @pytest.mark.parametrize(
76
+ ("error", "expected_reason", "expects_scope_hint"),
77
+ [
78
+ (APIInsufficientPermissions(status_code=403), "APIInsufficientPermissions", True),
79
+ (APIInsufficientQuota(status_code=403), "APIInsufficientQuota", False),
80
+ ],
81
+ )
82
+ def test_get_repo_info_repo_creation_failure_reason(
83
+ core, mock_sdk_with_responses, caplog, error, expected_reason, expects_scope_hint
84
+ ):
85
+ """Message-less SDK errors still name a reason, and only permission 403s get the scope hint"""
86
+ mock_sdk_with_responses.repos.repo.side_effect = APIResourceNotFound(status_code=404)
87
+ mock_sdk_with_responses.repos.post.side_effect = error
88
+
89
+ with caplog.at_level(logging.INFO, logger="socketdev"), pytest.raises(SystemExit):
90
+ core.get_repo_info("new-repo")
91
+
92
+ messages = [record.getMessage() for record in caplog.records]
93
+ assert f"API failure while creating repository new-repo (HTTP 403): {expected_reason}" in messages
94
+ assert any("repo:create" in message for message in messages) is expects_scope_hint
95
+
96
+
97
+ def test_get_repo_info_restores_log_level_after_creating_repo(
98
+ core, mock_sdk_with_responses, repo_info_response, caplog
99
+ ):
100
+ """Creating a missing repo must not leave the socketdev logger muted for the rest of the run"""
101
+ mock_sdk_with_responses.repos.repo.side_effect = [
102
+ APIResourceNotFound(status_code=404),
103
+ repo_info_response,
104
+ ]
105
+ mock_sdk_with_responses.repos.post.return_value = {"id": "created"}
106
+
107
+ with caplog.at_level(logging.INFO, logger="socketdev"):
108
+ repo_info = core.get_repo_info("new-repo")
109
+ assert logging.getLogger("socketdev").level == logging.INFO
110
+
111
+ assert repo_info.id == "f639d6c9-acc3-4d8a-9fb5-2090ad651c7e"
112
+
113
+
47
114
  def test_get_head_scan_for_repo(core, mock_sdk_with_responses):
48
115
  """Test getting head scan ID for a repository"""
49
116
  head_scan_id = core.get_head_scan_for_repo("test")