Skip to content

Commit b34ed1b

Browse files
feat(api): add CheckRepositoryAccess API for repository access validation
1 parent df1cf39 commit b34ed1b

File tree

7 files changed

+268
-4
lines changed

7 files changed

+268
-4
lines changed

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 169
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-6b80aebab53bff73bb7b87c5f91f98c6dd5db2d623b6c613aaa5e61252b74d75.yml
3-
openapi_spec_hash: 9636e315ac739c1ab9cba65a7ead6559
4-
config_hash: 73893621fd64bbd87b86671decf334e6
1+
configured_endpoints: 170
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-024993504dfc744ff138b0d1b1a151e28129f9f5a8b55adff4c7b559b0556c62.yml
3+
openapi_spec_hash: 4773277eb2a6ac6be0b2e8f89a2201d8
4+
config_hash: 942ffc968ca0131e192c1a7ac5dd8990

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ from gitpod.types import (
597597
RunnerCreateResponse,
598598
RunnerRetrieveResponse,
599599
RunnerCheckAuthenticationForHostResponse,
600+
RunnerCheckRepositoryAccessResponse,
600601
RunnerCreateLogsTokenResponse,
601602
RunnerCreateRunnerTokenResponse,
602603
RunnerListScmOrganizationsResponse,
@@ -613,6 +614,7 @@ Methods:
613614
- <code title="post /gitpod.v1.RunnerService/ListRunners">client.runners.<a href="./src/gitpod/resources/runners/runners.py">list</a>(\*\*<a href="src/gitpod/types/runner_list_params.py">params</a>) -> <a href="./src/gitpod/types/runner.py">SyncRunnersPage[Runner]</a></code>
614615
- <code title="post /gitpod.v1.RunnerService/DeleteRunner">client.runners.<a href="./src/gitpod/resources/runners/runners.py">delete</a>(\*\*<a href="src/gitpod/types/runner_delete_params.py">params</a>) -> object</code>
615616
- <code title="post /gitpod.v1.RunnerService/CheckAuthenticationForHost">client.runners.<a href="./src/gitpod/resources/runners/runners.py">check_authentication_for_host</a>(\*\*<a href="src/gitpod/types/runner_check_authentication_for_host_params.py">params</a>) -> <a href="./src/gitpod/types/runner_check_authentication_for_host_response.py">RunnerCheckAuthenticationForHostResponse</a></code>
617+
- <code title="post /gitpod.v1.RunnerService/CheckRepositoryAccess">client.runners.<a href="./src/gitpod/resources/runners/runners.py">check_repository_access</a>(\*\*<a href="src/gitpod/types/runner_check_repository_access_params.py">params</a>) -> <a href="./src/gitpod/types/runner_check_repository_access_response.py">RunnerCheckRepositoryAccessResponse</a></code>
616618
- <code title="post /gitpod.v1.RunnerService/CreateRunnerLogsToken">client.runners.<a href="./src/gitpod/resources/runners/runners.py">create_logs_token</a>(\*\*<a href="src/gitpod/types/runner_create_logs_token_params.py">params</a>) -> <a href="./src/gitpod/types/runner_create_logs_token_response.py">RunnerCreateLogsTokenResponse</a></code>
617619
- <code title="post /gitpod.v1.RunnerService/CreateRunnerToken">client.runners.<a href="./src/gitpod/resources/runners/runners.py">create_runner_token</a>(\*\*<a href="src/gitpod/types/runner_create_runner_token_params.py">params</a>) -> <a href="./src/gitpod/types/runner_create_runner_token_response.py">RunnerCreateRunnerTokenResponse</a></code>
618620
- <code title="post /gitpod.v1.RunnerService/ListSCMOrganizations">client.runners.<a href="./src/gitpod/resources/runners/runners.py">list_scm_organizations</a>(\*\*<a href="src/gitpod/types/runner_list_scm_organizations_params.py">params</a>) -> <a href="./src/gitpod/types/runner_list_scm_organizations_response.py">RunnerListScmOrganizationsResponse</a></code>

src/gitpod/resources/runners/runners.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
runner_create_runner_token_params,
2121
runner_search_repositories_params,
2222
runner_list_scm_organizations_params,
23+
runner_check_repository_access_params,
2324
runner_check_authentication_for_host_params,
2425
)
2526
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
@@ -62,6 +63,7 @@
6263
from ...types.runner_create_runner_token_response import RunnerCreateRunnerTokenResponse
6364
from ...types.runner_search_repositories_response import RunnerSearchRepositoriesResponse
6465
from ...types.runner_list_scm_organizations_response import RunnerListScmOrganizationsResponse
66+
from ...types.runner_check_repository_access_response import RunnerCheckRepositoryAccessResponse
6567
from ...types.runner_check_authentication_for_host_response import RunnerCheckAuthenticationForHostResponse
6668

