Skip to content

Commit ceb3572

Browse files
authored
Add workspace flag to CLI args (#164)
* Add support for --workspace flag Signed-off-by: lelia <lelia@socket.dev> * Add tests to cover new workspace CLI args Signed-off-by: lelia <lelia@socket.dev> * Update README to document new CLI flag, and differentiate it from existing workspace-name flag Signed-off-by: lelia <lelia@socket.dev> * Update refs to use generic project names Signed-off-by: lelia <lelia@socket.dev> * Bump CLI version Signed-off-by: lelia <lelia@socket.dev> * Pin python and virtualenv versions to unblock builds Signed-off-by: lelia <lelia@socket.dev> * Bump published SDK version refs Signed-off-by: lelia <lelia@socket.dev> * Tweak helper text for CLI flag Signed-off-by: lelia <lelia@socket.dev> * Update CODEOWNERS to reflect proper team structure Signed-off-by: lelia <lelia@socket.dev> * Increment version again for release Signed-off-by: lelia <lelia@socket.dev> --------- Signed-off-by: lelia <lelia@socket.dev>
1 parent b3fdd33 commit ceb3572

File tree

10 files changed

+63
-22
lines changed

10 files changed

+63
-22
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @SocketDev/eng
1+
* @SocketDev/customer-engineering

.github/workflows/pr-preview.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ jobs:
1616
fetch-depth: 0
1717
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
1818
with:
19-
python-version: '3.x'
19+
python-version: '3.13'
2020

2121
# Install all dependencies from pyproject.toml
2222
- name: Install dependencies
2323
run: |
2424
python -m pip install --upgrade pip
25+
pip install "virtualenv<20.36"
2526
pip install hatchling==1.27.0 hatch==1.14.0
2627

2728
- name: Inject full dynamic version

.github/workflows/release.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ jobs:
1515
fetch-depth: 0
1616
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3
1717
with:
18-
python-version: '3.x'
18+
python-version: '3.13'
1919

2020
# Install all dependencies from pyproject.toml
2121
- name: Install dependencies
2222
run: |
2323
python -m pip install --upgrade pip
24+
pip install "virtualenv<20.36"
2425
pip install hatchling==1.27.0 hatch==1.14.0
2526

2627
- name: Get Version

README.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ These examples are production-ready and include best practices for each platform
4343

4444
## Monorepo Workspace Support
4545

46+
> **Note:** If you're looking to associate a scan with a named Socket workspace (e.g. because your repo is identified as `org/repo`), see the [`--workspace` flag](#repository) instead. The `--workspace-name` flag described in this section is an unrelated monorepo feature.
47+
4648
The Socket CLI supports scanning specific workspaces within monorepo structures while preserving git context from the repository root. This is useful for organizations that maintain multiple applications or services in a single repository.
4749

4850
### Key Features
@@ -114,7 +116,7 @@ This will simultaneously generate:
114116
## Usage
115117

116118
```` shell
117-
socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--repo-is-public] [--branch BRANCH] [--integration {api,github,gitlab,azure,bitbucket}]
119+
socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--workspace WORKSPACE] [--repo-is-public] [--branch BRANCH] [--integration {api,github,gitlab,azure,bitbucket}]
118120
[--owner OWNER] [--pr-number PR_NUMBER] [--commit-message COMMIT_MESSAGE] [--commit-sha COMMIT_SHA] [--committers [COMMITTERS ...]]
119121
[--target-path TARGET_PATH] [--sbom-file SBOM_FILE] [--license-file-name LICENSE_FILE_NAME] [--save-submitted-files-list SAVE_SUBMITTED_FILES_LIST]
120122
[--save-manifest-tar SAVE_MANIFEST_TAR] [--files FILES] [--sub-path SUB_PATH] [--workspace-name WORKSPACE_NAME]
@@ -138,14 +140,21 @@ If you don't want to provide the Socket API Token every time then you can use th
138140
| --api-token | False | | Socket Security API token (can also be set via SOCKET_SECURITY_API_TOKEN env var) |
139141

140142
#### Repository
141-
| Parameter | Required | Default | Description |
142-
|:-----------------|:---------|:--------|:------------------------------------------------------------------------|
143-
| --repo | False | *auto* | Repository name in owner/repo format (auto-detected from git remote) |
144-
| --repo-is-public | False | False | If set, flags a new repository creation as public. Defaults to false. |
145-
| --integration | False | api | Integration type (api, github, gitlab, azure, bitbucket) |
146-
| --owner | False | | Name of the integration owner, defaults to the socket organization slug |
147-
| --branch | False | *auto* | Branch name (auto-detected from git) |
148-
| --committers | False | *auto* | Committer(s) to filter by (auto-detected from git commit) |
143+
| Parameter | Required | Default | Description |
144+
|:-----------------|:---------|:--------|:------------------------------------------------------------------------------------------------------------------|
145+
| --repo | False | *auto* | Repository name in owner/repo format (auto-detected from git remote) |
146+
| --workspace | False | | The Socket workspace to associate the scan with (e.g. `my-org` in `my-org/my-repo`). See note below. |
147+
| --repo-is-public | False | False | If set, flags a new repository creation as public. Defaults to false. |
148+
| --integration | False | api | Integration type (api, github, gitlab, azure, bitbucket) |
149+
| --owner | False | | Name of the integration owner, defaults to the socket organization slug |
150+
| --branch | False | *auto* | Branch name (auto-detected from git) |
151+
| --committers | False | *auto* | Committer(s) to filter by (auto-detected from git commit) |
152+
153+
> **`--workspace` vs `--workspace-name`** — these are two distinct flags for different purposes:
154+
>
155+
> - **`--workspace <string>`** maps to the Socket API's `workspace` query parameter on `CreateOrgFullScan`. Use it when your repository belongs to a named Socket workspace (e.g. an org with multiple workspace groups). Example: `--repo my-repo --workspace my-org`. Without this flag, scans are created without workspace context and may not appear under the correct workspace in the Socket dashboard.
156+
>
157+
> - **`--workspace-name <string>`** is a monorepo feature. It appends a suffix to the repository slug to create a unique name in Socket (e.g. `my-repo-frontend`). It must always be paired with `--sub-path` and has nothing to do with the API `workspace` field. See [Monorepo Workspace Support](#monorepo-workspace-support) below.
149158

150159
#### Pull Request and Commit
151160
| Parameter | Required | Default | Description |

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
66

77
[project]
88
name = "socketsecurity"
9-
version = "2.2.73"
9+
version = "2.2.74"
1010
requires-python = ">= 3.10"
1111
license = {"file" = "LICENSE"}
1212
dependencies = [
@@ -16,7 +16,7 @@ dependencies = [
1616
'GitPython',
1717
'packaging',
1818
'python-dotenv',
19-
"socketdev>=3.0.29,<4.0.0",
19+
"socketdev>=3.0.31,<4.0.0",
2020
"bs4>=0.0.2",
2121
"markdown>=3.10",
2222
]

socketsecurity/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
__author__ = 'socket.dev'
2-
__version__ = '2.2.73'
2+
__version__ = '2.2.74'
33
USER_AGENT = f'SocketPythonCLI/{__version__}'

socketsecurity/config.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class CliConfig:
6666
save_manifest_tar: Optional[str] = None
6767
sub_paths: List[str] = field(default_factory=list)
6868
workspace_name: Optional[str] = None
69+
workspace: Optional[str] = None
6970
# Reachability Flags
7071
reach: bool = False
7172
reach_version: Optional[str] = None
@@ -145,6 +146,7 @@ def from_args(cls, args_list: Optional[List[str]] = None) -> 'CliConfig':
145146
'save_manifest_tar': args.save_manifest_tar,
146147
'sub_paths': args.sub_paths or [],
147148
'workspace_name': args.workspace_name,
149+
'workspace': args.workspace,
148150
'slack_webhook': args.slack_webhook,
149151
'reach': args.reach,
150152
'reach_version': args.reach_version,
@@ -256,6 +258,12 @@ def create_argument_parser() -> argparse.ArgumentParser:
256258
help="Repository name in owner/repo format",
257259
required=False
258260
)
261+
repo_group.add_argument(
262+
"--workspace",
263+
metavar="<string>",
264+
help="The workspace in the Socket Organization that the repository is in to associate with the full scan.",
265+
required=False
266+
)
259267
repo_group.add_argument(
260268
"--repo-is-public",
261269
dest="repo_is_public",

socketsecurity/socketcli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,8 @@ def main_code():
464464
make_default_branch=is_default_branch,
465465
set_as_pending_head=is_default_branch,
466466
tmp=False,
467-
scan_type='socket_tier1' if config.reach else 'socket'
467+
scan_type='socket_tier1' if config.reach else 'socket',
468+
workspace=config.workspace or None,
468469
)
469470

470471
params.include_license_details = not config.exclude_license_details

tests/unit/test_cli_config.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,25 @@ def test_strict_blocking_with_disable_blocking(self):
6060
"--disable-blocking"
6161
])
6262
assert config.strict_blocking is True
63-
assert config.disable_blocking is True
63+
assert config.disable_blocking is True
64+
65+
def test_workspace_flag(self):
66+
"""Test that --workspace is parsed and stored correctly."""
67+
config = CliConfig.from_args(["--api-token", "test", "--workspace", "my-workspace"])
68+
assert config.workspace == "my-workspace"
69+
70+
def test_workspace_default_is_none(self):
71+
"""Test that workspace defaults to None when not supplied."""
72+
config = CliConfig.from_args(["--api-token", "test"])
73+
assert config.workspace is None
74+
75+
def test_workspace_is_independent_of_workspace_name(self):
76+
"""--workspace and --workspace-name are distinct flags with distinct purposes."""
77+
config = CliConfig.from_args([
78+
"--api-token", "test",
79+
"--workspace", "my-workspace",
80+
"--sub-path", ".",
81+
"--workspace-name", "monorepo-suffix",
82+
])
83+
assert config.workspace == "my-workspace"
84+
assert config.workspace_name == "monorepo-suffix"

uv.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)