diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0a27f5c..38d490d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ include: - - project: 'externalci/ci-image' + - project: '$CI_TEMPLATE' ref: master file: '.gitlab-ci-default.yaml' diff --git a/pyproject.toml b/pyproject.toml index 933b174..c312fd7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "polyswarm" -version = "4.2.0" +version = "4.2.1" description = "CLI for using the PolySwarm Customer APIs" readme = "README.md" authors = [{ name = "PolySwarm Developers", email = "info@polyswarm.io" }] @@ -51,7 +51,7 @@ include-package-data = true where = ["src"] [tool.bumpversion] -current_version = "4.2.0" +current_version = "4.2.1" commit = true tag = false sign_tags = true diff --git a/src/polyswarm/__init__.py b/src/polyswarm/__init__.py index ea5d65f..0d6a4f2 100644 --- a/src/polyswarm/__init__.py +++ b/src/polyswarm/__init__.py @@ -1 +1 @@ -__version__ = '4.2.0' +__version__ = '4.2.1' diff --git a/src/polyswarm/client/polyswarm.py b/src/polyswarm/client/polyswarm.py index 48bd1e1..1a3f83f 100644 --- a/src/polyswarm/client/polyswarm.py +++ b/src/polyswarm/client/polyswarm.py @@ -44,14 +44,14 @@ PROD_API_URI = 'https://api.polyswarm.network/v3' # Convenience environment shortcuts so callers can write `--stage` instead of -# `--api-uri https://api.stage-v3.polyswarm.network/v3`. Keys are the click +# `--api-uri https://api.stage-blue.polyswarm.network/v3`. Keys are the click # parameter names (click maps `--prod-eu` -> `prod_eu`). API_URI_SHORTCUTS = { 'prod': PROD_API_URI, - 'stage': 'https://api.stage-v3.polyswarm.network/v3', + 'stage': 'https://api.stage-blue.polyswarm.network/v3', 'local': 'http://localhost:9696/v3', 'prod_eu': 'https://api.prod-eu-v3.polyswarm.network/v3', - 'stage_eu': 'https://api.stage-eu-v3.polyswarm.network/v3', + 'stage_eu': 'https://api.stage-eu-blue.polyswarm.network/v3', } _SHORTCUT_FLAGS = { @@ -184,13 +184,13 @@ def invoke(self, ctx): @click.option('--prod', is_flag=True, default=False, help='Target the production API (https://api.polyswarm.network/v3) — same as the default.') @click.option('--stage', is_flag=True, default=False, - help='Target the US staging API (https://api.stage-v3.polyswarm.network/v3).') + help='Target the US staging API (https://api.stage-blue.polyswarm.network/v3).') @click.option('--local', is_flag=True, default=False, help='Target a local API (http://localhost:9696/v3).') @click.option('--prod-eu', 'prod_eu', is_flag=True, default=False, help='Target the EU production API (https://api.prod-eu-v3.polyswarm.network/v3).') @click.option('--stage-eu', 'stage_eu', is_flag=True, default=False, - help='Target the EU staging API (https://api.stage-eu-v3.polyswarm.network/v3).') + help='Target the EU staging API (https://api.stage-eu-blue.polyswarm.network/v3).') @click.option('-o', '--output-file', type=click.File('w', encoding='utf8'), help='Path to output file.') @click.option('--output-format', '--fmt', default='text', type=click.Choice(formatters.keys()), help='Output format. Human-readable text or JSON.') diff --git a/tests/api_uri_test.py b/tests/api_uri_test.py index 18ca699..b9809e3 100644 --- a/tests/api_uri_test.py +++ b/tests/api_uri_test.py @@ -48,10 +48,10 @@ def test_env_api_uri_used_when_no_flag(self): def test_each_shortcut_resolves(self): expected = { 'prod': 'https://api.polyswarm.network/v3', - 'stage': 'https://api.stage-v3.polyswarm.network/v3', + 'stage': 'https://api.stage-blue.polyswarm.network/v3', 'local': 'http://localhost:9696/v3', 'prod_eu': 'https://api.prod-eu-v3.polyswarm.network/v3', - 'stage_eu': 'https://api.stage-eu-v3.polyswarm.network/v3', + 'stage_eu': 'https://api.stage-eu-blue.polyswarm.network/v3', } # guard against the constant drifting from the verified ingress hosts assert API_URI_SHORTCUTS == expected @@ -124,7 +124,7 @@ def test_shortcut_beats_env_var(self): # --- each shortcut --- def test_stage_shortcut(self): - assert self._resolved_base('--stage') == 'https://api.stage-v3.polyswarm.network/v3' + assert self._resolved_base('--stage') == 'https://api.stage-blue.polyswarm.network/v3' def test_local_shortcut(self): assert self._resolved_base('--local') == 'http://localhost:9696/v3' @@ -133,7 +133,7 @@ def test_prod_eu_shortcut(self): assert self._resolved_base('--prod-eu') == 'https://api.prod-eu-v3.polyswarm.network/v3' def test_stage_eu_shortcut(self): - assert self._resolved_base('--stage-eu') == 'https://api.stage-eu-v3.polyswarm.network/v3' + assert self._resolved_base('--stage-eu') == 'https://api.stage-eu-blue.polyswarm.network/v3' def test_prod_shortcut_matches_default(self): assert self._resolved_base('--prod') == 'https://api.polyswarm.network/v3' diff --git a/tests/kgb_test.py b/tests/kgb_test.py index a51525d..57bc09b 100644 --- a/tests/kgb_test.py +++ b/tests/kgb_test.py @@ -33,17 +33,17 @@ def test_kgb_create_get_delete_text(self): @vcr.use_cassette() def test_kgb_create_get_json(self): - created = self._run_cli(['--fmt', 'json', 'kgb', 'create', 'winget', SHA_B]) + created = self._run_cli(['--fmt', 'json', 'kgb', 'create', 'commercial', SHA_B]) self.assertEqual(0, created.exit_code, created.output) payload = json.loads(created.output.strip().splitlines()[-1]) assert payload['sha256'] == SHA_B - assert 'winget' in payload.get('sources', []) + assert 'commercial' in payload.get('sources', []) got = self._run_cli(['--fmt', 'json', 'kgb', 'get', SHA_B]) self.assertEqual(0, got.exit_code, got.output) payload = json.loads(got.output.strip().splitlines()[-1]) assert payload['sha256'] == SHA_B - assert 'winget' in payload.get('sources', []) + assert 'commercial' in payload.get('sources', []) @vcr.use_cassette() def test_kgb_get_after_delete_not_found(self): diff --git a/tests/known_good_field_test.py b/tests/known_good_field_test.py index 7b9a434..f35f9b7 100644 --- a/tests/known_good_field_test.py +++ b/tests/known_good_field_test.py @@ -33,14 +33,14 @@ def _render(instance): class TestKnownGoodTextRendering: def test_known_good_instance_renders_feeds_and_status(self): feeds = [ - {'tool': 'winget', 'tool_metadata': {}, 'created': '2026-06-11T00:00:00', + {'tool': 'commercial', 'tool_metadata': {}, 'created': '2026-06-11T00:00:00', 'updated': '2026-06-11T00:00:00'}, {'tool': 'nsrl', 'tool_metadata': {}, 'created': '2026-06-11T00:00:00', 'updated': '2026-06-11T00:00:00'}, ] text = _render(_instance(known_good=feeds)) # Feeds are listed (sorted) and the status reflects known-good. - assert 'known-good binary (flagged by: nsrl, winget); it is not scanned.' in text + assert 'known-good binary (flagged by: commercial, nsrl); it is not scanned.' in text assert 'Status: Known good' in text # A known-good binary must NOT be told to rescan / that no engines responded. assert 'trigger a rescan' not in text @@ -67,11 +67,11 @@ def test_state_known_good_without_feeds(self): assert 'No engines responded' not in text def test_state_known_good_with_feeds_lists_them(self): - feeds = [{'tool': 'winget', 'tool_metadata': {}, + feeds = [{'tool': 'commercial', 'tool_metadata': {}, 'created': '2026-06-11T00:00:00', 'updated': '2026-06-11T00:00:00'}] text = _render(_instance(state='KNOWN_GOOD', known_good=feeds)) # When feeds are present the richer message still lists them. - assert 'known-good binary (flagged by: winget); it is not scanned.' in text + assert 'known-good binary (flagged by: commercial); it is not scanned.' in text assert 'Status: Known good' in text def test_non_known_good_state_unchanged(self): diff --git a/tests/vcr/test_kgb_create_get_json.vcr b/tests/vcr/test_kgb_create_get_json.vcr index ead57f4..78b9beb 100644 --- a/tests/vcr/test_kgb_create_get_json.vcr +++ b/tests/vcr/test_kgb_create_get_json.vcr @@ -1,6 +1,6 @@ interactions: - request: - body: '{"sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","source":"winget","community":"gamma"}' + body: '{"sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","source":"commercial","community":"gamma"}' headers: accept: - '*/*' @@ -11,18 +11,18 @@ interactions: connection: - keep-alive content-length: - - '115' + - '119' content-type: - application/json host: - artifact-index-e2e:9696 user-agent: - - polyswarm_api/4.0.0 (x86_64-Linux-CPython-3.14.4) + - polyswarm_api/4.1.0 (x86_64-Linux-CPython-3.12.3) method: POST uri: http://artifact-index-e2e:9696/v3/known-good response: body: - string: '{"result":{"artifact_instance_id":"2369287781010758","created":"2026-06-15T18:51:09.785317+00:00","id":"28878017864712926","sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","sources":["winget"]},"status":"OK"} + string: '{"result":{"artifact_instance_id":"94148575775325033","created":"2026-06-29T18:31:04.436511+00:00","id":"94927448183592703","sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","sources":["commercial"]},"status":"OK"} ' headers: @@ -33,11 +33,11 @@ interactions: Connection: - keep-alive Content-Length: - - '236' + - '241' Content-Type: - application/json Date: - - Mon, 15 Jun 2026 19:14:34 GMT + - Mon, 29 Jun 2026 18:31:04 GMT Server: - gunicorn X-Billing-ID: @@ -59,12 +59,12 @@ interactions: host: - artifact-index-e2e:9696 user-agent: - - polyswarm_api/4.0.0 (x86_64-Linux-CPython-3.14.4) + - polyswarm_api/4.1.0 (x86_64-Linux-CPython-3.12.3) method: GET uri: http://artifact-index-e2e:9696/v3/known-good?sha256=b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2&community=gamma response: body: - string: '{"result":{"artifact_instance_id":"2369287781010758","created":"2026-06-15T18:51:09.785317+00:00","id":"28878017864712926","sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","sources":["winget"]},"status":"OK"} + string: '{"result":{"artifact_instance_id":"94148575775325033","created":"2026-06-29T18:31:04.436511+00:00","id":"94927448183592703","sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","sources":["commercial"]},"status":"OK"} ' headers: @@ -75,11 +75,11 @@ interactions: Connection: - keep-alive Content-Length: - - '236' + - '241' Content-Type: - application/json Date: - - Mon, 15 Jun 2026 19:14:34 GMT + - Mon, 29 Jun 2026 18:31:04 GMT Server: - gunicorn X-Billing-ID: