diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 800f691..8f3951d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,10 +19,10 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/gitpod-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
@@ -41,10 +41,10 @@ jobs:
contents: read
id-token: write
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
@@ -57,7 +57,7 @@ jobs:
- name: Get GitHub OIDC Token
if: github.repository == 'stainless-sdks/gitpod-typescript'
id: github-oidc
- uses: actions/github-script@v6
+ uses: actions/github-script@00f12e3e20659f42342b1c0226afda7f7c042325 # v6
with:
script: core.setOutput('github_token', await core.getIDToken());
@@ -74,10 +74,10 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/gitpod-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml
index 7936e80..c95a4ba 100644
--- a/.github/workflows/publish-npm.yml
+++ b/.github/workflows/publish-npm.yml
@@ -23,10 +23,10 @@ jobs:
id-token: write
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '24'
registry-url: 'https://registry.npmjs.org'
diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml
index 742b303..6e13518 100644
--- a/.github/workflows/release-doctor.yml
+++ b/.github/workflows/release-doctor.yml
@@ -12,7 +12,7 @@ jobs:
if: github.repository == 'gitpod-io/gitpod-sdk-typescript' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Check release environment
run: |
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 64f3cdd..76d5538 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.8.0"
+ ".": "0.9.0"
}
diff --git a/.stats.yml b/.stats.yml
index 0fdb5b6..f59d5bf 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 159
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-d62ef4b9187c1f3d36f428abc4b31d8a09ffd36e93d39b8136c60c8f463c838e.yml
-openapi_spec_hash: d7f01b6f24e88eb46d744ecd28061f26
-config_hash: 26e4a10dfc6ec809322e60d889d15414
+configured_endpoints: 160
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-8b86b2ad546df57ba9b530cb8d31733d99c4b629bbcac61bc10775bbd577e6b4.yml
+openapi_spec_hash: 9d895493e3b1ad702e554d9e2b19e8bc
+config_hash: 8e1b089e9f5af438fd56b523014af4f2
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f86e4aa..f5f4e52 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## 0.9.0 (2025-12-19)
+
+Full Changelog: [v0.8.0...v0.9.0](https://github.com/gitpod-io/gitpod-sdk-typescript/compare/v0.8.0...v0.9.0)
+
+### Features
+
+* **agent:** add group-based SCM tools access control ([9f8d2f9](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/9f8d2f902fc221a89e27ae74e47315d6300f2af2))
+
+
+### Chores
+
+* pin GitHub Actions to SHA ([d29f17d](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/d29f17de8d5cb9632525387669978058c18ba0a7))
+
## 0.8.0 (2025-12-15)
Full Changelog: [v0.7.11...v0.8.0](https://github.com/gitpod-io/gitpod-sdk-typescript/compare/v0.7.11...v0.8.0)
diff --git a/api.md b/api.md
index 07e45cb..c15a29c 100644
--- a/api.md
+++ b/api.md
@@ -275,11 +275,13 @@ Types:
- GroupMembership
- MembershipCreateResponse
+- MembershipRetrieveResponse
- MembershipDeleteResponse
Methods:
- client.groups.memberships.create({ ...params }) -> MembershipCreateResponse
+- client.groups.memberships.retrieve({ ...params }) -> MembershipRetrieveResponse
- client.groups.memberships.list({ ...params }) -> GroupMembershipsMembersPage
- client.groups.memberships.delete({ ...params }) -> unknown
diff --git a/package.json b/package.json
index d491c93..d42136d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@gitpod/sdk",
- "version": "0.8.0",
+ "version": "0.9.0",
"description": "The official TypeScript library for the Gitpod API",
"author": "Gitpod ",
"types": "dist/index.d.ts",
diff --git a/src/resources/groups/groups.ts b/src/resources/groups/groups.ts
index 5c566bf..6c991f4 100644
--- a/src/resources/groups/groups.ts
+++ b/src/resources/groups/groups.ts
@@ -10,6 +10,8 @@ import {
MembershipDeleteParams,
MembershipDeleteResponse,
MembershipListParams,
+ MembershipRetrieveParams,
+ MembershipRetrieveResponse,
Memberships,
} from './memberships';
import * as RoleAssignmentsAPI from './role-assignments';
@@ -528,9 +530,11 @@ export declare namespace Groups {
Memberships as Memberships,
type GroupMembership as GroupMembership,
type MembershipCreateResponse as MembershipCreateResponse,
+ type MembershipRetrieveResponse as MembershipRetrieveResponse,
type MembershipDeleteResponse as MembershipDeleteResponse,
type GroupMembershipsMembersPage as GroupMembershipsMembersPage,
type MembershipCreateParams as MembershipCreateParams,
+ type MembershipRetrieveParams as MembershipRetrieveParams,
type MembershipListParams as MembershipListParams,
type MembershipDeleteParams as MembershipDeleteParams,
};
diff --git a/src/resources/groups/index.ts b/src/resources/groups/index.ts
index 80bf45e..bdaec7e 100644
--- a/src/resources/groups/index.ts
+++ b/src/resources/groups/index.ts
@@ -18,8 +18,10 @@ export {
Memberships,
type GroupMembership,
type MembershipCreateResponse,
+ type MembershipRetrieveResponse,
type MembershipDeleteResponse,
type MembershipCreateParams,
+ type MembershipRetrieveParams,
type MembershipListParams,
type MembershipDeleteParams,
type GroupMembershipsMembersPage,
diff --git a/src/resources/groups/memberships.ts b/src/resources/groups/memberships.ts
index 097335a..20e0929 100644
--- a/src/resources/groups/memberships.ts
+++ b/src/resources/groups/memberships.ts
@@ -48,6 +48,48 @@ export class Memberships extends APIResource {
return this._client.post('/gitpod.v1.GroupService/CreateMembership', { body, ...options });
}
+ /**
+ * Gets a specific membership by group ID and subject.
+ *
+ * Use this method to:
+ *
+ * - Check if a user or service account is a member of a group
+ * - Verify group membership for access control
+ *
+ * ### Examples
+ *
+ * - Check user membership:
+ *
+ * Checks if a user is a member of a specific group.
+ *
+ * ```yaml
+ * groupId: "d2c94c27-3b76-4a42-b88c-95a85e392c68"
+ * subject:
+ * id: "f53d2330-3795-4c5d-a1f3-453121af9c60"
+ * principal: PRINCIPAL_USER
+ * ```
+ *
+ * ### Authorization
+ *
+ * All organization members can check group membership (transparency model).
+ *
+ * @example
+ * ```ts
+ * const membership = await client.groups.memberships.retrieve(
+ * {
+ * subject: {
+ * id: 'f53d2330-3795-4c5d-a1f3-453121af9c60',
+ * principal: 'PRINCIPAL_USER',
+ * },
+ * groupId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68',
+ * },
+ * );
+ * ```
+ */
+ retrieve(body: MembershipRetrieveParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/gitpod.v1.GroupService/GetMembership', { body, ...options });
+ }
+
/**
* Lists all memberships of a group.
*
@@ -172,6 +214,13 @@ export interface MembershipCreateResponse {
member?: GroupMembership;
}
+export interface MembershipRetrieveResponse {
+ /**
+ * The membership if found, nil if subject is not a member
+ */
+ member?: GroupMembership;
+}
+
/**
* Empty response
*/
@@ -186,6 +235,15 @@ export interface MembershipCreateParams {
subject?: Shared.Subject;
}
+export interface MembershipRetrieveParams {
+ /**
+ * Subject to check membership for
+ */
+ subject: Shared.Subject;
+
+ groupId?: string;
+}
+
export interface MembershipListParams extends MembersPageParams {
/**
* Body param:
@@ -228,9 +286,11 @@ export declare namespace Memberships {
export {
type GroupMembership as GroupMembership,
type MembershipCreateResponse as MembershipCreateResponse,
+ type MembershipRetrieveResponse as MembershipRetrieveResponse,
type MembershipDeleteResponse as MembershipDeleteResponse,
type GroupMembershipsMembersPage as GroupMembershipsMembersPage,
type MembershipCreateParams as MembershipCreateParams,
+ type MembershipRetrieveParams as MembershipRetrieveParams,
type MembershipListParams as MembershipListParams,
type MembershipDeleteParams as MembershipDeleteParams,
};
diff --git a/src/resources/organizations/policies.ts b/src/resources/organizations/policies.ts
index 86b9b7c..da14a6b 100644
--- a/src/resources/organizations/policies.ts
+++ b/src/resources/organizations/policies.ts
@@ -111,6 +111,12 @@ export interface AgentPolicy {
* disabled for agents
*/
scmToolsDisabled: boolean;
+
+ /**
+ * scm_tools_allowed_group_id restricts SCM tools access to members of this group.
+ * Empty means no restriction (all users can use SCM tools if not disabled).
+ */
+ scmToolsAllowedGroupId?: string;
}
/**
@@ -411,6 +417,12 @@ export namespace PolicyUpdateParams {
*/
mcpDisabled?: boolean | null;
+ /**
+ * scm_tools_allowed_group_id restricts SCM tools access to members of this group.
+ * Empty means no restriction (all users can use SCM tools if not disabled).
+ */
+ scmToolsAllowedGroupId?: string | null;
+
/**
* scm_tools_disabled controls whether SCM (Source Control Management) tools are
* disabled for agents
diff --git a/src/resources/projects/projects.ts b/src/resources/projects/projects.ts
index b7d4d83..139b882 100644
--- a/src/resources/projects/projects.ts
+++ b/src/resources/projects/projects.ts
@@ -23,6 +23,7 @@ import {
ProjectPolicy,
ProjectRole,
} from './policies';
+import * as RunnersAPI from '../runners/runners';
import { APIPromise } from '../../core/api-promise';
import { PagePromise, ProjectsPage, type ProjectsPageParams } from '../../core/pagination';
import { RequestOptions } from '../../internal/request-options';
@@ -821,6 +822,12 @@ export namespace ProjectListParams {
*/
runnerIds?: Array;
+ /**
+ * runner_kinds filters the response to only projects that use environment classes
+ * from runners of these kinds
+ */
+ runnerKinds?: Array;
+
/**
* search performs case-insensitive search across project name, project ID, and
* repository name
diff --git a/src/version.ts b/src/version.ts
index 23f967c..5c16194 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.8.0'; // x-release-please-version
+export const VERSION = '0.9.0'; // x-release-please-version
diff --git a/tests/api-resources/groups/memberships.test.ts b/tests/api-resources/groups/memberships.test.ts
index 5a8f3cf..e28a932 100644
--- a/tests/api-resources/groups/memberships.test.ts
+++ b/tests/api-resources/groups/memberships.test.ts
@@ -20,6 +20,26 @@ describe('resource memberships', () => {
expect(dataAndResponse.response).toBe(rawResponse);
});
+ // Prism tests are disabled
+ test.skip('retrieve: only required params', async () => {
+ const responsePromise = client.groups.memberships.retrieve({ subject: {} });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism tests are disabled
+ test.skip('retrieve: required and optional params', async () => {
+ const response = await client.groups.memberships.retrieve({
+ subject: { id: 'f53d2330-3795-4c5d-a1f3-453121af9c60', principal: 'PRINCIPAL_USER' },
+ groupId: 'd2c94c27-3b76-4a42-b88c-95a85e392c68',
+ });
+ });
+
// Prism tests are disabled
test.skip('list', async () => {
const responsePromise = client.groups.memberships.list({});
diff --git a/tests/api-resources/organizations/policies.test.ts b/tests/api-resources/organizations/policies.test.ts
index fbbc3b8..609ca00 100644
--- a/tests/api-resources/organizations/policies.test.ts
+++ b/tests/api-resources/organizations/policies.test.ts
@@ -47,7 +47,12 @@ describe('resource policies', () => {
test.skip('update: required and optional params', async () => {
const response = await client.organizations.policies.update({
organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047',
- agentPolicy: { commandDenyList: ['string'], mcpDisabled: true, scmToolsDisabled: true },
+ agentPolicy: {
+ commandDenyList: ['string'],
+ mcpDisabled: true,
+ scmToolsAllowedGroupId: 'scmToolsAllowedGroupId',
+ scmToolsDisabled: true,
+ },
allowedEditorIds: ['string'],
allowLocalRunners: true,
defaultEditorId: 'defaultEditorId',