diff --git a/content/code-security/reference/supply-chain-security/dependabot-options-reference.md b/content/code-security/reference/supply-chain-security/dependabot-options-reference.md index 2b2d74225fd6..aea6d55c4831 100644 --- a/content/code-security/reference/supply-chain-security/dependabot-options-reference.md +++ b/content/code-security/reference/supply-chain-security/dependabot-options-reference.md @@ -572,7 +572,7 @@ Package manager | YAML value | Supported versions | | pip | `pip` | 24.2 | | pip-compile | `pip` | 7.5.3 | | pipenv | `pip` | <= 2024.4.1 | -| pnpm | `npm` | v7, v8
v9, v10 (version updates only) | +| pnpm | `npm` | v7, v8, v9, v10 | | poetry | `pip` | v2 | | {% ifversion dependabot-pre-commit-support %} | | pre-commit | `pre-commit` | Not applicable | diff --git a/content/rest/about-the-rest-api/api-versions.md b/content/rest/about-the-rest-api/api-versions.md index 519be84db7ca..068243fcd4bc 100644 --- a/content/rest/about-the-rest-api/api-versions.md +++ b/content/rest/about-the-rest-api/api-versions.md @@ -36,7 +36,7 @@ curl {% data reusables.rest-api.version-header %} https://api.github.com/zen Requests without the `X-GitHub-Api-Version` header will default to use the `{{ defaultRestApiVersion }}` version. -If you specify an API version that is no longer supported, you will receive a `400` error. +If you specify an API version that is no longer supported, you will receive a `410 Gone` response. ## Upgrading to a new API version @@ -46,12 +46,45 @@ When you update your integration to specify the new API version in the `X-GitHub Once your integration is updated, test your integration to verify that it works with the new API version. +## API version {% data variables.release-phases.closing_down %} + +API versions are supported for 24 months after a newer API version is released. + +While a version is within its support window but approaching {% data variables.release-phases.closing_down %}, {% data variables.product.github %} includes the following headers in API responses to help you prepare for migration: + +* `Deprecation` — The date when the API version will be {% data variables.release-phases.closing_down %}, formatted as an HTTP date per [RFC 7231](https://tools.ietf.org/html/rfc7231#section-7.1.1.1). For example: `Wed, 27 Nov 2019 14:34:29 GMT`. +* `Sunset` — The date when the API version will be completely removed ({% data variables.release-phases.retired %}), after which requests will return a `410 Gone` response. Follows [RFC 8594](https://tools.ietf.org/html/rfc8594). For example: `Fri, 27 Nov 2020 14:34:29 GMT`. + +After the support window ends: + +* Requests that specify a {% data variables.release-phases.closing_down %} API version receive a `410 Gone` response. +* Requests that do not specify an API version default to the next oldest supported version, not the {% data variables.release-phases.closing_down %} version. If you rely on unversioned requests, you may observe behavioral changes as older versions are removed from support. + +For more information on migrating to a newer API version, see [AUTOTITLE](/rest/about-the-rest-api/breaking-changes). + +## Exceptions to standard versioning + +In rare cases, {% data variables.product.github %} may make changes outside the normal API versioning cadence. These are exceptional interventions that do not alter the standard versioning guarantees for most integrators. + +### Security, availability, and reliability issues + +Critical security vulnerabilities, data exposure risks, or severe reliability issues may require changes outside the normal release schedule. {% data variables.product.github %} may release an unscheduled API version, backport fixes to supported versions, or in rare cases, introduce a breaking change to an existing version to protect users and platform integrity. + +{% data variables.product.github %} will communicate such changes through release notes, changelogs, and direct communication explaining what changed and why. Where feasible, advance notice will be provided. Immediate action may be taken without advance notice when required. + +### Low-usage services + +For certain services with very low usage, {% data variables.product.github %} may deprecate functionality outside the standard versioning process. In these cases, {% data variables.product.github %} will communicate the intent and reach out to affected integrators directly. + ## Supported API versions -The following REST API versions are currently supported: +The following REST API versions are currently supported. -{% for apiVersion in allVersions[currentVersion].apiVersions %} -{{ apiVersion }} -{% endfor %} +| API version | End of support date | +| --- | --- | +{%- for apiVersion in allVersions[currentVersion].apiVersions %} +{%- assign versionData = tables.rest-api-versions.versions[apiVersion] %} +| `{{ apiVersion }}` | {{ versionData.end_of_support | default: "Not yet scheduled" }} | +{%- endfor %} You can also make an API request to get all of the supported API versions. For more information, see [AUTOTITLE](/rest/meta/meta#get-all-api-versions). diff --git a/data/reusables/rest-api/about-api-versions.md b/data/reusables/rest-api/about-api-versions.md index f6aece67bb61..729b78ec3bfc 100644 --- a/data/reusables/rest-api/about-api-versions.md +++ b/data/reusables/rest-api/about-api-versions.md @@ -1,6 +1,6 @@ The {% data variables.product.github %} REST API is versioned. The API version name is based on the date when the API version was released. For example, the API version `{{ initialRestVersioningReleaseDate }}` was released on {{ initialRestVersioningReleaseDateLong }}. -Breaking changes are changes that can potentially break an integration. We will provide advance notice before releasing breaking changes. Breaking changes include: +Breaking changes are changes that can potentially break an integration. Breaking changes will be released in a new API version. We will provide advance notice before releasing breaking changes. Breaking changes include: * Removing an entire operation * Removing or renaming a parameter diff --git a/data/tables/rest-api-versions.yml b/data/tables/rest-api-versions.yml new file mode 100644 index 000000000000..9de73b822984 --- /dev/null +++ b/data/tables/rest-api-versions.yml @@ -0,0 +1,8 @@ +# REST API calendar date versions and their end of support dates. +# Rendering code lives in content/rest/about-the-rest-api/api-versions.md + +versions: + '2022-11-28': + end_of_support: 'March 10, 2028' + '2026-03-10': + end_of_support: ~ diff --git a/src/data-directory/lib/data-schemas/tables/rest-api-versions.ts b/src/data-directory/lib/data-schemas/tables/rest-api-versions.ts new file mode 100644 index 000000000000..046c02afe403 --- /dev/null +++ b/src/data-directory/lib/data-schemas/tables/rest-api-versions.ts @@ -0,0 +1,22 @@ +// This schema enforces the structure in data/tables/rest-api-versions.yml + +export default { + type: 'object', + additionalProperties: false, + required: ['versions'], + properties: { + versions: { + type: 'object', + additionalProperties: { + type: 'object', + additionalProperties: false, + required: ['end_of_support'], + properties: { + end_of_support: { + type: ['string', 'null'], + }, + }, + }, + }, + }, +} diff --git a/src/github-apps/data/fpt-2022-11-28/fine-grained-pat-permissions.json b/src/github-apps/data/fpt-2022-11-28/fine-grained-pat-permissions.json index 0ac456e84042..ec3f990cc4cd 100644 --- a/src/github-apps/data/fpt-2022-11-28/fine-grained-pat-permissions.json +++ b/src/github-apps/data/fpt-2022-11-28/fine-grained-pat-permissions.json @@ -1076,6 +1076,102 @@ } ] }, + "organization_copilot_spaces": { + "title": "Copilot Spaces", + "displayTitle": "Organization permissions for \"Copilot Spaces\"", + "permissions": [ + { + "category": "copilot-spaces", + "slug": "list-organization-copilot-spaces", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "create-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "get-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "set-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "delete-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "list-resources-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "create-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "get-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "set-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "delete-a-resource-from-an-organization-copilot-space", + "subcategory": "resources", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "write" + } + ] + }, "organization_copilot_agent_settings": { "title": "Copilot agent settings", "displayTitle": "Organization permissions for \"Copilot agent settings\"", diff --git a/src/github-apps/data/fpt-2022-11-28/server-to-server-permissions.json b/src/github-apps/data/fpt-2022-11-28/server-to-server-permissions.json index 9fb0e35ffdce..55279401e371 100644 --- a/src/github-apps/data/fpt-2022-11-28/server-to-server-permissions.json +++ b/src/github-apps/data/fpt-2022-11-28/server-to-server-permissions.json @@ -1553,6 +1553,122 @@ } ] }, + "organization_copilot_spaces": { + "title": "Copilot Spaces", + "displayTitle": "Organization permissions for \"Copilot Spaces\"", + "permissions": [ + { + "category": "copilot-spaces", + "slug": "list-organization-copilot-spaces", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "create-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "get-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "set-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "delete-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "list-resources-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "create-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "get-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "set-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "delete-a-resource-from-an-organization-copilot-space", + "subcategory": "resources", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + } + ] + }, "organization_copilot_agent_settings": { "title": "Copilot agent settings", "displayTitle": "Organization permissions for \"Copilot agent settings\"", diff --git a/src/github-apps/data/fpt-2026-03-10/fine-grained-pat-permissions.json b/src/github-apps/data/fpt-2026-03-10/fine-grained-pat-permissions.json index 0ac456e84042..ec3f990cc4cd 100644 --- a/src/github-apps/data/fpt-2026-03-10/fine-grained-pat-permissions.json +++ b/src/github-apps/data/fpt-2026-03-10/fine-grained-pat-permissions.json @@ -1076,6 +1076,102 @@ } ] }, + "organization_copilot_spaces": { + "title": "Copilot Spaces", + "displayTitle": "Organization permissions for \"Copilot Spaces\"", + "permissions": [ + { + "category": "copilot-spaces", + "slug": "list-organization-copilot-spaces", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "create-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "get-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "set-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "delete-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "list-resources-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "create-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "get-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "set-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "delete-a-resource-from-an-organization-copilot-space", + "subcategory": "resources", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "write" + } + ] + }, "organization_copilot_agent_settings": { "title": "Copilot agent settings", "displayTitle": "Organization permissions for \"Copilot agent settings\"", diff --git a/src/github-apps/data/fpt-2026-03-10/server-to-server-permissions.json b/src/github-apps/data/fpt-2026-03-10/server-to-server-permissions.json index 9fb0e35ffdce..55279401e371 100644 --- a/src/github-apps/data/fpt-2026-03-10/server-to-server-permissions.json +++ b/src/github-apps/data/fpt-2026-03-10/server-to-server-permissions.json @@ -1553,6 +1553,122 @@ } ] }, + "organization_copilot_spaces": { + "title": "Copilot Spaces", + "displayTitle": "Organization permissions for \"Copilot Spaces\"", + "permissions": [ + { + "category": "copilot-spaces", + "slug": "list-organization-copilot-spaces", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "create-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "get-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "set-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "delete-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "list-resources-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "create-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "get-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "set-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "delete-a-resource-from-an-organization-copilot-space", + "subcategory": "resources", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + } + ] + }, "organization_copilot_agent_settings": { "title": "Copilot agent settings", "displayTitle": "Organization permissions for \"Copilot agent settings\"", diff --git a/src/github-apps/data/ghec-2022-11-28/fine-grained-pat-permissions.json b/src/github-apps/data/ghec-2022-11-28/fine-grained-pat-permissions.json index 4229083596da..10f9dd3a85ca 100644 --- a/src/github-apps/data/ghec-2022-11-28/fine-grained-pat-permissions.json +++ b/src/github-apps/data/ghec-2022-11-28/fine-grained-pat-permissions.json @@ -1112,6 +1112,102 @@ } ] }, + "organization_copilot_spaces": { + "title": "Copilot Spaces", + "displayTitle": "Organization permissions for \"Copilot Spaces\"", + "permissions": [ + { + "category": "copilot-spaces", + "slug": "list-organization-copilot-spaces", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "create-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "get-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "set-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "delete-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "list-resources-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "create-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "get-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "set-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "delete-a-resource-from-an-organization-copilot-space", + "subcategory": "resources", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "write" + } + ] + }, "organization_copilot_agent_settings": { "title": "Copilot agent settings", "displayTitle": "Organization permissions for \"Copilot agent settings\"", diff --git a/src/github-apps/data/ghec-2022-11-28/server-to-server-permissions.json b/src/github-apps/data/ghec-2022-11-28/server-to-server-permissions.json index 8977d37dcfd9..e49590ecc6a9 100644 --- a/src/github-apps/data/ghec-2022-11-28/server-to-server-permissions.json +++ b/src/github-apps/data/ghec-2022-11-28/server-to-server-permissions.json @@ -2255,6 +2255,122 @@ } ] }, + "organization_copilot_spaces": { + "title": "Copilot Spaces", + "displayTitle": "Organization permissions for \"Copilot Spaces\"", + "permissions": [ + { + "category": "copilot-spaces", + "slug": "list-organization-copilot-spaces", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "create-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "get-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "set-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "delete-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "list-resources-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "create-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "get-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "set-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "delete-a-resource-from-an-organization-copilot-space", + "subcategory": "resources", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + } + ] + }, "organization_copilot_agent_settings": { "title": "Copilot agent settings", "displayTitle": "Organization permissions for \"Copilot agent settings\"", diff --git a/src/github-apps/data/ghec-2026-03-10/fine-grained-pat-permissions.json b/src/github-apps/data/ghec-2026-03-10/fine-grained-pat-permissions.json index 4229083596da..10f9dd3a85ca 100644 --- a/src/github-apps/data/ghec-2026-03-10/fine-grained-pat-permissions.json +++ b/src/github-apps/data/ghec-2026-03-10/fine-grained-pat-permissions.json @@ -1112,6 +1112,102 @@ } ] }, + "organization_copilot_spaces": { + "title": "Copilot Spaces", + "displayTitle": "Organization permissions for \"Copilot Spaces\"", + "permissions": [ + { + "category": "copilot-spaces", + "slug": "list-organization-copilot-spaces", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "create-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "get-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "set-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "delete-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "list-resources-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "create-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "get-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "read" + }, + { + "category": "copilot-spaces", + "slug": "set-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "write" + }, + { + "category": "copilot-spaces", + "slug": "delete-a-resource-from-an-organization-copilot-space", + "subcategory": "resources", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "additional-permissions": false, + "access": "write" + } + ] + }, "organization_copilot_agent_settings": { "title": "Copilot agent settings", "displayTitle": "Organization permissions for \"Copilot agent settings\"", diff --git a/src/github-apps/data/ghec-2026-03-10/server-to-server-permissions.json b/src/github-apps/data/ghec-2026-03-10/server-to-server-permissions.json index 8977d37dcfd9..e49590ecc6a9 100644 --- a/src/github-apps/data/ghec-2026-03-10/server-to-server-permissions.json +++ b/src/github-apps/data/ghec-2026-03-10/server-to-server-permissions.json @@ -2255,6 +2255,122 @@ } ] }, + "organization_copilot_spaces": { + "title": "Copilot Spaces", + "displayTitle": "Organization permissions for \"Copilot Spaces\"", + "permissions": [ + { + "category": "copilot-spaces", + "slug": "list-organization-copilot-spaces", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "create-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "get-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "set-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "delete-an-organization-copilot-space", + "subcategory": "copilot-spaces", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "list-resources-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "create-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "post", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "get-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "get", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "set-a-resource-for-an-organization-copilot-space", + "subcategory": "resources", + "verb": "put", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "copilot-spaces", + "slug": "delete-a-resource-from-an-organization-copilot-space", + "subcategory": "resources", + "verb": "delete", + "requestPath": "/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + } + ] + }, "organization_copilot_agent_settings": { "title": "Copilot agent settings", "displayTitle": "Organization permissions for \"Copilot agent settings\"", diff --git a/src/webhooks/lib/index.ts b/src/webhooks/lib/index.ts index dae7fd331078..9868ab4287a0 100644 --- a/src/webhooks/lib/index.ts +++ b/src/webhooks/lib/index.ts @@ -77,17 +77,22 @@ export async function getInitialPageWebhooks(version: string): Promise ({ + ...bodyParam, + ...(bodyParam.childParamsGroups ? { childParamsGroups: [] } : {}), + })), } } - initialWebhooks.push({ ...initialWebhook }) + initialWebhooks.push(initialWebhook) } initialWebhooksCache.set(version, initialWebhooks) return initialWebhooks diff --git a/src/webhooks/lib/tests/index.ts b/src/webhooks/lib/tests/index.ts new file mode 100644 index 000000000000..182d2043271d --- /dev/null +++ b/src/webhooks/lib/tests/index.ts @@ -0,0 +1,59 @@ +import { describe, expect, it } from 'vitest' + +import { getInitialPageWebhooks, getWebhook } from '../index' + +// Use a version that's guaranteed to exist in the data directory. +const VERSION = 'free-pro-team@latest' + +// Pick a webhook category whose data file has body parameters with +// non-empty childParamsGroups so we can verify they survive the +// initial-page stripping. +const CATEGORY = 'projects_v2_item' + +describe('getInitialPageWebhooks does not corrupt the getWebhook cache', () => { + it('strips childParamsGroups from the initial-page data', async () => { + const initial = await getInitialPageWebhooks(VERSION) + const initialWebhook = initial.find((w) => w.name === CATEGORY) + expect(initialWebhook).toBeDefined() + + for (const bp of initialWebhook!.data.bodyParameters ?? []) { + if (bp.childParamsGroups) { + expect(bp.childParamsGroups, `initial ${bp.name} should be stripped`).toHaveLength(0) + } + } + }) + + it('preserves childParamsGroups in the getWebhook cache after getInitialPageWebhooks runs', async () => { + // Seed the cache and record original childParamsGroups lengths. + const before = await getWebhook(VERSION, CATEGORY) + expect(before).toBeDefined() + + const originalLengths: Record = {} + for (const [action, actionData] of Object.entries(before!)) { + for (const bp of actionData.bodyParameters ?? []) { + if (bp.childParamsGroups && bp.childParamsGroups.length > 0) { + originalLengths[`${action}.${bp.name}`] = bp.childParamsGroups.length + } + } + } + expect(Object.keys(originalLengths).length).toBeGreaterThan(0) + + // This intentionally empties childParamsGroups for the initial page render. + await getInitialPageWebhooks(VERSION) + + // getWebhook returns cached data — it must NOT have been mutated. + const after = await getWebhook(VERSION, CATEGORY) + expect(after).toBeDefined() + + for (const [key, expectedLen] of Object.entries(originalLengths)) { + const [action, paramName] = key.split('.') + const bp = after![action]?.bodyParameters?.find( + (p: { name?: string }) => p.name === paramName, + ) + expect( + bp?.childParamsGroups?.length, + `${key}.childParamsGroups should still have ${expectedLen} entries`, + ).toBe(expectedLen) + } + }) +})