From d3b837ff28793c39fabad5ae37540554f1ac2602 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2026 01:11:12 +0000 Subject: [PATCH 01/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e93723a0..ab885989 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3dcdbd68ce4b336149d28d17ab08f211538ed6630112ae4883af2f6680643159.yml -openapi_spec_hash: 7e4333995b65cf32663166801e2444bb +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-1122bbd6558bb1ce02f8dfc967697900cd32a18ef62481537f4f5a6ad5932260.yml +openapi_spec_hash: e5a3f1cb78e8eac5e0d4ac0bdb2c73a6 config_hash: 8d7b241284195a8c51f5d670fbbe0ab4 From da8b4a6e37bd3c6a9243a2bac3b80869f94b253c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2026 23:48:29 +0000 Subject: [PATCH 02/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index ab885989..f39bf498 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-1122bbd6558bb1ce02f8dfc967697900cd32a18ef62481537f4f5a6ad5932260.yml -openapi_spec_hash: e5a3f1cb78e8eac5e0d4ac0bdb2c73a6 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-bb01d257acff1b3c58a570307eff6c618f2eb1c2740a8149736c644341504031.yml +openapi_spec_hash: f1a73aad352f34b1162560eb00ce2abe config_hash: 8d7b241284195a8c51f5d670fbbe0ab4 From 3e12437695a48d7ebc66ce018eea955203b7c743 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 10:19:10 +0000 Subject: [PATCH 03/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index f39bf498..d93c13eb 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-bb01d257acff1b3c58a570307eff6c618f2eb1c2740a8149736c644341504031.yml -openapi_spec_hash: f1a73aad352f34b1162560eb00ce2abe -config_hash: 8d7b241284195a8c51f5d670fbbe0ab4 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-ee5c1f5d47838a4ee7e114173d3b37b65abc3b3714615a0b9f06c16e3bbea076.yml +openapi_spec_hash: 4c08bb9223c4537e9bdc985a7937ad07 +config_hash: 6d27da09c9efc26556069dbefd693a37 From b7f0b1d27ef51872bf81541dd7f81a8101f856af Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:12:08 +0000 Subject: [PATCH 04/66] fix(client): preserve hardcoded query params when merging with user params --- src/gitpod/_base_client.py | 4 ++++ tests/test_client.py | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/gitpod/_base_client.py b/src/gitpod/_base_client.py index cc7f8af2..a9da58f9 100644 --- a/src/gitpod/_base_client.py +++ b/src/gitpod/_base_client.py @@ -540,6 +540,10 @@ def _build_request( files = cast(HttpxRequestFiles, ForceMultipartDict()) prepared_url = self._prepare_url(options.url) + # preserve hard-coded query params from the url + if params and prepared_url.query: + params = {**dict(prepared_url.params.items()), **params} + prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0]) if "_" in prepared_url.host: # work around https://github.com/encode/httpx/discussions/2880 kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")} diff --git a/tests/test_client.py b/tests/test_client.py index 92b0eea3..c105b4d9 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -438,6 +438,30 @@ def test_default_query_option(self) -> None: client.close() + def test_hardcoded_query_params_in_url(self, client: Gitpod) -> None: + request = client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_request_extra_json(self, client: Gitpod) -> None: request = client._build_request( FinalRequestOptions( @@ -1363,6 +1387,30 @@ async def test_default_query_option(self) -> None: await client.close() + async def test_hardcoded_query_params_in_url(self, async_client: AsyncGitpod) -> None: + request = async_client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_request_extra_json(self, client: Gitpod) -> None: request = client._build_request( FinalRequestOptions( From 9bbf63390cb0bf91661950d37c068409d2850eec Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:38:37 +0000 Subject: [PATCH 05/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index d93c13eb..5284245e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-ee5c1f5d47838a4ee7e114173d3b37b65abc3b3714615a0b9f06c16e3bbea076.yml -openapi_spec_hash: 4c08bb9223c4537e9bdc985a7937ad07 -config_hash: 6d27da09c9efc26556069dbefd693a37 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-7366f3114f6f2fae72e3141480d2b2a67094d37391b5a068210e69ead83045f2.yml +openapi_spec_hash: aa2198d5846e9e12e09c823f64b65dca +config_hash: 843d5f356bfb6295862722a8d71d08e0 From 897c6658f1864958dfa034116f5923a7d7f4defc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 11:54:00 +0000 Subject: [PATCH 06/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5284245e..a75e53d1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-7366f3114f6f2fae72e3141480d2b2a67094d37391b5a068210e69ead83045f2.yml -openapi_spec_hash: aa2198d5846e9e12e09c823f64b65dca +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-35cd7fa73c7adecfbdc71193bb6d59e34a427dae598401575870571ec220cd70.yml +openapi_spec_hash: 65118e845e2ad858c647c58016355820 config_hash: 843d5f356bfb6295862722a8d71d08e0 From 308ce72ede2ea2989619af0ac162ed76d356c6dc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 16:18:08 +0000 Subject: [PATCH 07/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a75e53d1..0e153d52 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-35cd7fa73c7adecfbdc71193bb6d59e34a427dae598401575870571ec220cd70.yml -openapi_spec_hash: 65118e845e2ad858c647c58016355820 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-9b7fd2030480921db661aeb8eb6c454e8b53accf4bddecc66e740383ab7ad074.yml +openapi_spec_hash: deb597c2dbac0fddcdd136aae19aba44 config_hash: 843d5f356bfb6295862722a8d71d08e0 From faca2b27b88f17a759bd91c305e5ea2a856a1e2c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 16:22:17 +0000 Subject: [PATCH 08/66] feat(api): remove terminal field from RunsOn type --- .stats.yml | 4 ++-- src/gitpod/types/shared/runs_on.py | 6 ------ src/gitpod/types/shared_params/runs_on.py | 6 ------ .../api_resources/environments/automations/test_services.py | 4 ---- tests/api_resources/environments/automations/test_tasks.py | 4 ---- tests/api_resources/environments/test_automations.py | 4 ---- 6 files changed, 2 insertions(+), 26 deletions(-) diff --git a/.stats.yml b/.stats.yml index 0e153d52..45335695 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-9b7fd2030480921db661aeb8eb6c454e8b53accf4bddecc66e740383ab7ad074.yml -openapi_spec_hash: deb597c2dbac0fddcdd136aae19aba44 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-ffc8cf0ed565636356f70cba5521094ee367d0b30bacb266a70f4ea98889c74c.yml +openapi_spec_hash: bf1abc17445dd410c3c3f8607c5a4937 config_hash: 843d5f356bfb6295862722a8d71d08e0 diff --git a/src/gitpod/types/shared/runs_on.py b/src/gitpod/types/shared/runs_on.py index 5f26ef47..33cf1bd5 100644 --- a/src/gitpod/types/shared/runs_on.py +++ b/src/gitpod/types/shared/runs_on.py @@ -18,9 +18,3 @@ class RunsOn(BaseModel): machine: Optional[object] = None """Machine runs the service/task directly on the VM/machine level.""" - - terminal: Optional[object] = None - """ - Terminal runs the service inside a managed PTY terminal in the devcontainer. - Users can attach to the terminal interactively via the terminal API. - """ diff --git a/src/gitpod/types/shared_params/runs_on.py b/src/gitpod/types/shared_params/runs_on.py index 0182710a..8fc0fd3c 100644 --- a/src/gitpod/types/shared_params/runs_on.py +++ b/src/gitpod/types/shared_params/runs_on.py @@ -20,9 +20,3 @@ class RunsOn(TypedDict, total=False): machine: object """Machine runs the service/task directly on the VM/machine level.""" - - terminal: object - """ - Terminal runs the service inside a managed PTY terminal in the devcontainer. - Users can attach to the terminal interactively via the terminal API. - """ diff --git a/tests/api_resources/environments/automations/test_services.py b/tests/api_resources/environments/automations/test_services.py index 3a80cc01..3d1ccf73 100644 --- a/tests/api_resources/environments/automations/test_services.py +++ b/tests/api_resources/environments/automations/test_services.py @@ -75,7 +75,6 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "image": "x", }, "machine": {}, - "terminal": {}, }, "session": "session", "spec_version": "specVersion", @@ -188,7 +187,6 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "image": "x", }, "machine": {}, - "terminal": {}, }, }, status={ @@ -437,7 +435,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "image": "x", }, "machine": {}, - "terminal": {}, }, "session": "session", "spec_version": "specVersion", @@ -550,7 +547,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "image": "x", }, "machine": {}, - "terminal": {}, }, }, status={ diff --git a/tests/api_resources/environments/automations/test_tasks.py b/tests/api_resources/environments/automations/test_tasks.py index 29599ec1..242dc25e 100644 --- a/tests/api_resources/environments/automations/test_tasks.py +++ b/tests/api_resources/environments/automations/test_tasks.py @@ -71,7 +71,6 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "image": "x", }, "machine": {}, - "terminal": {}, }, }, ) @@ -178,7 +177,6 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "image": "x", }, "machine": {}, - "terminal": {}, }, }, ) @@ -377,7 +375,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "image": "x", }, "machine": {}, - "terminal": {}, }, }, ) @@ -484,7 +481,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "image": "x", }, "machine": {}, - "terminal": {}, }, }, ) diff --git a/tests/api_resources/environments/test_automations.py b/tests/api_resources/environments/test_automations.py index bed1aa5a..15f3fe3a 100644 --- a/tests/api_resources/environments/test_automations.py +++ b/tests/api_resources/environments/test_automations.py @@ -44,7 +44,6 @@ def test_method_upsert_with_all_params(self, client: Gitpod) -> None: "image": "x", }, "machine": {}, - "terminal": {}, }, "triggered_by": ["postDevcontainerStart"], } @@ -61,7 +60,6 @@ def test_method_upsert_with_all_params(self, client: Gitpod) -> None: "image": "x", }, "machine": {}, - "terminal": {}, }, "triggered_by": ["postEnvironmentStart"], } @@ -126,7 +124,6 @@ async def test_method_upsert_with_all_params(self, async_client: AsyncGitpod) -> "image": "x", }, "machine": {}, - "terminal": {}, }, "triggered_by": ["postDevcontainerStart"], } @@ -143,7 +140,6 @@ async def test_method_upsert_with_all_params(self, async_client: AsyncGitpod) -> "image": "x", }, "machine": {}, - "terminal": {}, }, "triggered_by": ["postEnvironmentStart"], } From 368d727b1704acb0d8438dce44ec4d8947054aaa Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:18:51 +0000 Subject: [PATCH 09/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 45335695..4764b18b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-ffc8cf0ed565636356f70cba5521094ee367d0b30bacb266a70f4ea98889c74c.yml -openapi_spec_hash: bf1abc17445dd410c3c3f8607c5a4937 -config_hash: 843d5f356bfb6295862722a8d71d08e0 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-b9c344a37f60a4c5459a97503d3a06356209ebc50086ffef43305e85be508183.yml +openapi_spec_hash: 3e2a15c9cc346e05f8e6406acb4d0549 +config_hash: 93d77fe2271e1d5867977aa102e3c944 From 23bc7c313ba3f0d6e6b34802b2de17439a7befe0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:57:58 +0000 Subject: [PATCH 10/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 4764b18b..14a1d63c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-b9c344a37f60a4c5459a97503d3a06356209ebc50086ffef43305e85be508183.yml -openapi_spec_hash: 3e2a15c9cc346e05f8e6406acb4d0549 -config_hash: 93d77fe2271e1d5867977aa102e3c944 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-5ffe9b518bd3a240d0262f71b53b207da01ef03d7532ce3c906ec42401efec96.yml +openapi_spec_hash: 4abaf13d8709ebb1af302ecab14f74df +config_hash: 459bd8a85f3cca1801bd9d5c3462cee9 From 4a1affd0a6f9b13ebd30894bcbfecd4ce9597725 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:47:40 +0000 Subject: [PATCH 11/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 14a1d63c..e293ff0a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-5ffe9b518bd3a240d0262f71b53b207da01ef03d7532ce3c906ec42401efec96.yml -openapi_spec_hash: 4abaf13d8709ebb1af302ecab14f74df -config_hash: 459bd8a85f3cca1801bd9d5c3462cee9 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-5899adbe0e83d93afad45dbe14d4c83c92ed9a68021602f2b6a567b00471c190.yml +openapi_spec_hash: d851857366f97e4f4e9562bbea1b2219 +config_hash: d73914a733b27d121d59aa43bc7c710e From eeedd00d580a6ef1f9536751a9130b84665fed70 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 05:44:24 +0000 Subject: [PATCH 12/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e293ff0a..7ff68c57 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-5899adbe0e83d93afad45dbe14d4c83c92ed9a68021602f2b6a567b00471c190.yml -openapi_spec_hash: d851857366f97e4f4e9562bbea1b2219 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-e6bd64d0391186862b785448f5a2dd781a89415c8edf2d7a365eed6ce7870812.yml +openapi_spec_hash: eab33ae9c929dead86c0c04598c5c71c config_hash: d73914a733b27d121d59aa43bc7c710e From db5b24c5f4260914ab0d5583562bb7e8388eaca5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 08:06:35 +0000 Subject: [PATCH 13/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 7ff68c57..bb79b8b0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-e6bd64d0391186862b785448f5a2dd781a89415c8edf2d7a365eed6ce7870812.yml -openapi_spec_hash: eab33ae9c929dead86c0c04598c5c71c +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c96c88897f8d19fbdbc198611166980daa0448074a92a083b3db2014e670c474.yml +openapi_spec_hash: 4a1f0f6bbd23a8943700da97162255ab config_hash: d73914a733b27d121d59aa43bc7c710e From d79d4d49ef41a889a81a0d484616fca442849356 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 09:39:46 +0000 Subject: [PATCH 14/66] feat(api): add old_path field to ContentGitChangedFile --- .stats.yml | 4 ++-- src/gitpod/types/environment_status.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index bb79b8b0..d879ff20 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c96c88897f8d19fbdbc198611166980daa0448074a92a083b3db2014e670c474.yml -openapi_spec_hash: 4a1f0f6bbd23a8943700da97162255ab +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-95aec32d54661e6522d78deca8c182908b30bae1db5762b365a3ef338dbaccfa.yml +openapi_spec_hash: cd08bb12843c15e0fe783957866deb83 config_hash: d73914a733b27d121d59aa43bc7c710e diff --git a/src/gitpod/types/environment_status.py b/src/gitpod/types/environment_status.py index 45ad12ca..d5ed5c65 100644 --- a/src/gitpod/types/environment_status.py +++ b/src/gitpod/types/environment_status.py @@ -91,6 +91,12 @@ class ContentGitChangedFile(BaseModel): ] = FieldInfo(alias="changeType", default=None) """ChangeType is the type of change that happened to the file""" + old_path: Optional[str] = FieldInfo(alias="oldPath", default=None) + """ + old_path is the previous path of the file before a rename or copy. Only set when + change_type is RENAMED or COPIED. + """ + path: Optional[str] = None """path is the path of the file""" From 5c02854efdc2874535d3d7867823048d5e8d4693 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 14:57:23 +0000 Subject: [PATCH 15/66] fix: ensure file data are only sent as 1 parameter --- src/gitpod/_utils/_utils.py | 5 +++-- tests/test_extract_files.py | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/gitpod/_utils/_utils.py b/src/gitpod/_utils/_utils.py index eec7f4a1..63b8cd60 100644 --- a/src/gitpod/_utils/_utils.py +++ b/src/gitpod/_utils/_utils.py @@ -86,8 +86,9 @@ def _extract_items( index += 1 if is_dict(obj): try: - # We are at the last entry in the path so we must remove the field - if (len(path)) == index: + # Remove the field if there are no more dict keys in the path, + # only "" traversal markers or end. + if all(p == "" for p in path[index:]): item = obj.pop(key) else: item = obj[key] diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py index 0ca5a8dc..a9d8b167 100644 --- a/tests/test_extract_files.py +++ b/tests/test_extract_files.py @@ -35,6 +35,15 @@ def test_multiple_files() -> None: assert query == {"documents": [{}, {}]} +def test_top_level_file_array() -> None: + query = {"files": [b"file one", b"file two"], "title": "hello"} + assert extract_files(query, paths=[["files", ""]]) == [ + ("files[]", b"file one"), + ("files[]", b"file two"), + ] + assert query == {"title": "hello"} + + @pytest.mark.parametrize( "query,paths,expected", [ From 5a292cb1ef87a0dd73d93445707412d25c0e95e0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 14:59:08 +0000 Subject: [PATCH 16/66] docs(api): update trigger usage note in AutomationTrigger --- .stats.yml | 4 ++-- src/gitpod/types/shared/automation_trigger.py | 2 +- src/gitpod/types/shared_params/automation_trigger.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index d879ff20..f0b85f43 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-95aec32d54661e6522d78deca8c182908b30bae1db5762b365a3ef338dbaccfa.yml -openapi_spec_hash: cd08bb12843c15e0fe783957866deb83 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-803e9a382bb3f4d9b6ef7b1dd12c5541bf93608d3f4c240e99054929130f260b.yml +openapi_spec_hash: e2eae7e0a5a1fc83f3af40662b1ffbd1 config_hash: d73914a733b27d121d59aa43bc7c710e diff --git a/src/gitpod/types/shared/automation_trigger.py b/src/gitpod/types/shared/automation_trigger.py index 8ffd732b..3d1fafb8 100644 --- a/src/gitpod/types/shared/automation_trigger.py +++ b/src/gitpod/types/shared/automation_trigger.py @@ -20,7 +20,7 @@ class AutomationTrigger(BaseModel): The `prebuild` field starts the automation during a prebuild of an environment. This phase does not have user secrets available. The `before_snapshot` field triggers the automation after all prebuild tasks complete but before the snapshot is taken. This is used for tasks that need to run last during prebuilds, such as IDE warmup. - Note: The prebuild and before_snapshot triggers can only be used with tasks, not services. + Note: The before_snapshot trigger can only be used with tasks, not services. """ before_snapshot: Optional[bool] = FieldInfo(alias="beforeSnapshot", default=None) diff --git a/src/gitpod/types/shared_params/automation_trigger.py b/src/gitpod/types/shared_params/automation_trigger.py index 27dc462b..1020f005 100644 --- a/src/gitpod/types/shared_params/automation_trigger.py +++ b/src/gitpod/types/shared_params/automation_trigger.py @@ -20,7 +20,7 @@ class AutomationTrigger(TypedDict, total=False): The `prebuild` field starts the automation during a prebuild of an environment. This phase does not have user secrets available. The `before_snapshot` field triggers the automation after all prebuild tasks complete but before the snapshot is taken. This is used for tasks that need to run last during prebuilds, such as IDE warmup. - Note: The prebuild and before_snapshot triggers can only be used with tasks, not services. + Note: The before_snapshot trigger can only be used with tasks, not services. """ before_snapshot: Annotated[bool, PropertyInfo(alias="beforeSnapshot")] From af2c44e64fac19bf848c4325e0b39b183c998e74 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 09:38:45 +0000 Subject: [PATCH 17/66] feat(api): add prebuild trigger value to environments automations --- .stats.yml | 4 ++-- src/gitpod/types/environments/automations_file_param.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index f0b85f43..71f636ca 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-803e9a382bb3f4d9b6ef7b1dd12c5541bf93608d3f4c240e99054929130f260b.yml -openapi_spec_hash: e2eae7e0a5a1fc83f3af40662b1ffbd1 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-0c7c44116a92283a25ed199143e085b16a97dd804e0199e0058ec8ba61fa82a6.yml +openapi_spec_hash: 52646ebb63427df86c33aca56688b9a7 config_hash: d73914a733b27d121d59aa43bc7c710e diff --git a/src/gitpod/types/environments/automations_file_param.py b/src/gitpod/types/environments/automations_file_param.py index 226782ce..68deffa5 100644 --- a/src/gitpod/types/environments/automations_file_param.py +++ b/src/gitpod/types/environments/automations_file_param.py @@ -54,7 +54,8 @@ class Services(TypedDict, total=False): runs_on: Annotated[RunsOn, PropertyInfo(alias="runsOn")] triggered_by: Annotated[ - List[Literal["manual", "postEnvironmentStart", "postDevcontainerStart"]], PropertyInfo(alias="triggeredBy") + List[Literal["manual", "postEnvironmentStart", "postDevcontainerStart", "prebuild"]], + PropertyInfo(alias="triggeredBy"), ] From 201d9c6afdcc6f550f9bb0a7ba012ad70b754776 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:37:27 +0000 Subject: [PATCH 18/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 71f636ca..c99a6553 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-0c7c44116a92283a25ed199143e085b16a97dd804e0199e0058ec8ba61fa82a6.yml -openapi_spec_hash: 52646ebb63427df86c33aca56688b9a7 -config_hash: d73914a733b27d121d59aa43bc7c710e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-eb884d2b7e612a947d702820ae4cb60dbb9fa1b4127982ae8df8bc31cfe2222e.yml +openapi_spec_hash: 9a49114388edad25943a8660407db780 +config_hash: 25c7c72de891ed240ee62c4fb9a99756 From ad622d8589ad7caa87621919ec2d0217c21791cc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 05:20:51 +0000 Subject: [PATCH 19/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index c99a6553..9cc0d2e6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-eb884d2b7e612a947d702820ae4cb60dbb9fa1b4127982ae8df8bc31cfe2222e.yml -openapi_spec_hash: 9a49114388edad25943a8660407db780 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c148bac55f33b187604bab867c9b75124734cc8e4e72d4087e5a8e9b7472adff.yml +openapi_spec_hash: b98efd1fad1247c31ca39e482a151040 config_hash: 25c7c72de891ed240ee62c4fb9a99756 From 077b6622dc4e21a2033c8275c46716286a6515b8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 10:43:06 +0000 Subject: [PATCH 20/66] feat(api): add integration_id field, make webhook_id required in pull_request trigger --- .stats.yml | 4 ++-- src/gitpod/types/workflow_trigger.py | 7 +++++++ src/gitpod/types/workflow_trigger_param.py | 7 +++++++ tests/api_resources/test_automations.py | 4 ++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9cc0d2e6..96f9664b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c148bac55f33b187604bab867c9b75124734cc8e4e72d4087e5a8e9b7472adff.yml -openapi_spec_hash: b98efd1fad1247c31ca39e482a151040 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-5f25564854b84c1757f66d81caaa50f47db40dc697d4cc91877c2f4e59fa16aa.yml +openapi_spec_hash: 132db01aff2713a9a0a4d9e858ec1bba config_hash: 25c7c72de891ed240ee62c4fb9a99756 diff --git a/src/gitpod/types/workflow_trigger.py b/src/gitpod/types/workflow_trigger.py index 4b044761..f0a3f0e9 100644 --- a/src/gitpod/types/workflow_trigger.py +++ b/src/gitpod/types/workflow_trigger.py @@ -31,6 +31,13 @@ class PullRequest(BaseModel): ] ] = None + integration_id: Optional[str] = FieldInfo(alias="integrationId", default=None) + """ + integration_id is the optional ID of an integration that acts as the source of + webhook events. When set, the trigger will be activated when the webhook + receives events. + """ + webhook_id: Optional[str] = FieldInfo(alias="webhookId", default=None) """ webhook_id is the optional ID of a webhook that this trigger is bound to. When diff --git a/src/gitpod/types/workflow_trigger_param.py b/src/gitpod/types/workflow_trigger_param.py index ed28c9f8..362991a5 100644 --- a/src/gitpod/types/workflow_trigger_param.py +++ b/src/gitpod/types/workflow_trigger_param.py @@ -29,6 +29,13 @@ class PullRequest(TypedDict, total=False): ] ] + integration_id: Annotated[Optional[str], PropertyInfo(alias="integrationId")] + """ + integration_id is the optional ID of an integration that acts as the source of + webhook events. When set, the trigger will be activated when the webhook + receives events. + """ + webhook_id: Annotated[Optional[str], PropertyInfo(alias="webhookId")] """ webhook_id is the optional ID of a webhook that this trigger is bound to. When diff --git a/tests/api_resources/test_automations.py b/tests/api_resources/test_automations.py index f1412921..943c0d0a 100644 --- a/tests/api_resources/test_automations.py +++ b/tests/api_resources/test_automations.py @@ -113,6 +113,7 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "manual": {}, "pull_request": { "events": ["PULL_REQUEST_EVENT_UNSPECIFIED"], + "integration_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "webhook_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, "time": {"cron_expression": "cronExpression"}, @@ -256,6 +257,7 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "manual": {}, "pull_request": { "events": ["PULL_REQUEST_EVENT_UNSPECIFIED"], + "integration_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "webhook_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, "time": {"cron_expression": "cronExpression"}, @@ -793,6 +795,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "manual": {}, "pull_request": { "events": ["PULL_REQUEST_EVENT_UNSPECIFIED"], + "integration_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "webhook_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, "time": {"cron_expression": "cronExpression"}, @@ -936,6 +939,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "manual": {}, "pull_request": { "events": ["PULL_REQUEST_EVENT_UNSPECIFIED"], + "integration_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "webhook_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, "time": {"cron_expression": "cronExpression"}, From 59fa709bbf30705ae1aadf99bc784a79334d2438 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 07:01:45 +0000 Subject: [PATCH 21/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 96f9664b..4ed0bd13 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-5f25564854b84c1757f66d81caaa50f47db40dc697d4cc91877c2f4e59fa16aa.yml -openapi_spec_hash: 132db01aff2713a9a0a4d9e858ec1bba +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-baa75e208ad1eecd8764ebbf015adb7b94e929910b0f4d5520710ec7b3555a5e.yml +openapi_spec_hash: 01b460f045b05da799c85a5813321605 config_hash: 25c7c72de891ed240ee62c4fb9a99756 From c7f52384568a1bd3fd36e5616b81a3b1599154bf Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 07:49:24 +0000 Subject: [PATCH 22/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 4ed0bd13..3043de41 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-baa75e208ad1eecd8764ebbf015adb7b94e929910b0f4d5520710ec7b3555a5e.yml -openapi_spec_hash: 01b460f045b05da799c85a5813321605 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-6ec0a3dc7648f06e6ab5f66e8b441dae208e3664646194942afab30c2838d754.yml +openapi_spec_hash: 666f25bc2bafe875f1816feb0efab84f config_hash: 25c7c72de891ed240ee62c4fb9a99756 From e77b613ace22d0bf6e795719ea42efbb49cdc58b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:32:32 +0000 Subject: [PATCH 23/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3043de41..1d52292c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-6ec0a3dc7648f06e6ab5f66e8b441dae208e3664646194942afab30c2838d754.yml -openapi_spec_hash: 666f25bc2bafe875f1816feb0efab84f +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-f570506d82942fdb3a9f4b7a5d132ed844382dd75805f29dfeeeaf5204053301.yml +openapi_spec_hash: cd8bd23d7ff803f061fce04b772d9466 config_hash: 25c7c72de891ed240ee62c4fb9a99756 From c29b09596d2d87caaea047e61613a333c2fe4e31 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 07:13:29 +0000 Subject: [PATCH 24/66] feat(api): add port_authentication capability to runner_capability --- .stats.yml | 4 ++-- src/gitpod/types/runner_capability.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 1d52292c..2b98967d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-f570506d82942fdb3a9f4b7a5d132ed844382dd75805f29dfeeeaf5204053301.yml -openapi_spec_hash: cd8bd23d7ff803f061fce04b772d9466 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-f3b2ada71e17af494850c3c8b1b00cf5c6625b26f19f22d289ba37173f3019f5.yml +openapi_spec_hash: efd6b17f7ccf946e8888236ea24111d2 config_hash: 25c7c72de891ed240ee62c4fb9a99756 diff --git a/src/gitpod/types/runner_capability.py b/src/gitpod/types/runner_capability.py index c2e50b46..2e473ac1 100644 --- a/src/gitpod/types/runner_capability.py +++ b/src/gitpod/types/runner_capability.py @@ -18,4 +18,5 @@ "RUNNER_CAPABILITY_RUNNER_SIDE_AGENT", "RUNNER_CAPABILITY_WARM_POOL", "RUNNER_CAPABILITY_ASG_WARM_POOL", + "RUNNER_CAPABILITY_PORT_AUTHENTICATION", ] From 0352b9bee9b4a2aa8c132c934711a9a98d44b356 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 09:39:47 +0000 Subject: [PATCH 25/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2b98967d..8ba66106 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-f3b2ada71e17af494850c3c8b1b00cf5c6625b26f19f22d289ba37173f3019f5.yml -openapi_spec_hash: efd6b17f7ccf946e8888236ea24111d2 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-aaa301821ff7b0f6e0a55a197a2cc86f27b8117cc5011fef261eccde7fd64928.yml +openapi_spec_hash: ed6ad2ad221e8abfef79ac7f3f2667c3 config_hash: 25c7c72de891ed240ee62c4fb9a99756 From 72091d606c9087409ad26fcb8d4ff18ea8929eef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:34:41 +0000 Subject: [PATCH 26/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8ba66106..3684387f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-aaa301821ff7b0f6e0a55a197a2cc86f27b8117cc5011fef261eccde7fd64928.yml -openapi_spec_hash: ed6ad2ad221e8abfef79ac7f3f2667c3 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-83988f0b809f1fac483b4a3600397960b51b588aad5bc2483ec1234b72e4cff7.yml +openapi_spec_hash: 0c46d3bd9c1354e06feed3a85651c406 config_hash: 25c7c72de891ed240ee62c4fb9a99756 From 443b04e44954bb5a1ee26ad1bc71e92e7df44921 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 22:34:03 +0000 Subject: [PATCH 27/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3684387f..d8395430 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-83988f0b809f1fac483b4a3600397960b51b588aad5bc2483ec1234b72e4cff7.yml -openapi_spec_hash: 0c46d3bd9c1354e06feed3a85651c406 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-5136c01edc5507b8b534b7239a1f70e53b1860cbab729a99e33d65a114cb8097.yml +openapi_spec_hash: ca515ab45b8858fbc806f73ce6270702 config_hash: 25c7c72de891ed240ee62c4fb9a99756 From 242a3ab60ed3580fd9488858727294ed86568ccf Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:30:55 +0000 Subject: [PATCH 28/66] feat(api): add PULL_REQUEST_EVENT_REVIEW_REQUESTED to workflow_trigger events --- .stats.yml | 4 ++-- src/gitpod/types/workflow_trigger.py | 1 + src/gitpod/types/workflow_trigger_param.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index d8395430..983ecb08 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-5136c01edc5507b8b534b7239a1f70e53b1860cbab729a99e33d65a114cb8097.yml -openapi_spec_hash: ca515ab45b8858fbc806f73ce6270702 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-2cf38267930eaef11e8ba7d229c924d43f3e22d614aa586ad1ddffe65b9b4548.yml +openapi_spec_hash: e2ffe61e23fa87d7f8932b8d7764ee76 config_hash: 25c7c72de891ed240ee62c4fb9a99756 diff --git a/src/gitpod/types/workflow_trigger.py b/src/gitpod/types/workflow_trigger.py index f0a3f0e9..cefa42fc 100644 --- a/src/gitpod/types/workflow_trigger.py +++ b/src/gitpod/types/workflow_trigger.py @@ -27,6 +27,7 @@ class PullRequest(BaseModel): "PULL_REQUEST_EVENT_MERGED", "PULL_REQUEST_EVENT_CLOSED", "PULL_REQUEST_EVENT_READY_FOR_REVIEW", + "PULL_REQUEST_EVENT_REVIEW_REQUESTED", ] ] ] = None diff --git a/src/gitpod/types/workflow_trigger_param.py b/src/gitpod/types/workflow_trigger_param.py index 362991a5..ee1ef3c1 100644 --- a/src/gitpod/types/workflow_trigger_param.py +++ b/src/gitpod/types/workflow_trigger_param.py @@ -26,6 +26,7 @@ class PullRequest(TypedDict, total=False): "PULL_REQUEST_EVENT_MERGED", "PULL_REQUEST_EVENT_CLOSED", "PULL_REQUEST_EVENT_READY_FOR_REVIEW", + "PULL_REQUEST_EVENT_REVIEW_REQUESTED", ] ] From 74af5338d7f6447df5a6464a2b2ef893c3bf4f6e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:32:29 +0000 Subject: [PATCH 29/66] feat(api): add SUPPORTED_MODEL_OPUS_4_7 to agent_execution Status --- .stats.yml | 4 ++-- src/gitpod/types/agent_execution.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 983ecb08..b0ef81ab 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-2cf38267930eaef11e8ba7d229c924d43f3e22d614aa586ad1ddffe65b9b4548.yml -openapi_spec_hash: e2ffe61e23fa87d7f8932b8d7764ee76 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-0e20f536f7f833dd7205eaadd72826bd527a3ed91fcb006323e3232550abb04e.yml +openapi_spec_hash: 7a96aca1a75735a1664edd091b277940 config_hash: 25c7c72de891ed240ee62c4fb9a99756 diff --git a/src/gitpod/types/agent_execution.py b/src/gitpod/types/agent_execution.py index 07f02eda..02be3ac1 100644 --- a/src/gitpod/types/agent_execution.py +++ b/src/gitpod/types/agent_execution.py @@ -455,6 +455,7 @@ class Status(BaseModel): "SUPPORTED_MODEL_OPUS_4_5_EXTENDED", "SUPPORTED_MODEL_OPUS_4_6", "SUPPORTED_MODEL_OPUS_4_6_EXTENDED", + "SUPPORTED_MODEL_OPUS_4_7", "SUPPORTED_MODEL_HAIKU_4_5", "SUPPORTED_MODEL_OPENAI_4O", "SUPPORTED_MODEL_OPENAI_4O_MINI", From cb792b633104ff26eb799d8c32703920213ec23e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:38:13 +0000 Subject: [PATCH 30/66] perf(client): optimize file structure copying in multipart requests --- src/gitpod/_files.py | 56 ++++++++++++++++++-- src/gitpod/_utils/__init__.py | 1 - src/gitpod/_utils/_utils.py | 15 ------ tests/test_deepcopy.py | 58 -------------------- tests/test_files.py | 99 ++++++++++++++++++++++++++++++++++- 5 files changed, 151 insertions(+), 78 deletions(-) delete mode 100644 tests/test_deepcopy.py diff --git a/src/gitpod/_files.py b/src/gitpod/_files.py index cc14c14f..0fdce17b 100644 --- a/src/gitpod/_files.py +++ b/src/gitpod/_files.py @@ -3,8 +3,8 @@ import io import os import pathlib -from typing import overload -from typing_extensions import TypeGuard +from typing import Sequence, cast, overload +from typing_extensions import TypeVar, TypeGuard import anyio @@ -17,7 +17,9 @@ HttpxFileContent, HttpxRequestFiles, ) -from ._utils import is_tuple_t, is_mapping_t, is_sequence_t +from ._utils import is_list, is_mapping, is_tuple_t, is_mapping_t, is_sequence_t + +_T = TypeVar("_T") def is_base64_file_input(obj: object) -> TypeGuard[Base64FileInput]: @@ -121,3 +123,51 @@ async def async_read_file_content(file: FileContent) -> HttpxFileContent: return await anyio.Path(file).read_bytes() return file + + +def deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]]) -> _T: + """Copy only the containers along the given paths. + + Used to guard against mutation by extract_files without copying the entire structure. + Only dicts and lists that lie on a path are copied; everything else + is returned by reference. + + For example, given paths=[["foo", "files", "file"]] and the structure: + { + "foo": { + "bar": {"baz": {}}, + "files": {"file": } + } + } + The root dict, "foo", and "files" are copied (they lie on the path). + "bar" and "baz" are returned by reference (off the path). + """ + return _deepcopy_with_paths(item, paths, 0) + + +def _deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]], index: int) -> _T: + if not paths: + return item + if is_mapping(item): + key_to_paths: dict[str, list[Sequence[str]]] = {} + for path in paths: + if index < len(path): + key_to_paths.setdefault(path[index], []).append(path) + + # if no path continues through this mapping, it won't be mutated and copying it is redundant + if not key_to_paths: + return item + + result = dict(item) + for key, subpaths in key_to_paths.items(): + if key in result: + result[key] = _deepcopy_with_paths(result[key], subpaths, index + 1) + return cast(_T, result) + if is_list(item): + array_paths = [path for path in paths if index < len(path) and path[index] == ""] + + # if no path expects a list here, nothing will be mutated inside it - return by reference + if not array_paths: + return cast(_T, item) + return cast(_T, [_deepcopy_with_paths(entry, array_paths, index + 1) for entry in item]) + return item diff --git a/src/gitpod/_utils/__init__.py b/src/gitpod/_utils/__init__.py index 10cb66d2..1c090e51 100644 --- a/src/gitpod/_utils/__init__.py +++ b/src/gitpod/_utils/__init__.py @@ -24,7 +24,6 @@ coerce_integer as coerce_integer, file_from_path as file_from_path, strip_not_given as strip_not_given, - deepcopy_minimal as deepcopy_minimal, get_async_library as get_async_library, maybe_coerce_float as maybe_coerce_float, get_required_header as get_required_header, diff --git a/src/gitpod/_utils/_utils.py b/src/gitpod/_utils/_utils.py index 63b8cd60..771859f5 100644 --- a/src/gitpod/_utils/_utils.py +++ b/src/gitpod/_utils/_utils.py @@ -177,21 +177,6 @@ def is_iterable(obj: object) -> TypeGuard[Iterable[object]]: return isinstance(obj, Iterable) -def deepcopy_minimal(item: _T) -> _T: - """Minimal reimplementation of copy.deepcopy() that will only copy certain object types: - - - mappings, e.g. `dict` - - list - - This is done for performance reasons. - """ - if is_mapping(item): - return cast(_T, {k: deepcopy_minimal(v) for k, v in item.items()}) - if is_list(item): - return cast(_T, [deepcopy_minimal(entry) for entry in item]) - return item - - # copied from https://github.com/Rapptz/RoboDanny def human_join(seq: Sequence[str], *, delim: str = ", ", final: str = "or") -> str: size = len(seq) diff --git a/tests/test_deepcopy.py b/tests/test_deepcopy.py deleted file mode 100644 index c498f531..00000000 --- a/tests/test_deepcopy.py +++ /dev/null @@ -1,58 +0,0 @@ -from gitpod._utils import deepcopy_minimal - - -def assert_different_identities(obj1: object, obj2: object) -> None: - assert obj1 == obj2 - assert id(obj1) != id(obj2) - - -def test_simple_dict() -> None: - obj1 = {"foo": "bar"} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - - -def test_nested_dict() -> None: - obj1 = {"foo": {"bar": True}} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1["foo"], obj2["foo"]) - - -def test_complex_nested_dict() -> None: - obj1 = {"foo": {"bar": [{"hello": "world"}]}} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1["foo"], obj2["foo"]) - assert_different_identities(obj1["foo"]["bar"], obj2["foo"]["bar"]) - assert_different_identities(obj1["foo"]["bar"][0], obj2["foo"]["bar"][0]) - - -def test_simple_list() -> None: - obj1 = ["a", "b", "c"] - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - - -def test_nested_list() -> None: - obj1 = ["a", [1, 2, 3]] - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1[1], obj2[1]) - - -class MyObject: ... - - -def test_ignores_other_types() -> None: - # custom classes - my_obj = MyObject() - obj1 = {"foo": my_obj} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert obj1["foo"] is my_obj - - # tuples - obj3 = ("a", "b") - obj4 = deepcopy_minimal(obj3) - assert obj3 is obj4 diff --git a/tests/test_files.py b/tests/test_files.py index efde0d4e..2e09e8a4 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -4,7 +4,8 @@ import pytest from dirty_equals import IsDict, IsList, IsBytes, IsTuple -from gitpod._files import to_httpx_files, async_to_httpx_files +from gitpod._files import to_httpx_files, deepcopy_with_paths, async_to_httpx_files +from gitpod._utils import extract_files readme_path = Path(__file__).parent.parent.joinpath("README.md") @@ -49,3 +50,99 @@ def test_string_not_allowed() -> None: "file": "foo", # type: ignore } ) + + +def assert_different_identities(obj1: object, obj2: object) -> None: + assert obj1 == obj2 + assert obj1 is not obj2 + + +class TestDeepcopyWithPaths: + def test_copies_top_level_dict(self) -> None: + original = {"file": b"data", "other": "value"} + result = deepcopy_with_paths(original, [["file"]]) + assert_different_identities(result, original) + + def test_file_value_is_same_reference(self) -> None: + file_bytes = b"contents" + original = {"file": file_bytes} + result = deepcopy_with_paths(original, [["file"]]) + assert_different_identities(result, original) + assert result["file"] is file_bytes + + def test_list_popped_wholesale(self) -> None: + files = [b"f1", b"f2"] + original = {"files": files, "title": "t"} + result = deepcopy_with_paths(original, [["files", ""]]) + assert_different_identities(result, original) + result_files = result["files"] + assert isinstance(result_files, list) + assert_different_identities(result_files, files) + + def test_nested_array_path_copies_list_and_elements(self) -> None: + elem1 = {"file": b"f1", "extra": 1} + elem2 = {"file": b"f2", "extra": 2} + original = {"items": [elem1, elem2]} + result = deepcopy_with_paths(original, [["items", "", "file"]]) + assert_different_identities(result, original) + result_items = result["items"] + assert isinstance(result_items, list) + assert_different_identities(result_items, original["items"]) + assert_different_identities(result_items[0], elem1) + assert_different_identities(result_items[1], elem2) + + def test_empty_paths_returns_same_object(self) -> None: + original = {"foo": "bar"} + result = deepcopy_with_paths(original, []) + assert result is original + + def test_multiple_paths(self) -> None: + f1 = b"file1" + f2 = b"file2" + original = {"a": f1, "b": f2, "c": "unchanged"} + result = deepcopy_with_paths(original, [["a"], ["b"]]) + assert_different_identities(result, original) + assert result["a"] is f1 + assert result["b"] is f2 + assert result["c"] is original["c"] + + def test_extract_files_does_not_mutate_original_top_level(self) -> None: + file_bytes = b"contents" + original = {"file": file_bytes, "other": "value"} + + copied = deepcopy_with_paths(original, [["file"]]) + extracted = extract_files(copied, paths=[["file"]]) + + assert extracted == [("file", file_bytes)] + assert original == {"file": file_bytes, "other": "value"} + assert copied == {"other": "value"} + + def test_extract_files_does_not_mutate_original_nested_array_path(self) -> None: + file1 = b"f1" + file2 = b"f2" + original = { + "items": [ + {"file": file1, "extra": 1}, + {"file": file2, "extra": 2}, + ], + "title": "example", + } + + copied = deepcopy_with_paths(original, [["items", "", "file"]]) + extracted = extract_files(copied, paths=[["items", "", "file"]]) + + assert extracted == [("items[][file]", file1), ("items[][file]", file2)] + assert original == { + "items": [ + {"file": file1, "extra": 1}, + {"file": file2, "extra": 2}, + ], + "title": "example", + } + assert copied == { + "items": [ + {"extra": 1}, + {"extra": 2}, + ], + "title": "example", + } From ea300f4314c14529c02ffec1e38f474d8a426844 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 11:51:47 +0000 Subject: [PATCH 31/66] feat(api): add UserInputMetadata type --- .stats.yml | 6 +++--- api.md | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index b0ef81ab..340b6728 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-0e20f536f7f833dd7205eaadd72826bd527a3ed91fcb006323e3232550abb04e.yml -openapi_spec_hash: 7a96aca1a75735a1664edd091b277940 -config_hash: 25c7c72de891ed240ee62c4fb9a99756 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-ac173b64bb40160fa60a528c250b18b70b60676d8d639d22065a430a40e6406a.yml +openapi_spec_hash: 10763c4df593dae81fe9729e8a6ff799 +config_hash: d579aac01b686dadf777791467e135dd diff --git a/api.md b/api.md index dbd40b76..178c06b3 100644 --- a/api.md +++ b/api.md @@ -75,6 +75,7 @@ from gitpod.types import ( Role, Type, UserInputBlock, + UserInputMetadata, WakeEvent, AgentCreateExecutionConversationTokenResponse, AgentCreatePromptResponse, From 5c7fa85594b4a9ce34dcbbe112e31ffa51c1757b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:10:07 +0000 Subject: [PATCH 32/66] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 340b6728..41e21590 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-ac173b64bb40160fa60a528c250b18b70b60676d8d639d22065a430a40e6406a.yml openapi_spec_hash: 10763c4df593dae81fe9729e8a6ff799 -config_hash: d579aac01b686dadf777791467e135dd +config_hash: bb4b1641dcadc46913d9be1cb461ad7b From 7eb2fad98d3dfc8024197ef3e86c89b9f5483ffe Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 16:09:14 +0000 Subject: [PATCH 33/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 41e21590..c44ca440 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-ac173b64bb40160fa60a528c250b18b70b60676d8d639d22065a430a40e6406a.yml -openapi_spec_hash: 10763c4df593dae81fe9729e8a6ff799 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-0eca3ab72da589e2e8bfb64d2e635db971bf98d990d8c6d36d61c2937571622c.yml +openapi_spec_hash: cc41f33b3befb78916300882eeb44b72 config_hash: bb4b1641dcadc46913d9be1cb461ad7b From 54503f5295a703ee855eac4c11694d2bbe465d13 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 10:41:02 +0000 Subject: [PATCH 34/66] feat(api): add SUPPORTED_MODEL_OPENAI_AUTO to agent_execution status --- .stats.yml | 6 +++--- src/gitpod/types/agent_execution.py | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index c44ca440..f1758b6f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-0eca3ab72da589e2e8bfb64d2e635db971bf98d990d8c6d36d61c2937571622c.yml -openapi_spec_hash: cc41f33b3befb78916300882eeb44b72 -config_hash: bb4b1641dcadc46913d9be1cb461ad7b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-e7101c6bd027d5c69246e02062396cecbe9eb5655e7a9e9f34d57ebdea6a9c1b.yml +openapi_spec_hash: 9ea4f9272509d3c8867735933d371070 +config_hash: d579aac01b686dadf777791467e135dd diff --git a/src/gitpod/types/agent_execution.py b/src/gitpod/types/agent_execution.py index 02be3ac1..102b08ca 100644 --- a/src/gitpod/types/agent_execution.py +++ b/src/gitpod/types/agent_execution.py @@ -461,6 +461,7 @@ class Status(BaseModel): "SUPPORTED_MODEL_OPENAI_4O_MINI", "SUPPORTED_MODEL_OPENAI_O1", "SUPPORTED_MODEL_OPENAI_O1_MINI", + "SUPPORTED_MODEL_OPENAI_AUTO", ] ] = FieldInfo(alias="supportedModel", default=None) """supported_model is the LLM model being used by the agent execution.""" From 5f05caacfd1a55617d435845771e28503eff687c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 13:56:05 +0000 Subject: [PATCH 35/66] chore(internal): more robust bootstrap script --- scripts/bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bootstrap b/scripts/bootstrap index b430fee3..fe8451e4 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -4,7 +4,7 @@ set -e cd "$(dirname "$0")/.." -if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then +if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then brew bundle check >/dev/null 2>&1 || { echo -n "==> Install Homebrew dependencies? (y/N): " read -r response From 846c6f80300f40a4ea96b8096888ba7638d43350 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 16:53:14 +0000 Subject: [PATCH 36/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index f1758b6f..e9f120d7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-e7101c6bd027d5c69246e02062396cecbe9eb5655e7a9e9f34d57ebdea6a9c1b.yml -openapi_spec_hash: 9ea4f9272509d3c8867735933d371070 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-513d76e17d0237b8a068d7aaa38427429b88432ebdf379dcef8bc12e45391471.yml +openapi_spec_hash: 82fb97ed0d6bf7515e79b442eedf1028 config_hash: d579aac01b686dadf777791467e135dd From d0d62cf61bd20912adb9cbb6f0f32a67065a566b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 05:21:18 +0000 Subject: [PATCH 37/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e9f120d7..c6cf393d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-513d76e17d0237b8a068d7aaa38427429b88432ebdf379dcef8bc12e45391471.yml -openapi_spec_hash: 82fb97ed0d6bf7515e79b442eedf1028 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-626284323060c0fad499fdb2041944dfb24eafe88ef53bb29aa637664aa0b619.yml +openapi_spec_hash: ad17546e9e0a56aee371b9a7bfc38eb4 config_hash: d579aac01b686dadf777791467e135dd From 5e7b9f3d7dd7af385ca75b17f01c1cab87da8cb6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 12:26:34 +0000 Subject: [PATCH 38/66] docs(types): mark is_admin deprecated in Organization model --- .stats.yml | 4 ++-- .../types/runner_list_scm_organizations_response.py | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index c6cf393d..49223517 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-626284323060c0fad499fdb2041944dfb24eafe88ef53bb29aa637664aa0b619.yml -openapi_spec_hash: ad17546e9e0a56aee371b9a7bfc38eb4 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-efe85a39b9b9cde6b97eba5ee4d437231be5e730c682122a475cbce3c0b8afab.yml +openapi_spec_hash: 251284ebeda328cabe9120cb0041dc87 config_hash: d579aac01b686dadf777791467e135dd diff --git a/src/gitpod/types/runner_list_scm_organizations_response.py b/src/gitpod/types/runner_list_scm_organizations_response.py index 8e9db077..d089df57 100644 --- a/src/gitpod/types/runner_list_scm_organizations_response.py +++ b/src/gitpod/types/runner_list_scm_organizations_response.py @@ -12,8 +12,13 @@ class Organization(BaseModel): is_admin: Optional[bool] = FieldInfo(alias="isAdmin", default=None) """ - Whether the user has admin permissions in this organization. Admin permissions - typically allow creating organization-level webhooks. + Deprecated: this field is unused by all known consumers and is scheduled for + removal in a future release. Do not read it. + + Originally intended to gate organization-level webhook creation in the + dashboard, but that gating was never implemented. Populating this field on the + GitLab path requires a second fully-paginated ListGroups call, which is the main + reason we are deprecating it. """ name: Optional[str] = None From 14ad30a251e4f2819b245b96d7bab197131b4196 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 17:29:47 +0000 Subject: [PATCH 39/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 49223517..bc7328f9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-efe85a39b9b9cde6b97eba5ee4d437231be5e730c682122a475cbce3c0b8afab.yml -openapi_spec_hash: 251284ebeda328cabe9120cb0041dc87 -config_hash: d579aac01b686dadf777791467e135dd +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-715182a0b2eb7ec05e17eaa8a5df88b5b4a1c42cb972cc1d17cdd5a059e22787.yml +openapi_spec_hash: 9ef9c72cb9727ac343d250c377627dee +config_hash: f35dbcdcd0d739add7d045e3ea0a7003 From 9236eb4173504e1205261bfc7a9c51a450b3a59c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 20:17:43 +0000 Subject: [PATCH 40/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index bc7328f9..8aefc1e4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-715182a0b2eb7ec05e17eaa8a5df88b5b4a1c42cb972cc1d17cdd5a059e22787.yml -openapi_spec_hash: 9ef9c72cb9727ac343d250c377627dee +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-dcabf4f75cca898f84c8b5faac6dfd6a0bbbe653bb3b3b64f027de1e0c6a6cfc.yml +openapi_spec_hash: 2e8df4e214a2fdef1a3f690fa6765dfd config_hash: f35dbcdcd0d739add7d045e3ea0a7003 From c318e03c64b18ffdbb7e79a975f0a19d7f07685f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 06:38:20 +0000 Subject: [PATCH 41/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8aefc1e4..b207c5a7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-dcabf4f75cca898f84c8b5faac6dfd6a0bbbe653bb3b3b64f027de1e0c6a6cfc.yml -openapi_spec_hash: 2e8df4e214a2fdef1a3f690fa6765dfd -config_hash: f35dbcdcd0d739add7d045e3ea0a7003 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-2e21ce480356fd18cc413421d9d85ef46d7ebd7961518933cfb5b469799c57d7.yml +openapi_spec_hash: f558f68f695c3c21bf10252e3505fdf1 +config_hash: 52dce9b7b86eca30b5b126335592f962 From 333311aebaefb657861e2a9f6e8adb0f2abdd4dc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 11:51:02 +0000 Subject: [PATCH 42/66] feat(api): add pagination and query parameter to runners.list_scm_organizations --- .stats.yml | 6 +- api.md | 2 +- src/gitpod/pagination.py | 53 +++++++++++++ src/gitpod/resources/runners/runners.py | 76 ++++++++++++++++--- .../runner_list_scm_organizations_params.py | 38 +++++++++- .../runner_list_scm_organizations_response.py | 11 +-- tests/api_resources/test_runners.py | 28 ++++--- 7 files changed, 182 insertions(+), 32 deletions(-) diff --git a/.stats.yml b/.stats.yml index b207c5a7..f88f2981 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-2e21ce480356fd18cc413421d9d85ef46d7ebd7961518933cfb5b469799c57d7.yml -openapi_spec_hash: f558f68f695c3c21bf10252e3505fdf1 -config_hash: 52dce9b7b86eca30b5b126335592f962 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-162fdc304a6f1f8e282b49c7cde2e2aa282e58045ac814869491340f932982d4.yml +openapi_spec_hash: 017607fc78184b5a49249ed134e1ad7c +config_hash: 4447d1e1149a80d1bec70d353fb8acbf diff --git a/api.md b/api.md index 178c06b3..0bc97406 100644 --- a/api.md +++ b/api.md @@ -710,7 +710,7 @@ Methods: - client.runners.check_repository_access(\*\*params) -> RunnerCheckRepositoryAccessResponse - client.runners.create_logs_token(\*\*params) -> RunnerCreateLogsTokenResponse - client.runners.create_runner_token(\*\*params) -> RunnerCreateRunnerTokenResponse -- client.runners.list_scm_organizations(\*\*params) -> RunnerListScmOrganizationsResponse +- client.runners.list_scm_organizations(\*\*params) -> SyncOrganizationsPage[RunnerListScmOrganizationsResponse] - client.runners.parse_context_url(\*\*params) -> RunnerParseContextURLResponse - client.runners.search_repositories(\*\*params) -> RunnerSearchRepositoriesResponse diff --git a/src/gitpod/pagination.py b/src/gitpod/pagination.py index b55ecc60..83771ae0 100644 --- a/src/gitpod/pagination.py +++ b/src/gitpod/pagination.py @@ -51,6 +51,9 @@ "MembersPagePagination", "SyncMembersPage", "AsyncMembersPage", + "OrganizationsPagePagination", + "SyncOrganizationsPage", + "AsyncOrganizationsPage", "OutputsPagePagination", "SyncOutputsPage", "AsyncOutputsPage", @@ -819,6 +822,56 @@ def next_page_info(self) -> Optional[PageInfo]: return PageInfo(params={"token": next_token}) +class OrganizationsPagePagination(BaseModel): + next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) + + +class SyncOrganizationsPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]): + organizations: List[_T] + pagination: Optional[OrganizationsPagePagination] = None + + @override + def _get_page_items(self) -> List[_T]: + organizations = self.organizations + if not organizations: + return [] + return organizations + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + +class AsyncOrganizationsPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): + organizations: List[_T] + pagination: Optional[OrganizationsPagePagination] = None + + @override + def _get_page_items(self) -> List[_T]: + organizations = self.organizations + if not organizations: + return [] + return organizations + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + class OutputsPagePagination(BaseModel): next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) diff --git a/src/gitpod/resources/runners/runners.py b/src/gitpod/resources/runners/runners.py index 5a0ee2e4..1d92c061 100644 --- a/src/gitpod/resources/runners/runners.py +++ b/src/gitpod/resources/runners/runners.py @@ -41,7 +41,7 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ...pagination import SyncRunnersPage, AsyncRunnersPage +from ...pagination import SyncRunnersPage, AsyncRunnersPage, SyncOrganizationsPage, AsyncOrganizationsPage from ..._base_client import AsyncPaginator, make_request_options from ...types.runner import Runner from ...types.runner_kind import RunnerKind @@ -681,6 +681,8 @@ def list_scm_organizations( *, token: str | Omit = omit, page_size: int | Omit = omit, + pagination: runner_list_scm_organizations_params.Pagination | Omit = omit, + query: str | Omit = omit, runner_id: str | Omit = omit, scm_host: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -689,7 +691,7 @@ def list_scm_organizations( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> RunnerListScmOrganizationsResponse: + ) -> SyncOrganizationsPage[RunnerListScmOrganizationsResponse]: """ Lists SCM organizations the user belongs to. @@ -709,7 +711,29 @@ def list_scm_organizations( scmHost: "github.com" ``` + - Search GitLab groups: + + Returns the first page of GitLab groups matching the substring. + + ```yaml + runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + scmHost: "gitlab.com" + query: "platform" + pagination: + pageSize: 25 + ``` + Args: + pagination: Pagination parameters. When unset, defaults to the standard PaginationRequest + defaults (page_size 25, max 100). Tokens are opaque and provider-specific. + + query: Optional substring filter applied to the organization name. + + - GitLab: forwarded to the upstream `search` parameter (server-side, + case-insensitive substring on name/path). + - GitHub and Bitbucket: not implemented as they don't support searching Empty + value means no filter. + scm_host: The SCM host to list organizations from (e.g., "github.com", "gitlab.com") extra_headers: Send extra headers @@ -720,10 +744,13 @@ def list_scm_organizations( timeout: Override the client-level default timeout for this request, in seconds """ - return self._post( + return self._get_api_list( "/gitpod.v1.RunnerService/ListSCMOrganizations", + page=SyncOrganizationsPage[RunnerListScmOrganizationsResponse], body=maybe_transform( { + "pagination": pagination, + "query": query, "runner_id": runner_id, "scm_host": scm_host, }, @@ -742,7 +769,8 @@ def list_scm_organizations( runner_list_scm_organizations_params.RunnerListScmOrganizationsParams, ), ), - cast_to=RunnerListScmOrganizationsResponse, + model=RunnerListScmOrganizationsResponse, + method="post", ) def parse_context_url( @@ -1505,11 +1533,13 @@ async def create_runner_token( cast_to=RunnerCreateRunnerTokenResponse, ) - async def list_scm_organizations( + def list_scm_organizations( self, *, token: str | Omit = omit, page_size: int | Omit = omit, + pagination: runner_list_scm_organizations_params.Pagination | Omit = omit, + query: str | Omit = omit, runner_id: str | Omit = omit, scm_host: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1518,7 +1548,7 @@ async def list_scm_organizations( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> RunnerListScmOrganizationsResponse: + ) -> AsyncPaginator[RunnerListScmOrganizationsResponse, AsyncOrganizationsPage[RunnerListScmOrganizationsResponse]]: """ Lists SCM organizations the user belongs to. @@ -1538,7 +1568,29 @@ async def list_scm_organizations( scmHost: "github.com" ``` + - Search GitLab groups: + + Returns the first page of GitLab groups matching the substring. + + ```yaml + runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + scmHost: "gitlab.com" + query: "platform" + pagination: + pageSize: 25 + ``` + Args: + pagination: Pagination parameters. When unset, defaults to the standard PaginationRequest + defaults (page_size 25, max 100). Tokens are opaque and provider-specific. + + query: Optional substring filter applied to the organization name. + + - GitLab: forwarded to the upstream `search` parameter (server-side, + case-insensitive substring on name/path). + - GitHub and Bitbucket: not implemented as they don't support searching Empty + value means no filter. + scm_host: The SCM host to list organizations from (e.g., "github.com", "gitlab.com") extra_headers: Send extra headers @@ -1549,10 +1601,13 @@ async def list_scm_organizations( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._post( + return self._get_api_list( "/gitpod.v1.RunnerService/ListSCMOrganizations", - body=await async_maybe_transform( + page=AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], + body=maybe_transform( { + "pagination": pagination, + "query": query, "runner_id": runner_id, "scm_host": scm_host, }, @@ -1563,7 +1618,7 @@ async def list_scm_organizations( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "token": token, "page_size": page_size, @@ -1571,7 +1626,8 @@ async def list_scm_organizations( runner_list_scm_organizations_params.RunnerListScmOrganizationsParams, ), ), - cast_to=RunnerListScmOrganizationsResponse, + model=RunnerListScmOrganizationsResponse, + method="post", ) async def parse_context_url( diff --git a/src/gitpod/types/runner_list_scm_organizations_params.py b/src/gitpod/types/runner_list_scm_organizations_params.py index bd1f788b..a852d57b 100644 --- a/src/gitpod/types/runner_list_scm_organizations_params.py +++ b/src/gitpod/types/runner_list_scm_organizations_params.py @@ -6,7 +6,7 @@ from .._utils import PropertyInfo -__all__ = ["RunnerListScmOrganizationsParams"] +__all__ = ["RunnerListScmOrganizationsParams", "Pagination"] class RunnerListScmOrganizationsParams(TypedDict, total=False): @@ -14,7 +14,43 @@ class RunnerListScmOrganizationsParams(TypedDict, total=False): page_size: Annotated[int, PropertyInfo(alias="pageSize")] + pagination: Pagination + """Pagination parameters. + + When unset, defaults to the standard PaginationRequest defaults (page_size 25, + max 100). Tokens are opaque and provider-specific. + """ + + query: str + """Optional substring filter applied to the organization name. + + - GitLab: forwarded to the upstream `search` parameter (server-side, + case-insensitive substring on name/path). + - GitHub and Bitbucket: not implemented as they don't support searching Empty + value means no filter. + """ + runner_id: Annotated[str, PropertyInfo(alias="runnerId")] scm_host: Annotated[str, PropertyInfo(alias="scmHost")] """The SCM host to list organizations from (e.g., "github.com", "gitlab.com")""" + + +class Pagination(TypedDict, total=False): + """Pagination parameters. + + When unset, defaults to the standard PaginationRequest defaults + (page_size 25, max 100). Tokens are opaque and provider-specific. + """ + + token: str + """ + Token for the next set of results that was returned as next_token of a + PaginationResponse + """ + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Page size is the maximum number of results to retrieve per page. Defaults to 25. + + Maximum 100. + """ diff --git a/src/gitpod/types/runner_list_scm_organizations_response.py b/src/gitpod/types/runner_list_scm_organizations_response.py index d089df57..8c8c50e8 100644 --- a/src/gitpod/types/runner_list_scm_organizations_response.py +++ b/src/gitpod/types/runner_list_scm_organizations_response.py @@ -1,15 +1,15 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from pydantic import Field as FieldInfo from .._models import BaseModel -__all__ = ["RunnerListScmOrganizationsResponse", "Organization"] +__all__ = ["RunnerListScmOrganizationsResponse"] -class Organization(BaseModel): +class RunnerListScmOrganizationsResponse(BaseModel): is_admin: Optional[bool] = FieldInfo(alias="isAdmin", default=None) """ Deprecated: this field is unused by all known consumers and is scheduled for @@ -26,8 +26,3 @@ class Organization(BaseModel): url: Optional[str] = None """Organization URL (e.g., "https://github.com/gitpod-io")""" - - -class RunnerListScmOrganizationsResponse(BaseModel): - organizations: Optional[List[Organization]] = None - """List of organizations the user belongs to""" diff --git a/tests/api_resources/test_runners.py b/tests/api_resources/test_runners.py index 3a7c4506..dad788c8 100644 --- a/tests/api_resources/test_runners.py +++ b/tests/api_resources/test_runners.py @@ -21,7 +21,7 @@ RunnerCheckRepositoryAccessResponse, RunnerCheckAuthenticationForHostResponse, ) -from gitpod.pagination import SyncRunnersPage, AsyncRunnersPage +from gitpod.pagination import SyncRunnersPage, AsyncRunnersPage, SyncOrganizationsPage, AsyncOrganizationsPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -416,7 +416,7 @@ def test_streaming_response_create_runner_token(self, client: Gitpod) -> None: @parametrize def test_method_list_scm_organizations(self, client: Gitpod) -> None: runner = client.runners.list_scm_organizations() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(SyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -424,10 +424,15 @@ def test_method_list_scm_organizations_with_all_params(self, client: Gitpod) -> runner = client.runners.list_scm_organizations( token="token", page_size=0, + pagination={ + "token": "token", + "page_size": 100, + }, + query="query", runner_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", scm_host="github.com", ) - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(SyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -437,7 +442,7 @@ def test_raw_response_list_scm_organizations(self, client: Gitpod) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" runner = response.parse() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(SyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -447,7 +452,7 @@ def test_streaming_response_list_scm_organizations(self, client: Gitpod) -> None assert response.http_request.headers.get("X-Stainless-Lang") == "python" runner = response.parse() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(SyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) assert cast(Any, response.is_closed) is True @@ -925,7 +930,7 @@ async def test_streaming_response_create_runner_token(self, async_client: AsyncG @parametrize async def test_method_list_scm_organizations(self, async_client: AsyncGitpod) -> None: runner = await async_client.runners.list_scm_organizations() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -933,10 +938,15 @@ async def test_method_list_scm_organizations_with_all_params(self, async_client: runner = await async_client.runners.list_scm_organizations( token="token", page_size=0, + pagination={ + "token": "token", + "page_size": 100, + }, + query="query", runner_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", scm_host="github.com", ) - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -946,7 +956,7 @@ async def test_raw_response_list_scm_organizations(self, async_client: AsyncGitp assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" runner = await response.parse() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -956,7 +966,7 @@ async def test_streaming_response_list_scm_organizations(self, async_client: Asy assert response.http_request.headers.get("X-Stainless-Lang") == "python" runner = await response.parse() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) assert cast(Any, response.is_closed) is True From 8d2d67efea7fe30dba14c8d12eb40fc392ec8fe5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 12:47:02 +0000 Subject: [PATCH 43/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index f88f2981..31cb8c27 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-162fdc304a6f1f8e282b49c7cde2e2aa282e58045ac814869491340f932982d4.yml -openapi_spec_hash: 017607fc78184b5a49249ed134e1ad7c +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3648b39143360cbfc8c544ee90a300a57e2da09d9a7153cf5e003ae29164664d.yml +openapi_spec_hash: 1206eef2a61f6fba496715f1fabacb47 config_hash: 4447d1e1149a80d1bec70d353fb8acbf From e2b45a600764d642191eeb482af8dd5cc82ae6b1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 12:56:47 +0000 Subject: [PATCH 44/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 31cb8c27..2a5eaf4a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3648b39143360cbfc8c544ee90a300a57e2da09d9a7153cf5e003ae29164664d.yml -openapi_spec_hash: 1206eef2a61f6fba496715f1fabacb47 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c5b3669c8db150b04d14f02596f3fd59076b7ac971fbb66583231a1189a8c91b.yml +openapi_spec_hash: a4114b38d47f0696fdf23bfe64dc446c config_hash: 4447d1e1149a80d1bec70d353fb8acbf From 8ddb8c8e3b4e635f8ad6a22e0db738df8236a21c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 12:07:57 +0000 Subject: [PATCH 45/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2a5eaf4a..957e8bd3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c5b3669c8db150b04d14f02596f3fd59076b7ac971fbb66583231a1189a8c91b.yml -openapi_spec_hash: a4114b38d47f0696fdf23bfe64dc446c +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-e8c1d2dbde2a6b9f6064c7dc2bd3b9429a834131660e0826c49a1d620d807b78.yml +openapi_spec_hash: f770f8bfb695c692341c74e79930fe61 config_hash: 4447d1e1149a80d1bec70d353fb8acbf From 974e4d0d003712103f37fa1ac10ec05e566c3da1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 13:58:14 +0000 Subject: [PATCH 46/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 957e8bd3..97339761 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-e8c1d2dbde2a6b9f6064c7dc2bd3b9429a834131660e0826c49a1d620d807b78.yml -openapi_spec_hash: f770f8bfb695c692341c74e79930fe61 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-439cda23bbab7cb3207b4350637971f50e98624270abba0e636cef39b54d34bd.yml +openapi_spec_hash: 5b2ead9eced70d525d4348b2ed3f1387 config_hash: 4447d1e1149a80d1bec70d353fb8acbf From c731392aa36e5a3bba895d4e52a7d50addab326a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:03:21 +0000 Subject: [PATCH 47/66] fix: use correct field name format for multipart file arrays --- src/gitpod/_qs.py | 8 ++----- src/gitpod/_types.py | 3 +++ src/gitpod/_utils/_utils.py | 42 ++++++++++++++++++++++++++++++------- tests/test_extract_files.py | 28 ++++++++++++++++++++----- tests/test_files.py | 2 +- 5 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/gitpod/_qs.py b/src/gitpod/_qs.py index de8c99bc..4127c19c 100644 --- a/src/gitpod/_qs.py +++ b/src/gitpod/_qs.py @@ -2,17 +2,13 @@ from typing import Any, List, Tuple, Union, Mapping, TypeVar from urllib.parse import parse_qs, urlencode -from typing_extensions import Literal, get_args +from typing_extensions import get_args -from ._types import NotGiven, not_given +from ._types import NotGiven, ArrayFormat, NestedFormat, not_given from ._utils import flatten _T = TypeVar("_T") - -ArrayFormat = Literal["comma", "repeat", "indices", "brackets"] -NestedFormat = Literal["dots", "brackets"] - PrimitiveData = Union[str, int, float, bool, None] # this should be Data = Union[PrimitiveData, "List[Data]", "Tuple[Data]", "Mapping[str, Data]"] # https://github.com/microsoft/pyright/issues/3555 diff --git a/src/gitpod/_types.py b/src/gitpod/_types.py index dbebac09..8a15cebe 100644 --- a/src/gitpod/_types.py +++ b/src/gitpod/_types.py @@ -47,6 +47,9 @@ ModelT = TypeVar("ModelT", bound=pydantic.BaseModel) _T = TypeVar("_T") +ArrayFormat = Literal["comma", "repeat", "indices", "brackets"] +NestedFormat = Literal["dots", "brackets"] + # Approximates httpx internal ProxiesTypes and RequestFiles types # while adding support for `PathLike` instances diff --git a/src/gitpod/_utils/_utils.py b/src/gitpod/_utils/_utils.py index 771859f5..199cd231 100644 --- a/src/gitpod/_utils/_utils.py +++ b/src/gitpod/_utils/_utils.py @@ -17,11 +17,11 @@ ) from pathlib import Path from datetime import date, datetime -from typing_extensions import TypeGuard +from typing_extensions import TypeGuard, get_args import sniffio -from .._types import Omit, NotGiven, FileTypes, HeadersLike +from .._types import Omit, NotGiven, FileTypes, ArrayFormat, HeadersLike _T = TypeVar("_T") _TupleT = TypeVar("_TupleT", bound=Tuple[object, ...]) @@ -40,25 +40,45 @@ def extract_files( query: Mapping[str, object], *, paths: Sequence[Sequence[str]], + array_format: ArrayFormat = "brackets", ) -> list[tuple[str, FileTypes]]: """Recursively extract files from the given dictionary based on specified paths. A path may look like this ['foo', 'files', '', 'data']. + ``array_format`` controls how ```` segments contribute to the emitted + field name. Supported values: ``"brackets"`` (``foo[]``), ``"repeat"`` and + ``"comma"`` (``foo``), ``"indices"`` (``foo[0]``, ``foo[1]``). + Note: this mutates the given dictionary. """ files: list[tuple[str, FileTypes]] = [] for path in paths: - files.extend(_extract_items(query, path, index=0, flattened_key=None)) + files.extend(_extract_items(query, path, index=0, flattened_key=None, array_format=array_format)) return files +def _array_suffix(array_format: ArrayFormat, array_index: int) -> str: + if array_format == "brackets": + return "[]" + if array_format == "indices": + return f"[{array_index}]" + if array_format == "repeat" or array_format == "comma": + # Both repeat the bare field name for each file part; there is no + # meaningful way to comma-join binary parts. + return "" + raise NotImplementedError( + f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}" + ) + + def _extract_items( obj: object, path: Sequence[str], *, index: int, flattened_key: str | None, + array_format: ArrayFormat, ) -> list[tuple[str, FileTypes]]: try: key = path[index] @@ -75,9 +95,11 @@ def _extract_items( if is_list(obj): files: list[tuple[str, FileTypes]] = [] - for entry in obj: - assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "") - files.append((flattened_key + "[]", cast(FileTypes, entry))) + for array_index, entry in enumerate(obj): + suffix = _array_suffix(array_format, array_index) + emitted_key = (flattened_key + suffix) if flattened_key else suffix + assert_is_file_content(entry, key=emitted_key) + files.append((emitted_key, cast(FileTypes, entry))) return files assert_is_file_content(obj, key=flattened_key) @@ -106,6 +128,7 @@ def _extract_items( path, index=index, flattened_key=flattened_key, + array_format=array_format, ) elif is_list(obj): if key != "": @@ -117,9 +140,12 @@ def _extract_items( item, path, index=index, - flattened_key=flattened_key + "[]" if flattened_key is not None else "[]", + flattened_key=( + (flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index) + ), + array_format=array_format, ) - for item in obj + for array_index, item in enumerate(obj) ] ) diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py index a9d8b167..4a107218 100644 --- a/tests/test_extract_files.py +++ b/tests/test_extract_files.py @@ -4,7 +4,7 @@ import pytest -from gitpod._types import FileTypes +from gitpod._types import FileTypes, ArrayFormat from gitpod._utils import extract_files @@ -37,10 +37,7 @@ def test_multiple_files() -> None: def test_top_level_file_array() -> None: query = {"files": [b"file one", b"file two"], "title": "hello"} - assert extract_files(query, paths=[["files", ""]]) == [ - ("files[]", b"file one"), - ("files[]", b"file two"), - ] + assert extract_files(query, paths=[["files", ""]]) == [("files[]", b"file one"), ("files[]", b"file two")] assert query == {"title": "hello"} @@ -71,3 +68,24 @@ def test_ignores_incorrect_paths( expected: list[tuple[str, FileTypes]], ) -> None: assert extract_files(query, paths=paths) == expected + + +@pytest.mark.parametrize( + "array_format,expected_top_level,expected_nested", + [ + ("brackets", [("files[]", b"a"), ("files[]", b"b")], [("items[][file]", b"a"), ("items[][file]", b"b")]), + ("repeat", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]), + ("comma", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]), + ("indices", [("files[0]", b"a"), ("files[1]", b"b")], [("items[0][file]", b"a"), ("items[1][file]", b"b")]), + ], +) +def test_array_format_controls_file_field_names( + array_format: ArrayFormat, + expected_top_level: list[tuple[str, FileTypes]], + expected_nested: list[tuple[str, FileTypes]], +) -> None: + top_level = {"files": [b"a", b"b"]} + assert extract_files(top_level, paths=[["files", ""]], array_format=array_format) == expected_top_level + + nested = {"items": [{"file": b"a"}, {"file": b"b"}]} + assert extract_files(nested, paths=[["items", "", "file"]], array_format=array_format) == expected_nested diff --git a/tests/test_files.py b/tests/test_files.py index 2e09e8a4..d8f636ba 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -131,7 +131,7 @@ def test_extract_files_does_not_mutate_original_nested_array_path(self) -> None: copied = deepcopy_with_paths(original, [["items", "", "file"]]) extracted = extract_files(copied, paths=[["items", "", "file"]]) - assert extracted == [("items[][file]", file1), ("items[][file]", file2)] + assert [entry for _, entry in extracted] == [file1, file2] assert original == { "items": [ {"file": file1, "extra": 1}, From 8786477b21152c9040f3281d5b2cb17f3eada5f2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 17:47:39 +0000 Subject: [PATCH 48/66] feat(api): add readiness_timeout field to service spec types --- .stats.yml | 4 +- .../environments/automations/service_spec.py | 6 ++ .../automations/service_spec_param.py | 6 ++ .../automations/service_update_params.py | 61 +++++++++++++++++++ .../environments/automations_file_param.py | 61 +++++++++++++++++++ .../environments/automations/test_services.py | 4 ++ .../environments/test_automations.py | 2 + 7 files changed, 142 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 97339761..ef9a2135 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-439cda23bbab7cb3207b4350637971f50e98624270abba0e636cef39b54d34bd.yml -openapi_spec_hash: 5b2ead9eced70d525d4348b2ed3f1387 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c1f318f2e8413e0195faf5e4216a17cf106cf942e2c51c5174476e801c097e2b.yml +openapi_spec_hash: d6ec53f1cd8364bb6261cd3c0a5d2869 config_hash: 4447d1e1149a80d1bec70d353fb8acbf diff --git a/src/gitpod/types/environments/automations/service_spec.py b/src/gitpod/types/environments/automations/service_spec.py index 98b9b1f6..4f451cd8 100644 --- a/src/gitpod/types/environments/automations/service_spec.py +++ b/src/gitpod/types/environments/automations/service_spec.py @@ -62,6 +62,12 @@ class ServiceSpec(BaseModel): env: Optional[List[EnvironmentVariableItem]] = None """env specifies environment variables for the service.""" + readiness_timeout: Optional[str] = FieldInfo(alias="readinessTimeout", default=None) + """ + readiness_timeout is the maximum duration a service may remain in the Starting + phase while readiness checks run. 0s disables the timeout. + """ + runs_on: Optional[RunsOn] = FieldInfo(alias="runsOn", default=None) """runs_on specifies the environment the service should run on.""" diff --git a/src/gitpod/types/environments/automations/service_spec_param.py b/src/gitpod/types/environments/automations/service_spec_param.py index 93bed6a8..dc93d720 100644 --- a/src/gitpod/types/environments/automations/service_spec_param.py +++ b/src/gitpod/types/environments/automations/service_spec_param.py @@ -63,6 +63,12 @@ class ServiceSpecParam(TypedDict, total=False): env: Iterable[EnvironmentVariableItem] """env specifies environment variables for the service.""" + readiness_timeout: Annotated[str, PropertyInfo(alias="readinessTimeout")] + """ + readiness_timeout is the maximum duration a service may remain in the Starting + phase while readiness checks run. 0s disables the timeout. + """ + runs_on: Annotated[RunsOn, PropertyInfo(alias="runsOn")] """runs_on specifies the environment the service should run on.""" diff --git a/src/gitpod/types/environments/automations/service_update_params.py b/src/gitpod/types/environments/automations/service_update_params.py index 7ec0e436..bbcef01e 100644 --- a/src/gitpod/types/environments/automations/service_update_params.py +++ b/src/gitpod/types/environments/automations/service_update_params.py @@ -69,6 +69,67 @@ class Spec(TypedDict, total=False): env: Iterable[EnvironmentVariableItem] + readiness_timeout: Annotated[str, PropertyInfo(alias="readinessTimeout")] + """ + A Duration represents a signed, fixed-length span of time represented as a count + of seconds and fractions of seconds at nanosecond resolution. It is independent + of any calendar and concepts like "day" or "month". It is related to Timestamp + in that the difference between two Timestamp values is a Duration and it can be + added or subtracted from a Timestamp. Range is approximately +-10,000 years. + + # Examples + + Example 1: Compute Duration from two Timestamps in pseudo code. + + Timestamp start = ...; + Timestamp end = ...; + Duration duration = ...; + + duration.seconds = end.seconds - start.seconds; + duration.nanos = end.nanos - start.nanos; + + if (duration.seconds < 0 && duration.nanos > 0) { + duration.seconds += 1; + duration.nanos -= 1000000000; + } else if (duration.seconds > 0 && duration.nanos < 0) { + duration.seconds -= 1; + duration.nanos += 1000000000; + } + + Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. + + Timestamp start = ...; + Duration duration = ...; + Timestamp end = ...; + + end.seconds = start.seconds + duration.seconds; + end.nanos = start.nanos + duration.nanos; + + if (end.nanos < 0) { + end.seconds -= 1; + end.nanos += 1000000000; + } else if (end.nanos >= 1000000000) { + end.seconds += 1; + end.nanos -= 1000000000; + } + + Example 3: Compute Duration from datetime.timedelta in Python. + + td = datetime.timedelta(days=3, minutes=10) + duration = Duration() + duration.FromTimedelta(td) + + # JSON Mapping + + In JSON format, the Duration type is encoded as a string rather than an object, + where the string ends in the suffix "s" (indicating seconds) and is preceded by + the number of seconds, with nanoseconds expressed as fractional seconds. For + example, 3 seconds with 0 nanoseconds should be encoded in JSON format as "3s", + while 3 seconds and 1 nanosecond should be expressed in JSON format as + "3.000000001s", and 3 seconds and 1 microsecond should be expressed in JSON + format as "3.000001s". + """ + runs_on: Annotated[Optional[RunsOn], PropertyInfo(alias="runsOn")] diff --git a/src/gitpod/types/environments/automations_file_param.py b/src/gitpod/types/environments/automations_file_param.py index 68deffa5..71161a2e 100644 --- a/src/gitpod/types/environments/automations_file_param.py +++ b/src/gitpod/types/environments/automations_file_param.py @@ -49,6 +49,67 @@ class Services(TypedDict, total=False): name: str + readiness_timeout: Annotated[str, PropertyInfo(alias="readinessTimeout")] + """ + A Duration represents a signed, fixed-length span of time represented as a count + of seconds and fractions of seconds at nanosecond resolution. It is independent + of any calendar and concepts like "day" or "month". It is related to Timestamp + in that the difference between two Timestamp values is a Duration and it can be + added or subtracted from a Timestamp. Range is approximately +-10,000 years. + + # Examples + + Example 1: Compute Duration from two Timestamps in pseudo code. + + Timestamp start = ...; + Timestamp end = ...; + Duration duration = ...; + + duration.seconds = end.seconds - start.seconds; + duration.nanos = end.nanos - start.nanos; + + if (duration.seconds < 0 && duration.nanos > 0) { + duration.seconds += 1; + duration.nanos -= 1000000000; + } else if (duration.seconds > 0 && duration.nanos < 0) { + duration.seconds -= 1; + duration.nanos += 1000000000; + } + + Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. + + Timestamp start = ...; + Duration duration = ...; + Timestamp end = ...; + + end.seconds = start.seconds + duration.seconds; + end.nanos = start.nanos + duration.nanos; + + if (end.nanos < 0) { + end.seconds -= 1; + end.nanos += 1000000000; + } else if (end.nanos >= 1000000000) { + end.seconds += 1; + end.nanos -= 1000000000; + } + + Example 3: Compute Duration from datetime.timedelta in Python. + + td = datetime.timedelta(days=3, minutes=10) + duration = Duration() + duration.FromTimedelta(td) + + # JSON Mapping + + In JSON format, the Duration type is encoded as a string rather than an object, + where the string ends in the suffix "s" (indicating seconds) and is preceded by + the number of seconds, with nanoseconds expressed as fractional seconds. For + example, 3 seconds with 0 nanoseconds should be encoded in JSON format as "3s", + while 3 seconds and 1 nanosecond should be expressed in JSON format as + "3.000000001s", and 3 seconds and 1 microsecond should be expressed in JSON + format as "3.000001s". + """ + role: Literal["", "default", "editor", "ai-agent"] runs_on: Annotated[RunsOn, PropertyInfo(alias="runsOn")] diff --git a/tests/api_resources/environments/automations/test_services.py b/tests/api_resources/environments/automations/test_services.py index 3d1ccf73..daa24e8d 100644 --- a/tests/api_resources/environments/automations/test_services.py +++ b/tests/api_resources/environments/automations/test_services.py @@ -69,6 +69,7 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "readiness_timeout": "+9125115.360s", "runs_on": { "docker": { "environment": ["string"], @@ -181,6 +182,7 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "readiness_timeout": "+9125115.360s", "runs_on": { "docker": { "environment": ["string"], @@ -429,6 +431,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "readiness_timeout": "+9125115.360s", "runs_on": { "docker": { "environment": ["string"], @@ -541,6 +544,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "readiness_timeout": "+9125115.360s", "runs_on": { "docker": { "environment": ["string"], diff --git a/tests/api_resources/environments/test_automations.py b/tests/api_resources/environments/test_automations.py index 15f3fe3a..0f1eb63c 100644 --- a/tests/api_resources/environments/test_automations.py +++ b/tests/api_resources/environments/test_automations.py @@ -37,6 +37,7 @@ def test_method_upsert_with_all_params(self, client: Gitpod) -> None: }, "description": "Development web server", "name": "Web Server", + "readiness_timeout": "+9125115.360s", "role": "", "runs_on": { "docker": { @@ -117,6 +118,7 @@ async def test_method_upsert_with_all_params(self, async_client: AsyncGitpod) -> }, "description": "Development web server", "name": "Web Server", + "readiness_timeout": "+9125115.360s", "role": "", "runs_on": { "docker": { From c5ebbf3904c0ba986ee583bd27d098e1e63051eb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 18:29:55 +0000 Subject: [PATCH 49/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index ef9a2135..d4935d18 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-c1f318f2e8413e0195faf5e4216a17cf106cf942e2c51c5174476e801c097e2b.yml -openapi_spec_hash: d6ec53f1cd8364bb6261cd3c0a5d2869 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-174838e2894923e3ff69ca22fed3c1588b9578d0f38f286a58a038b16ba9db81.yml +openapi_spec_hash: 5b2b0e06a471629508cd4402b9450a6c config_hash: 4447d1e1149a80d1bec70d353fb8acbf From c544eaff18707e01f379a7df1b915c89c6e4ab7e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 22:08:29 +0000 Subject: [PATCH 50/66] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index d4935d18..a50613a8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-174838e2894923e3ff69ca22fed3c1588b9578d0f38f286a58a038b16ba9db81.yml -openapi_spec_hash: 5b2b0e06a471629508cd4402b9450a6c +openapi_spec_hash: 5331987cbc46299f3170b063b9bf06c1 config_hash: 4447d1e1149a80d1bec70d353fb8acbf From 4e4f3fe4d03901b3b63bccd13012197be6cc50ec Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 22:32:01 +0000 Subject: [PATCH 51/66] feat: support setting headers via env --- src/gitpod/_client.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gitpod/_client.py b/src/gitpod/_client.py index dddc11d8..454815c2 100644 --- a/src/gitpod/_client.py +++ b/src/gitpod/_client.py @@ -19,7 +19,11 @@ RequestOptions, not_given, ) -from ._utils import is_given, get_async_library +from ._utils import ( + is_given, + is_mapping_t, + get_async_library, +) from ._compat import cached_property from ._version import __version__ from ._streaming import Stream as Stream, AsyncStream as AsyncStream @@ -115,6 +119,15 @@ def __init__( if base_url is None: base_url = f"https://app.gitpod.io/api" + custom_headers_env = os.environ.get("GITPOD_CUSTOM_HEADERS") + if custom_headers_env is not None: + parsed: dict[str, str] = {} + for line in custom_headers_env.split("\n"): + colon = line.find(":") + if colon >= 0: + parsed[line[:colon].strip()] = line[colon + 1 :].strip() + default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})} + super().__init__( version=__version__, base_url=base_url, @@ -396,6 +409,15 @@ def __init__( if base_url is None: base_url = f"https://app.gitpod.io/api" + custom_headers_env = os.environ.get("GITPOD_CUSTOM_HEADERS") + if custom_headers_env is not None: + parsed: dict[str, str] = {} + for line in custom_headers_env.split("\n"): + colon = line.find(":") + if colon >= 0: + parsed[line[:colon].strip()] = line[colon + 1 :].strip() + default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})} + super().__init__( version=__version__, base_url=base_url, From 4942a703b999261d0b0935f4db63e76c8db5d103 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:52:55 +0000 Subject: [PATCH 52/66] feat(api): add max_port_admission_level to organizations policies --- .stats.yml | 4 ++-- src/gitpod/resources/organizations/policies.py | 16 ++++++++++++++++ .../types/organizations/policy_update_params.py | 9 +++++++++ .../api_resources/organizations/test_policies.py | 2 ++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a50613a8..50f4f10b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-174838e2894923e3ff69ca22fed3c1588b9578d0f38f286a58a038b16ba9db81.yml -openapi_spec_hash: 5331987cbc46299f3170b063b9bf06c1 -config_hash: 4447d1e1149a80d1bec70d353fb8acbf +openapi_spec_hash: 805193dd7418d079e23e6cdb594e4e59 +config_hash: a2977efc262539c5e31ba0e6dfb6a0a1 diff --git a/src/gitpod/resources/organizations/policies.py b/src/gitpod/resources/organizations/policies.py index a9d30bfb..5e21ea52 100644 --- a/src/gitpod/resources/organizations/policies.py +++ b/src/gitpod/resources/organizations/policies.py @@ -6,6 +6,7 @@ import httpx +from ...types import AdmissionLevel from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ..._utils import maybe_transform, async_maybe_transform from ..._compat import cached_property @@ -18,6 +19,7 @@ ) from ..._base_client import make_request_options from ...types.organizations import policy_update_params, policy_retrieve_params +from ...types.admission_level import AdmissionLevel from ...types.organizations.veto_exec_policy_param import VetoExecPolicyParam from ...types.organizations.policy_retrieve_response import PolicyRetrieveResponse @@ -109,6 +111,7 @@ def update( maximum_environments_per_user: Optional[str] | Omit = omit, maximum_environment_timeout: Optional[str] | Omit = omit, maximum_running_environments_per_user: Optional[str] | Omit = omit, + max_port_admission_level: Optional[AdmissionLevel] | Omit = omit, members_create_projects: Optional[bool] | Omit = omit, members_require_projects: Optional[bool] | Omit = omit, port_sharing_disabled: Optional[bool] | Omit = omit, @@ -201,6 +204,11 @@ def update( maximum_running_environments_per_user: maximum_running_environments_per_user limits simultaneously running environments per user + max_port_admission_level: max_port_admission_level caps the maximum admission level a user-opened port may + use. UNSPECIFIED means no cap (any AdmissionLevel value is allowed). System + ports (VS Code Browser, agents) are exempt. The legacy port_sharing_disabled + field, when true, takes precedence and blocks all user-initiated port sharing. + members_create_projects: members_create_projects controls whether members can create projects members_require_projects: members_require_projects controls whether environments can only be created from @@ -245,6 +253,7 @@ def update( "maximum_environments_per_user": maximum_environments_per_user, "maximum_environment_timeout": maximum_environment_timeout, "maximum_running_environments_per_user": maximum_running_environments_per_user, + "max_port_admission_level": max_port_admission_level, "members_create_projects": members_create_projects, "members_require_projects": members_require_projects, "port_sharing_disabled": port_sharing_disabled, @@ -349,6 +358,7 @@ async def update( maximum_environments_per_user: Optional[str] | Omit = omit, maximum_environment_timeout: Optional[str] | Omit = omit, maximum_running_environments_per_user: Optional[str] | Omit = omit, + max_port_admission_level: Optional[AdmissionLevel] | Omit = omit, members_create_projects: Optional[bool] | Omit = omit, members_require_projects: Optional[bool] | Omit = omit, port_sharing_disabled: Optional[bool] | Omit = omit, @@ -441,6 +451,11 @@ async def update( maximum_running_environments_per_user: maximum_running_environments_per_user limits simultaneously running environments per user + max_port_admission_level: max_port_admission_level caps the maximum admission level a user-opened port may + use. UNSPECIFIED means no cap (any AdmissionLevel value is allowed). System + ports (VS Code Browser, agents) are exempt. The legacy port_sharing_disabled + field, when true, takes precedence and blocks all user-initiated port sharing. + members_create_projects: members_create_projects controls whether members can create projects members_require_projects: members_require_projects controls whether environments can only be created from @@ -485,6 +500,7 @@ async def update( "maximum_environments_per_user": maximum_environments_per_user, "maximum_environment_timeout": maximum_environment_timeout, "maximum_running_environments_per_user": maximum_running_environments_per_user, + "max_port_admission_level": max_port_admission_level, "members_create_projects": members_create_projects, "members_require_projects": members_require_projects, "port_sharing_disabled": port_sharing_disabled, diff --git a/src/gitpod/types/organizations/policy_update_params.py b/src/gitpod/types/organizations/policy_update_params.py index e0776802..a953b488 100644 --- a/src/gitpod/types/organizations/policy_update_params.py +++ b/src/gitpod/types/organizations/policy_update_params.py @@ -7,6 +7,7 @@ from ..._types import SequenceNotStr from ..._utils import PropertyInfo +from ..admission_level import AdmissionLevel from .veto_exec_policy_param import VetoExecPolicyParam from .conversation_sharing_policy import ConversationSharingPolicy @@ -98,6 +99,14 @@ class PolicyUpdateParams(TypedDict, total=False): per user """ + max_port_admission_level: Annotated[Optional[AdmissionLevel], PropertyInfo(alias="maxPortAdmissionLevel")] + """ + max_port_admission_level caps the maximum admission level a user-opened port may + use. UNSPECIFIED means no cap (any AdmissionLevel value is allowed). System + ports (VS Code Browser, agents) are exempt. The legacy port_sharing_disabled + field, when true, takes precedence and blocks all user-initiated port sharing. + """ + members_create_projects: Annotated[Optional[bool], PropertyInfo(alias="membersCreateProjects")] """members_create_projects controls whether members can create projects""" diff --git a/tests/api_resources/organizations/test_policies.py b/tests/api_resources/organizations/test_policies.py index 56814db9..8ad83019 100644 --- a/tests/api_resources/organizations/test_policies.py +++ b/tests/api_resources/organizations/test_policies.py @@ -84,6 +84,7 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: maximum_environments_per_user="20", maximum_environment_timeout="3600s", maximum_running_environments_per_user="5", + max_port_admission_level="ADMISSION_LEVEL_UNSPECIFIED", members_create_projects=True, members_require_projects=True, port_sharing_disabled=True, @@ -203,6 +204,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> maximum_environments_per_user="20", maximum_environment_timeout="3600s", maximum_running_environments_per_user="5", + max_port_admission_level="ADMISSION_LEVEL_UNSPECIFIED", members_create_projects=True, members_require_projects=True, port_sharing_disabled=True, From 3bddede119602e39cc0fc40d37ec336807d33e7d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 19:02:16 +0000 Subject: [PATCH 53/66] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 50f4f10b..ccd7f9e4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-174838e2894923e3ff69ca22fed3c1588b9578d0f38f286a58a038b16ba9db81.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-733dd06e091046fb3d5c5f612a4231e5c2d9da46dc16dcfb42ce5b7af8c32c1d.yml openapi_spec_hash: 805193dd7418d079e23e6cdb594e4e59 config_hash: a2977efc262539c5e31ba0e6dfb6a0a1 From e99dc409933596ef561dbd6784e7041d4d64a084 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:22:09 +0000 Subject: [PATCH 54/66] feat(api): add RESOURCE_ROLE_ORG_ENVIRONMENTS_READER to resource_role --- .stats.yml | 4 ++-- src/gitpod/types/shared/resource_role.py | 1 + src/gitpod/types/shared_params/resource_role.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index ccd7f9e4..b5bc25ec 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-733dd06e091046fb3d5c5f612a4231e5c2d9da46dc16dcfb42ce5b7af8c32c1d.yml -openapi_spec_hash: 805193dd7418d079e23e6cdb594e4e59 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-683cfb7a7ed700a43cac2852fe1e616d44d8112a5729739e2eb011a6ef79e1e0.yml +openapi_spec_hash: c0d0010ffe278692a0f5236a64a3d259 config_hash: a2977efc262539c5e31ba0e6dfb6a0a1 diff --git a/src/gitpod/types/shared/resource_role.py b/src/gitpod/types/shared/resource_role.py index 45759abb..1f0241d7 100644 --- a/src/gitpod/types/shared/resource_role.py +++ b/src/gitpod/types/shared/resource_role.py @@ -12,6 +12,7 @@ "RESOURCE_ROLE_ORG_PROJECTS_ADMIN", "RESOURCE_ROLE_ORG_AUTOMATIONS_ADMIN", "RESOURCE_ROLE_ORG_GROUPS_ADMIN", + "RESOURCE_ROLE_ORG_ENVIRONMENTS_READER", "RESOURCE_ROLE_ORG_AUDIT_LOG_READER", "RESOURCE_ROLE_GROUP_ADMIN", "RESOURCE_ROLE_GROUP_VIEWER", diff --git a/src/gitpod/types/shared_params/resource_role.py b/src/gitpod/types/shared_params/resource_role.py index 94f5abcc..71f2a545 100644 --- a/src/gitpod/types/shared_params/resource_role.py +++ b/src/gitpod/types/shared_params/resource_role.py @@ -14,6 +14,7 @@ "RESOURCE_ROLE_ORG_PROJECTS_ADMIN", "RESOURCE_ROLE_ORG_AUTOMATIONS_ADMIN", "RESOURCE_ROLE_ORG_GROUPS_ADMIN", + "RESOURCE_ROLE_ORG_ENVIRONMENTS_READER", "RESOURCE_ROLE_ORG_AUDIT_LOG_READER", "RESOURCE_ROLE_GROUP_ADMIN", "RESOURCE_ROLE_GROUP_VIEWER", From bcfef9389c66ed0dbb2c8402df42c0c9f28ba288 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:59:38 +0000 Subject: [PATCH 55/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index b5bc25ec..1e9cf56c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-683cfb7a7ed700a43cac2852fe1e616d44d8112a5729739e2eb011a6ef79e1e0.yml -openapi_spec_hash: c0d0010ffe278692a0f5236a64a3d259 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-f283069cd64e780428f84f28d9b3515a349f06b19cd8ec7f8e241cf9e6202b8f.yml +openapi_spec_hash: a5928ad32b13eec97e5e6b036604c126 config_hash: a2977efc262539c5e31ba0e6dfb6a0a1 From 4bf1bad2f66425302ae214d66c936c832da93ba3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 14:42:26 +0000 Subject: [PATCH 56/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 1e9cf56c..57b7fd59 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-f283069cd64e780428f84f28d9b3515a349f06b19cd8ec7f8e241cf9e6202b8f.yml -openapi_spec_hash: a5928ad32b13eec97e5e6b036604c126 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-7740ccd8e1f202fa72fb98622e311c5906694a66263b2f9f68e7dbb637769661.yml +openapi_spec_hash: 65ba2769da436db7d521a8fa169a16ec config_hash: a2977efc262539c5e31ba0e6dfb6a0a1 From 1dd064f2aa964dd461befa80ef03d0aef37dc509 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 18:18:17 +0000 Subject: [PATCH 57/66] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 57b7fd59..ad88f2fc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-7740ccd8e1f202fa72fb98622e311c5906694a66263b2f9f68e7dbb637769661.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-7740ccd8e1f202fa72fb98622e311c5906694a66263b2f9f68e7dbb637769661.yml openapi_spec_hash: 65ba2769da436db7d521a8fa169a16ec config_hash: a2977efc262539c5e31ba0e6dfb6a0a1 From 1314feb43ddcada3148a176fc566f6171b4c2b98 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 20:21:01 +0000 Subject: [PATCH 58/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index ad88f2fc..63252a1b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-7740ccd8e1f202fa72fb98622e311c5906694a66263b2f9f68e7dbb637769661.yml -openapi_spec_hash: 65ba2769da436db7d521a8fa169a16ec -config_hash: a2977efc262539c5e31ba0e6dfb6a0a1 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-34d4634f81e22d3e86c32a5c5c9a4ceab861dad6c7fed70bb761bd5d10c49f61.yml +openapi_spec_hash: f4891aac3517e486b0634de9ca73ff62 +config_hash: b14a6ba343ae97ee0281ea63762fa26d From 9cabb50f0bf4a6b3de5c9be3c0acd1aec5b7d235 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:25:44 +0000 Subject: [PATCH 59/66] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 63252a1b..050a108f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-34d4634f81e22d3e86c32a5c5c9a4ceab861dad6c7fed70bb761bd5d10c49f61.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-c08dba5cc76752c58c15fd6fa6511697467595ea10837588e06d7a8406f54987.yml openapi_spec_hash: f4891aac3517e486b0634de9ca73ff62 config_hash: b14a6ba343ae97ee0281ea63762fa26d From b061deb38573beb2771beb0dfe92a5c3ba09b9d3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 21:00:55 +0000 Subject: [PATCH 60/66] chore(internal): reformat pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5d1671eb..f278fc4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -171,7 +171,7 @@ show_error_codes = true # # We also exclude our `tests` as mypy doesn't always infer # types correctly and Pyright will still catch any type errors. -exclude = ['src/gitpod/_files.py', '_dev/.*.py', 'tests/.*'] +exclude = ["src/gitpod/_files.py", "_dev/.*.py", "tests/.*"] strict_equality = true implicit_reexport = true From 00538d2159cdc6d4bff72b51fc113309ba77ff67 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 12:09:58 +0000 Subject: [PATCH 61/66] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 050a108f..2a356b30 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-c08dba5cc76752c58c15fd6fa6511697467595ea10837588e06d7a8406f54987.yml -openapi_spec_hash: f4891aac3517e486b0634de9ca73ff62 -config_hash: b14a6ba343ae97ee0281ea63762fa26d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-cb731bb078ce83c206e64e6d32f5d9364dad6384161c3a229e20e02a24c6df61.yml +openapi_spec_hash: 2bd8bc5a1af393eb35d85c51ebe5089e +config_hash: 80140724b84647203353ddc02da48816 From 003cd7dcac020428985564e76c2bb6e45acd434c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 12:13:08 +0000 Subject: [PATCH 62/66] feat(api): remove deprecated access_token from runner responses --- .stats.yml | 4 ++-- src/gitpod/types/runner_create_response.py | 3 --- src/gitpod/types/runner_create_runner_token_response.py | 3 --- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2a356b30..e1b4c816 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-cb731bb078ce83c206e64e6d32f5d9364dad6384161c3a229e20e02a24c6df61.yml -openapi_spec_hash: 2bd8bc5a1af393eb35d85c51ebe5089e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-d8d06d7ffc04df2d9941889b28db92f1a9c6554214411ed68a939d94e149507a.yml +openapi_spec_hash: 82c005c96e438a429717d51f24596467 config_hash: 80140724b84647203353ddc02da48816 diff --git a/src/gitpod/types/runner_create_response.py b/src/gitpod/types/runner_create_response.py index 2f6821f7..6272114c 100644 --- a/src/gitpod/types/runner_create_response.py +++ b/src/gitpod/types/runner_create_response.py @@ -13,9 +13,6 @@ class RunnerCreateResponse(BaseModel): runner: Runner - access_token: Optional[str] = FieldInfo(alias="accessToken", default=None) - """deprecated, will be removed. Use exchange_token instead.""" - exchange_token: Optional[str] = FieldInfo(alias="exchangeToken", default=None) """ exchange_token is a one-time use token that should be exchanged by the runner diff --git a/src/gitpod/types/runner_create_runner_token_response.py b/src/gitpod/types/runner_create_runner_token_response.py index 0f793a38..c6e0c84e 100644 --- a/src/gitpod/types/runner_create_runner_token_response.py +++ b/src/gitpod/types/runner_create_runner_token_response.py @@ -10,9 +10,6 @@ class RunnerCreateRunnerTokenResponse(BaseModel): - access_token: Optional[str] = FieldInfo(alias="accessToken", default=None) - """deprecated, will be removed. Use exchange_token instead.""" - exchange_token: Optional[str] = FieldInfo(alias="exchangeToken", default=None) """ exchange_token is a one-time use token that should be exchanged by the runner From c53496334c33f9cffca9393fb0ae9e55810de7c7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 15:07:47 +0000 Subject: [PATCH 63/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e1b4c816..1e2e9715 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-d8d06d7ffc04df2d9941889b28db92f1a9c6554214411ed68a939d94e149507a.yml -openapi_spec_hash: 82c005c96e438a429717d51f24596467 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-3ca2980a02d73847672b67d021301839bfd63392fc1691c05236925840ade238.yml +openapi_spec_hash: 51110b8f63252ea5e955f6950594cab7 config_hash: 80140724b84647203353ddc02da48816 From 92e400aed0761bf0330b0f9f4e62ddfc44cc47e6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 15:08:43 +0000 Subject: [PATCH 64/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 1e2e9715..e95a8022 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-3ca2980a02d73847672b67d021301839bfd63392fc1691c05236925840ade238.yml -openapi_spec_hash: 51110b8f63252ea5e955f6950594cab7 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-c84a131403106388b12f346da2ec96f1b9f687eea6863b0ffc65c5222661ebbc.yml +openapi_spec_hash: 3c8dda12e37b547f69e8d02b9e507f3a config_hash: 80140724b84647203353ddc02da48816 From da146994610311e55ea39d60865a0460c4b1d99f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 17:07:36 +0000 Subject: [PATCH 65/66] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e95a8022..3f8356db 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-c84a131403106388b12f346da2ec96f1b9f687eea6863b0ffc65c5222661ebbc.yml -openapi_spec_hash: 3c8dda12e37b547f69e8d02b9e507f3a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-f8b7dff8b795ac883b8879e286fc37bd3086b1777d9f22643cebe2631802c0c9.yml +openapi_spec_hash: c2a56f79f49e488d7bade92b125c9d23 config_hash: 80140724b84647203353ddc02da48816 From 3f4b4a0ec64130772419b1a0beb5bda2085aa496 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 17:08:22 +0000 Subject: [PATCH 66/66] release: 0.12.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 46 +++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- src/gitpod/_version.py | 2 +- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f7014c35..a7130553 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.11.0" + ".": "0.12.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ddc444e4..7fea67e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,51 @@ # Changelog +## 0.12.0 (2026-05-04) + +Full Changelog: [v0.11.0...v0.12.0](https://github.com/gitpod-io/gitpod-sdk-python/compare/v0.11.0...v0.12.0) + +### Features + +* **api:** add integration_id field, make webhook_id required in pull_request trigger ([077b662](https://github.com/gitpod-io/gitpod-sdk-python/commit/077b6622dc4e21a2033c8275c46716286a6515b8)) +* **api:** add max_port_admission_level to organizations policies ([4942a70](https://github.com/gitpod-io/gitpod-sdk-python/commit/4942a703b999261d0b0935f4db63e76c8db5d103)) +* **api:** add old_path field to ContentGitChangedFile ([d79d4d4](https://github.com/gitpod-io/gitpod-sdk-python/commit/d79d4d49ef41a889a81a0d484616fca442849356)) +* **api:** add pagination and query parameter to runners.list_scm_organizations ([333311a](https://github.com/gitpod-io/gitpod-sdk-python/commit/333311aebaefb657861e2a9f6e8adb0f2abdd4dc)) +* **api:** add port_authentication capability to runner_capability ([c29b095](https://github.com/gitpod-io/gitpod-sdk-python/commit/c29b09596d2d87caaea047e61613a333c2fe4e31)) +* **api:** add prebuild trigger value to environments automations ([af2c44e](https://github.com/gitpod-io/gitpod-sdk-python/commit/af2c44e64fac19bf848c4325e0b39b183c998e74)) +* **api:** add PULL_REQUEST_EVENT_REVIEW_REQUESTED to workflow_trigger events ([242a3ab](https://github.com/gitpod-io/gitpod-sdk-python/commit/242a3ab60ed3580fd9488858727294ed86568ccf)) +* **api:** add readiness_timeout field to service spec types ([8786477](https://github.com/gitpod-io/gitpod-sdk-python/commit/8786477b21152c9040f3281d5b2cb17f3eada5f2)) +* **api:** add RESOURCE_ROLE_ORG_ENVIRONMENTS_READER to resource_role ([e99dc40](https://github.com/gitpod-io/gitpod-sdk-python/commit/e99dc409933596ef561dbd6784e7041d4d64a084)) +* **api:** add SUPPORTED_MODEL_OPENAI_AUTO to agent_execution status ([54503f5](https://github.com/gitpod-io/gitpod-sdk-python/commit/54503f5295a703ee855eac4c11694d2bbe465d13)) +* **api:** add SUPPORTED_MODEL_OPUS_4_7 to agent_execution Status ([74af533](https://github.com/gitpod-io/gitpod-sdk-python/commit/74af5338d7f6447df5a6464a2b2ef893c3bf4f6e)) +* **api:** add UserInputMetadata type ([ea300f4](https://github.com/gitpod-io/gitpod-sdk-python/commit/ea300f4314c14529c02ffec1e38f474d8a426844)) +* **api:** remove deprecated access_token from runner responses ([003cd7d](https://github.com/gitpod-io/gitpod-sdk-python/commit/003cd7dcac020428985564e76c2bb6e45acd434c)) +* **api:** remove terminal field from RunsOn type ([faca2b2](https://github.com/gitpod-io/gitpod-sdk-python/commit/faca2b27b88f17a759bd91c305e5ea2a856a1e2c)) +* support setting headers via env ([4e4f3fe](https://github.com/gitpod-io/gitpod-sdk-python/commit/4e4f3fe4d03901b3b63bccd13012197be6cc50ec)) + + +### Bug Fixes + +* **client:** preserve hardcoded query params when merging with user params ([b7f0b1d](https://github.com/gitpod-io/gitpod-sdk-python/commit/b7f0b1d27ef51872bf81541dd7f81a8101f856af)) +* ensure file data are only sent as 1 parameter ([5c02854](https://github.com/gitpod-io/gitpod-sdk-python/commit/5c02854efdc2874535d3d7867823048d5e8d4693)) +* use correct field name format for multipart file arrays ([c731392](https://github.com/gitpod-io/gitpod-sdk-python/commit/c731392aa36e5a3bba895d4e52a7d50addab326a)) + + +### Performance Improvements + +* **client:** optimize file structure copying in multipart requests ([cb792b6](https://github.com/gitpod-io/gitpod-sdk-python/commit/cb792b633104ff26eb799d8c32703920213ec23e)) + + +### Chores + +* **internal:** more robust bootstrap script ([5f05caa](https://github.com/gitpod-io/gitpod-sdk-python/commit/5f05caacfd1a55617d435845771e28503eff687c)) +* **internal:** reformat pyproject.toml ([b061deb](https://github.com/gitpod-io/gitpod-sdk-python/commit/b061deb38573beb2771beb0dfe92a5c3ba09b9d3)) + + +### Documentation + +* **api:** update trigger usage note in AutomationTrigger ([5a292cb](https://github.com/gitpod-io/gitpod-sdk-python/commit/5a292cb1ef87a0dd73d93445707412d25c0e95e0)) +* **types:** mark is_admin deprecated in Organization model ([5e7b9f3](https://github.com/gitpod-io/gitpod-sdk-python/commit/5e7b9f3d7dd7af385ca75b17f01c1cab87da8cb6)) + ## 0.11.0 (2026-04-02) Full Changelog: [v0.10.0...v0.11.0](https://github.com/gitpod-io/gitpod-sdk-python/compare/v0.10.0...v0.11.0) diff --git a/pyproject.toml b/pyproject.toml index f278fc4d..6c612339 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "gitpod-sdk" -version = "0.11.0" +version = "0.12.0" description = "The official Python library for the gitpod API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/gitpod/_version.py b/src/gitpod/_version.py index 7504df3f..6521e93a 100644 --- a/src/gitpod/_version.py +++ b/src/gitpod/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "gitpod" -__version__ = "0.11.0" # x-release-please-version +__version__ = "0.12.0" # x-release-please-version