6769
__all__ = ["RunnersResource", "AsyncRunnersResource"]
@@ -510,6 +512,70 @@ def check_authentication_for_host(
510512
cast_to=RunnerCheckAuthenticationForHostResponse,
511513
)
512514

515+
def check_repository_access(
516+
self,
517+
*,
518+
repository_url: str | Omit = omit,
519+
runner_id: str | Omit = omit,
520+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
521+
# The extra values given here take precedence over values defined on the client or passed to this method.
522+
extra_headers: Headers | None = None,
523+
extra_query: Query | None = None,
524+
extra_body: Body | None = None,
525+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
526+
) -> RunnerCheckRepositoryAccessResponse:
527+
"""
528+
Checks if a principal has read access to a repository.
529+
530+
Use this method to:
531+
532+
- Validate repository access before workflow execution
533+
- Verify executor credentials for automation bindings
534+
535+
Returns:
536+
537+
- has_access: true if the principal can read the repository
538+
- FAILED_PRECONDITION if authentication is required
539+
- INVALID_ARGUMENT if the repository URL is invalid
540+
541+
### Examples
542+
543+
- Check access:
544+
545+
Verifies read access to a repository.
546+
547+
```yaml
548+
runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68"
549+
repositoryUrl: "https://github.com/org/repo"
550+
```
551+
552+
Args:
553+
repository_url: repository_url is the URL of the repository to check access for. Can be a clone
554+
URL (https://github.com/org/repo.git) or web URL (https://github.com/org/repo).
555+
556+
extra_headers: Send extra headers
557+
558+
extra_query: Add additional query parameters to the request
559+
560+
extra_body: Add additional JSON properties to the request
561+
562+
timeout: Override the client-level default timeout for this request, in seconds
563+
"""
564+
return self._post(
565+
"/gitpod.v1.RunnerService/CheckRepositoryAccess",
566+
body=maybe_transform(
567+
{
568+
"repository_url": repository_url,
569+
"runner_id": runner_id,
570+
},
571+
runner_check_repository_access_params.RunnerCheckRepositoryAccessParams,
572+
),
573+
options=make_request_options(
574+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
575+
),
576+
cast_to=RunnerCheckRepositoryAccessResponse,
577+
)
578+
513579
def create_logs_token(
514580
self,
515581
*,
@@ -1273,6 +1339,70 @@ async def check_authentication_for_host(
12731339
cast_to=RunnerCheckAuthenticationForHostResponse,
12741340
)
12751341

1342+
async def check_repository_access(
1343+
self,
1344+
*,
1345+
repository_url: str | Omit = omit,
1346+
runner_id: str | Omit = omit,
1347+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1348+
# The extra values given here take precedence over values defined on the client or passed to this method.
1349+
extra_headers: Headers | None = None,
1350+
extra_query: Query | None = None,
1351+
extra_body: Body | None = None,
1352+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
1353+
) -> RunnerCheckRepositoryAccessResponse:
1354+
"""
1355+
Checks if a principal has read access to a repository.
1356+
1357+
Use this method to:
1358+
1359+
- Validate repository access before workflow execution
1360+
- Verify executor credentials for automation bindings
1361+
1362+
Returns:
1363+
1364+
- has_access: true if the principal can read the repository
1365+
- FAILED_PRECONDITION if authentication is required
1366+
- INVALID_ARGUMENT if the repository URL is invalid
1367+
1368+
### Examples
1369+
1370+
- Check access:
1371+
1372+
Verifies read access to a repository.
1373+
1374+
```yaml
1375+
runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68"
1376+
repositoryUrl: "https://github.com/org/repo"
1377+
```
1378+
1379+
Args:
1380+
repository_url: repository_url is the URL of the repository to check access for. Can be a clone
1381+
URL (https://github.com/org/repo.git) or web URL (https://github.com/org/repo).
1382+
1383+
extra_headers: Send extra headers
1384+
1385+
extra_query: Add additional query parameters to the request
1386+
1387+
extra_body: Add additional JSON properties to the request
1388+
1389+
timeout: Override the client-level default timeout for this request, in seconds
1390+
"""
1391+
return await self._post(
1392+
"/gitpod.v1.RunnerService/CheckRepositoryAccess",
1393+
body=await async_maybe_transform(
1394+
{
1395+
"repository_url": repository_url,
1396+
"runner_id": runner_id,
1397+
},
1398+
runner_check_repository_access_params.RunnerCheckRepositoryAccessParams,
1399+
),
1400+
options=make_request_options(
1401+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1402+
),
1403+
cast_to=RunnerCheckRepositoryAccessResponse,
1404+
)
1405+
12761406
async def create_logs_token(
12771407
self,
12781408
*,
@@ -1617,6 +1747,9 @@ def __init__(self, runners: RunnersResource) -> None:
16171747
self.check_authentication_for_host = to_raw_response_wrapper(
16181748
runners.check_authentication_for_host,
16191749
)
1750+
self.check_repository_access = to_raw_response_wrapper(
1751+
runners.check_repository_access,
1752+
)
16201753
self.create_logs_token = to_raw_response_wrapper(
16211754
runners.create_logs_token,
16221755
)
@@ -1664,6 +1797,9 @@ def __init__(self, runners: AsyncRunnersResource) -> None:
16641797
self.check_authentication_for_host = async_to_raw_response_wrapper(
16651798
runners.check_authentication_for_host,
16661799
)
1800+
self.check_repository_access = async_to_raw_response_wrapper(
1801+
runners.check_repository_access,
1802+
)
16671803
self.create_logs_token = async_to_raw_response_wrapper(
16681804
runners.create_logs_token,
16691805
)
@@ -1711,6 +1847,9 @@ def __init__(self, runners: RunnersResource) -> None:
17111847
self.check_authentication_for_host = to_streamed_response_wrapper(
17121848
runners.check_authentication_for_host,
17131849
)
1850+
self.check_repository_access = to_streamed_response_wrapper(
1851+
runners.check_repository_access,
1852+
)
17141853
self.create_logs_token = to_streamed_response_wrapper(
17151854
runners.create_logs_token,
17161855
)
@@ -1758,6 +1897,9 @@ def __init__(self, runners: AsyncRunnersResource) -> None:
17581897
self.check_authentication_for_host = async_to_streamed_response_wrapper(
17591898
runners.check_authentication_for_host,
17601899
)
1900+
self.check_repository_access = async_to_streamed_response_wrapper(
1901+
runners.check_repository_access,
1902+
)
17611903
self.create_logs_token = async_to_streamed_response_wrapper(
17621904
runners.create_logs_token,
17631905
)

src/gitpod/types/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@
224224
from .project_prebuild_configuration_param import ProjectPrebuildConfigurationParam as ProjectPrebuildConfigurationParam
225225
from .runner_list_scm_organizations_params import RunnerListScmOrganizationsParams as RunnerListScmOrganizationsParams
226226
from .user_get_authenticated_user_response import UserGetAuthenticatedUserResponse as UserGetAuthenticatedUserResponse
227+
from .runner_check_repository_access_params import (
228+
RunnerCheckRepositoryAccessParams as RunnerCheckRepositoryAccessParams,
229+
)
227230
from .environment_create_from_project_params import (
228231
EnvironmentCreateFromProjectParams as EnvironmentCreateFromProjectParams,
229232
)
@@ -236,6 +239,9 @@
236239
from .runner_list_scm_organizations_response import (
237240
RunnerListScmOrganizationsResponse as RunnerListScmOrganizationsResponse,
238241
)
242+
from .runner_check_repository_access_response import (
243+
RunnerCheckRepositoryAccessResponse as RunnerCheckRepositoryAccessResponse,
244+
)
239245
from .environment_create_from_project_response import (
240246
EnvironmentCreateFromProjectResponse as EnvironmentCreateFromProjectResponse,
241247
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import Annotated, TypedDict
6+
7+
from .._utils import PropertyInfo
8+
9+
__all__ = ["RunnerCheckRepositoryAccessParams"]
10+
11+
12+
class RunnerCheckRepositoryAccessParams(TypedDict, total=False):
13+
repository_url: Annotated[str, PropertyInfo(alias="repositoryUrl")]
14+
"""
15+
repository_url is the URL of the repository to check access for. Can be a clone
16+
URL (https://github.com/org/repo.git) or web URL (https://github.com/org/repo).
17+
"""
18+
19+
runner_id: Annotated[str, PropertyInfo(alias="runnerId")]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing import Optional
4+
5+
from pydantic import Field as FieldInfo
6+
7+
from .._models import BaseModel
8+
9+
__all__ = ["RunnerCheckRepositoryAccessResponse"]
10+
11+
12+
class RunnerCheckRepositoryAccessResponse(BaseModel):
13+
error_message: Optional[str] = FieldInfo(alias="errorMessage", default=None)
14+
"""
15+
error_message provides details when access check fails. Empty when has_access is
16+
true.
17+
"""
18+
19+
has_access: Optional[bool] = FieldInfo(alias="hasAccess", default=None)
20+
"""has_access indicates whether the principal has read access to the repository."""

tests/api_resources/test_runners.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
RunnerCreateRunnerTokenResponse,
1919
RunnerSearchRepositoriesResponse,
2020
RunnerListScmOrganizationsResponse,
21+
RunnerCheckRepositoryAccessResponse,
2122
RunnerCheckAuthenticationForHostResponse,
2223
)
2324
from gitpod.pagination import SyncRunnersPage, AsyncRunnersPage
@@ -292,6 +293,43 @@ def test_streaming_response_check_authentication_for_host(self, client: Gitpod)
292293

293294
assert cast(Any, response.is_closed) is True
294295

296+
@pytest.mark.skip(reason="Prism tests are disabled")
297+
@parametrize
298+
def test_method_check_repository_access(self, client: Gitpod) -> None:
299+
runner = client.runners.check_repository_access()
300+
assert_matches_type(RunnerCheckRepositoryAccessResponse, runner, path=["response"])
301+
302+
@pytest.mark.skip(reason="Prism tests are disabled")
303+
@parametrize
304+
def test_method_check_repository_access_with_all_params(self, client: Gitpod) -> None:
305+
runner = client.runners.check_repository_access(
306+
repository_url="https://github.com/org/repo",
307+
runner_id="d2c94c27-3b76-4a42-b88c-95a85e392c68",
308+
)
309+
assert_matches_type(RunnerCheckRepositoryAccessResponse, runner, path=["response"])
310+
311+
@pytest.mark.skip(reason="Prism tests are disabled")
312+
@parametrize
313+
def test_raw_response_check_repository_access(self, client: Gitpod) -> None:
314+
response = client.runners.with_raw_response.check_repository_access()
315+
316+
assert response.is_closed is True
317+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
318+
runner = response.parse()
319+
assert_matches_type(RunnerCheckRepositoryAccessResponse, runner, path=["response"])
320+
321+
@pytest.mark.skip(reason="Prism tests are disabled")
322+
@parametrize
323+
def test_streaming_response_check_repository_access(self, client: Gitpod) -> None:
324+
with client.runners.with_streaming_response.check_repository_access() as response:
325+
assert not response.is_closed
326+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
327+
328+
runner = response.parse()
329+
assert_matches_type(RunnerCheckRepositoryAccessResponse, runner, path=["response"])
330+
331+
assert cast(Any, response.is_closed) is True
332+
295333
@pytest.mark.skip(reason="Prism tests are disabled")
296334
@parametrize
297335
def test_method_create_logs_token(self, client: Gitpod) -> None:
@@ -754,6 +792,43 @@ async def test_streaming_response_check_authentication_for_host(self, async_clie
754792

755793
assert cast(Any, response.is_closed) is True
756794

795+
@pytest.mark.skip(reason="Prism tests are disabled")
796+
@parametrize
797+
async def test_method_check_repository_access(self, async_client: AsyncGitpod) -> None:
798+
runner = await async_client.runners.check_repository_access()
799+
assert_matches_type(RunnerCheckRepositoryAccessResponse, runner, path=["response"])
800+
801+
@pytest.mark.skip(reason="Prism tests are disabled")
802+
@parametrize
803+
async def test_method_check_repository_access_with_all_params(self, async_client: AsyncGitpod) -> None:
804+
runner = await async_client.runners.check_repository_access(
805+
repository_url="https://github.com/org/repo",
806+
runner_id="d2c94c27-3b76-4a42-b88c-95a85e392c68",
807+
)
808+
assert_matches_type(RunnerCheckRepositoryAccessResponse, runner, path=["response"])
809+
810+
@pytest.mark.skip(reason="Prism tests are disabled")
811+
@parametrize
812+
async def test_raw_response_check_repository_access(self, async_client: AsyncGitpod) -> None:
813+
response = await async_client.runners.with_raw_response.check_repository_access()
814+
815+
assert response.is_closed is True
816+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
817+
runner = await response.parse()
818+
assert_matches_type(RunnerCheckRepositoryAccessResponse, runner, path=["response"])
819+
820+
@pytest.mark.skip(reason="Prism tests are disabled")
821+
@parametrize
822+
async def test_streaming_response_check_repository_access(self, async_client: AsyncGitpod) -> None:
823+
async with async_client.runners.with_streaming_response.check_repository_access() as response:
824+
assert not response.is_closed
825+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
826+
827+
runner = await response.parse()
828+
assert_matches_type(RunnerCheckRepositoryAccessResponse, runner, path=["response"])
829+
830+
assert cast(Any, response.is_closed) is True
831+
757832
@pytest.mark.skip(reason="Prism tests are disabled")
758833
@parametrize
759834
async def test_method_create_logs_token(self, async_client: AsyncGitpod) -> None:

0 commit comments

Comments
 (0)