From 837aff3c27380f769318e82587becdb69b4215a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 16:14:12 -0700 Subject: [PATCH 01/13] Bump axios from 1.15.0 to 1.16.0 in the npm_and_yarn group across 1 directory (#61068) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index fff13072d6f5..32814307b8b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6035,12 +6035,12 @@ } }, "node_modules/axios": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", - "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } From 65bf2e6ceffd343a9ff5773b64358fdf1ae7f765 Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Tue, 5 May 2026 16:15:12 -0700 Subject: [PATCH 02/13] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Allow=20Node.js=2026?= =?UTF-8?q?=20in=20engines=20(Phase=201)=20(#61007)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 32814307b8b5..505b50cbc82e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -191,7 +191,7 @@ "website-scraper": "^5.3.1" }, "engines": { - "node": "^24" + "node": "^24 || ^26" }, "optionalDependencies": { "esm": "^3.2.25" diff --git a/package.json b/package.json index 816e1bf326b8..c15190af8115 100644 --- a/package.json +++ b/package.json @@ -360,7 +360,7 @@ "esm": "^3.2.25" }, "engines": { - "node": "^24" + "node": "^24 || ^26" }, "cacheDirectories": [ "node_modules", From fda5ec16158b5185b15b9ac1cb8dbc5f6ef9b53a Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Tue, 5 May 2026 16:17:05 -0700 Subject: [PATCH 03/13] =?UTF-8?q?=F0=9F=8C=8E=20Fix=20translated=20Liquid?= =?UTF-8?q?=20syntax=20causing=20daily=20search-scrape=20failures=20(#6102?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../lib/correct-translation-content.ts | 188 ++++++++++++++++++ .../tests/correct-translation-content.ts | 140 +++++++++++++ 2 files changed, 328 insertions(+) diff --git a/src/languages/lib/correct-translation-content.ts b/src/languages/lib/correct-translation-content.ts index 1df23bd1acd9..1a0376a00a74 100644 --- a/src/languages/lib/correct-translation-content.ts +++ b/src/languages/lib/correct-translation-content.ts @@ -183,6 +183,23 @@ export function correctTranslatedContentStrings( /\{%-?(\s+(?:ifversion|elsif|if)\s+(?:not\s+)?(?:fpt|ghec|ghes|ghae)(?:\s+(?:or|and)\s+(?:not\s+)?(?:fpt|ghec|ghes|ghae))*)\}/g, '{%$1 %}', ) + + // [SCRAPE-6548] Per-file fix for the Spanish reusable + // `data/reusables/dependency-graph/deduplication.md`. The translation + // dropped the `{% endif %}` after the Dependabot graph jobs item (the + // English source has it, scoped to fpt/ghec). Restore it so the outer + // `{% ifversion fpt or ghec %}` block balances. Scoped by both + // `dottedPath` (production reusable rendering via get-data.ts) and + // `relativePath` (count-translation-corruptions.ts validation path). + if ( + context.dottedPath === 'reusables.dependency-graph.deduplication' || + context.relativePath?.endsWith('data/reusables/dependency-graph/deduplication.md') + ) { + content = content.replace( + 'tienen prioridad sobre el envío automático de dependencias.\n', + 'tienen prioridad sobre el envío automático de dependencias.{% endif %}\n', + ) + } } if (context.code === 'ja') { @@ -385,6 +402,58 @@ export function correctTranslatedContentStrings( content = content.replaceAll('{% Windows ターミナル %}', '{% windows %}') // `{% indented_data_reference 再利用可能.X.Y spaces=N %}` — translated path content = content.replace(/(\{%-?\s*indented_data_reference\s+)再利用可能\./g, '$1reusables.') + + // [SCRAPE-6548] Per-file fixes for ja pages whose intro/title/shortTitle + // Liquid was structurally scrambled (orphan endif, swapped tag order, + // unclosed ifversion). Each replacement is scoped by the unique broken + // substring in the source field and rewrites only the broken Liquid; the + // Japanese prose is preserved exactly. These run only when context.code is + // 'ja' so they cannot affect other languages. + + // admin/managing-iam/iam-configuration-reference/index.md (intro): orphan + // `{% endif %}` injected before `{% ifversion ghec %}` — drop it. + content = content.replaceAll( + '{% data variables.location.product_location %}{% endif %} の認証 {% ifversion ghec %} および Enterprise {% elsif ghes %} のプロビジョニングの構成についての参照情報を表示できます。', + '{% data variables.location.product_location %} の認証 {% ifversion ghec %} および Enterprise {% elsif ghes %} のプロビジョニングの構成{% endif %} についての参照情報を表示できます。', + ) + + // admin/managing-iam/configuring-authentication-for-enterprise-managed-users/configuring-saml-single-sign-on-with-okta-for-enterprise-managed-users.md + // (intro): `{% ifversion ghec %}` opens but never closes. Append `{% endif %}`. + content = content.replaceAll( + '{% ifversion ghec %}{% data variables.product.prodname_dotcom_the_website %} または {% data variables.enterprise.data_residency_site %} で、{% data variables.product.prodname_emus %} の Okta を構成する方法を説明します。', + '{% ifversion ghec %}{% data variables.product.prodname_dotcom_the_website %} または {% data variables.enterprise.data_residency_site %} で、{% data variables.product.prodname_emus %} の Okta を構成する方法を説明します。{% endif %}', + ) + + // admin/managing-iam/provisioning-user-accounts-with-scim/index.md + // (title, shortTitle, intro): all three fields have endif/else/elsif/ifversion + // tags reordered so they don't parse. Replace each with a clean version. + content = content.replaceAll( + 'SCIM{% endif %} を使用したエンタープライズ マネージド ユーザー{% else %} 向けのプロビジョニング アカウント{% ifversion ghec %}', + '{% ifversion ghec %} SCIM を使用したエンタープライズ マネージド ユーザー{% else %} SCIM 向けのプロビジョニング アカウント{% endif %}', + ) + content = content.replaceAll( + 'SCIM{% endif %} を使用して{% ifversion ghec %} マネージド ユーザー アカウント{% else %} アカウントをプロビジョニングする', + '{% ifversion ghec %} SCIM を使用して マネージド ユーザー アカウント{% else %} SCIM アカウントをプロビジョニングする{% endif %}', + ) + content = content.replaceAll( + '{% data variables.location.product_location %}{% endif %} の {% data variables.enterprise.prodname_emu_enterprise %}{% elsif ghes %} のユーザー{% ifversion ghec %} に対してアカウントをプロビジョニングし、組織とチームのメンバーシップを管理する方法について説明します。', + '{% ifversion ghec %} {% data variables.enterprise.prodname_emu_enterprise %}{% elsif ghes %} {% data variables.location.product_location %} のユーザー{% endif %} に対してアカウントをプロビジョニングし、組織とチームのメンバーシップを管理する方法について説明します。', + ) + + // admin/managing-iam/provisioning-user-accounts-with-scim/configuring-scim-provisioning-for-users.md + // (title): tags reordered. Rewrite to a clean structure. + content = content.replaceAll( + 'ユーザー{% endif %} を管理するためのエンタープライズ マネージド ユーザー{% else %} の SCIM プロビジョニング {% ifversion ghec %} の構成', + '{% ifversion ghec %} エンタープライズ マネージド ユーザー{% else %} ユーザー{% endif %} を管理するための SCIM プロビジョニングの構成', + ) + + // code-security/.../configuring-code-scanning-for-your-appliance.md (intro): + // `{% ifversion default-setup-self-hosted-runners-GHEC %}` opens but never + // closes within the field. Append a closing `{% endif %}`. + content = content.replaceAll( + '{% data variables.product.prodname_dotcom %} ホステッド ランナー{% ifversion default-setup-self-hosted-runners-GHEC %}なしのエンタープライズに対して {% data variables.product.prodname_code_scanning %} を有効化、構成、および無効化できます。 {% data variables.product.prodname_code_scanning_caps %} を使用すると、コードの脆弱性やエラーをスキャンできます。', + '{% data variables.product.prodname_dotcom %} ホステッド ランナー{% ifversion default-setup-self-hosted-runners-GHEC %}なしのエンタープライズに対して{% endif %} {% data variables.product.prodname_code_scanning %} を有効化、構成、および無効化できます。 {% data variables.product.prodname_code_scanning_caps %} を使用すると、コードの脆弱性やエラーをスキャンできます。', + ) } if (context.code === 'pt') { @@ -399,6 +468,16 @@ export function correctTranslatedContentStrings( content = content.replaceAll('{%- dadosvariables', '{%- data variables') content = content.replaceAll('{% datavariables', '{% data variables') content = content.replaceAll('{%- datavariables', '{%- data variables') + // No space between `{%` and `datavariables` (translator dropped both spaces) + content = content.replaceAll('{%datavariables', '{% data variables') + content = content.replaceAll('{%-datavariables', '{%- data variables') + // `{% data variables.product. prodname_X %}` — stray space inside the dotted + // path, just after `.product.`. Liquid tokenizes the path as a single ident, + // so the extra space breaks the lookup. Restore. + content = content.replace( + /\{%(-?)\s*data\s+variables\.product\.\s+(prodname_[A-Za-z0-9_]+)/g, + '{%$1 data variables.product.$2', + ) // Fully translated reusables path: `{% dados reutilizáveis.X.Y %}` → `{% data reusables.X.Y %}` content = content.replaceAll('{% dados reutilizáveis.', '{% data reusables.') // Translated path segment inside reusables path: `repositórios` → `repositories` @@ -538,6 +617,16 @@ export function correctTranslatedContentStrings( // `{% modelo %}` / `{% modelo` — `template` (alias for `tool`)? Actually "modelo" // appears as `{% modelo %}` orphaned. Drop unmatched bare `{% modelo %}` is // risky; instead, leave as-is (Liquid will raise but rare). + + // Per-file targeted fixes for translator-scrambled Liquid that we can't + // catch via generic patterns. These are scoped tightly to the originating + // file so they're a no-op everywhere else, and they touch only the + // already-broken Liquid fragments — translated prose is preserved. + // + // [SCRAPE-6548] migrating-between-github-products: intro had a stray space + // inside `{% data variables.product. prodname_ghe_cloud %}`. The generic + // pt regex above already restored it, but here we only need to confirm — + // no extra per-file replacement required. } if (context.code === 'zh') { @@ -628,6 +717,39 @@ export function correctTranslatedContentStrings( /(\{%-?\s*indented_data_reference\s+)可(?:重|复)用(?:项|组件|s)?\./g, '$1reusables.', ) + + // [SCRAPE-6548] Per-file fixes for zh pages whose Liquid was structurally + // scrambled. Each replacement uses the unique broken substring as a + // discriminator so it only fires for the right field of the right file. + + // account-and-profile/concepts/username-changes.md (intro): orphan + // `{% endif %}` and `{% ifversion ghes %}` swapped — drop both. + content = content.replaceAll( + '如果实例使用内置身份验证{% endif %},则可以更改 {% data variables.product.github %} 帐户 {% ifversion ghes %} 的用户名。', + '可以更改 {% data variables.product.github %} 帐户的用户名。{% ifversion ghes %} 如果实例使用内置身份验证。{% endif %}', + ) + + // admin/managing-iam/using-saml-for-enterprise-iam/index.md (intro): + // three `{% ifversion %}` opens against one `{% endif %}`. Rebalance. + content = content.replaceAll( + '可以通过 SAML 单点登录 (SSO){% ifversion ghec %}和跨域身份管理系统 (SCIM){% endif %} 集中管理 {% ifversion ghes %} 帐户以及对 {% ifversion ghes %}{% data variables.location.product_location %}{% elsif ghec %}你的企业资源{% endif %}的访问权限。', + '可以通过 SAML 单点登录 (SSO){% ifversion ghec %}和跨域身份管理系统 (SCIM){% endif %} 集中管理帐户以及对 {% ifversion ghes %}{% data variables.location.product_location %}{% elsif ghec %}你的企业资源{% endif %}的访问权限。', + ) + + // code-security/.../configuring-access-to-private-registries-for-dependabot.md + // (intro): `{% ifversion dependabot-on-actions-self-hosted %}` opens but + // never closes. Append `{% endif %}`. + content = content.replaceAll( + '可以将身份验证信息(如密码和访问令牌)存储为加密机密,然后在配置文件中 {% data variables.product.prodname_dependabot %} 引用这些信息。{% ifversion dependabot-on-actions-self-hosted %} 如果您在专用网络上有注册表,您也可以在使用自托管运行程序执行{% data variables.product.prodname_dependabot %}时配置{% data variables.product.prodname_dependabot %}访问权限。', + '可以将身份验证信息(如密码和访问令牌)存储为加密机密,然后在配置文件中 {% data variables.product.prodname_dependabot %} 引用这些信息。{% ifversion dependabot-on-actions-self-hosted %} 如果您在专用网络上有注册表,您也可以在使用自托管运行程序执行{% data variables.product.prodname_dependabot %}时配置{% data variables.product.prodname_dependabot %}访问权限。{% endif %}', + ) + + // authentication/keeping-your-account-and-data-secure/security-log-events.md + // (markdown body line 15): the `> *` bullet has a duplicate + // `{% ifversion ghes %}` after the outer `{% ifversion ghes %}` block + // already opened on the previous line. Drop the inner duplicate so the + // outer endif balances correctly. + content = content.replaceAll('> * {% ifversion ghes %} 本文包含', '> * 本文包含') } if (context.code === 'ru') { @@ -864,6 +986,36 @@ export function correctTranslatedContentStrings( content = content.replace(/\{%-?\s+(?:ifversion|elsif|if)\s+[^%]*?\sи\s[^%]*?-?%\}/g, (m) => m.replace(/\sи\s/g, ' and '), ) + + // [SCRAPE-6548] Per-file fixes for ru pages whose Liquid was structurally + // scrambled. Each replacement is scoped by the unique broken substring. + + // admin/.../viewing-and-managing-a-users-saml-access-to-your-enterprise.md + // (intro): `{% ghec ghec` is not a valid tag and `{% ifversion %}` lacks + // an expression. Replace with a clean `{% ifversion ghec %}` ... `{% else %}` + // ... `{% endif %}` structure that matches the English source. + content = content.replaceAll( + 'Вы можете просмотреть и отозвать {% ghec ghec для участников предприятия {% ifversion %}linked identity, активные сеансы и авторизованные учетные данные{%else %}активные сеансы SAML{% endif %}.', + 'Вы можете просмотреть и отозвать {% ifversion ghec %}связанные удостоверения, активные сеансы и авторизованные учетные данные участников предприятия{% else %}активные сеансы SAML{% endif %}.', + ) + + // organizations/.../permissions-of-custom-organization-roles.md (intro): + // `{% ifversion org-custom-role-with-repo-permissions %}` opens with an + // `{% else %}` branch but never closes. Append `{% endif %}`. + content = content.replaceAll( + 'Вы можете управлять доступом к параметрам и репозиториям организации {% ifversion org-custom-role-with-repo-permissions %}, а также к параметрам организации {% else %}организации с пользовательскими ролями организации.', + 'Вы можете управлять доступом к параметрам и репозиториям организации {% ifversion org-custom-role-with-repo-permissions %}, а также к параметрам организации {% else %}организации с пользовательскими ролями организации.{% endif %}', + ) + + // packages/.../migrating-to-the-container-registry-from-the-docker-registry.md + // (intro): after the existing ru Cat A keyword fixes promote `данных`/ + // `переменных данных` to `data variables`, this intro is left with an + // open `{% ifversion ghes %}` ... `{% else %}` and no `{% endif %}`. + // Append it. + content = content.replaceAll( + '{% ifversion ghes %}Владелец предприятия может{%else %}{% data variables.product.company_short %} перенести образы Docker, ранее хранящиеся в реестре Docker на {% data variables.product.github %} на {% data variables.product.prodname_container_registry %}.', + '{% ifversion ghes %}Владелец предприятия может{% else %}{% data variables.product.company_short %} может{% endif %} перенести образы Docker, ранее хранящиеся в реестре Docker на {% data variables.product.github %} на {% data variables.product.prodname_container_registry %}.', + ) } if (context.code === 'fr') { @@ -1002,6 +1154,23 @@ export function correctTranslatedContentStrings( content = content.replace(/\{%-?\s+(?:ifversion|elsif|if)\s+[^%]*?\set\s[^%]*?-?%\}/g, (m) => m.replace(/\set\s/g, ' and '), ) + + // [SCRAPE-6548] `{% ifversion ghes}` / `{% elsif ghec or ghes}` — translator + // dropped the closing `%` before `}`. Same shape as the Spanish fix above. + // Match plan name (fpt|ghec|ghes|ghae) followed by `}` not `%}`. + content = content.replace( + /\{%-?(\s+(?:ifversion|elsif|if)\s+(?:not\s+)?(?:fpt|ghec|ghes|ghae)(?:\s+(?:or|and)\s+(?:not\s+)?(?:fpt|ghec|ghes|ghae))*)\}/g, + '{%$1 %}', + ) + + // [SCRAPE-6548] `{% des … variables.X %}` — translator translated `data` + // to `des` and inserted French prose before `variables.`. Tighten by + // forbidding `%`, `{`, `}`, `\n` inside the tag, and require `variables.` + // immediately before the dotted path. + content = content.replace( + /\{%(-?)\s*des(?:\s+[^{}%\n]+?)?\s+variables\.([A-Za-z0-9._-]+)(\s*-?%\})/g, + '{%$1 data variables.$2$3', + ) } if (context.code === 'ko') { @@ -1114,6 +1283,16 @@ export function correctTranslatedContentStrings( // `{% Variable.` (capital V) — variant content = content.replaceAll('{% Variable.', '{% data variables.') content = content.replaceAll('{%- Variable.', '{%- data variables.') + + // [SCRAPE-6548] Per-file fix: + // account-and-profile/concepts/username-changes.md (intro): orphan + // `{% endif %}` and `{% ifversion ghes %}` swapped — the conditional + // wraps the wrong piece of prose. Rewrite to wrap the + // "if you use built-in authentication" clause inside the ghes branch. + content = content.replaceAll( + '인스턴스에서 기본 제공 인증{% endif %}를 사용하는 경우 {% data variables.product.github %} 계정 {% ifversion ghes %}의 사용자 이름을 변경할 수 있습니다.', + '{% data variables.product.github %} 계정의 사용자 이름을 변경할 수 있습니다.{% ifversion ghes %} 인스턴스에서 기본 제공 인증을 사용하는 경우.{% endif %}', + ) } if (context.code === 'de') { @@ -1280,6 +1459,15 @@ export function correctTranslatedContentStrings( // Translated tag name `{% eingerucktes_datenverweis ... %}` → `{% indented_data_reference ... %}` content = content.replaceAll('{% eingerucktes_datenverweis ', '{% indented_data_reference ') content = content.replaceAll('{%- eingerucktes_datenverweis ', '{%- indented_data_reference ') + + // [SCRAPE-6548] Per-file fix: + // organizations/.../permissions-of-custom-organization-roles.md (intro): + // `{% ifversion org-custom-role-with-repo-permissions %}` opens with an + // `{% else %}` branch but never closes. Append `{% endif %}`. + content = content.replaceAll( + 'Mit angepassten Organisationsrollen kannst du den Zugriff auf die Einstellungen deiner {% ifversion org-custom-role-with-repo-permissions %}Organisation und die Repositories{% else %}einer Organisation steuern.', + 'Mit angepassten Organisationsrollen kannst du den Zugriff auf die Einstellungen deiner {% ifversion org-custom-role-with-repo-permissions %}Organisation und die Repositories{% else %}einer Organisation{% endif %} steuern.', + ) } // --- Generic fixes (all languages) --- diff --git a/src/languages/tests/correct-translation-content.ts b/src/languages/tests/correct-translation-content.ts index 3afdf2bcf042..6b82bb0a507d 100644 --- a/src/languages/tests/correct-translation-content.ts +++ b/src/languages/tests/correct-translation-content.ts @@ -1693,4 +1693,144 @@ Para más información, consulta "[AUTOTITLE](/path)". expect(elapsed).toBeLessThan(2000) }) }) + + // ─── SCRAPE-6548: search-scrape failures ───────────────────────────── + // Tests for the per-file Liquid corrections added to stop the daily + // search-scrape failures reported in github/docs-engineering#6548. + describe('SCRAPE-6548 per-file fixes', () => { + function fixAt(content: string, code: string, relativePath: string) { + return correctTranslatedContentStrings(content, '', { + code, + relativePath, + skipOrphanStripping: true, + }) + } + + test('pt: {%datavariables (no spaces) → {% data variables', () => { + expect(fix('{%datavariables.product.github %}', 'pt')).toBe( + '{% data variables.product.github %}', + ) + expect(fix('{%-datavariables.product.github %}', 'pt')).toBe( + '{%- data variables.product.github %}', + ) + }) + + test('pt: stray space after {% data variables.product.', () => { + expect(fix('{% data variables.product. prodname_ghe_cloud %}', 'pt')).toBe( + '{% data variables.product.prodname_ghe_cloud %}', + ) + expect(fix('{%- data variables.product. prodname_ghe_server %}', 'pt')).toBe( + '{%- data variables.product.prodname_ghe_server %}', + ) + }) + + test('pt: leaves correct path alone', () => { + const ok = '{% data variables.product.prodname_ghe_cloud %}' + expect(fix(ok, 'pt')).toBe(ok) + }) + + test('fr: missing-% in {% ifversion ghes} / {% elsif ghec or ghes}', () => { + expect(fix('{% ifversion ghes}', 'fr')).toBe('{% ifversion ghes %}') + expect(fix('{% elsif ghec or ghes}', 'fr')).toBe('{% elsif ghec or ghes %}') + }) + + test('fr: {% des … variables.X %} → {% data variables.X %}', () => { + expect(fix('{% des instances de variables.product.prodname_ghe_server %}', 'fr')).toBe( + '{% data variables.product.prodname_ghe_server %}', + ) + }) + + test('fr: leaves unrelated `des` prose alone', () => { + const ok = 'Les métriques des données sont utiles.' + expect(fix(ok, 'fr')).toBe(ok) + }) + + test('ko: username-changes intro orphan-endif fix', () => { + const broken = + '인스턴스에서 기본 제공 인증{% endif %}를 사용하는 경우 {% data variables.product.github %} 계정 {% ifversion ghes %}의 사용자 이름을 변경할 수 있습니다.' + const out = fixAt(broken, 'ko', 'account-and-profile/concepts/username-changes.md') + expect(out).not.toContain('{% endif %}를') + expect(out).toContain('{% endif %}') + expect(out).toContain('{% ifversion ghes %}') + }) + + test('zh: username-changes intro orphan-endif fix', () => { + const broken = + '如果实例使用内置身份验证{% endif %},则可以更改 {% data variables.product.github %} 帐户 {% ifversion ghes %} 的用户名。' + const out = fixAt(broken, 'zh', 'account-and-profile/concepts/username-changes.md') + expect(out).not.toContain('{% endif %},') + expect(out).toContain('{% endif %}') + }) + + test('zh: security-log-events markdown duplicate ifversion ghes', () => { + const broken = '> * {% ifversion ghes %} 本文包含最新版本' + expect(fix(broken, 'zh')).toBe('> * 本文包含最新版本') + }) + + test('de: permissions-of-custom-organization-roles intro append endif', () => { + const broken = + 'Mit angepassten Organisationsrollen kannst du den Zugriff auf die Einstellungen deiner {% ifversion org-custom-role-with-repo-permissions %}Organisation und die Repositories{% else %}einer Organisation steuern.' + const out = fixAt( + broken, + 'de', + 'organizations/managing-peoples-access-to-your-organization-with-roles/permissions-of-custom-organization-roles.md', + ) + expect(out).toContain('{% endif %} steuern.') + }) + + test('ru: permissions-of-custom-organization-roles intro append endif', () => { + const broken = + 'Вы можете управлять доступом к параметрам и репозиториям организации {% ifversion org-custom-role-with-repo-permissions %}, а также к параметрам организации {% else %}организации с пользовательскими ролями организации.' + const out = fixAt( + broken, + 'ru', + 'organizations/managing-peoples-access-to-your-organization-with-roles/permissions-of-custom-organization-roles.md', + ) + expect(out).toMatch(/\{% endif %\}$/) + }) + + test('ja: scim/index title rebalances tags', () => { + const broken = + 'SCIM{% endif %} を使用したエンタープライズ マネージド ユーザー{% else %} 向けのプロビジョニング アカウント{% ifversion ghec %}' + const out = fix(broken, 'ja') + // After fix: balanced ifversion/else/endif and starts with ifversion + expect(out).toMatch(/^\{% ifversion ghec %\}/) + expect(out).toMatch(/\{% endif %\}$/) + expect(out.match(/\{% endif %\}/g) || []).toHaveLength(1) + }) + + test('es: deduplication reusable appends endif when scoped by dottedPath', () => { + const broken = 'tienen prioridad sobre el envío automático de dependencias.\n1. Otra cosa.' + const out = correctTranslatedContentStrings(broken, '', { + code: 'es', + dottedPath: 'reusables.dependency-graph.deduplication', + skipOrphanStripping: true, + }) + expect(out).toContain( + 'tienen prioridad sobre el envío automático de dependencias.{% endif %}\n', + ) + }) + + test('es: deduplication reusable also fires when scoped by relativePath', () => { + const broken = 'tienen prioridad sobre el envío automático de dependencias.\n1. Otra cosa.' + const out = correctTranslatedContentStrings(broken, '', { + code: 'es', + relativePath: 'data/reusables/dependency-graph/deduplication.md', + skipOrphanStripping: true, + }) + expect(out).toContain( + 'tienen prioridad sobre el envío automático de dependencias.{% endif %}\n', + ) + }) + + test('es: deduplication fix does NOT fire on unrelated paths', () => { + const text = 'tienen prioridad sobre el envío automático de dependencias.\n1. Otra.' + const out = correctTranslatedContentStrings(text, '', { + code: 'es', + relativePath: 'some/other/file.md', + skipOrphanStripping: true, + }) + expect(out).toBe(text) + }) + }) }) From 57851b50570c67382cf49a176a3a1cc801621813 Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Tue, 5 May 2026 16:20:33 -0700 Subject: [PATCH 04/13] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Override=20uuid?= =?UTF-8?q?=20to=20v14=20and=20postcss=20to=20v8.5.10=20to=20fix=20vulns?= =?UTF-8?q?=20(#61049)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- package-lock.json | 55 ++++++++++++++--------------------------------- package.json | 4 +++- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 505b50cbc82e..df746cb71c67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13832,9 +13832,9 @@ } }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", "funding": [ { "type": "opencollective", @@ -13849,10 +13849,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -16600,11 +16601,16 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", + "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist-node/bin/uuid" } }, "node_modules/validate.io-array": { @@ -16825,35 +16831,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/vite/node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, "node_modules/vitest": { "version": "4.0.18", "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.18.tgz", diff --git a/package.json b/package.json index c15190af8115..e952100abcb2 100644 --- a/package.json +++ b/package.json @@ -354,7 +354,9 @@ "esbuild": "^0.25", "vite": "^7.3.2", "path-to-regexp": "^8.4.0", - "apache-arrow": "file:src/search/vendor/apache-arrow-stub" + "apache-arrow": "file:src/search/vendor/apache-arrow-stub", + "uuid": "^14.0.0", + "postcss": "^8.5.10" }, "optionalDependencies": { "esm": "^3.2.25" From ee2aa2b170396d756997035ded8d86b99c3a3da7 Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Tue, 5 May 2026 16:20:49 -0700 Subject: [PATCH 05/13] =?UTF-8?q?=F0=9F=94=A7=20Fix=20OTel=20traces=20endp?= =?UTF-8?q?oint=20and=20disable=20unused=20exporters=20(#61053)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- config/moda/configuration/default/env.yaml | 12 ++++++++---- config/moda/configuration/production/env.yaml | 7 +++++-- src/observability/lib/tracing.ts | 6 ------ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/config/moda/configuration/default/env.yaml b/config/moda/configuration/default/env.yaml index 03135c30f86e..681bb075176c 100644 --- a/config/moda/configuration/default/env.yaml +++ b/config/moda/configuration/default/env.yaml @@ -9,7 +9,11 @@ data: RATE_LIMIT_MAX: '21' # Moda uses a non-default port for sending datadog metrics DD_DOGSTATSD_PORT: '28125' - # OTel distributed tracing — sends spans to OTel Collector via OTLP/HTTP (proto). - # Uses stamp address (not mesh) since docs-internal is not on the service mesh. - # See https://thehub.github.com/epd/engineering/dev-practicals/observability/distributed-tracing/instrumentation/ - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'https://otelcol.service.%stamp%.github.net/v1/traces' + # NodeSDK auto-enables OTLP metrics and logs exporters when these env vars + # are unset. We only want traces, so explicitly disable the others to avoid + # spamming export errors. See https://opentelemetry.io/docs/specs/otel/protocol/exporter/ + OTEL_METRICS_EXPORTER: 'none' + OTEL_LOGS_EXPORTER: 'none' + # OTel traces endpoint is set per-environment (see production/env.yaml). + # Stagings don't have OTEL_EXPORTER_OTLP_TRACES_HEADERS, so they don't + # export traces — tracing.ts gates SDK startup on the endpoint env var. diff --git a/config/moda/configuration/production/env.yaml b/config/moda/configuration/production/env.yaml index 706f1c44df0d..a66e0692fb3f 100644 --- a/config/moda/configuration/production/env.yaml +++ b/config/moda/configuration/production/env.yaml @@ -13,6 +13,9 @@ data: # Equivalent to HEAVEN_DEPLOYED_ENV === 'production' MODA_PROD_SERVICE_ENV: 'true' # OTel distributed tracing — sends spans to OTel Collector via OTLP/HTTP (proto). - # Uses stamp address (not mesh) since docs-internal is not on the service mesh. + # Uses %site% template (not %stamp%) since docs-internal is not on the service + # mesh and not on a Proxima stamp (region: iad, profile: general). %site% + # interpolates to the cluster's site (e.g. iad), giving a hostname like + # otelcol.service.iad.github.net that resolves from production pods. # See https://thehub.github.com/epd/engineering/dev-practicals/observability/distributed-tracing/instrumentation/ - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'https://otelcol.service.%stamp%.github.net/v1/traces' + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'https://otelcol.service.%site%.github.net/v1/traces' diff --git a/src/observability/lib/tracing.ts b/src/observability/lib/tracing.ts index 1e782f262be0..894d4406cf36 100644 --- a/src/observability/lib/tracing.ts +++ b/src/observability/lib/tracing.ts @@ -26,14 +26,8 @@ import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express' import { HttpInstrumentation } from '@opentelemetry/instrumentation-http' import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici' import { NodeSDK } from '@opentelemetry/sdk-node' -import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api' -// TEMPORARY: enable OTel diagnostic logging to investigate why traces aren't -// arriving in the collector. See github/docs-engineering#6046. Revert once -// the export pipeline is confirmed working. if (process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) { - diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO) - const sdk = new NodeSDK({ serviceName: process.env.OTEL_SERVICE_NAME || 'docs-internal', traceExporter: new OTLPTraceExporter({}), From f4cb44f0986092296d9152cb78a37c9709da7190 Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Tue, 5 May 2026 16:22:07 -0700 Subject: [PATCH 06/13] =?UTF-8?q?=F0=9F=8E=A7=20Skip=20docs-engineering=20?= =?UTF-8?q?review=20for=20lockfile-only=20churn=20PRs=20(#61060)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../workflows/reviewers-docs-engineering.yml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/.github/workflows/reviewers-docs-engineering.yml b/.github/workflows/reviewers-docs-engineering.yml index d9510db35d92..86e2a7479332 100644 --- a/.github/workflows/reviewers-docs-engineering.yml +++ b/.github/workflows/reviewers-docs-engineering.yml @@ -40,6 +40,7 @@ jobs: ${{ github.repository == 'github/docs-internal' && !github.event.pull_request.draft && !contains(github.event.pull_request.labels.*.name, 'reviewers-docs-engineering') && + !contains(github.event.pull_request.labels.*.name, 'lockfile-churn-only') && github.event.pull_request.head.ref != 'repo-sync' }} runs-on: ubuntu-latest env: @@ -50,7 +51,45 @@ jobs: - name: Checkout repository uses: actions/checkout@v6.0.1 + # Detect PRs that only changed package-lock.json (no engineering source files). + # These are usually cross-platform `npm install` churn from contributors + # editing content. We comment with reset instructions instead of pulling in + # docs-engineering for review. + - name: Detect lockfile-only churn + id: detect + run: | + changed=$(gh pr diff "$PR" --name-only) + echo "Changed files:" + echo "$changed" + lockfile=$(echo "$changed" | grep -c '^package-lock\.json$' || true) + other_eng=$(echo "$changed" | grep -cE '(\.tsx?$|\.scss$|^src/|^package\.json$|^\.github/|^config/|^\.devcontainer/|Dockerfile)' || true) + if [ "$lockfile" -gt 0 ] && [ "$other_eng" -eq 0 ]; then + echo "lockfile_only=true" >> "$GITHUB_OUTPUT" + else + echo "lockfile_only=false" >> "$GITHUB_OUTPUT" + fi + + - name: Comment and label lockfile-only PRs + if: steps.detect.outputs.lockfile_only == 'true' + run: | + cat > /tmp/lockfile-churn-body.md <<'EOF' + _Posted by Copilot on behalf of docs-engineering._ + + This PR includes `package-lock.json` changes but no engineering files. Please reset the lockfile: + + ``` + git checkout origin/main -- package-lock.json + git commit -m "Reset package-lock.json" + git push + ``` + + If the lockfile change is intentional, remove the `lockfile-churn-only` label and request docs-engineering review. + EOF + gh pr comment "$PR" --body-file /tmp/lockfile-churn-body.md + gh pr edit "$PR" --add-label lockfile-churn-only + - name: Add docs engineering as a reviewer + if: steps.detect.outputs.lockfile_only != 'true' uses: ./.github/actions/retry-command with: command: gh pr edit $PR --add-reviewer github/docs-engineering --add-label reviewers-docs-engineering From b21cd6be74785c36b83f19b9a4df0d7e5145bce4 Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Tue, 5 May 2026 16:26:32 -0700 Subject: [PATCH 07/13] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Remove=20any=20types?= =?UTF-8?q?=20from=20several=20files=20(#61048)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eslint.config.ts | 9 -- src/article-api/liquid-renderers/rest-tags.ts | 20 ++-- .../transformers/github-apps-transformer.ts | 4 +- src/content-render/liquid/engine.ts | 31 +++---- src/frame/lib/create-tree.ts | 28 +++--- src/frame/lib/frontmatter.ts | 33 ++++--- src/frame/lib/page.ts | 29 ++++-- src/github-apps/lib/index.ts | 37 +++++--- ...or-fine-grained-personal-access-tokens.tsx | 2 +- ...-github-app-installation-access-tokens.tsx | 2 +- ...able-for-github-app-user-access-tokens.tsx | 2 +- ...or-fine-grained-personal-access-tokens.tsx | 2 +- .../permissions-required-for-github-apps.tsx | 2 +- src/landings/pages/home.tsx | 20 ++-- src/links/scripts/update-internal-links.ts | 91 +++++++++++-------- src/tests/helpers/e2etest.ts | 6 +- 16 files changed, 172 insertions(+), 146 deletions(-) diff --git a/eslint.config.ts b/eslint.config.ts index 0d3ef1e2b087..c76186489aa9 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -229,14 +229,12 @@ export default [ // Legacy files with @typescript-eslint/no-explicit-any violations (see github/docs-engineering#5797) { files: [ - 'src/article-api/liquid-renderers/rest-tags.ts', 'src/article-api/scripts/generate-api-docs.ts', 'src/article-api/transformers/audit-logs-transformer.ts', 'src/article-api/transformers/rest-transformer.ts', 'src/codeql-cli/scripts/convert-markdown-for-docs.ts', 'src/content-linter/scripts/lint-content.ts', - 'src/content-render/liquid/engine.ts', 'src/content-render/liquid/index.ts', 'src/content-render/scripts/liquid-tags.ts', 'src/content-render/scripts/move-content.ts', @@ -245,13 +243,9 @@ export default [ 'src/data-directory/lib/get-data.ts', 'src/fixtures/tests/guides.ts', 'src/frame/components/context/MainContext.tsx', - 'src/frame/lib/create-tree.ts', - 'src/frame/lib/frontmatter.ts', 'src/frame/lib/page-data.ts', - 'src/frame/lib/page.ts', 'src/frame/tests/page.ts', 'src/frame/tests/server.ts', - 'src/github-apps/lib/index.ts', 'src/graphql/lib/index.ts', 'src/graphql/pages/reference.tsx', 'src/graphql/scripts/utils/process-schemas.ts', @@ -260,14 +254,12 @@ export default [ 'src/landings/components/CookBookFilter.tsx', 'src/landings/components/ProductGuidesContext.tsx', 'src/landings/components/SidebarProduct.tsx', - 'src/landings/pages/home.tsx', 'src/landings/pages/product.tsx', 'src/languages/lib/correct-translation-content.ts', 'src/languages/lib/render-with-fallback.ts', 'src/languages/lib/translation-utils.ts', 'src/links/lib/update-internal-links.ts', 'src/links/scripts/check-github-github-links.ts', - 'src/links/scripts/update-internal-links.ts', 'src/rest/components/get-rest-code-samples.ts', 'src/rest/pages/category.tsx', 'src/rest/pages/subcategory.tsx', @@ -294,7 +286,6 @@ export default [ 'src/search/scripts/index/utils/indexing-elasticsearch-utils.ts', 'src/search/scripts/scrape/lib/parse-page-sections-into-records.ts', 'src/tests/helpers/check-url.ts', - 'src/tests/helpers/e2etest.ts', 'src/tests/scripts/copy-fixture-data.ts', 'src/tests/vitest.setup.ts', 'src/types/github__markdownlint-github.d.ts', diff --git a/src/article-api/liquid-renderers/rest-tags.ts b/src/article-api/liquid-renderers/rest-tags.ts index 2a2918bc60ed..63b3ee52cd6f 100644 --- a/src/article-api/liquid-renderers/rest-tags.ts +++ b/src/article-api/liquid-renderers/rest-tags.ts @@ -1,4 +1,4 @@ -import type { TagToken, Context as LiquidContext } from 'liquidjs' +import type { TagToken, Context as LiquidContext, Liquid, Emitter, TopLevelToken } from 'liquidjs' import { fastTextOnly } from '@/content-render/unified/text-only' import { renderContent } from '@/content-render/index' import type { Context } from '@/types' @@ -16,15 +16,15 @@ export class RestParameter { constructor( token: TagToken, - remainTokens: TagToken[], - liquid: { options: any; parser: any }, + remainTokens: TopLevelToken[], + liquid: Liquid, private liquidContext?: LiquidContext, ) { // The tag receives the parameter object from the template context this.paramName = token.args.trim() } - async render(ctx: LiquidContext, emitter: any): Promise { + async render(ctx: LiquidContext, emitter: Emitter): Promise { const param = ctx.get([this.paramName]) as Parameter const context = ctx.get(['context']) as Context @@ -63,8 +63,8 @@ export class RestParameter { export class RestBodyParameter { constructor( token: TagToken, - remainTokens: TagToken[], - liquid: { options: any; parser: any }, + remainTokens: TopLevelToken[], + liquid: Liquid, private liquidContext?: LiquidContext, ) { // Parse arguments - param name and optional indent level @@ -76,7 +76,7 @@ export class RestBodyParameter { private param: string private indent: number - async render(ctx: LiquidContext, emitter: any): Promise { + async render(ctx: LiquidContext, emitter: Emitter): Promise { const param = ctx.get([this.param]) as BodyParameter const context = ctx.get(['context']) as Context const indent = this.indent @@ -126,14 +126,14 @@ export class RestStatusCode { constructor( token: TagToken, - remainTokens: TagToken[], - liquid: { options: any; parser: any }, + remainTokens: TopLevelToken[], + liquid: Liquid, private liquidContext?: LiquidContext, ) { this.statusCodeName = token.args.trim() } - async render(ctx: LiquidContext, emitter: any): Promise { + async render(ctx: LiquidContext, emitter: Emitter): Promise { const statusCode = ctx.get([this.statusCodeName]) as StatusCode const context = ctx.get(['context']) as Context diff --git a/src/article-api/transformers/github-apps-transformer.ts b/src/article-api/transformers/github-apps-transformer.ts index b13f5e22de87..72cecd46999b 100644 --- a/src/article-api/transformers/github-apps-transformer.ts +++ b/src/article-api/transformers/github-apps-transformer.ts @@ -124,7 +124,9 @@ export class GithubAppsTransformer implements PageTransformer { } // Get the GitHub Apps data - const appsData = await getAppsData(pageType, currentVersion, effectiveApiVersion) + const appsData = (await getAppsData(pageType, currentVersion, effectiveApiVersion)) as + | GitHubAppsListData + | GitHubAppsPermissionsData // Prepare manual content let manualContent = '' diff --git a/src/content-render/liquid/engine.ts b/src/content-render/liquid/engine.ts index 77591e81471b..4f176179aefa 100644 --- a/src/content-render/liquid/engine.ts +++ b/src/content-render/liquid/engine.ts @@ -1,44 +1,41 @@ import { Liquid } from 'liquidjs' import GithubSlugger from 'github-slugger' -// Copilot: When converting data.js to TypeScript, remove the 'as any' assertion for anyData below import Data from './data' import Octicon from './octicon' -// Copilot: When converting ifversion.js to TypeScript, remove the 'as any' assertion for anyIfversion below import Ifversion from './ifversion' -// Copilot: When converting tool.js to TypeScript, remove the 'as any' assertion for anyTool below import { Tool, tags as toolTags } from './tool' import { Spotlight, tags as spotlightTags } from './spotlight' import { Prompt } from './prompt' import IndentedDataReference from './indented-data-reference' -// Type assertions for .js files without type definitions -// Copilot: Remove these assertions when the corresponding .js files are converted to TypeScript -const anyData = Data as any -const anyIfversion = Ifversion as any -const anyTool = Tool as any -const anySpotlight = Spotlight as any -const anyPrompt = Prompt as any -const anyIndentedDataReference = IndentedDataReference as any +type LiquidTagDef = Parameters[1] + +const dataTag = Data as unknown as LiquidTagDef +const ifversionTag = Ifversion as unknown as LiquidTagDef +const toolTag = Tool as unknown as LiquidTagDef +const spotlightTag = Spotlight as unknown as LiquidTagDef +const promptTag = Prompt as unknown as LiquidTagDef +const indentedDataReferenceTag = IndentedDataReference as unknown as LiquidTagDef export const engine = new Liquid({ extname: '.html', dynamicPartials: false, }) -engine.registerTag('indented_data_reference', anyIndentedDataReference) -engine.registerTag('data', anyData) +engine.registerTag('indented_data_reference', indentedDataReferenceTag) +engine.registerTag('data', dataTag) engine.registerTag('octicon', Octicon) -engine.registerTag('ifversion', anyIfversion) +engine.registerTag('ifversion', ifversionTag) for (const tag of toolTags) { - engine.registerTag(tag, anyTool) + engine.registerTag(tag, toolTag) } for (const tag in spotlightTags) { - engine.registerTag(tag, anySpotlight) + engine.registerTag(tag, spotlightTag) } -engine.registerTag('prompt', anyPrompt) +engine.registerTag('prompt', promptTag) /** * Like the `size` filter, but specifically for diff --git a/src/frame/lib/create-tree.ts b/src/frame/lib/create-tree.ts index 2c0a71b6149b..e452c819c40c 100644 --- a/src/frame/lib/create-tree.ts +++ b/src/frame/lib/create-tree.ts @@ -76,10 +76,7 @@ export default async function createTree( basePath, relativePath, languageCode: 'en', - mtime, - // PageInitOptions doesn't include mtime in its type definition, but PageReadResult uses `& any` - // which allows additional properties to be passed through to the Page constructor - } as any) + }) if (!newPage) { throw Error(`Cannot initialize page for ${filepath}`) } @@ -100,22 +97,19 @@ export default async function createTree( // It's not enough to rely on *length* of the array before and after // because the change could have been to remove one and add another. // Page class has dynamic frontmatter properties like 'children' that aren't in the type definition - children: (page as any).children || [], + children: page.children || [], childPages: [], } // Process frontmatter children recursively. - // Page class has dynamic frontmatter properties like 'children' that aren't in the type definition - if ((page as any).children) { - assertUniqueChildren(page as any) + if (page.children) { + assertUniqueChildren(page) item.childPages = ( await Promise.all( - // Page class has dynamic frontmatter properties like 'children' that aren't in the type definition - ((page as any).children as string[]).map(async (child: string, i: number) => { + (page.children as string[]).map(async (child: string, i: number) => { let childPreviousTree: UnversionedTree | undefined if (previousTree && previousTree.childPages) { - // Page class has dynamic frontmatter properties like 'children' that aren't in the type definition - if (equalArray((page as any).children, previousTree.children)) { + if (equalArray(page.children as string[], previousTree.children)) { // We can only safely rely on picking the same "n'th" item // from the array if we're confident the names are the same // as they were before. @@ -163,7 +157,7 @@ export default async function createTree( // mutate the `page.children` so we can benefit from the // ability to reload the site tree on consecutive requests. // Page class has dynamic frontmatter properties like 'children' that aren't in the type definition - ;(page as any).children = ((page as any).children as string[]).filter( + ;(page.children as string[]) = (page.children as string[]).filter( (c: string) => c !== child, ) } @@ -189,11 +183,11 @@ async function getMtime(filePath: string): Promise { return Math.round((await fs.stat(filePath)).mtimeMs) } -// Page class has dynamic frontmatter properties that aren't in the type definition -function assertUniqueChildren(page: any): void { - if (page.children.length !== new Set(page.children).size) { +function assertUniqueChildren(page: Page): void { + const children = page.children || [] + if (children.length !== new Set(children).size) { const count: Record = {} - for (const entry of page.children) { + for (const entry of children) { count[entry] = 1 + (count[entry] || 0) } let msg = `${page.relativePath} has duplicates in the 'children' key.` diff --git a/src/frame/lib/frontmatter.ts b/src/frame/lib/frontmatter.ts index 539e707235b6..ec37a80246d0 100644 --- a/src/frame/lib/frontmatter.ts +++ b/src/frame/lib/frontmatter.ts @@ -1,6 +1,7 @@ // when updating to typescript, // update links in content/contributing as well +import type { SchemaObject } from 'ajv' import parse from '@/frame/lib/read-frontmatter' import { allVersions } from '@/versions/lib/all-versions' import { allTools } from '@/tools/lib/all-tools' @@ -10,22 +11,27 @@ interface SchemaProperty { type?: string | string[] translatable?: boolean deprecated?: boolean - default?: any + default?: unknown minimum?: number maximum?: number - enum?: any[] + enum?: unknown[] errorMessage?: string - items?: any - properties?: Record + items?: SchemaProperty | SchemaProperty[] + properties?: Record required?: string[] additionalProperties?: boolean - patternProperties?: Record + patternProperties?: Record format?: string description?: string minItems?: number maxItems?: number } +interface FrontmatterOptions { + schema?: SchemaObject + filepath?: string | null +} + interface Schema { type: string required: string[] @@ -442,17 +448,20 @@ const semverRange = { errorMessage: 'Must be a valid SemVer range: ${0}', } -;(schema.properties as Record).versions = { +;(schema.properties as Record).versions = { type: ['object', 'string'], // allow a '*' string to indicate all versions additionalProperties: false, // don't allow any versions in FM that aren't defined in lib/all-versions - properties: Object.values(allVersions).reduce((acc: any, versionObj) => { - acc[versionObj.plan] = semverRange - acc[versionObj.shortName] = semverRange - return acc - }, featureVersionsProp), + properties: Object.values(allVersions).reduce( + (acc: Record, versionObj) => { + acc[versionObj.plan] = semverRange + acc[versionObj.shortName] = semverRange + return acc + }, + featureVersionsProp, + ), } -export function frontmatter(markdown: string, opts: any = {}) { +export function frontmatter(markdown: string, opts: FrontmatterOptions = {}) { const defaults = { schema, } diff --git a/src/frame/lib/page.ts b/src/frame/lib/page.ts index f690eadb5468..6c30129432a1 100644 --- a/src/frame/lib/page.ts +++ b/src/frame/lib/page.ts @@ -19,6 +19,7 @@ import { renderContentWithFallback } from '@/languages/lib/render-with-fallback' import { deprecated, supported } from '@/versions/lib/enterprise-server-releases' import { allPlatforms } from '@/tools/lib/all-platforms' import type { Context, FrontmatterVersions, FeaturedLinksExpanded } from '@/types' +import type { Product } from '@/products/lib/all-products' const isProduction = process.env.NODE_ENV === 'production' @@ -28,10 +29,17 @@ const isProduction = process.env.NODE_ENV === 'production' // every single time, we turn it into a Set once. const productMapKeysAsSet = new Set(Object.keys(productMap)) +type FrontmatterError = { + reason: string + message?: string + filepath?: string + property?: string +} + type ReadFileContentsResult = { - data?: any + data?: Record content?: string - errors?: any[] + errors?: FrontmatterError[] } type PageInitOptions = { @@ -43,8 +51,9 @@ type PageInitOptions = { type PageReadResult = PageInitOptions & { fullPath: string markdown: string - frontmatterErrors?: any[] -} & any + frontmatterErrors?: FrontmatterError[] + [key: string]: unknown +} type RenderOptions = { preferShort?: boolean @@ -59,9 +68,9 @@ type CommunityRedirect = { } export class FrontmatterErrorsError extends Error { - public frontmatterErrors: string[] + public frontmatterErrors: FrontmatterError[] - constructor(message: string, frontmatterErrors: string[]) { + constructor(message: string, frontmatterErrors: FrontmatterError[]) { super(message) this.frontmatterErrors = frontmatterErrors } @@ -181,8 +190,8 @@ class Page { mtime, frontmatterErrors, } as PageReadResult - } catch (err: any) { - if (err.code === 'ENOENT') return false + } catch (err) { + if (err instanceof Error && (err as NodeJS.ErrnoException).code === 'ENOENT') return false console.error(err) return false } @@ -234,7 +243,7 @@ class Page { if (versionsParentProductIsNotAvailableIn.length) { throw new Error( - `\`versions\` frontmatter in ${this.fullPath} contains ${versionsParentProductIsNotAvailableIn}, which ${this.parentProduct.id} product is not available in!`, + `\`versions\` frontmatter in ${this.fullPath} contains ${versionsParentProductIsNotAvailableIn}, which ${this.parentProduct?.id} product is not available in!`, ) } } @@ -289,7 +298,7 @@ class Page { return id } - get parentProduct(): any { + get parentProduct(): Product | undefined { const id = this.parentProductId return id ? productMap[id] : undefined } diff --git a/src/github-apps/lib/index.ts b/src/github-apps/lib/index.ts index afb258d72e14..a2b4f8ea0f00 100644 --- a/src/github-apps/lib/index.ts +++ b/src/github-apps/lib/index.ts @@ -1,16 +1,19 @@ import path from 'path' import fs from 'fs' +import type { GetServerSidePropsContext } from 'next' import { readCompressedJsonFileFallback } from '@/frame/lib/read-json-file' import { getOpenApiVersion } from '@/versions/lib/all-versions' import { categoriesWithoutSubcategories } from '../../rest/lib/index' +import type { Context, ExtendedRequest } from '@/types' interface AppsConfig { pages: Record } -// Note: Using 'any' for AppsData to maintain compatibility with existing consumers that expect different shapes -type AppsData = any +// Per-page apps data shapes vary (enabled lists, permissions, etc.), so callers +// are expected to provide the concrete shape via the generic parameter. +type AppsData = Record const DEBUG = process.env.RUNNER_DEBUG === '1' || process.env.DEBUG === '1' const ENABLED_APPS_DIR = 'src/github-apps/data' @@ -25,11 +28,11 @@ for (const pageType of Object.keys(appsDataConfig.pages)) { githubAppsData.set(pageType, new Map()) } -export async function getAppsData( +export async function getAppsData( pageType: string, docsVersion: string, apiVersion?: string, -): Promise { +): Promise { if (DEBUG) { console.log( `[DEBUG] getAppsData: ROOT=${process.env.ROOT || '(not set)'}, path=${ENABLED_APPS_DIR}`, @@ -43,39 +46,45 @@ export async function getAppsData( // The `readCompressedJsonFileFallback()` function // will check for both a .br and .json extension. const appDataPath = path.join(ENABLED_APPS_DIR, openApiVersion, filename) - const data = readCompressedJsonFileFallback(appDataPath) + const data = readCompressedJsonFileFallback(appDataPath) as AppsData pageTypeMap.set(openApiVersion, data) } - return pageTypeMap.get(openApiVersion)! + return pageTypeMap.get(openApiVersion)! as T } +type AppsItemWithDisplayTitle = { displayTitle?: string } + export async function getAppsServerSideProps( - context: any, + context: GetServerSidePropsContext, pageType: string, { useDisplayTitle = false }: { useDisplayTitle?: boolean }, ): Promise<{ currentVersion: string - appsItems: AppsData + appsItems: unknown categoriesWithoutSubcategories: string[] }> { const { getAutomatedPageMiniTocItems } = await import('@/frame/lib/get-mini-toc-items') const { getAutomatedPageContextFromRequest } = await import('@/automated-pipelines/components/AutomatedPageContext') - const currentVersion: string = context.query.versionId - const allVersions = context.req.context.allVersions - const queryApiVersion: string = context.query.apiVersion + const req = context.req as unknown as ExtendedRequest + const currentVersion = context.query.versionId as string + const allVersions = req.context!.allVersions! + const queryApiVersion = context.query.apiVersion as string const apiVersion: string = allVersions[currentVersion].apiVersions.includes(queryApiVersion) ? queryApiVersion : allVersions[currentVersion].latestApiVersion const appsItems: AppsData = await getAppsData(pageType, currentVersion, apiVersion) // Create minitoc - const { miniTocItems } = getAutomatedPageContextFromRequest(context.req) + const { miniTocItems } = getAutomatedPageContextFromRequest(req) const titles: string[] = useDisplayTitle - ? Object.values(appsItems).map((item: any) => item.displayTitle!) + ? Object.values(appsItems).map((item) => (item as AppsItemWithDisplayTitle).displayTitle!) : Object.keys(appsItems) - const appMiniToc = await getAutomatedPageMiniTocItems(titles, context) + // Note: getAutomatedPageMiniTocItems expects a `Context`, but this code path + // historically passed Next.js's GetServerSidePropsContext at runtime. Keep + // that runtime behavior but document the divergence via the assertion below. + const appMiniToc = await getAutomatedPageMiniTocItems(titles, context as unknown as Context) if (appMiniToc) { miniTocItems.push(...appMiniToc) } diff --git a/src/github-apps/pages/endpoints-available-for-fine-grained-personal-access-tokens.tsx b/src/github-apps/pages/endpoints-available-for-fine-grained-personal-access-tokens.tsx index 7ac81235628c..4ed5f5886956 100644 --- a/src/github-apps/pages/endpoints-available-for-fine-grained-personal-access-tokens.tsx +++ b/src/github-apps/pages/endpoints-available-for-fine-grained-personal-access-tokens.tsx @@ -43,7 +43,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => props: { mainContext: await getMainContext(context.req, context.res), currentVersion, - appsItems, + appsItems: appsItems as EnabledListT, automatedPageContext: getAutomatedPageContextFromRequest(context.req), categoriesWithoutSubcategories, }, diff --git a/src/github-apps/pages/endpoints-available-for-github-app-installation-access-tokens.tsx b/src/github-apps/pages/endpoints-available-for-github-app-installation-access-tokens.tsx index 03e9a2c225e6..3ac0fccc0f76 100644 --- a/src/github-apps/pages/endpoints-available-for-github-app-installation-access-tokens.tsx +++ b/src/github-apps/pages/endpoints-available-for-github-app-installation-access-tokens.tsx @@ -43,7 +43,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => props: { mainContext: await getMainContext(context.req, context.res), currentVersion, - appsItems, + appsItems: appsItems as EnabledListT, automatedPageContext: getAutomatedPageContextFromRequest(context.req), categoriesWithoutSubcategories, }, diff --git a/src/github-apps/pages/endpoints-available-for-github-app-user-access-tokens.tsx b/src/github-apps/pages/endpoints-available-for-github-app-user-access-tokens.tsx index f9ba0047e49c..4f45615698b8 100644 --- a/src/github-apps/pages/endpoints-available-for-github-app-user-access-tokens.tsx +++ b/src/github-apps/pages/endpoints-available-for-github-app-user-access-tokens.tsx @@ -43,7 +43,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => props: { mainContext: await getMainContext(context.req, context.res), currentVersion, - appsItems, + appsItems: appsItems as EnabledListT, automatedPageContext: getAutomatedPageContextFromRequest(context.req), categoriesWithoutSubcategories, }, diff --git a/src/github-apps/pages/permissions-required-for-fine-grained-personal-access-tokens.tsx b/src/github-apps/pages/permissions-required-for-fine-grained-personal-access-tokens.tsx index 8ede643f192c..cd84db30b503 100644 --- a/src/github-apps/pages/permissions-required-for-fine-grained-personal-access-tokens.tsx +++ b/src/github-apps/pages/permissions-required-for-fine-grained-personal-access-tokens.tsx @@ -44,7 +44,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => props: { mainContext: await getMainContext(context.req, context.res), currentVersion, - appsItems, + appsItems: appsItems as PermissionListT, automatedPageContext: getAutomatedPageContextFromRequest(context.req), categoriesWithoutSubcategories, }, diff --git a/src/github-apps/pages/permissions-required-for-github-apps.tsx b/src/github-apps/pages/permissions-required-for-github-apps.tsx index 13c0c19925ff..583a234b7a5a 100644 --- a/src/github-apps/pages/permissions-required-for-github-apps.tsx +++ b/src/github-apps/pages/permissions-required-for-github-apps.tsx @@ -44,7 +44,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => props: { mainContext: await getMainContext(context.req, context.res), currentVersion, - appsItems, + appsItems: appsItems as PermissionListT, automatedPageContext: getAutomatedPageContextFromRequest(context.req), categoriesWithoutSubcategories, }, diff --git a/src/landings/pages/home.tsx b/src/landings/pages/home.tsx index f3ccf36fe38f..ee1c8af94287 100644 --- a/src/landings/pages/home.tsx +++ b/src/landings/pages/home.tsx @@ -1,5 +1,6 @@ import React from 'react' import type { GetServerSideProps } from 'next' +import type { Response } from 'express' import { MainContextT, @@ -14,6 +15,7 @@ import { ArticleList } from '@/landings/components/ArticleList' import { HomePageHero } from '@/landings/components/HomePageHero' import type { ProductGroupT } from '@/landings/components/ProductSelections' import { ProductSelections } from '@/landings/components/ProductSelections' +import type { ExtendedRequest, FeaturedLinkExpanded } from '@/types' type FeaturedLink = { href: string @@ -78,8 +80,8 @@ function HomePage(props: HomePageProps) { } export const getServerSideProps: GetServerSideProps = async (context) => { - const req = context.req as any - const res = context.res as any + const req = context.req as unknown as ExtendedRequest + const res = context.res as unknown as Response const mainContext = await getMainContext(req, res) addUINamespaces(req, mainContext.data.ui, ['homepage', 'product_landing']) @@ -87,15 +89,13 @@ export const getServerSideProps: GetServerSideProps = async (context) => return { props: { mainContext, - productGroups: req.context.productGroups, - gettingStartedLinks: req.context.featuredLinks.gettingStarted.map( - ({ title, href, intro }: any) => ({ title, href, intro }), + productGroups: (req.context!.productGroups || []) as unknown as ProductGroupT[], + gettingStartedLinks: (req.context!.featuredLinks?.gettingStarted || []).map( + ({ title, href, intro }: FeaturedLinkExpanded) => ({ title, href, intro: intro || '' }), + ), + popularLinks: (req.context!.featuredLinks?.popular || []).map( + ({ title, href, intro }: FeaturedLinkExpanded) => ({ title, href, intro: intro || '' }), ), - popularLinks: req.context.featuredLinks.popular.map(({ title, href, intro }: any) => ({ - title, - href, - intro, - })), }, } } diff --git a/src/links/scripts/update-internal-links.ts b/src/links/scripts/update-internal-links.ts index 164cf2400cbc..f6c595508cfb 100755 --- a/src/links/scripts/update-internal-links.ts +++ b/src/links/scripts/update-internal-links.ts @@ -207,18 +207,18 @@ async function main(files: string[], opts: Options) { } else if (opts.check) { console.log(chalk.green('No changes needed or necessary. 🌈')) } - } catch (err: any) { + } catch (err) { if (debug) { throw err } - console.error(chalk.red(err.toString())) + console.error(chalk.red(err instanceof Error ? err.toString() : String(err))) process.exit(1) } } function printObjectDifference( - objFrom: Record, - objTo: Record, + objFrom: Record, + objTo: Record, rawContent: string, parentKey = '', ) { @@ -226,94 +226,109 @@ function printObjectDifference( // an array, and it's different, print that difference. for (const [key, value] of Object.entries(objFrom)) { const combinedKey = `${parentKey}.${key}` - if (Array.isArray(value) && !equalArray(value, objTo[key])) { - const printedKeys = new Set() + const otherValue = objTo[key] + if (Array.isArray(value) && Array.isArray(otherValue) && !equalArray(value, otherValue)) { + const printedKeys = new Set() for (let i = 0; i < value.length; i++) { const entry = value[i] + const otherEntry = otherValue[i] // If it was an array of objects, we need to go deeper! - if (isObject(entry)) { - printObjectDifference(entry, objTo[key][i], rawContent, combinedKey) + if (isObject(entry) && isObject(otherEntry)) { + printObjectDifference(entry, otherEntry, rawContent, combinedKey) } else { - if (entry !== objTo[key][i]) { + if (entry !== otherEntry) { if (!printedKeys.has(combinedKey)) { console.log(`In frontmatter key: ${chalk.bold(combinedKey)}`) printedKeys.add(combinedKey) } console.log(chalk.red(`- ${entry}`)) - console.log(chalk.green(`+ ${objTo[key][i]}`)) + console.log(chalk.green(`+ ${otherEntry}`)) const needle = new RegExp(`- ${entry}\\b`) const index = rawContent.split(/\n/g).findIndex((line) => needle.test(line)) console.log(' ', chalk.dim(`line ${(index && index + 1) || 'unknown'}`)) } } } - } else if (typeof value === 'object' && value !== null) { - printObjectDifference(value, objTo[key], rawContent, combinedKey) + } else if (isObject(value) && isObject(otherValue)) { + printObjectDifference(value, otherValue, rawContent, combinedKey) } } } // This assumes them to be the same shape with possibly different node values -function equalObject(obj1: Record, obj2: Record) { +function equalObject(obj1: Record, obj2: Record) { if (!equalSet(new Set(Object.keys(obj1)), new Set(Object.keys(obj2)))) { return false } for (const [key, value] of Object.entries(obj1)) { + const otherValue = obj2[key] if (Array.isArray(value)) { + if (!Array.isArray(otherValue)) return false // Can't easily compare two arrays because the entries might be objects. - if (value.length !== obj2[key].length) return false + if (value.length !== otherValue.length) return false let i = 0 for (const each of value) { - if (isObject(each)) { - if (!equalObject(each, obj2[key][i])) { + const otherEach = otherValue[i] + if (isObject(each) && isObject(otherEach)) { + if (!equalObject(each, otherEach)) { return false } } else { - if (each !== obj2[key][i]) { + if (each !== otherEach) { return false } } i++ } } else if (isObject(value)) { - if (!equalObject(value, obj2[key])) { + if (!isObject(otherValue) || !equalObject(value, otherValue)) { return false } - } else if (value !== obj2[key]) { + } else if (value !== otherValue) { return false } } return true } -function isObject(thing: any) { +function isObject(thing: unknown): thing is Record { return typeof thing === 'object' && thing !== null && !Array.isArray(thing) } -function equalSet(set1: Set, set2: Set) { +function equalSet(set1: Set, set2: Set) { return set1.size === set2.size && [...set1].every((x) => set2.has(x)) } -function equalArray(arr1: any[], arr2: any[]) { +function equalArray(arr1: unknown[], arr2: unknown[]) { return arr1.length === arr2.length && arr1.every((item, i) => item === arr2[i]) } -function countByTree( - results: { - data: { - [key: string]: any - } - content: string - rawContent: string - newContent: string - replacements: any[] - warnings: any[] - newData: { - [key: string]: any - } - file: string - }[], -) { +type Replacement = { + asMarkdown: string + newAsMarkdown: string + line: number + column: number +} + +type Warning = { + warning: string + asMarkdown: string + line: number + column: number +} + +type UpdateResult = { + data: Record + content: string + rawContent: string + newContent: string + replacements: Replacement[] + warnings: Warning[] + newData: Record + file: string +} + +function countByTree(results: UpdateResult[]) { const files: Record = {} const changes: Record = {} for (const { file, replacements } of results) { diff --git a/src/tests/helpers/e2etest.ts b/src/tests/helpers/e2etest.ts index 85f66ad70412..db21f2d8c160 100644 --- a/src/tests/helpers/e2etest.ts +++ b/src/tests/helpers/e2etest.ts @@ -5,13 +5,13 @@ import { omitBy, isUndefined } from 'lodash-es' type ResponseTypes = 'buffer' | 'json' | 'text' type ResponseTypeMap = { buffer: ArrayBuffer - json: any + json: unknown text: string } interface GetOptions { method?: string - body?: any + body?: RequestInit['body'] followRedirects?: boolean followAllRedirects?: boolean headers?: Record @@ -191,7 +191,7 @@ export async function getDOM(route: string, options: GetDOMOptions = {}): Promis * @param opts - Options for the request. * @returns A promise that resolves to the parsed JSON object. */ -export async function getJSON( +export async function getJSON( route: string, opts: Omit = {}, ): Promise { From 22df14d99bdb424b31191be6e18ce187c0004bdc Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Tue, 5 May 2026 16:33:44 -0700 Subject: [PATCH 08/13] =?UTF-8?q?=F0=9F=A7=B9=20Remove=20product-landing?= =?UTF-8?q?=20layout=20code=20(#61036)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/test.yml | 1 - content/README.md | 3 +- content/account-and-profile/index.md | 5 - content/actions/index.md | 2 - content/admin/index.md | 2 - content/apps/index.md | 2 - content/authentication/index.md | 2 - content/billing/index.md | 2 - content/code-security/index.md | 5 - content/codespaces/index.md | 2 - content/communities/index.md | 2 - content/contributing/index.md | 2 - .../using-yaml-frontmatter.md | 3 +- content/copilot/index.md | 2 - content/desktop/index.md | 4 - content/discussions/index.md | 2 - content/education/index.md | 2 - content/github-cli/index.md | 2 - content/graphql/index.md | 2 - content/issues/index.md | 1 - content/nonprofit/index.md | 2 - content/packages/index.md | 3 - content/pages/index.md | 2 - content/pull-requests/index.md | 2 - content/rest/index.md | 2 - content/search-github/index.md | 2 - content/sponsors/index.md | 2 - .../subscriptions-and-notifications/index.md | 2 - content/webhooks/index.md | 2 - contributing/translations-for-translators.md | 1 - data/product-examples/README.md | 44 --- .../discussions/community-examples.yml | 37 --- .../sponsors/user-examples.yml | 19 -- eslint.config.ts | 2 - package-lock.json | 34 --- package.json | 3 - .../tests/product-landing-transformer.ts | 42 --- src/article-api/transformers/index.ts | 2 - .../product-landing-transformer.ts | 280 ------------------ src/changelogs/README.md | 67 ----- src/changelogs/lib/changelog.ts | 141 --------- src/changelogs/tests/get-rss-feeds.ts | 70 ----- .../tests/fixtures/actions/index.md | 2 +- .../tests/fixtures/early-access/index.md | 2 +- .../landing-carousels/duplicate-carousels.md | 2 +- .../duplicate-recommended.md | 2 +- .../landing-carousels/invalid-paths.md | 2 +- .../landing-carousels/no-carousels.md | 2 +- .../landing-carousels/no-recommended.md | 2 +- .../landing-carousels/test-absolute-only.md | 2 +- .../test-absolute-priority.md | 2 +- .../landing-carousels/test-path-priority.md | 2 +- .../test-priority-validation.md | 2 +- .../landing-carousels/valid-landing.md | 2 +- src/data-directory/README.md | 2 +- src/data-directory/lib/get-data.ts | 2 +- src/fixtures/fixtures/changelog-feed.json | 1 - .../fixtures/content/actions/index.md | 4 +- src/fixtures/fixtures/content/admin/index.md | 4 +- .../fixtures/content/authentication/index.md | 4 +- .../fixtures/content/code-security/index.md | 2 +- .../fixtures/content/get-started/index.md | 2 +- .../fixtures/content/organizations/index.md | 2 +- src/fixtures/fixtures/content/pages/index.md | 2 +- src/fixtures/fixtures/content/rest/index.md | 4 +- .../fixtures/content/webhooks/index.md | 4 +- src/fixtures/fixtures/rss-feed.xml | 103 ------- src/fixtures/tests/landing-hero.ts | 14 - src/fixtures/tests/playwright-a11y.spec.ts | 2 +- .../context/CategoryLandingContext.tsx | 4 +- src/frame/components/context/MainContext.tsx | 4 +- .../components/context/TocLandingContext.tsx | 4 +- src/frame/lib/frontmatter.ts | 7 +- .../middleware/context/product-examples.ts | 52 ---- .../middleware/context/whats-new-changelog.ts | 39 --- src/frame/middleware/index.ts | 4 - src/landings/README.md | 8 +- src/landings/components/ArticleList.tsx | 2 +- src/landings/components/CommunityExamples.tsx | 24 -- src/landings/components/FeaturedArticles.tsx | 50 ---- src/landings/components/GuideCard.tsx | 32 -- src/landings/components/GuideCards.tsx | 40 --- src/landings/components/LandingHero.tsx | 84 ------ .../ProductArticlesList.module.scss | 15 - .../components/ProductArticlesList.tsx | 57 ---- .../components/ProductGuidesContext.tsx | 20 -- src/landings/components/ProductLanding.tsx | 76 ----- .../components/ProductLandingContext.tsx | 191 ------------ src/landings/components/ProductReleases.tsx | 81 ----- src/landings/components/RepoCard.tsx | 34 --- src/landings/components/SponsorsExamples.tsx | 24 -- src/landings/components/UserCard.tsx | 34 --- .../components/discovery/DiscoveryLanding.tsx | 5 + .../shared/LandingArticleGridWithFilter.tsx | 1 + src/landings/context/LandingContext.tsx | 5 +- src/landings/lib/featured-links.ts | 36 +++ src/landings/middleware/featured-links.ts | 17 +- src/landings/pages/product.tsx | 18 -- src/landings/tests/featured-links.ts | 18 +- src/landings/types.ts | 9 + src/tests/README.md | 1 - src/types/types.ts | 15 - 102 files changed, 104 insertions(+), 1892 deletions(-) delete mode 100644 data/product-examples/README.md delete mode 100644 data/product-examples/discussions/community-examples.yml delete mode 100644 data/product-examples/sponsors/user-examples.yml delete mode 100644 src/article-api/tests/product-landing-transformer.ts delete mode 100644 src/article-api/transformers/product-landing-transformer.ts delete mode 100644 src/changelogs/README.md delete mode 100644 src/changelogs/lib/changelog.ts delete mode 100644 src/changelogs/tests/get-rss-feeds.ts delete mode 100644 src/fixtures/fixtures/changelog-feed.json delete mode 100644 src/fixtures/fixtures/rss-feed.xml delete mode 100644 src/frame/middleware/context/product-examples.ts delete mode 100644 src/frame/middleware/context/whats-new-changelog.ts delete mode 100644 src/landings/components/CommunityExamples.tsx delete mode 100644 src/landings/components/FeaturedArticles.tsx delete mode 100644 src/landings/components/GuideCard.tsx delete mode 100644 src/landings/components/GuideCards.tsx delete mode 100644 src/landings/components/LandingHero.tsx delete mode 100644 src/landings/components/ProductArticlesList.module.scss delete mode 100644 src/landings/components/ProductArticlesList.tsx delete mode 100644 src/landings/components/ProductGuidesContext.tsx delete mode 100644 src/landings/components/ProductLanding.tsx delete mode 100644 src/landings/components/ProductLandingContext.tsx delete mode 100644 src/landings/components/ProductReleases.tsx delete mode 100644 src/landings/components/RepoCard.tsx delete mode 100644 src/landings/components/SponsorsExamples.tsx delete mode 100644 src/landings/components/UserCard.tsx create mode 100644 src/landings/lib/featured-links.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f337044a2876..289061169169 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,7 +42,6 @@ jobs: - audit-logs - automated-pipelines # - bookmarklets - - changelogs # - code-scanning # - codeql-cli - color-schemes diff --git a/content/README.md b/content/README.md index 5d8a363af188..e158ddcba32f 100644 --- a/content/README.md +++ b/content/README.md @@ -149,8 +149,7 @@ shortTitle: Contributing to projects ### `layout` - Purpose: Render the proper page layout. -- Type: `String` that matches the name of the layout. -For a layout named `components/landing`, the value would be `product-landing`. +- Type: `String` that matches the name of a supported layout. See `layoutNames` in `src/frame/lib/frontmatter.ts` for the authoritative list (for example, `discovery-landing`, `journey-landing`, `bespoke-landing`, `category-landing`, `toc-landing`, `inline`). - Optional. If omitted, `DefaultLayout` is used. ### `children` diff --git a/content/account-and-profile/index.md b/content/account-and-profile/index.md index bd00edfbb808..fbd7eb394c96 100644 --- a/content/account-and-profile/index.md +++ b/content/account-and-profile/index.md @@ -6,11 +6,6 @@ introLinks: quickstart: /account-and-profile/get-started/account overview: /account-and-profile/get-started/profile layout: discovery-landing -changelog: - label: profiles, github-themes - versions: - fpt: '*' - ghec: '*' versions: fpt: '*' ghes: '*' diff --git a/content/actions/index.md b/content/actions/index.md index 208c69015731..20ace6c5313e 100644 --- a/content/actions/index.md +++ b/content/actions/index.md @@ -5,8 +5,6 @@ intro: 'Automate, customize, and execute your software development workflows rig introLinks: overview: /actions/get-started/understand-github-actions quickstart: /actions/get-started/quickstart -changelog: - label: actions redirect_from: - /articles/automating-your-workflow-with-github-actions - /articles/customizing-your-project-with-github-actions diff --git a/content/admin/index.md b/content/admin/index.md index 3a56f4103fc1..1c7550056be5 100644 --- a/content/admin/index.md +++ b/content/admin/index.md @@ -64,8 +64,6 @@ redirect_from: - /insights/installing-and-configuring-github-insights/managing-data-in-github-insights/managing-repositories - /admin/configuration/configuring-your-enterprise/configuring-data-encryption-for-your-enterprise - /admin/guides -changelog: - label: enterprise layout: discovery-landing includedCategories: - Get started with GitHub Enterprise diff --git a/content/apps/index.md b/content/apps/index.md index 95e7a018addb..d9ad169da59e 100644 --- a/content/apps/index.md +++ b/content/apps/index.md @@ -17,8 +17,6 @@ carousels: - /apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps - /apps/creating-github-apps/writing-code-for-a-github-app/building-a-github-app-that-responds-to-webhook-events - /apps/creating-github-apps/about-creating-github-apps/best-practices-for-creating-a-github-app -changelog: - label: apps versions: fpt: '*' ghes: '*' diff --git a/content/authentication/index.md b/content/authentication/index.md index 8314aa0e5e7e..bd42d9015330 100644 --- a/content/authentication/index.md +++ b/content/authentication/index.md @@ -20,8 +20,6 @@ versions: ghec: '*' introLinks: overview: /authentication/keeping-your-account-and-data-secure/about-authentication-to-github -changelog: - label: '2FA,authentication,security keys,SSH,token authentication' layout: discovery-landing carousels: recommended: diff --git a/content/billing/index.md b/content/billing/index.md index dac2d02f85a9..a1c6317b1cc2 100644 --- a/content/billing/index.md +++ b/content/billing/index.md @@ -7,8 +7,6 @@ redirect_from: - /categories/setting-up-and-managing-billing-and-payments-on-github introLinks: overview: '{% ifversion fpt or ghec %}/billing/get-started/how-billing-works {% elsif ghes %}/billing/concepts/enterprise-billing/billing-for-enterprises{% endif %}' -changelog: - label: account-management layout: discovery-landing includedCategories: - 'Get started with billing' diff --git a/content/code-security/index.md b/content/code-security/index.md index 7f7148b33b32..b6d94975348e 100644 --- a/content/code-security/index.md +++ b/content/code-security/index.md @@ -7,11 +7,6 @@ redirect_from: introLinks: overview: '{% ifversion ghes %}/code-security/getting-started/github-security-features{% endif %}' generate_secret_risk_assessment_report_for_free: '{% ifversion secret-risk-assessment %}https://github.com/get_started?with=risk-assessment{% endif %}' -changelog: - label: security-and-compliance - versions: - fpt: '*' - ghec: '*' layout: discovery-landing contentType: landing includedCategories: diff --git a/content/codespaces/index.md b/content/codespaces/index.md index 698c9987f370..242cc36762db 100644 --- a/content/codespaces/index.md +++ b/content/codespaces/index.md @@ -28,8 +28,6 @@ carousels: - /codespaces/developing-in-a-codespace/using-source-control-in-your-codespace - /codespaces/managing-codespaces-for-your-organization/enabling-or-disabling-github-codespaces-for-your-organization - /codespaces/reference/security-in-github-codespaces -changelog: - label: codespaces communityRedirect: name: Provide GitHub Feedback href: 'https://github.com/orgs/community/discussions/categories/codespaces' diff --git a/content/communities/index.md b/content/communities/index.md index f58231ab31d5..18b4f78e46c0 100644 --- a/content/communities/index.md +++ b/content/communities/index.md @@ -5,8 +5,6 @@ intro: "Learn best practices for moderating and setting up collaborative, safe, redirect_from: - /categories/building-a-strong-community - /github/building-a-strong-community -changelog: - label: wikis layout: discovery-landing introLinks: overview: /communities/setting-up-your-project-for-healthy-contributions/about-community-management-and-moderation diff --git a/content/contributing/index.md b/content/contributing/index.md index 91632945da15..e9233731b522 100644 --- a/content/contributing/index.md +++ b/content/contributing/index.md @@ -5,8 +5,6 @@ intro: 'Learn about how the {% data variables.product.prodname_docs %} team crea introLinks: overview: /contributing/collaborating-on-github-docs/about-contributing-to-github-docs quickstart: /contributing/writing-for-github-docs/best-practices-for-github-docs -changelog: - label: docs layout: discovery-landing includedCategories: - Understand the GitHub approach to docs diff --git a/content/contributing/writing-for-github-docs/using-yaml-frontmatter.md b/content/contributing/writing-for-github-docs/using-yaml-frontmatter.md index 40b060957ad9..4d53c34c0e84 100644 --- a/content/contributing/writing-for-github-docs/using-yaml-frontmatter.md +++ b/content/contributing/writing-for-github-docs/using-yaml-frontmatter.md @@ -145,8 +145,7 @@ shortTitle: Contributing to projects ### `layout` * Purpose: Render the proper page layout. -* Type: `String` that matches the name of the layout. -For a layout named `components/landing`, the value would be `product-landing`. +* Type: `String` that matches the name of a supported layout. See `layoutNames` in `src/frame/lib/frontmatter.ts` for the authoritative list (for example, `discovery-landing`, `journey-landing`, `bespoke-landing`, `category-landing`, `toc-landing`, `inline`). * Optional. If omitted, `DefaultLayout` is used. ### `children` diff --git a/content/copilot/index.md b/content/copilot/index.md index 3cc07776c593..0caf34eccd6d 100644 --- a/content/copilot/index.md +++ b/content/copilot/index.md @@ -5,8 +5,6 @@ intro: 'You can use {% data variables.product.prodname_copilot %} to enhance you redirect_from: - /github/copilot - /copilot/using-github-copilot/using-github-copilot-for-pull-requests/using-copilot-to-help-you-work-on-a-pull-request -changelog: - label: copilot introLinks: overview: /copilot/get-started/what-is-github-copilot quickstart: /copilot/get-started/quickstart diff --git a/content/desktop/index.md b/content/desktop/index.md index df36a2fd3b5f..07b5753e5775 100644 --- a/content/desktop/index.md +++ b/content/desktop/index.md @@ -22,10 +22,6 @@ carousels: - /desktop/making-changes-in-a-branch/pushing-changes-to-github-from-github-desktop - /desktop/working-with-your-remote-repository-on-github-or-github-enterprise/creating-an-issue-or-pull-request-from-github-desktop - /desktop/managing-commits/options-for-managing-commits-in-github-desktop -changelog: - label: desktop - versions: - feature: desktop layout: discovery-landing versions: feature: desktop diff --git a/content/discussions/index.md b/content/discussions/index.md index 3757af3d53ca..898db9820c58 100644 --- a/content/discussions/index.md +++ b/content/discussions/index.md @@ -14,8 +14,6 @@ redirect_from: - /rest/teams/discussion-comments - /rest/teams/discussions - /rest/repos/discussions -changelog: - label: discussions layout: discovery-landing includedCategories: - Participate in discussions diff --git a/content/education/index.md b/content/education/index.md index 55ee2d06c2dc..3fe3ad721504 100644 --- a/content/education/index.md +++ b/content/education/index.md @@ -8,8 +8,6 @@ redirect_from: - /education/explore-internship-projects-with-github-octernships/about-github-octernships - /education/explore-internship-projects-with-github-octernships/applying-for-github-octernships - /education/explore-internship-projects-with-github-octernships -changelog: - label: education layout: discovery-landing includedCategories: - Apply for GitHub Education diff --git a/content/github-cli/index.md b/content/github-cli/index.md index ccaf59f07c2c..5a2375510a73 100644 --- a/content/github-cli/index.md +++ b/content/github-cli/index.md @@ -5,8 +5,6 @@ intro: '{% data reusables.cli.about-cli %}' introLinks: overview: /github-cli/github-cli/about-github-cli quickstart: /github-cli/github-cli/quickstart -changelog: - label: cli layout: discovery-landing includedCategories: - Learn the basics diff --git a/content/graphql/index.md b/content/graphql/index.md index f4487a46b13d..4f59e9eeee93 100644 --- a/content/graphql/index.md +++ b/content/graphql/index.md @@ -5,8 +5,6 @@ shortTitle: GraphQL API introLinks: overview: /graphql/overview/about-the-graphql-api quickstart: /graphql/guides/forming-calls-with-graphql -changelog: - label: 'api, apis' layout: discovery-landing redirect_from: - /v4 diff --git a/content/issues/index.md b/content/issues/index.md index b4848a6be389..4611a87f5844 100644 --- a/content/issues/index.md +++ b/content/issues/index.md @@ -25,7 +25,6 @@ carousels: - /issues/planning-and-tracking-with-projects/automating-your-project/using-the-built-in-automations - /issues/tracking-your-work-with-issues/administering-issues/triaging-an-issue-with-ai layout: discovery-landing -beta_product: false versions: fpt: '*' ghes: '*' diff --git a/content/nonprofit/index.md b/content/nonprofit/index.md index 51c2951a876f..2e5436185d0f 100644 --- a/content/nonprofit/index.md +++ b/content/nonprofit/index.md @@ -6,8 +6,6 @@ introLinks: quickstart: /nonprofit/quickstart redirect_from: - /billing/managing-the-plan-for-your-github-account/discounted-plans-for-github-accounts.md -changelog: - label: nonprofit layout: discovery-landing includedCategories: - Apply for nonprofit benefits diff --git a/content/packages/index.md b/content/packages/index.md index d965789afc7b..12407d2d5043 100644 --- a/content/packages/index.md +++ b/content/packages/index.md @@ -20,9 +20,6 @@ carousels: - /packages/working-with-a-github-packages-registry/working-with-the-container-registry - /packages/working-with-a-github-packages-registry/working-with-the-npm-registry - /packages/learn-github-packages/configuring-a-packages-access-control-and-visibility -changelog: - label: packages - prefix: 'Packages: ' redirect_from: - /github/managing-packages-with-github-packages - /categories/managing-packages-with-github-package-registry diff --git a/content/pages/index.md b/content/pages/index.md index 0077819f03b9..22978eb83830 100644 --- a/content/pages/index.md +++ b/content/pages/index.md @@ -5,8 +5,6 @@ intro: '{% data variables.product.prodname_pages %} turns any {% data variables. introLinks: quickstart: /pages/quickstart overview: /pages/getting-started-with-github-pages/what-is-github-pages -changelog: - label: pages layout: discovery-landing includedCategories: - Learn about GitHub Pages diff --git a/content/pull-requests/index.md b/content/pull-requests/index.md index 934e0217c934..f29a33b89b91 100644 --- a/content/pull-requests/index.md +++ b/content/pull-requests/index.md @@ -3,8 +3,6 @@ title: Pull requests documentation intro: 'Learn how to use pull requests to suggest changes to a project, receive suggested changes to your own projects, and address issues in pull requests, such as merge conflicts.' introLinks: overview: /pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests -changelog: - label: pull-requests layout: discovery-landing carousels: recommended: diff --git a/content/rest/index.md b/content/rest/index.md index ef968e86617d..019daa3d7699 100644 --- a/content/rest/index.md +++ b/content/rest/index.md @@ -7,8 +7,6 @@ intro: >- introLinks: overview: /rest/about-the-rest-api/about-the-rest-api quickstart: /rest/quickstart -changelog: - label: api, apis layout: discovery-landing includedCategories: - Learn about the REST API diff --git a/content/search-github/index.md b/content/search-github/index.md index 29dea111e726..0a15bf13fc4c 100644 --- a/content/search-github/index.md +++ b/content/search-github/index.md @@ -3,8 +3,6 @@ title: Search on GitHub documentation intro: 'Learn how to use the search functions available on GitHub to find different types of information, like projects, people, and code.' introLinks: overview: /search-github/getting-started-with-searching-on-github/about-searching-on-github -changelog: - label: search layout: discovery-landing includedCategories: - Get started with search diff --git a/content/sponsors/index.md b/content/sponsors/index.md index 01ce11604bb6..8ccfe7fef5e0 100644 --- a/content/sponsors/index.md +++ b/content/sponsors/index.md @@ -9,8 +9,6 @@ redirect_from: - /categories/supporting-the-open-source-community-with-github-sponsors - /github/supporting-the-open-source-community-with-github-sponsors - /sponsors/guides -changelog: - label: sponsors layout: discovery-landing contentType: landing versions: diff --git a/content/subscriptions-and-notifications/index.md b/content/subscriptions-and-notifications/index.md index d8ef25c0e18d..d093c64ae7e6 100644 --- a/content/subscriptions-and-notifications/index.md +++ b/content/subscriptions-and-notifications/index.md @@ -10,8 +10,6 @@ redirect_from: introLinks: overview: /subscriptions-and-notifications/concepts/about-notifications quickstart: /subscriptions-and-notifications/get-started/configuring-notifications -changelog: - label: notifications layout: discovery-landing includedCategories: - Understand notifications diff --git a/content/webhooks/index.md b/content/webhooks/index.md index f7fc4af5fd40..06470027066f 100644 --- a/content/webhooks/index.md +++ b/content/webhooks/index.md @@ -15,8 +15,6 @@ children: - /webhook-events-and-payloads - /using-webhooks - /testing-and-troubleshooting-webhooks -changelog: - label: webhooks layout: discovery-landing redirect_from: - /developers/webhooks-and-events diff --git a/contributing/translations-for-translators.md b/contributing/translations-for-translators.md index b0f2e26f6414..4982f7726386 100644 --- a/contributing/translations-for-translators.md +++ b/contributing/translations-for-translators.md @@ -8,7 +8,6 @@ We only translate: - `/data/reusables` - `/data/variables` - **except** `/data/variables/product.yml` - `/data/glossaries/external.yml` -- `/data/product-examples` ## Translation guidelines diff --git a/data/product-examples/README.md b/data/product-examples/README.md deleted file mode 100644 index c9bb346b96f8..000000000000 --- a/data/product-examples/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# Product landing examples - -Pages that use the `product-landing` layout may optionally include an `Examples` section. Currently, we support three types of examples: - -1. Community examples - See https://docs.github.com/en/discussions#community-examples. - -1. User examples - See https://docs.github.com/en/sponsors#community-examples. - -## How it works - -Example data for each product is defined in `data/product-landing-examples`, in a subdirectory named for the **product** and a YML file named for the **example type** (e.g., `data/product-examples/sponsors/user-examples.yml` or `data/product-examples/discussions/community-examples.yml`). We currently only support one type of example per product. - -### Versioning - -At the moment, versioning is only supported in code examples. If an example block should be available in **all** versions, you don't need to do anything special. But if an example block should only be available in some versions, you can add a `versions` prop like this: - -``` yaml -- title: Dependabot version update PR - description: >- - Example pull request generated by the Dependabot version - updates configuration in the Super linter repository. - href: /github/super-linter/pull/1398 - languages: - tags: - - Dependabot - - Version updates - - Pull requests - versions: - fpt: '*' -``` - -where the syntax for `versions` is the same as the [frontmatter `versions` property](/content/README.md) and can support semver notation. - -## Rendering - -The product example data is added to the `context` object in `src/frame/middleware/context/product-examples.ts`. - -The data is then rendered by `components/landing`. - -## Schema enforcement - -TODO diff --git a/data/product-examples/discussions/community-examples.yml b/data/product-examples/discussions/community-examples.yml deleted file mode 100644 index 1167ef1bdf6d..000000000000 --- a/data/product-examples/discussions/community-examples.yml +++ /dev/null @@ -1,37 +0,0 @@ -# Images and descriptions are pulled directly from the repo - -- repo: vercel/next.js - description: The React Framework - -- repo: gatsbyjs/gatsby - description: Build blazing fast, modern apps and websites with React - -- repo: nodejs/node - description: Node.js JavaScript runtime ✨🐢🚀✨ - -- repo: tailwindlabs/tailwindcss - description: A utility-first CSS framework for rapid UI development. - -- repo: laravel/framework - description: Laravel is a web application framework with expressive, elegant syntax. - -- repo: prisma/prisma - description: Modern database access (ORM alternative) for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB & SQLite - -- repo: dotnet/csharplang - description: The official repo for the design of the C# programming language - -- repo: home-assistant/frontend - description: 🍭 Frontend for Home Assistant - -- repo: jspsych/jsPsych - description: A JavaScript library for creating and running behavioral experiments in a web browser - -- repo: adonisjs/core - description: 🚀 The Node.js Framework highly focused on developer ergonomics, stability and confidence - -- repo: ImageMagick/ImageMagick - description: 🧙‍♂️ ImageMagick 7 - -- repo: react-hook-form/react-hook-form - description: 📋 React Hooks for forms validation (Web + React Native) diff --git a/data/product-examples/sponsors/user-examples.yml b/data/product-examples/sponsors/user-examples.yml deleted file mode 100644 index 6695ac0a588c..000000000000 --- a/data/product-examples/sponsors/user-examples.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Images and descriptions are pulled directly from the repo - -- user: chaynHQ - description: Chayn helps women experiencing abuse find the right information and support they need to take control of their lives. - -- user: foosel - description: 👋 I'm Gina, and I'm mostly known for being the creator and main developer of OctoPrint 🐙. - -- user: dayhaysoos - description: What's up? I'm Nick. I'm an engineer who has a new-found passion for removing friction from the e-commerce developer experience. - -- user: yyx990803 - description: I'm working fulltime on Vue.js, a frontend JavaScript framework for building web applications, and Vite, a modern web build tool. - -- user: calebporzio - description: 🚶‍♂️I left my day job in Jan 2019 to pursue open-source. Since then, I've built Laravel Livewire, AlpineJS, and a bunch of other stuff. - -- user: kjaymiller - description: Hi Y'all I'm Jay! 👋 I'm a Marine Corps Veteran turned developer that's been actively coding since 2014. I'm also involved in the productivity space where I can be found helping people with automations for some of their favorite apps and tools. diff --git a/eslint.config.ts b/eslint.config.ts index c76186489aa9..4c58be15aefa 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -176,7 +176,6 @@ export default [ 'src/ai-tools/**/*.{ts,js}', 'src/article-api/**/*.{ts,js}', 'src/audit-logs/**/*.{ts,js}', - 'src/changelogs/**/*.{ts,js}', 'src/color-schemes/**/*.{ts,js}', 'src/content-render/**/*.{ts,js}', 'src/data-directory/**/*.{ts,js}', @@ -252,7 +251,6 @@ export default [ 'src/graphql/scripts/utils/schema-helpers.ts', 'src/graphql/tests/validate-schema.ts', 'src/landings/components/CookBookFilter.tsx', - 'src/landings/components/ProductGuidesContext.tsx', 'src/landings/components/SidebarProduct.tsx', 'src/landings/pages/product.tsx', 'src/languages/lib/correct-translation-content.ts', diff --git a/package-lock.json b/package-lock.json index df746cb71c67..fdb6a59d8055 100644 --- a/package-lock.json +++ b/package-lock.json @@ -97,7 +97,6 @@ "remark-rehype": "^11.1.2", "remark-remove-comments": "^1.1.1", "remark-stringify": "^11.0.0", - "rss-parser": "^3.13.0", "scroll-anchoring": "^0.1.0", "semver": "^7.7.4", "sharp": "0.33.5", @@ -7591,13 +7590,6 @@ "version": "1.1.1", "license": "ISC" }, - "node_modules/entities": { - "version": "2.2.0", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", @@ -14600,14 +14592,6 @@ "node": ">= 18" } }, - "node_modules/rss-parser": { - "version": "3.13.0", - "license": "MIT", - "dependencies": { - "entities": "^2.0.3", - "xml2js": "^0.5.0" - } - }, "node_modules/run-applescript": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", @@ -17347,24 +17331,6 @@ "version": "1.0.2", "license": "ISC" }, - "node_modules/xml2js": { - "version": "0.5.0", - "license": "MIT", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index e952100abcb2..36e38b9f2710 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,6 @@ "sync-webhooks": "npx tsx src/rest/scripts/update-files.ts -o webhooks", "test": "vitest", "test:article-api": "cross-env ROOT=src/fixtures/fixtures TRANSLATIONS_FIXTURE_ROOT=src/fixtures/fixtures/translations npm test -- --no-file-parallelism --maxWorkers=1 src/article-api/tests/", - "test:changelogs": "cross-env CHANGELOG_CACHE_FILE_PATH=src/fixtures/fixtures/changelog-feed.json npm test -- src/changelogs/tests/", "test:fixtures": "cross-env ROOT=src/fixtures/fixtures TRANSLATIONS_FIXTURE_ROOT=src/fixtures/fixtures/translations npm test -- src/fixtures/tests/", "test:landings": "cross-env ROOT=src/fixtures/fixtures npm test -- src/landings/tests/", "test:languages": "cross-env ENABLED_LANGUAGES=all ELASTICSEARCH_URL=http://localhost:9200/ npm test -- src/languages/tests/", @@ -140,7 +139,6 @@ "data/reusables", "data/variables", "data/glossaries", - "data/product-examples", "rest-api-description", "semmle-code" ] @@ -257,7 +255,6 @@ "remark-rehype": "^11.1.2", "remark-remove-comments": "^1.1.1", "remark-stringify": "^11.0.0", - "rss-parser": "^3.13.0", "scroll-anchoring": "^0.1.0", "semver": "^7.7.4", "sharp": "0.33.5", diff --git a/src/article-api/tests/product-landing-transformer.ts b/src/article-api/tests/product-landing-transformer.ts deleted file mode 100644 index 93349c8807e3..000000000000 --- a/src/article-api/tests/product-landing-transformer.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { describe, expect, test } from 'vitest' - -import { get } from '@/tests/helpers/e2etest' - -const makeURL = (pathname: string): string => - `/api/article/body?${new URLSearchParams({ pathname })}` - -describe('product landing transformer', () => { - test('renders a product landing page with basic structure', async () => { - // /en/actions is a product landing page in fixtures - const res = await get(makeURL('/en/actions')) - expect(res.statusCode).toBe(200) - expect(res.headers['content-type']).toContain('text/markdown') - - // Check for title - expect(res.body).toContain('# GitHub Actions Documentation') - - // Should have intro - expect(res.body).toContain('Automate away with') - }) - - test('renders child categories under Links section', async () => { - const res = await get(makeURL('/en/actions')) - expect(res.statusCode).toBe(200) - - // All children should be listed under Links section - expect(res.body).toContain('## Links') - - // Should contain child categories from fixtures (uses full title, not shortTitle) - expect(res.body).toContain('[Category page of GitHub Actions](/en/actions/category)') - expect(res.body).toContain('[Using workflows](/en/actions/using-workflows)') - }) - - test('includes child intros', async () => { - const res = await get(makeURL('/en/actions')) - expect(res.statusCode).toBe(200) - - // Each child should have its intro - expect(res.body).toContain('Learn how to migrate your existing CI/CD workflows') - expect(res.body).toContain('Learn how to use workflows') - }) -}) diff --git a/src/article-api/transformers/index.ts b/src/article-api/transformers/index.ts index cc8ba96f44e3..986f29f0cf84 100644 --- a/src/article-api/transformers/index.ts +++ b/src/article-api/transformers/index.ts @@ -14,7 +14,6 @@ import { BespokeLandingTransformer } from './bespoke-landing-transformer' import { JourneyLandingTransformer } from './journey-landing-transformer' import { CategoryLandingTransformer } from './category-landing-transformer' import { DiscoveryLandingTransformer } from './discovery-landing-transformer' -import { ProductLandingTransformer } from './product-landing-transformer' import { SearchPageTransformer } from './search-page-transformer' import { ArticleTransformer } from './article-transformer' @@ -39,7 +38,6 @@ transformerRegistry.register(new BespokeLandingTransformer()) transformerRegistry.register(new JourneyLandingTransformer()) transformerRegistry.register(new CategoryLandingTransformer()) transformerRegistry.register(new DiscoveryLandingTransformer()) -transformerRegistry.register(new ProductLandingTransformer()) transformerRegistry.register(new SearchPageTransformer()) // ArticleTransformer is the catch-all — must be registered last. transformerRegistry.register(new ArticleTransformer()) diff --git a/src/article-api/transformers/product-landing-transformer.ts b/src/article-api/transformers/product-landing-transformer.ts deleted file mode 100644 index 510491362fa2..000000000000 --- a/src/article-api/transformers/product-landing-transformer.ts +++ /dev/null @@ -1,280 +0,0 @@ -import type { Context, Page, ResolvedArticle } from '@/types' -import type { PageTransformer, TemplateData, Section, LinkGroup, LinkData } from './types' -import { renderContent } from '@/content-render/index' -import { loadTemplate } from '@/article-api/lib/load-template' -import { resolvePath } from '@/article-api/lib/resolve-path' -import { getLinkData } from '@/article-api/lib/get-link-data' - -interface ProductPage extends Omit { - featuredLinks?: Record> - children?: string[] - carousels?: Record - rawCarousels?: Record - includedCategories?: string[] -} - -interface PageWithChildren extends Page { - children?: string[] - category?: string[] -} - -/** - * Transforms product-landing pages into markdown format. - * Handles featured links (startHere, popular), guide cards, - * article grids with category filtering, and children listings. - */ -export class ProductLandingTransformer implements PageTransformer { - templateName = 'landing-page.template.md' - - canTransform(page: Page): boolean { - return page.layout === 'product-landing' - } - - async transform(page: Page, pathname: string, context: Context): Promise { - const templateData = await this.prepareTemplateData(page, pathname, context) - - const templateContent = loadTemplate(this.templateName) - - const rendered = await renderContent(templateContent, { - ...context, - ...templateData, - markdownRequested: true, - }) - - return rendered - } - - private async prepareTemplateData( - page: Page, - pathname: string, - context: Context, - ): Promise { - const productPage = page as ProductPage - const languageCode = page.languageCode || 'en' - const sections: Section[] = [] - - // Process carousels (each carousel becomes a section) - const carousels = productPage.carousels ?? productPage.rawCarousels - if (carousels && typeof carousels === 'object') { - const { default: getPageLinkData } = await import('@/frame/lib/get-link-data') - - for (const [carouselKey, articles] of Object.entries(carousels)) { - if (!Array.isArray(articles) || articles.length === 0) continue - - let links: LinkData[] - if (typeof articles[0] === 'object' && 'title' in articles[0]) { - // Already resolved articles - links = articles.map((item) => ({ - href: typeof item === 'string' ? item : item.href, - title: (typeof item === 'object' && item.title) || '', - intro: (typeof item === 'object' && item.intro) || '', - })) - } else { - // Raw paths that need resolution - const linkData = await getPageLinkData(articles as string[], context, { - title: true, - intro: true, - }) - links = (linkData || []).map( - (item: { href: string; title?: string; intro?: string }) => ({ - href: item.href, - title: item.title || '', - intro: item.intro || '', - }), - ) - } - - const validLinks = links.filter((l) => l.href && l.title) - if (validLinks.length > 0) { - // Use carousel key as title (capitalize first letter) - const sectionTitle = carouselKey.charAt(0).toUpperCase() + carouselKey.slice(1) - sections.push({ - title: sectionTitle, - groups: [{ title: null, links: validLinks }], - }) - } - } - } - - // Featured links (startHere, popular, etc.) - const rawFeaturedLinks = productPage.featuredLinks - if (rawFeaturedLinks) { - const { default: getPageLinkData } = await import('@/frame/lib/get-link-data') - - const featuredKeys = ['startHere', 'popular'] - const featuredGroups: LinkGroup[] = [] - - for (const key of featuredKeys) { - const links = rawFeaturedLinks[key] - if (!Array.isArray(links) || links.length === 0) continue - - const sectionTitle = this.getSectionTitle(key) - - // featuredLinks are page hrefs that need Liquid evaluation - const stringLinks = links.map((item) => (typeof item === 'string' ? item : item.href)) - const linkData = await getPageLinkData(stringLinks, context, { - title: true, - intro: true, - }) - const resolvedLinks = (linkData || []).map((item) => ({ - href: item.href, - title: item.title || '', - intro: item.intro || '', - })) - - const validLinks = resolvedLinks.filter((l) => l.href) - if (validLinks.length > 0) { - featuredGroups.push({ - title: sectionTitle, - links: validLinks, - }) - } - } - - if (featuredGroups.length > 0) { - sections.push({ - title: 'Featured', - groups: featuredGroups, - }) - } - } - - // Guide cards - if (rawFeaturedLinks?.guideCards) { - const links = rawFeaturedLinks.guideCards - if (Array.isArray(links)) { - const resolvedLinks = await Promise.all( - links.map(async (link) => { - if (typeof link === 'string') { - return await getLinkData(link, languageCode, pathname, context, resolvePath) - } else if (link.href) { - return { - href: link.href, - title: link.title, - intro: link.intro || '', - } - } - return null - }), - ) - - const validLinks = resolvedLinks.filter((l): l is LinkData => l !== null && !!l.href) - if (validLinks.length > 0) { - sections.push({ - title: 'Guides', - groups: [{ title: null, links: validLinks }], - }) - } - } - } - - // Article grid with includedCategories filtering - if (productPage.children && productPage.includedCategories) { - const gridGroups: LinkGroup[] = [] - const includedCategories = productPage.includedCategories - - for (const childHref of productPage.children) { - const childPage = resolvePath(childHref, languageCode, pathname, context) as - | PageWithChildren - | undefined - if (!childPage?.children) continue - - const childChildren = childPage.children - if (childChildren.length === 0) continue - - // Get the child page's pathname to use for resolving grandchildren - const childPermalink = childPage.permalinks.find( - (p) => p.languageCode === languageCode && p.pageVersion === context.currentVersion, - ) - const childPathname = childPermalink ? childPermalink.href : pathname + childHref - - const articles = await Promise.all( - childChildren.map(async (grandchildHref: string) => { - const linkData = await getLinkData( - grandchildHref, - languageCode, - childPathname, - context, - resolvePath, - ) - - if (includedCategories.length > 0) { - const linkedPage = resolvePath( - grandchildHref, - languageCode, - childPathname, - context, - ) as PageWithChildren | undefined - if (linkedPage) { - const pageCategories = linkedPage.category || [] - const hasMatchingCategory = - Array.isArray(pageCategories) && - pageCategories.some((cat: string) => - includedCategories.some( - (included) => included.toLowerCase() === cat.toLowerCase(), - ), - ) - if (!hasMatchingCategory) { - return null - } - } - } - - return linkData - }), - ) - - const validArticles = articles.filter((a): a is LinkData => a !== null && !!a.href) - if (validArticles.length > 0) { - const childTitle = await childPage.renderTitle(context, { unwrap: true }) - gridGroups.push({ - title: childTitle, - links: validArticles, - }) - } - } - - if (gridGroups.length > 0) { - sections.push({ - title: 'Articles', - groups: gridGroups, - }) - } - } - - // All children (full listing) - if (productPage.children) { - const links = await Promise.all( - productPage.children.map(async (childHref) => { - return await getLinkData(childHref, languageCode, pathname, context, resolvePath) - }), - ) - const validLinks = links.filter((l) => l.href) - if (validLinks.length > 0) { - sections.push({ - title: 'Links', - groups: [{ title: null, links: validLinks }], - }) - } - } - - const intro = page.intro ? await page.renderProp('intro', context, { textOnly: true }) : '' - const title = await page.renderTitle(context, { unwrap: true }) - - return { - title, - intro, - sections, - } - } - - private getSectionTitle(key: string): string { - const map: Record = { - gettingStarted: 'Getting started', - startHere: 'Start here', - guideCards: 'Guides', - popular: 'Popular', - } - return map[key] || key - } -} diff --git a/src/changelogs/README.md b/src/changelogs/README.md deleted file mode 100644 index eec5e747b43f..000000000000 --- a/src/changelogs/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Changelogs (`src/changelogs`) - -This directory contains the logic for fetching, parsing, and caching RSS feeds from the GitHub Blog to display changelog items on documentation pages. - -## Purpose & Scope - -The primary purpose is to provide a "What's New" section on specific documentation pages by pulling the latest updates from relevant GitHub Blog RSS feeds. It handles fetching RSS feeds, caching responses to prevent rate limiting, and parsing feed items for display. - -## Architecture & Key Assets - -### Core Logic - -`lib/changelog.ts` is the main module. It uses `rss-parser` to fetch feeds and implements a two-layer caching strategy: - -1. Memory Cache: `globalCache` Map for fast access within the process. -2. Disk Cache: Writes JSON files to `os.tmpdir()` (or a custom path) to persist across server restarts in development/test environments. - -`getChangelogItems` is the public API that returns a list of formatted changelog items. - -### Consumers - -The middleware `src/frame/middleware/context/whats-new-changelog.ts` uses this library to inject changelog data into the page context (`req.context.whatsNewChangelog`) based on page frontmatter. - -Currently, the following product landing pages display a changelog: - -- GitHub Actions (`content/actions/index.md`) -- GitHub Education (`content/education/index.md`) -- GitHub Enterprise (`content/admin/index.md`) -- GitHub Packages (`content/packages/index.md`) - -## Setup & Usage - -### Enabling on a Page - -To display a changelog on a documentation page, add the `changelog` property to the page's frontmatter: - -```yaml -changelog: - label: packages - prefix: "Packages: " -``` - -- `label`: Determines the feed URL (e.g., `packages` -> `https://github.blog/changelog/label/packages`). -- `prefix`: (Optional) A string to strip from the beginning of feed item titles. -- `versions`: (Optional) Specifies which versions of the docs should display the changelog. - -### Environment Variables - -- `CHANGELOG_DISABLED`: Set to `true` to disable fetching (returns undefined). This is often necessary in tests where external network requests are flaky or blocked. -- `CHANGELOG_CACHE_FILE_PATH`: (Optional) Override the default disk cache location. - -## Data & External Dependencies - -- Source: [GitHub Blog](https://github.blog) RSS feeds (e.g., `https://github.blog/changelog/label/packages/feed`). -- Dependencies: `rss-parser` is used to parse the XML RSS feeds. - -## Cross-links & Ownership - -- **Owner**: Docs Engineering owns this code. Marketing Engineering owns the GitHub Blog and its feeds. -- **Related Directories**: - - `src/frame/middleware/context`: Contains the middleware that invokes this logic. - - `src/changelogs/tests`: Contains tests for this module. - -## Current State & Next Steps - -- **Current State**: The system is stable and considered KTLO (Keep the Lights On). It fetches the latest 3 items from the specified feed. -- **Next Steps**: None planned. diff --git a/src/changelogs/lib/changelog.ts b/src/changelogs/lib/changelog.ts deleted file mode 100644 index c0445e98949f..000000000000 --- a/src/changelogs/lib/changelog.ts +++ /dev/null @@ -1,141 +0,0 @@ -import os from 'os' -import fs from 'fs' -import path from 'path' - -import Parser from 'rss-parser' - -import type { ChangelogItem } from '@/types' - -const CHANGELOG_CACHE_FILE_PATH = process.env.CHANGELOG_CACHE_FILE_PATH -// This is useful to set when doing things like sync search. -const CHANGELOG_DISABLED = Boolean(JSON.parse(process.env.CHANGELOG_DISABLED || 'false')) - -async function getRssFeed(url: string) { - const parser = new Parser({ timeout: 5000 }) - const feedUrl = `${url}/feed` - let feed - - try { - feed = await parser.parseURL(feedUrl) - } catch (err) { - console.error(`cannot get ${feedUrl}: ${err instanceof Error ? err.message : err}`) - return - } - - return feed -} - -export async function getChangelogItems( - prefix: string | undefined, - feedUrl: string, - ignoreCache = false, -): Promise { - if (CHANGELOG_DISABLED) { - if (process.env.NODE_ENV === 'development') { - console.warn(`Downloading changelog (${feedUrl}) items is disabled.`) - } - return - } - if (!ignoreCache) { - const fromCache = getChangelogItemsFromCache(prefix, feedUrl) - if (fromCache) return fromCache - } - - const feed = await getRssFeed(feedUrl) - - if (!feed || !feed.items) { - console.log(feed) - console.error('feed is not valid or has no items') - return - } - - // only show the first 3 posts - const changelog: ChangelogItem[] = feed.items.slice(0, 3).map((item) => { - const rawTitle = item.title as string - // remove the prefix if it exists (Ex: 'GitHub Actions: '), where the colon and expected whitespace should be hardcoded. - const title = prefix ? rawTitle.replace(new RegExp(`^${prefix}`), '') : rawTitle - return { - // capitalize the first letter of the title - title: title.trim().charAt(0).toUpperCase() + title.slice(1), - date: item.isoDate as string, - href: item.link as string, - } - }) - - // We don't cache the raw payload we'd get from the network request - // because it would waste memory. Instead we store the "serialized" - // object that's created from the raw payload. - setChangelogItemsCache(prefix, feedUrl, changelog) - - return changelog -} - -const globalCache = new Map() - -function getChangelogCacheKey(prefix: string | undefined, feedUrl: string) { - // Return a string that is only letters so it's safe to use this - // for the filename when caching to disk. - return `${prefix || ''}${feedUrl}`.replace(/[^a-z]+/gi, '') -} - -function getDiskCachePath(prefix: string | undefined, feedUrl: string) { - // When in local development or in tests, use disk caching - if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development') { - if (CHANGELOG_CACHE_FILE_PATH) { - return CHANGELOG_CACHE_FILE_PATH - } - const cacheKey = getChangelogCacheKey(prefix, feedUrl) - const date = new Date().toISOString().split('T')[0] - const fileName = `changelogcache-${cacheKey}-${date}.json` - return path.join(os.tmpdir(), fileName) - } -} - -function getChangelogItemsFromCache(prefix: string | undefined, feedUrl: string) { - const cacheKey = getChangelogCacheKey(prefix, feedUrl) - - if (globalCache.get(cacheKey)) { - return globalCache.get(cacheKey) - } - - const diskCachePath = getDiskCachePath(prefix, feedUrl) - if (diskCachePath) { - try { - const payload = JSON.parse(fs.readFileSync(diskCachePath, 'utf-8')) - if (process.env.NODE_ENV === 'development') - console.log(`Changelog disk-cache HIT on ${diskCachePath}`) - // Also, for next time, within this Node process, put it into - // the global cache so we don't need to read from disk again. - globalCache.set(cacheKey, payload) - return payload - } catch (err) { - // If it wasn't on disk, that's fine. - if (err instanceof Error && 'code' in err && err.code === 'ENOENT') return - // The JSON.parse() most likely failed. Ignore the error - // but delete the file so it won't be attempted again. - if (err instanceof SyntaxError) { - fs.unlinkSync(diskCachePath) - return - } - throw err - } - } -} - -function setChangelogItemsCache( - prefix: string | undefined, - feedUrl: string, - payload: ChangelogItem[], -) { - const cacheKey = getChangelogCacheKey(prefix, feedUrl) - globalCache.set(cacheKey, payload) - - const diskCachePath = getDiskCachePath(prefix, feedUrl) - // Note that `diskCachePath` is falsy if NODE_ENV==production which - // means we're not writing to disk in production. - if (diskCachePath) { - fs.writeFileSync(diskCachePath, JSON.stringify(payload), 'utf-8') - if (process.env.NODE_ENV === 'development') - console.log(`Wrote changelog cache to disk ${diskCachePath}`) - } -} diff --git a/src/changelogs/tests/get-rss-feeds.ts b/src/changelogs/tests/get-rss-feeds.ts deleted file mode 100644 index d2d394035ef3..000000000000 --- a/src/changelogs/tests/get-rss-feeds.ts +++ /dev/null @@ -1,70 +0,0 @@ -import fs from 'fs/promises' -import path from 'path' - -import nock from 'nock' -import { afterAll, beforeAll, describe, expect, test } from 'vitest' - -import { getChangelogItems } from '@/changelogs/lib/changelog' -import type { ChangelogItem } from '@/types' - -describe('getChangelogItems module', () => { - let changelog: ChangelogItem[] | undefined - - beforeAll(async () => { - const rssFeedContent = await fs.readFile( - path.join(process.cwd(), 'src/fixtures/fixtures/rss-feed.xml'), - 'utf8', - ) - - nock('https://github.blog').get('/changelog/label/packages/feed').reply(200, rssFeedContent) - - changelog = await getChangelogItems( - 'GitHub Actions:', - 'https://github.blog/changelog/label/packages', - // This means: Don't use the cache even if it's present. - // The reason we're doing this is because all other tests, the - // cache is prepopulated from a file from the test fixtures. But - // in this particular file, we really do want to execute that code - // that executes on a cache miss. But this particular file special - // because it explicitly uses nock() to mock the HTTP socket. - // So even if we say "Don't use the cache" here, it still won't - // depend on Internet access because we're using `nock` here. - true, - ) - }) - - afterAll(() => nock.cleanAll()) - - test('changelog contains 3 items', async () => { - expect(changelog && changelog.length).toEqual(3) - }) - - test('each changelog item has expected title, date, and href', async () => { - const expectedChangelogValues = [ - { - title: 'Authentication token format updates are generally available', - date: '2021-03-31T22:22:03.000Z', - href: 'https://github.blog/changelog/2021-03-31-authentication-token-format-updates-are-generally-available', - }, - { - title: 'Compare REST API now supports pagination', - date: '2021-03-23T02:49:54.000Z', - href: 'https://github.blog/changelog/2021-03-22-compare-rest-api-now-supports-pagination', - }, - { - title: 'GitHub Discussions GraphQL API public beta', - date: '2021-02-23T18:21:40.000Z', - href: 'https://github.blog/changelog/2021-02-23-github-discussions-graphql-api-public-beta', - }, - ] - - if (!changelog) throw new Error('changelog is undefined') - for (let i = 0; i < 3; i++) { - const changeLogEntry = changelog[i] - const expectedEntry = expectedChangelogValues[i] - expect(changeLogEntry.title).toBe(expectedEntry.title) - expect(changeLogEntry.date).toBe(expectedEntry.date) - expect(changeLogEntry.href).toBe(expectedEntry.href) - } - }) -}) diff --git a/src/content-linter/tests/fixtures/actions/index.md b/src/content-linter/tests/fixtures/actions/index.md index ea4f0a6e1ffd..a99e74d9c2fe 100644 --- a/src/content-linter/tests/fixtures/actions/index.md +++ b/src/content-linter/tests/fixtures/actions/index.md @@ -1,6 +1,6 @@ --- title: GitHub Actions Documentation -layout: product-landing +layout: discovery-landing children: - /hidden - /not-hidden diff --git a/src/content-linter/tests/fixtures/early-access/index.md b/src/content-linter/tests/fixtures/early-access/index.md index 03e5e5488758..99e0363d5cd7 100644 --- a/src/content-linter/tests/fixtures/early-access/index.md +++ b/src/content-linter/tests/fixtures/early-access/index.md @@ -1,6 +1,6 @@ --- title: Early Access Documentation -layout: product-landing +layout: discovery-landing children: - /hidden - /not-hidden diff --git a/src/content-linter/tests/fixtures/landing-carousels/duplicate-carousels.md b/src/content-linter/tests/fixtures/landing-carousels/duplicate-carousels.md index 8c2b950037ad..8bdd3ecb01d2 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/duplicate-carousels.md +++ b/src/content-linter/tests/fixtures/landing-carousels/duplicate-carousels.md @@ -1,6 +1,6 @@ --- title: Landing with Duplicates -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghec: '*' diff --git a/src/content-linter/tests/fixtures/landing-carousels/duplicate-recommended.md b/src/content-linter/tests/fixtures/landing-carousels/duplicate-recommended.md index 8c2b950037ad..8bdd3ecb01d2 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/duplicate-recommended.md +++ b/src/content-linter/tests/fixtures/landing-carousels/duplicate-recommended.md @@ -1,6 +1,6 @@ --- title: Landing with Duplicates -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghec: '*' diff --git a/src/content-linter/tests/fixtures/landing-carousels/invalid-paths.md b/src/content-linter/tests/fixtures/landing-carousels/invalid-paths.md index 5513edf1ad81..95a73e9fb8e4 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/invalid-paths.md +++ b/src/content-linter/tests/fixtures/landing-carousels/invalid-paths.md @@ -1,6 +1,6 @@ --- title: Landing with Invalid Paths -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghec: '*' diff --git a/src/content-linter/tests/fixtures/landing-carousels/no-carousels.md b/src/content-linter/tests/fixtures/landing-carousels/no-carousels.md index d96434782cc3..e3c95484ba5e 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/no-carousels.md +++ b/src/content-linter/tests/fixtures/landing-carousels/no-carousels.md @@ -1,6 +1,6 @@ --- title: Landing without Carousels -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghec: '*' diff --git a/src/content-linter/tests/fixtures/landing-carousels/no-recommended.md b/src/content-linter/tests/fixtures/landing-carousels/no-recommended.md index d96434782cc3..e3c95484ba5e 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/no-recommended.md +++ b/src/content-linter/tests/fixtures/landing-carousels/no-recommended.md @@ -1,6 +1,6 @@ --- title: Landing without Carousels -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghec: '*' diff --git a/src/content-linter/tests/fixtures/landing-carousels/test-absolute-only.md b/src/content-linter/tests/fixtures/landing-carousels/test-absolute-only.md index da9b8de286e9..ba1fd6646faa 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/test-absolute-only.md +++ b/src/content-linter/tests/fixtures/landing-carousels/test-absolute-only.md @@ -1,6 +1,6 @@ --- title: Test Absolute Only Path -layout: product-landing +layout: discovery-landing versions: fpt: '*' carousels: diff --git a/src/content-linter/tests/fixtures/landing-carousels/test-absolute-priority.md b/src/content-linter/tests/fixtures/landing-carousels/test-absolute-priority.md index ab8cd042fefe..c5390c34da32 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/test-absolute-priority.md +++ b/src/content-linter/tests/fixtures/landing-carousels/test-absolute-priority.md @@ -1,6 +1,6 @@ --- title: Test Absolute Path Priority -layout: product-landing +layout: discovery-landing versions: fpt: '*' carousels: diff --git a/src/content-linter/tests/fixtures/landing-carousels/test-path-priority.md b/src/content-linter/tests/fixtures/landing-carousels/test-path-priority.md index 30e078ff8b80..d1665aa5f01c 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/test-path-priority.md +++ b/src/content-linter/tests/fixtures/landing-carousels/test-path-priority.md @@ -1,6 +1,6 @@ --- title: Test Path Priority Resolution -layout: product-landing +layout: discovery-landing versions: fpt: '*' carousels: diff --git a/src/content-linter/tests/fixtures/landing-carousels/test-priority-validation.md b/src/content-linter/tests/fixtures/landing-carousels/test-priority-validation.md index 560b75a2ac78..e8382972145a 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/test-priority-validation.md +++ b/src/content-linter/tests/fixtures/landing-carousels/test-priority-validation.md @@ -1,6 +1,6 @@ --- title: Test Priority Validation -layout: product-landing +layout: discovery-landing versions: fpt: '*' carousels: diff --git a/src/content-linter/tests/fixtures/landing-carousels/valid-landing.md b/src/content-linter/tests/fixtures/landing-carousels/valid-landing.md index a0d2e4fdb11d..7ad72c52ffc0 100644 --- a/src/content-linter/tests/fixtures/landing-carousels/valid-landing.md +++ b/src/content-linter/tests/fixtures/landing-carousels/valid-landing.md @@ -1,6 +1,6 @@ --- title: Valid Landing Page -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghec: '*' diff --git a/src/data-directory/README.md b/src/data-directory/README.md index 2ce8e3cf6792..b57bb3388f01 100644 --- a/src/data-directory/README.md +++ b/src/data-directory/README.md @@ -18,7 +18,7 @@ Purpose-built utilities, schemas, and workflows that power our Liquid `{% data % ## Data loading contracts - `lib/get-data.ts` - - `getDataByLanguage(dottedPath, langCode)`: Returns a single value (YAML/MD/variables/reusables/ui/glossaries/release-notes/product-examples). + - `getDataByLanguage(dottedPath, langCode)`: Returns a single value (YAML/MD/variables/reusables/ui/glossaries/release-notes). - `getDeepDataByLanguage(dottedPath, langCode)`: Returns nested objects for an entire subtree (e.g., `tables`, `features`). - Translation fallbacks: If a localized file is missing or unparsable, falls back to English. Certain files are forced-English (`ALWAYS_ENGLISH_YAML_FILES`, `ALWAYS_ENGLISH_MD_FILES`). - Memoization: Caches reads except in `NODE_ENV=development` to simplify local debugging. diff --git a/src/data-directory/lib/get-data.ts b/src/data-directory/lib/get-data.ts index bb8b21649aff..746e7db26416 100644 --- a/src/data-directory/lib/get-data.ts +++ b/src/data-directory/lib/get-data.ts @@ -258,7 +258,7 @@ function getDataByDir( return get(allData, split.join('.')) } - if (first === 'product-examples' || first === 'glossaries' || first === 'release-notes') { + if (first === 'glossaries' || first === 'release-notes') { const basename = split.pop()! fullPath.push(...split) fullPath.push(`${basename}.yml`) diff --git a/src/fixtures/fixtures/changelog-feed.json b/src/fixtures/fixtures/changelog-feed.json deleted file mode 100644 index 6af168c61c5a..000000000000 --- a/src/fixtures/fixtures/changelog-feed.json +++ /dev/null @@ -1 +0,0 @@ -[{"title":"Authentication token format updates are generally available","date":"2021-03-31T22:22:03.000Z","href":"https://github.blog/changelog/2021-03-31-authentication-token-format-updates-are-generally-available"},{"title":"Compare REST API now supports pagination","date":"2021-03-23T02:49:54.000Z","href":"https://github.blog/changelog/2021-03-22-compare-rest-api-now-supports-pagination"},{"title":"GitHub Discussions GraphQL API public beta","date":"2021-02-23T18:21:40.000Z","href":"https://github.blog/changelog/2021-02-23-github-discussions-graphql-api-public-beta"}] \ No newline at end of file diff --git a/src/fixtures/fixtures/content/actions/index.md b/src/fixtures/fixtures/content/actions/index.md index 7dbd367ee809..5cfbbe99972a 100644 --- a/src/fixtures/fixtures/content/actions/index.md +++ b/src/fixtures/fixtures/content/actions/index.md @@ -2,9 +2,7 @@ title: GitHub Actions Documentation shortTitle: GitHub Actions intro: 'Automate away with {% data variables.product.prodname_actions %}.' -changelog: - label: actions -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghes: '*' diff --git a/src/fixtures/fixtures/content/admin/index.md b/src/fixtures/fixtures/content/admin/index.md index ac0afdc79daa..f9b1d55a8b88 100644 --- a/src/fixtures/fixtures/content/admin/index.md +++ b/src/fixtures/fixtures/content/admin/index.md @@ -3,9 +3,7 @@ title: Enterprise administrator documentation shortTitle: Enterprise administrators intro: 'Documentation and guides for enterprise administrators.' -changelog: - label: enterprise -layout: product-landing +layout: discovery-landing versions: ghec: '*' ghes: '*' diff --git a/src/fixtures/fixtures/content/authentication/index.md b/src/fixtures/fixtures/content/authentication/index.md index 080426a5bd32..06d4be0599a7 100644 --- a/src/fixtures/fixtures/content/authentication/index.md +++ b/src/fixtures/fixtures/content/authentication/index.md @@ -19,9 +19,7 @@ versions: ghes: '*' ghec: '*' -changelog: - label: '2FA,authentication,security keys,SSH,token authentication' -layout: product-landing +layout: discovery-landing children: - /keeping-your-account-and-data-secure --- diff --git a/src/fixtures/fixtures/content/code-security/index.md b/src/fixtures/fixtures/content/code-security/index.md index 3255d78d76c7..125dfdb3ccd6 100644 --- a/src/fixtures/fixtures/content/code-security/index.md +++ b/src/fixtures/fixtures/content/code-security/index.md @@ -2,7 +2,7 @@ title: '{% data variables.product.product_name %} Code security documentation' shortTitle: '{% data variables.product.product_name %} Code security' intro: 'Code security' -layout: product-landing +layout: discovery-landing featuredLinks: startHere: - /code-security/getting-started/quickstart diff --git a/src/fixtures/fixtures/content/get-started/index.md b/src/fixtures/fixtures/content/get-started/index.md index 6dea171a7489..7e00fc75d446 100644 --- a/src/fixtures/fixtures/content/get-started/index.md +++ b/src/fixtures/fixtures/content/get-started/index.md @@ -6,7 +6,7 @@ versions: fpt: '*' ghes: '*' ghec: '*' -layout: product-landing +layout: discovery-landing introLinks: quickstart: /get-started/start-your-journey featuredLinks: diff --git a/src/fixtures/fixtures/content/organizations/index.md b/src/fixtures/fixtures/content/organizations/index.md index 71adf32a694e..3baac81ff952 100644 --- a/src/fixtures/fixtures/content/organizations/index.md +++ b/src/fixtures/fixtures/content/organizations/index.md @@ -8,7 +8,7 @@ redirect_from: - /github/setting-up-and-managing-organizations-and-teams - /organizations/organizing-members-into-teams/disabling-team-discussions-for-your-organization -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghes: '*' diff --git a/src/fixtures/fixtures/content/pages/index.md b/src/fixtures/fixtures/content/pages/index.md index 2620b87857b7..b379230a6c4d 100644 --- a/src/fixtures/fixtures/content/pages/index.md +++ b/src/fixtures/fixtures/content/pages/index.md @@ -4,7 +4,7 @@ shortTitle: Pages ({% data variables.product.product_name %}) intro: 'Pages are cool on {% data variables.location.product_location %}. ' introLinks: quickstart: /pages/quickstart -layout: product-landing +layout: discovery-landing product: '{% data reusables.gated-features.pages %}' versions: fpt: '*' diff --git a/src/fixtures/fixtures/content/rest/index.md b/src/fixtures/fixtures/content/rest/index.md index 71127de8ea33..7b34c38e411d 100644 --- a/src/fixtures/fixtures/content/rest/index.md +++ b/src/fixtures/fixtures/content/rest/index.md @@ -9,9 +9,7 @@ introLinks: featuredLinks: popular: - /rest/about-the-rest-api/comparing-githubs-rest-api-and-graphql-api -changelog: - label: 'api, apis' -layout: product-landing +layout: discovery-landing versions: fpt: '*' ghes: '*' diff --git a/src/fixtures/fixtures/content/webhooks/index.md b/src/fixtures/fixtures/content/webhooks/index.md index 3985d71c64ca..cffa7bb1afd1 100644 --- a/src/fixtures/fixtures/content/webhooks/index.md +++ b/src/fixtures/fixtures/content/webhooks/index.md @@ -13,7 +13,5 @@ versions: ghec: '*' children: - /webhook-events-and-payloads -changelog: - label: webhooks -layout: product-landing +layout: discovery-landing --- diff --git a/src/fixtures/fixtures/rss-feed.xml b/src/fixtures/fixtures/rss-feed.xml deleted file mode 100644 index 871d455b63ad..000000000000 --- a/src/fixtures/fixtures/rss-feed.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - api – The GitHub Blog - - https://github.blog - Updates, ideas, and inspiration from GitHub to help developers build and design software. - Thu, 01 Apr 2021 20:48:29 +0000 - en-US - - hourly - - 1 - https://wordpress.org/?v=5.7 - - - https://github.blog/wp-content/uploads/2019/01/cropped-github-favicon-512.png?fit=32%2C32 - api – The GitHub Blog - https://github.blog - 32 - 32 - -153214340 - Authentication token format updates are generally available - https://github.blog/changelog/2021-03-31-authentication-token-format-updates-are-generally-available - - - Wed, 31 Mar 2021 22:22:03 +0000 - https://github.blog/changelog/2021-03-31-authentication-token-format-updates-are-generally-available - - - As we announced previously, the format of GitHub authentication tokens has changed. The following token types are affected:

- -

If you use any of these tokens, we encourage you to reset them now. This will give you additional security benefits and allow Secret Scanning to detect the tokens.

-

Notably, the token formats now include the following updates:

-
    -
  • The character set changed from [a-f0-9] to [A-Za-z0-9_]
  • -
  • The format now includes a prefix for each token type: -
      -
    • ghp_ for Personal Access Tokens
    • -
    • gho_ for OAuth Access tokens
    • -
    • ghu_ for GitHub App user-to-server tokens
    • -
    • ghs_ for GitHub App server-to-server tokens
    • -
    • ghr_ for GitHub App refresh tokens
    • -
    -
  • -
-

The length of our tokens is remaining the same for now. However, GitHub tokens will likely increase in length in future updates, so integrators should plan to support tokens up to 255 characters after June 1, 2021.

-]]>
- - - - 57117
- - Compare REST API now supports pagination - https://github.blog/changelog/2021-03-22-compare-rest-api-now-supports-pagination - - - Tue, 23 Mar 2021 02:49:54 +0000 - https://github.blog/changelog/2021-03-22-compare-rest-api-now-supports-pagination - - - The "Compare two commits" REST API, which returns a list of commits reachable from one commit (or branch) but not reachable from another, now supports pagination. It can also now return the results for comparisons over 250 commits.

-

To learn more, see the compare two commits API reference or the guide for using pagination.

-]]>
- - - - 56979
- - GitHub Discussions GraphQL API public beta - https://github.blog/changelog/2021-02-23-github-discussions-graphql-api-public-beta - - - Tue, 23 Feb 2021 18:21:40 +0000 - https://github.blog/changelog/2021-02-23-github-discussions-graphql-api-public-beta - - - The GitHub Discussions GraphQL API public beta is now available. Get started with the GitHub Discussions API.

-

For questions or feedback, visit GitHub Discussions feedback.

-]]>
- - - - 56364
-
-
\ No newline at end of file diff --git a/src/fixtures/tests/landing-hero.ts b/src/fixtures/tests/landing-hero.ts index 743b339fa793..bbf84e96339f 100644 --- a/src/fixtures/tests/landing-hero.ts +++ b/src/fixtures/tests/landing-hero.ts @@ -8,18 +8,4 @@ describe('product landing page', () => { const $: CheerioAPI = await getDOM('/get-started') expect($('h1').first().text()).toMatch(/Getting started with HubGit/) }) - - test('product landing page lists with shortTitle heading (free-pro-team)', async () => { - const $: CheerioAPI = await getDOM('/pages') - // Note that this particular page (in the fixtures) has Liquid - // in its shorTitle. - expect($('#all-docs a').first().text()).toMatch('All Pages (HubGit) docs') - }) - - test('product landing page lists with shortTitle heading (enterprise-server)', async () => { - const $: CheerioAPI = await getDOM('/enterprise-server@latest/pages') - // Note that this particular page (in the fixtures) has Liquid - // in its shorTitle. - expect($('#all-docs a').first().text()).toMatch('All Pages (HubGit Enterprise Server) docs') - }) }) diff --git a/src/fixtures/tests/playwright-a11y.spec.ts b/src/fixtures/tests/playwright-a11y.spec.ts index 0f518aaab224..5aff5bc5bec9 100644 --- a/src/fixtures/tests/playwright-a11y.spec.ts +++ b/src/fixtures/tests/playwright-a11y.spec.ts @@ -10,7 +10,7 @@ const pages: { [key: string]: string } = { '/code-security/getting-started/quickstart?learn=foo_bar&learnProduct=code-security', mapAndTopic: '/actions/category/subcategory', procedural: '/get-started/images/images-in-lists', - productLanding: '/code-security', + discoveryLanding: '/code-security', restCategory: '/rest/actions/artifacts', restLanding: '/rest', restOverview: '/rest/about-the-rest-api/comparing-githubs-rest-api-and-graphql-api', diff --git a/src/frame/components/context/CategoryLandingContext.tsx b/src/frame/components/context/CategoryLandingContext.tsx index f62969dac9ae..a56c14843f2b 100644 --- a/src/frame/components/context/CategoryLandingContext.tsx +++ b/src/frame/components/context/CategoryLandingContext.tsx @@ -1,6 +1,6 @@ import { createContext, useContext } from 'react' -import { FeaturedLink, getFeaturedLinksFromReq } from '@/landings/components/ProductLandingContext' -import type { RawTocItem, TocItem } from '@/landings/types' +import { getFeaturedLinksFromReq } from '@/landings/lib/featured-links' +import type { RawTocItem, TocItem, FeaturedLink } from '@/landings/types' import { mapRawTocItemToTocItem } from '@/landings/types' import type { SpotlightItem } from '@/types' diff --git a/src/frame/components/context/MainContext.tsx b/src/frame/components/context/MainContext.tsx index 57b852b9354f..d48b37267880 100644 --- a/src/frame/components/context/MainContext.tsx +++ b/src/frame/components/context/MainContext.tsx @@ -184,8 +184,8 @@ export const getMainContext = async (req: any, res: any): Promise const ui: UIStrings = {} addUINamespaces(req, ui, DEFAULT_UI_NAMESPACES) - // Every product landing page has a listing of all articles. - // It's used by the component. + // Product index pages (depth-2 index.md, e.g. actions/index.md) need the + // full product tree for landing rendering. const includeFullProductTree = documentType === 'product' const includeSidebarTree = documentType !== 'homepage' diff --git a/src/frame/components/context/TocLandingContext.tsx b/src/frame/components/context/TocLandingContext.tsx index 9366830f8efe..05a4b2a92706 100644 --- a/src/frame/components/context/TocLandingContext.tsx +++ b/src/frame/components/context/TocLandingContext.tsx @@ -1,6 +1,6 @@ import { createContext, useContext } from 'react' -import { FeaturedLink, getFeaturedLinksFromReq } from '@/landings/components/ProductLandingContext' -import type { RawTocItem, SimpleTocItem } from '@/landings/types' +import { getFeaturedLinksFromReq } from '@/landings/lib/featured-links' +import type { RawTocItem, SimpleTocItem, FeaturedLink } from '@/landings/types' import { mapRawTocItemToSimpleTocItem } from '@/landings/types' export type TocLandingContextT = { diff --git a/src/frame/lib/frontmatter.ts b/src/frame/lib/frontmatter.ts index ec37a80246d0..682d2d367144 100644 --- a/src/frame/lib/frontmatter.ts +++ b/src/frame/lib/frontmatter.ts @@ -42,7 +42,6 @@ interface Schema { const layoutNames = [ 'default', 'graphql-explorer', - 'product-landing', 'release-notes', 'inline', 'category-landing', @@ -174,7 +173,8 @@ export const schema: Schema = { }, }, }, - // Shown in `product-landing.html` "What's new" section + // DEPRECATED: tied to the removed product-landing layout. Schema entry kept + // because translations still carry `changelog:` until they catch up. changelog: { type: 'object', properties: { @@ -245,7 +245,8 @@ export const schema: Schema = { }, description: 'Array of journey tracks for journey landing pages', }, - // Used in `product-landing.html` + // DEPRECATED: tied to the removed product-landing layout. Schema entry kept + // because translations still carry `beta_product:` until they catch up. beta_product: { type: 'boolean', }, diff --git a/src/frame/middleware/context/product-examples.ts b/src/frame/middleware/context/product-examples.ts deleted file mode 100644 index 67143cc1bc35..000000000000 --- a/src/frame/middleware/context/product-examples.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type { Response, NextFunction } from 'express' - -import type { ExtendedRequest, ProductExample } from '@/types' -import { getDataByLanguage } from '@/data-directory/lib/get-data' - -function getProductExampleData( - product: string, - key: string, - language: string, -): ProductExample[] | undefined { - // Because getDataByLanguage() depends on reading data files from - // disk, asking for something that doesn't exist would throw a - // `ENOENT` error from `fs.readFile` but we want that to default - // to `undefined` because certain product's don't have all product - // examples. - try { - return getDataByLanguage(`product-examples.${product}.${key}`, language) - } catch (error) { - if (error instanceof Error && 'code' in error && error.code === 'ENOENT') return - throw error - } -} - -export default async function productExamples( - req: ExtendedRequest, - res: Response, - next: NextFunction, -) { - if (!req.context) throw new Error('request is not contextualized') - if (!req.context.page) return next() - if (req.context.currentLayoutName !== 'product-landing') return next() - - const { currentProduct, currentLanguage } = req.context - if (currentProduct === undefined) throw new Error('currentProduct is not set') - if (currentLanguage === undefined) throw new Error('currentLanguage is not set') - if (currentProduct.includes('.')) - throw new Error(`currentProduct cannot contain a . (${currentProduct})`) - - req.context.productCommunityExamples = getProductExampleData( - currentProduct, - 'community-examples', - currentLanguage, - ) - - req.context.productUserExamples = getProductExampleData( - currentProduct, - 'user-examples', - currentLanguage, - ) - - return next() -} diff --git a/src/frame/middleware/context/whats-new-changelog.ts b/src/frame/middleware/context/whats-new-changelog.ts deleted file mode 100644 index 726130be00dc..000000000000 --- a/src/frame/middleware/context/whats-new-changelog.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { Response, NextFunction } from 'express' - -import { getChangelogItems } from '@/changelogs/lib/changelog' -import getApplicableVersions from '@/versions/lib/get-applicable-versions' -import type { ExtendedRequest } from '@/types' - -export default async function whatsNewChangelog( - req: ExtendedRequest, - res: Response, - next: NextFunction, -) { - if (!req.context) throw new Error('request not contextualized') - if (!req.context.page) return next() - if (!req.context.page.changelog) return next() - const label = req.context.page.changelog.label.split(/\s+/g).join('') - - // If there is no `versions` prop in the changelog frontmatter, assume the changelog should display in all versions. - if (req.context.page.changelog.versions) { - const changelogVersions = getApplicableVersions(req.context.page.changelog.versions) - - // If the current version is not included, do not display a changelog. - if (!req.context.currentVersion || !changelogVersions.includes(req.context.currentVersion)) { - return next() - } - } - - const labelUrls: Record = { - education: 'https://github.blog/category/community/education', - enterprise: 'https://github.blog/category/enterprise/', - } - - req.context.changelogUrl = labelUrls[label] || `https://github.blog/changelog/label/${label}` - - req.context.whatsNewChangelog = await getChangelogItems( - req.context.page.changelog.prefix, - req.context.changelogUrl, - ) - return next() -} diff --git a/src/frame/middleware/index.ts b/src/frame/middleware/index.ts index 5383edbd4604..5a37a951c3cd 100644 --- a/src/frame/middleware/index.ts +++ b/src/frame/middleware/index.ts @@ -40,7 +40,6 @@ import triggerError from '@/observability/middleware/trigger-error' import dataTables from '@/data-directory/middleware/data-tables' import secretScanning from '@/secret-scanning/middleware/secret-scanning' import ghesReleaseNotes from '@/release-notes/middleware/ghes-release-notes' -import whatsNewChangelog from './context/whats-new-changelog' import layout from './context/layout' import currentProductTree from './context/current-product-tree' import genericToc from './context/generic-toc' @@ -49,7 +48,6 @@ import glossaries from './context/glossaries' import resolveCarousels from './resolve-carousels' import renderProductName from './context/render-product-name' import features from '@/versions/middleware/features' -import productExamples from './context/product-examples' import productGroups from './context/product-groups' import featuredLinks from '@/landings/middleware/featured-links' import journeyTrack from '@/journeys/middleware/journey-track' @@ -272,13 +270,11 @@ export default function index(app: Express) { app.use(asyncMiddleware(dataTables)) app.use(asyncMiddleware(secretScanning)) app.use(asyncMiddleware(ghesReleaseNotes)) - app.use(asyncMiddleware(whatsNewChangelog)) app.use(layout) app.use(features) // needs to come before product tree app.use(asyncMiddleware(currentProductTree)) app.use(asyncMiddleware(genericToc)) app.use(breadcrumbs) - app.use(asyncMiddleware(productExamples)) app.use(asyncMiddleware(productGroups)) app.use(asyncMiddleware(glossaries)) app.use(asyncMiddleware(generalSearchMiddleware)) diff --git a/src/landings/README.md b/src/landings/README.md index f14e1a93e124..5e0f2e31d8c9 100644 --- a/src/landings/README.md +++ b/src/landings/README.md @@ -1,15 +1,15 @@ # Landing pages -The landings subject provides components and logic for rendering various types of landing pages across docs.github.com, including the Docs home page, product landing pages, product guides pages, category pages, and specialized layouts like journey and discovery landings. +The landings subject provides components and logic for rendering various types of landing pages across docs.github.com, including the Docs home page, category pages, and specialized layouts like journey, discovery, and bespoke landings. ## Purpose & Scope This subject is responsible for: -- Rendering different landing page layouts (product, guides, category, journey, discovery, bespoke) +- Rendering different landing page layouts (toc, category, journey, discovery, bespoke) - Building and displaying featured links, article cards, and guide cards - Managing landing page context and data requirements - Providing hierarchical navigation for products and categories -- Displaying article carousels and product releases +- Displaying article carousels Landing pages serve as navigational hubs that provide a hierarchical view of their area, making it easier to find and discover documentation. @@ -17,11 +17,11 @@ Landing pages serve as navigational hubs that provide a hierarchical view of the | Landing Page Type | Layout Value | Purpose | |-------------------|--------------|---------| -| Product landing | `product-landing` | Product overview pages with featured links and release notes | | Category landing | `category-landing` | Category pages with hierarchical navigation | | Table of contents | `toc-landing` | Table of contents pages | | Journey landing | `journey-landing` | Guided learning journey pages with track navigation | | Discovery landing | `discovery-landing` | Discovery/exploration pages | +| Bespoke landing | `bespoke-landing` | Custom hand-built landing pages | | Home page | (special) | Docs.github.com homepage | ## Setup & Usage diff --git a/src/landings/components/ArticleList.tsx b/src/landings/components/ArticleList.tsx index d36b831f71bf..d951312800d2 100644 --- a/src/landings/components/ArticleList.tsx +++ b/src/landings/components/ArticleList.tsx @@ -1,5 +1,5 @@ import { Link } from '@/frame/components/Link' -import { FeaturedLink } from '@/landings/components/ProductLandingContext' +import type { FeaturedLink } from '@/landings/types' import { useTranslation } from '@/languages/components/useTranslation' import { ArrowRightIcon } from '@primer/octicons-react' import { ActionList } from '@primer/react' diff --git a/src/landings/components/CommunityExamples.tsx b/src/landings/components/CommunityExamples.tsx deleted file mode 100644 index 0aa685c5f095..000000000000 --- a/src/landings/components/CommunityExamples.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { useProductLandingContext } from '@/landings/components/ProductLandingContext' -import { RepoCard } from '@/landings/components/RepoCard' - -export const CommunityExamples = () => { - const { productCommunityExamples } = useProductLandingContext() - - if (!productCommunityExamples) { - return null - } - - return ( -
-
- {productCommunityExamples.map((repo) => { - return ( -
- -
- ) - })} -
-
- ) -} diff --git a/src/landings/components/FeaturedArticles.tsx b/src/landings/components/FeaturedArticles.tsx deleted file mode 100644 index 9981defd5ae9..000000000000 --- a/src/landings/components/FeaturedArticles.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import cx from 'classnames' - -import { useProductLandingContext } from '@/landings/components/ProductLandingContext' -import { useTranslation } from '@/languages/components/useTranslation' -import { ArticleList } from '@/landings/components/ArticleList' - -export const FeaturedArticles = () => { - const { featuredArticles = [], whatsNewChangelog, changelogUrl } = useProductLandingContext() - const hasWhatsNewChangelog = whatsNewChangelog && whatsNewChangelog.length > 0 - const { t } = useTranslation('toc') - - return ( -
- {featuredArticles.map((section, i) => { - const viewAllTitleText = `'${section.label}'` - - return ( -
- -
- ) - })} - - {hasWhatsNewChangelog && ( -
- { - return { - title: link.title, - date: link.date, - href: link.href, - } - })} - /> -
- )} -
- ) -} diff --git a/src/landings/components/GuideCard.tsx b/src/landings/components/GuideCard.tsx deleted file mode 100644 index a57d080c466f..000000000000 --- a/src/landings/components/GuideCard.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import type { FeaturedLink } from '@/landings/components/ProductLandingContext' -import cx from 'classnames' -import styles from './Landings.module.scss' - -const { hoverShadowLarge } = styles - -type Props = { - guide: FeaturedLink -} -export const GuideCard = ({ guide }: Props) => { - const authors = guide.authors && guide.authors.length > 0 ? guide.authors : ['GitHub'] - const authorString = `@${authors.join(', @')}` - - return ( -
  • - -

    {guide.title}

    -

    {guide.intro || ''}

    - -
    -
    {authorString}
    -
    -
    -
  • - ) -} diff --git a/src/landings/components/GuideCards.tsx b/src/landings/components/GuideCards.tsx deleted file mode 100644 index a83c3b9f0e1c..000000000000 --- a/src/landings/components/GuideCards.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { useRouter } from 'next/router' - -import { Link } from '@/frame/components/Link' -import { ArrowRightIcon } from '@primer/octicons-react' -import { useMainContext } from '@/frame/components/context/MainContext' - -import { useProductLandingContext } from '@/landings/components/ProductLandingContext' -import { GuideCard } from '@/landings/components/GuideCard' -import { useTranslation } from '@/languages/components/useTranslation' - -export const GuideCards = () => { - const router = useRouter() - const { currentCategory } = useMainContext() - const { featuredLinks, hasGuidesPage } = useProductLandingContext() - const { t } = useTranslation('product_landing') - - const routePath = `/${router.locale}${router.asPath.split('?')[0]}` // remove query string - - if (!featuredLinks.guideCards) { - return null - } - - return ( -
    -
    -
      - {(featuredLinks.guideCards || []).map((guide) => { - return - })} -
    -
    - - {!currentCategory && hasGuidesPage && ( - - {t('explore_guides')} - - )} -
    - ) -} diff --git a/src/landings/components/LandingHero.tsx b/src/landings/components/LandingHero.tsx deleted file mode 100644 index e727bb51b62c..000000000000 --- a/src/landings/components/LandingHero.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react' -import cx from 'classnames' -import { useRouter } from 'next/router' -import { LinkExternalIcon } from '@primer/octicons-react' - -import { Link } from '@/frame/components/Link' -import { useProductLandingContext } from '@/landings/components/ProductLandingContext' -import { useTranslation } from '@/languages/components/useTranslation' -import { useVersion } from '@/versions/components/useVersion' -import { Lead } from '@/frame/components/ui/Lead' - -export const LandingHero = () => { - const { title, beta_product, intro, introLinks } = useProductLandingContext() - const { t } = useTranslation(['product_landing']) - - return ( -
    -
    -

    - {title}{' '} - {beta_product && Beta} -

    - - {intro && {intro}} - -
    - {introLinks && - Object.entries(introLinks) - .filter(([key, link]) => { - return link && !key.includes('raw') - }) - .map(([key, link], i) => { - if (!link) { - return null - } - return ( - - {t(key)} - - ) - })} -
    -
    -
    - ) -} - -// Fully Qualified Link - it includes the version and locale in the path if -// the href is not an external link. -type Props = { - href: string - id: string - children: React.ReactNode - className?: string -} -export const FullLink = ({ href, id, children, className }: Props) => { - const router = useRouter() - const { currentVersion } = useVersion() - - const isExternal = href.startsWith('https') - let linkHref = href - if (!isExternal) { - const locale = router.locale || 'en' - linkHref = `/${locale}${ - currentVersion !== 'free-pro-team@latest' ? `/${currentVersion}` : '' - }${href}` - } - - return ( - - {children}{' '} - {isExternal && ( - - - - )} - - ) -} diff --git a/src/landings/components/ProductArticlesList.module.scss b/src/landings/components/ProductArticlesList.module.scss deleted file mode 100644 index 2a72356c5e1c..000000000000 --- a/src/landings/components/ProductArticlesList.module.scss +++ /dev/null @@ -1,15 +0,0 @@ -.linkItem { - border-radius: 0; - - &:hover { - border-radius: 0; - } - - a { - span { - user-select: text; - color: var(--fgColor-accent, var(--color-accent-fg)); - text-decoration: underline; - } - } -} diff --git a/src/landings/components/ProductArticlesList.tsx b/src/landings/components/ProductArticlesList.tsx deleted file mode 100644 index 83f7ccba3b7c..000000000000 --- a/src/landings/components/ProductArticlesList.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { ActionList } from '@primer/react' - -import { ProductTreeNode, useMainContext } from '@/frame/components/context/MainContext' -import { Link } from '@/frame/components/Link' -import { countArticles } from '@/landings/lib/count-articles' -import clsx from 'clsx' -import styles from './ProductArticlesList.module.scss' - -export const ProductArticlesList = () => { - const { currentProductTree } = useMainContext() - - if (!currentProductTree) { - return null - } - - return ( -
    - {currentProductTree.childPages - .filter((treeNode) => treeNode.childPages.length) - .map((treeNode) => { - return - })} -
    - ) -} - -const ProductTreeNodeList = ({ treeNode }: { treeNode: ProductTreeNode }) => { - return ( -
    -

    - - {treeNode.title} - -

    - - - {treeNode.childPages.map((childNode, index) => { - return ( - - {childNode.title} - {childNode.childPages.length > 0 ? ( - -  • {countArticles(childNode)} articles - - ) : null} - - ) - })} - -
    - ) -} diff --git a/src/landings/components/ProductGuidesContext.tsx b/src/landings/components/ProductGuidesContext.tsx deleted file mode 100644 index 0a9df2552a5a..000000000000 --- a/src/landings/components/ProductGuidesContext.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { createContext, useContext } from 'react' - -export type ProductGuidesContextT = { - title: string - intro: string -} - -export const ProductGuidesContext = createContext(null) - -export const useProductGuidesContext = (): ProductGuidesContextT => { - const context = useContext(ProductGuidesContext) - - if (!context) { - throw new Error( - '"useProductGuidesContext" may only be used inside "ProductGuidesContext.Provider"', - ) - } - - return context -} diff --git a/src/landings/components/ProductLanding.tsx b/src/landings/components/ProductLanding.tsx deleted file mode 100644 index 85f7a249a6fa..000000000000 --- a/src/landings/components/ProductLanding.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { useRouter } from 'next/router' -import { DefaultLayout } from '@/frame/components/DefaultLayout' -import { useProductLandingContext } from '@/landings/components/ProductLandingContext' - -import { LandingHero } from '@/landings/components/LandingHero' -import { FeaturedArticles } from '@/landings/components/FeaturedArticles' -import { GuideCards } from '@/landings/components/GuideCards' -import { SponsorsExamples } from '@/landings/components/SponsorsExamples' -import { CommunityExamples } from '@/landings/components/CommunityExamples' -import { LandingSection } from '@/landings/components/LandingSection' -import { useTranslation } from '@/languages/components/useTranslation' -import { ProductArticlesList } from '@/landings/components/ProductArticlesList' -import { ProductReleases } from '@/landings/components/ProductReleases' -import { useVersion } from '@/versions/components/useVersion' -import { RestRedirect } from '@/rest/components/RestRedirect' -import { UtmPreserver } from '@/frame/components/UtmPreserver' - -export const ProductLanding = () => { - const router = useRouter() - const { isEnterpriseServer } = useVersion() - const { title, shortTitle, featuredLinks, productUserExamples, productCommunityExamples } = - useProductLandingContext() - const { t } = useTranslation('product_landing') - - return ( - - -
    - {router.query.productId === 'rest' && } - - - - -
    - - - - - {productCommunityExamples.length > 0 && ( - - - - )} - - {productUserExamples.length > 0 && ( - - - - )} - - {router.query.productId === 'admin' && isEnterpriseServer && ( - - - - )} - - {featuredLinks.guideCards?.length > 0 && ( -
    - - - -
    - )} - - - - -
    -
    -
    - ) -} diff --git a/src/landings/components/ProductLandingContext.tsx b/src/landings/components/ProductLandingContext.tsx deleted file mode 100644 index 35c435c77739..000000000000 --- a/src/landings/components/ProductLandingContext.tsx +++ /dev/null @@ -1,191 +0,0 @@ -import { createContext, useContext } from 'react' -import pick from 'lodash/pick' -import type { SimpleTocItem } from '@/landings/types' -import type { ExtendedRequest, FeaturedLinkExpanded } from '@/types' -export type FeaturedLink = { - title: string - href: string - intro?: string - authors?: Array - date?: string - fullTitle?: string -} -export type CodeExample = { - title: string - description: string - languages: string // single comma separated string - href: string - tags: Array -} -export type Product = { - title: string - href: string -} - -type Release = { - version: string - firstPreviousRelease: string - secondPreviousRelease: string - patches: Array<{ date: string; version: string }> - isReleaseCandidate: boolean -} - -export type ProductLandingContextT = { - title: string - introPlainText: string - shortTitle: string - intro: string - beta_product: boolean - product: Product - introLinks: Record | null - heroImage?: string - featuredLinks: Record> - productUserExamples: Array<{ username: string; description: string }> - productCommunityExamples: Array<{ repo: string; description: string }> - featuredArticles: Array<{ - key: string // Featured article section key (startHere, popular, etc.) - label: string // Start here, Popular, etc. - viewAllHref?: string // If provided, adds a "View All ->" to the header - viewAllTitleText?: string // Adds 'title' attribute text for the "View All" href - articles: Array - }> - changelogUrl?: string - whatsNewChangelog?: Array<{ href: string; title: string; date: string }> - tocItems: Array - hasGuidesPage: boolean - ghesReleases: Array -} - -export const ProductLandingContext = createContext(null) - -export const useProductLandingContext = (): ProductLandingContextT => { - const context = useContext(ProductLandingContext) - - if (!context) { - throw new Error( - '"useProductLandingContext" may only be used inside "ProductLandingContext.Provider"', - ) - } - - return context -} - -// Minimal request shape needed to extract featured links. We use a structural type -// here because callers pass either an Express ExtendedRequest or a narrower -// per-context request type defined alongside other landing-context helpers. -type FeaturedLinksRequest = { - context?: { - featuredLinks?: Record | unknown - } -} - -export const getFeaturedLinksFromReq = ( - req: FeaturedLinksRequest, -): Record> => { - const featuredLinks = (req.context?.featuredLinks || {}) as Record - return Object.fromEntries( - Object.entries(featuredLinks).map(([key, entries]) => { - return [ - key, - ((entries as FeaturedLinkExpanded[]) || []).map((entry) => ({ - href: entry.href, - title: entry.title, - intro: entry.intro, - authors: (entry.page as { authors?: string[] } | undefined)?.authors || [], - fullTitle: entry.fullTitle, - })), - ] - }), - ) -} - -export const getProductLandingContextFromRequest = async ( - req: ExtendedRequest, -): Promise => { - const context = req.context - if (!context) { - throw new Error('"getProductLandingContextFromRequest" requires req.context') - } - const productTree = context.currentProductTree - if (!productTree) { - throw new Error('"getProductLandingContextFromRequest" requires req.context.currentProductTree') - } - const page = context.page - if (!page) { - throw new Error('"getProductLandingContextFromRequest" requires req.context.page') - } - const hasGuidesPage = (page.children || []).includes('/guides') - - const title = await page.renderProp('title', context, { textOnly: true }) - const shortTitle = (await page.renderProp('shortTitle', context, { textOnly: true })) || null - - // This props is displayed on the product landing page as "Supported - // releases". So we omit, if there is one, the release candidate. - const ghesReleases = ((context.ghesReleases || []) as Release[]).filter((release) => { - return !release.isReleaseCandidate - }) - - return { - title, - shortTitle: shortTitle || '', - ...(pick(page as unknown as Record, [ - 'introPlainText', - 'beta_product', - 'intro', - ]) as { introPlainText: string; beta_product: boolean; intro: string }), - heroImage: (page as { heroImage?: string }).heroImage, - hasGuidesPage, - product: { - href: productTree.href, - title: productTree.page.shortTitle || productTree.page.title, - }, - whatsNewChangelog: context.whatsNewChangelog || [], - changelogUrl: context.changelogUrl, - productCommunityExamples: (context.productCommunityExamples || - []) as ProductLandingContextT['productCommunityExamples'], - ghesReleases, - productUserExamples: (context.productUserExamples || []).map(({ user, description }) => ({ - username: user as string, - description, - })), - - introLinks: - ((page as { introLinks?: Record }).introLinks as - | Record - | undefined) || null, - - featuredLinks: getFeaturedLinksFromReq(req), - - tocItems: ((context as { tocItems?: SimpleTocItem[] }).tocItems || []) as SimpleTocItem[], - - featuredArticles: Object.entries(context.featuredLinks || {}) - .filter(([key]) => { - return key === 'startHere' || key === 'popular' - }) - .map(([key, links]) => { - const pageFeaturedLinks = (page.featuredLinks || {}) as unknown as Record - const tocLabels = ((context.site as { data?: { ui?: { toc?: Record } } }) - ?.data?.ui?.toc || {}) as Record - return { - key, - label: - key === 'popular' - ? pageFeaturedLinks[`${key}Heading`] || tocLabels[key] - : tocLabels[key], - viewAllHref: - key === 'startHere' && !context.currentCategory && hasGuidesPage - ? `${context.currentPath}/guides` - : '', - articles: (links as FeaturedLinkExpanded[]).map((link) => { - return { - href: link.href, - title: link.title, - intro: link.intro, - authors: (link.page as { authors?: string[] } | undefined)?.authors || [], - fullTitle: link.fullTitle, - } - }), - } - }), - } -} diff --git a/src/landings/components/ProductReleases.tsx b/src/landings/components/ProductReleases.tsx deleted file mode 100644 index df992b89ad71..000000000000 --- a/src/landings/components/ProductReleases.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { ArrowRightIcon, ArrowUpIcon, FileIcon, ListUnorderedIcon } from '@primer/octicons-react' -import { useMainContext } from '@/frame/components/context/MainContext' -import { useProductLandingContext } from '@/landings/components/ProductLandingContext' -import { useTranslation } from '@/languages/components/useTranslation' -import { Link } from '@/frame/components/Link' -import { useRouter } from 'next/router' - -export function ProductReleases() { - const { t } = useTranslation('product_landing') - const router = useRouter() - const { enterpriseServerReleases, allVersions } = useMainContext() - const { ghesReleases, title, shortTitle } = useProductLandingContext() - const currentPath = router.asPath.split('?')[0] - return ( -
    -
    - {ghesReleases.slice(0, 4).map((release) => { - const releaseNumber = release.version - if (!enterpriseServerReleases.supported.includes(releaseNumber)) { - return null - } - const releaseVersion = `enterprise-server@${releaseNumber}` - const latestPatch = release.patches[0] - const firstPreviousVersion = `enterprise-server@${release.firstPreviousRelease}` - const secondPreviousVersion = `enterprise-server@${release.secondPreviousRelease}` - return ( -
    -
    -

    {allVersions[releaseVersion].versionTitle}

    -

    - {' '} - - {t('release_notes_for')} {latestPatch.version} - {' '} - ({latestPatch.date}) -

    -

    - {t('upgrade_from')}{' '} - - {release.firstPreviousRelease} - {' '} - or{' '} - - {release.secondPreviousRelease} - -

    -

    - {' '} - - {t('browse_all_docs')} - -

    -
    -
    - ) - })} -
    - - - {t('explore_release_notes')} - -
    - ) -} diff --git a/src/landings/components/RepoCard.tsx b/src/landings/components/RepoCard.tsx deleted file mode 100644 index b3ab9c07dd1d..000000000000 --- a/src/landings/components/RepoCard.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import cx from 'classnames' -import styles from './Landings.module.scss' -const { hoverShadowLarge } = styles - -type Props = { - repo: { - repo: string - description: string - } - href?: string -} -export const RepoCard = ({ repo, href }: Props) => { - return ( - -
    - {repo.repo} -
    -
    -

    {repo.repo}

    -

    {repo.description}

    -
    -
    - ) -} diff --git a/src/landings/components/SponsorsExamples.tsx b/src/landings/components/SponsorsExamples.tsx deleted file mode 100644 index 5061b53b253d..000000000000 --- a/src/landings/components/SponsorsExamples.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { useProductLandingContext } from '@/landings/components/ProductLandingContext' -import { UserCard } from '@/landings/components/UserCard' - -export const SponsorsExamples = () => { - const { productUserExamples } = useProductLandingContext() - - if (!productUserExamples) { - return null - } - - return ( -
    -
    - {productUserExamples.map((user) => { - return ( -
    - -
    - ) - })} -
    -
    - ) -} diff --git a/src/landings/components/UserCard.tsx b/src/landings/components/UserCard.tsx deleted file mode 100644 index f291a66d5db0..000000000000 --- a/src/landings/components/UserCard.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import cx from 'classnames' -import styles from './Landings.module.scss' -const { hoverShadowLarge } = styles - -type Props = { - user: { - username: string - description: string - } - href?: string -} -export const UserCard = ({ user, href }: Props) => { - return ( - -
    - {user.username} -
    -
    -

    {user.username}

    -

    {user.description}

    -
    -
    - ) -} diff --git a/src/landings/components/discovery/DiscoveryLanding.tsx b/src/landings/components/discovery/DiscoveryLanding.tsx index fe18a1e88c88..bb45b45c56be 100644 --- a/src/landings/components/discovery/DiscoveryLanding.tsx +++ b/src/landings/components/discovery/DiscoveryLanding.tsx @@ -1,12 +1,16 @@ +import { useRouter } from 'next/router' + import { DefaultLayout } from '@/frame/components/DefaultLayout' import { useLandingContext } from '@/landings/context/LandingContext' import { LandingHero } from '@/landings/components/shared/LandingHero' import { ArticleGrid } from '@/landings/components/shared/LandingArticleGridWithFilter' import { LandingCarousel } from '@/landings/components/shared/LandingCarousel' import { UtmPreserver } from '@/frame/components/UtmPreserver' +import { RestRedirect } from '@/rest/components/RestRedirect' import { useMultiQueryParams } from '@/search/components/hooks/useMultiQueryParams' export const DiscoveryLanding = () => { + const router = useRouter() const { title, intro, @@ -25,6 +29,7 @@ export const DiscoveryLanding = () => { return ( + {router.query.productId === 'rest' && }
    diff --git a/src/landings/components/shared/LandingArticleGridWithFilter.tsx b/src/landings/components/shared/LandingArticleGridWithFilter.tsx index d3f08647f627..48d4cf4b8a5f 100644 --- a/src/landings/components/shared/LandingArticleGridWithFilter.tsx +++ b/src/landings/components/shared/LandingArticleGridWithFilter.tsx @@ -272,6 +272,7 @@ export const ArticleGrid = ({ ) => { diff --git a/src/landings/context/LandingContext.tsx b/src/landings/context/LandingContext.tsx index 7f4258c2a910..a74647f0d07a 100644 --- a/src/landings/context/LandingContext.tsx +++ b/src/landings/context/LandingContext.tsx @@ -1,10 +1,9 @@ import { createContext, useContext } from 'react' -import { getFeaturedLinksFromReq } from '@/landings/components/ProductLandingContext' +import { getFeaturedLinksFromReq } from '@/landings/lib/featured-links' import { mapRawTocItemToTocItem } from '@/landings/types' -import type { TocItem } from '@/landings/types' +import type { TocItem, FeaturedLink } from '@/landings/types' import type { ExtendedRequest, Context } from '@/types' import type { JourneyTrack } from '@/journeys/lib/journey-path-resolver' -import type { FeaturedLink } from '@/landings/components/ProductLandingContext' export type LandingType = 'bespoke' | 'discovery' | 'journey' diff --git a/src/landings/lib/featured-links.ts b/src/landings/lib/featured-links.ts new file mode 100644 index 000000000000..d024a02ce482 --- /dev/null +++ b/src/landings/lib/featured-links.ts @@ -0,0 +1,36 @@ +import type { FeaturedLink } from '@/landings/types' + +type FeaturedLinkEntry = { + href: string + title: string + intro?: string | null + fullTitle?: string | null + page?: { authors?: string[] } +} + +type ReqWithFeaturedLinks = { + context: { + featuredLinks?: Record + } +} + +// Helper that reshapes the resolved featured-link data placed on the request +// by the `featuredLinks` middleware into the FeaturedLink shape consumed by +// landing page contexts (toc, category, discovery, journey, bespoke). +export const getFeaturedLinksFromReq = (req: unknown): Record> => { + const { context } = req as ReqWithFeaturedLinks + return Object.fromEntries( + Object.entries(context.featuredLinks || {}).map(([key, entries]) => { + return [ + key, + (entries || []).map((entry) => ({ + href: entry.href, + title: entry.title, + intro: entry.intro || undefined, + authors: entry.page?.authors || [], + fullTitle: entry.fullTitle || undefined, + })), + ] + }), + ) +} diff --git a/src/landings/middleware/featured-links.ts b/src/landings/middleware/featured-links.ts index 5b392600fd1e..d8eae6d4097b 100644 --- a/src/landings/middleware/featured-links.ts +++ b/src/landings/middleware/featured-links.ts @@ -5,7 +5,7 @@ import getLinkData from '@/frame/lib/get-link-data' /** * This is the max. number of featured links, by any category, that we - * display on the product landing pages. + * display on index landing pages (homepage and TOC landings). * The reason it's variable is that some featured links are conditional. * For example: * @@ -20,12 +20,15 @@ import getLinkData from '@/frame/lib/get-link-data' * would end up being blank and thus omitted. * * The reason we don't want to display too many is because it might - * make the product landing page columns that lists links far too + * make the landing page columns that lists links far too * long ("high"). */ const MAX_FEATURED_LINKS = 4 -// this middleware adds properties to the context object +// This middleware resolves `featuredLinks` from the page's frontmatter into +// a `req.context.featuredLinks` object consumed by the homepage and toc +// landing renderers. It runs for any `index.md` page that defines +// `featuredLinks` in frontmatter. export default async function featuredLinks( req: ExtendedRequest, res: Response, @@ -34,13 +37,7 @@ export default async function featuredLinks( if (!req.context) throw new Error('request is not contextualized') if (!req.context.page) return next() - if ( - !( - req.context.page.relativePath.endsWith('index.md') || - req.context.page.layout === 'product-landing' - ) - ) - return next() + if (!req.context.page.relativePath.endsWith('index.md')) return next() if (!req.context.page.featuredLinks) return next() diff --git a/src/landings/pages/product.tsx b/src/landings/pages/product.tsx index 038c7b2b8c03..5f4eb31f8b84 100644 --- a/src/landings/pages/product.tsx +++ b/src/landings/pages/product.tsx @@ -15,12 +15,6 @@ import { addUINamespaces, } from '@/frame/components/context/MainContext' -import { - getProductLandingContextFromRequest, - ProductLandingContextT, - ProductLandingContext, -} from '@/landings/components/ProductLandingContext' - import { getArticleContextFromRequest, ArticleContextT, @@ -28,7 +22,6 @@ import { } from '@/frame/components/context/ArticleContext' import { ArticlePage } from '@/frame/components/article/ArticlePage' -import { ProductLanding } from '@/landings/components/ProductLanding' import { TocLanding } from '@/landings/components/TocLanding' import { CategoryLanding } from '@/landings/components/CategoryLanding' import { @@ -58,7 +51,6 @@ function initiateArticleScripts() { type Props = { mainContext: MainContextT - productLandingContext?: ProductLandingContextT tocLandingContext?: TocLandingContextT articleContext?: ArticleContextT categoryLandingContext?: CategoryLandingContextT @@ -68,7 +60,6 @@ type Props = { } const GlobalPage = ({ mainContext, - productLandingContext, tocLandingContext, articleContext, categoryLandingContext, @@ -106,12 +97,6 @@ const GlobalPage = ({ ) - } else if (productLandingContext) { - content = ( - - - - ) } else if (categoryLandingContext) { content = ( @@ -174,9 +159,6 @@ export const getServerSideProps: GetServerSideProps = async (context) => } else if (currentLayoutName === 'discovery-landing') { props.discoveryContext = await getLandingContextFromRequest(req, 'discovery') additionalUINamespaces.push('product_landing', 'carousels') - } else if (currentLayoutName === 'product-landing') { - props.productLandingContext = await getProductLandingContextFromRequest(req) - additionalUINamespaces.push('product_landing') } else if (relativePath?.endsWith('index.md')) { if (currentLayoutName === 'category-landing') { props.categoryLandingContext = getCategoryLandingContextFromRequest(req) diff --git a/src/landings/tests/featured-links.ts b/src/landings/tests/featured-links.ts index 02f638790138..75ee4203a7ba 100644 --- a/src/landings/tests/featured-links.ts +++ b/src/landings/tests/featured-links.ts @@ -1,7 +1,6 @@ import { describe, expect, test, vi } from 'vitest' import { getDOM } from '@/tests/helpers/e2etest' -import enterpriseServerReleases from '@/versions/lib/enterprise-server-releases' describe('featuredLinks', () => { vi.setConfig({ testTimeout: 60 * 1000 }) @@ -24,21 +23,10 @@ describe('featuredLinks', () => { ) }) - test('Enterprise intro links have expected values', async () => { + test('Enterprise get-started landing renders', async () => { const $ = await getDOM('/en/enterprise-server@latest/get-started') - const $featuredLinks = $('[data-testid=article-list] a') - expect($featuredLinks.length).toBeGreaterThan(0) - - // Fixture content expectations (CI environment) - expect($featuredLinks.eq(0).attr('href')).toBe( - `/en/enterprise-server@${enterpriseServerReleases.latestStable}/get-started/foo/bar`, - ) - expect($featuredLinks.eq(0).find('[data-testid=link-with-intro-title]').text()).toMatch( - 'Bar Usually Comes After Foo', - ) - expect($featuredLinks.eq(0).find('[data-testid=link-with-intro-intro]').text()).toMatch( - "This page doesn't really have an intro", - ) + // get-started uses discovery-landing, so it has hero/spotlight, not article-list. + expect($('h1').text()).toMatch(/Getting started/) }) // This is an important test because one of the popular links, diff --git a/src/landings/types.ts b/src/landings/types.ts index f6e0ddcfb763..8fa25ec196e7 100644 --- a/src/landings/types.ts +++ b/src/landings/types.ts @@ -4,6 +4,15 @@ import { ValidOcticon, isValidOcticon } from './lib/octicons' export type { ValidOcticon } export { isValidOcticon } +export type FeaturedLink = { + title: string + href: string + intro?: string + authors?: Array + date?: string + fullTitle?: string +} + // Base type for all TOC items with core properties export type BaseTocItem = { fullPath: string diff --git a/src/tests/README.md b/src/tests/README.md index f4d6402976ee..8fd2cfb9d25d 100644 --- a/src/tests/README.md +++ b/src/tests/README.md @@ -57,7 +57,6 @@ Some suites require environment variables or tests will fail with 404s or conten ```bash npm run test:article-api -npm run test:changelogs npm run test:fixtures npm run test:landings npm run test:languages # requires Elasticsearch running diff --git a/src/types/types.ts b/src/types/types.ts index 896237334f2c..ced06419308a 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -155,7 +155,6 @@ export type Context = { redirectNotFound?: string earlyAccessPageLinks?: string changelogUrl?: string - whatsNewChangelog?: ChangelogItem[] secretScanningData?: SecretScanningData[] ghesReleases?: GHESRelease[] ghesReleaseNotes?: GHESReleasePatch[] @@ -173,8 +172,6 @@ export type Context = { breadcrumbs?: Breadcrumb[] glossaries?: Glossary[] currentProductName?: string - productCommunityExamples?: ProductExample[] - productUserExamples?: ProductExample[] productGroups?: ProductGroup[] featuredLinks?: FeaturedLinksExpanded renderedPage?: string @@ -270,12 +267,6 @@ export type ReleaseNotes = { } } -export type ChangelogItem = { - title: string - date: string - href: string -} - export type SecretScanningData = { provider: string supportedSecret: string @@ -437,12 +428,6 @@ export type AllVersions = { // is not possible to happen at runtime. export type URLSearchParamsTypes = string | string[][] | Record | URLSearchParams -export type ProductExample = { - repo?: string - user?: string - description: string -} - export type FeatureData = { [key: string]: Versions } From b8982900b6723f374ff68df3d9bd778546d80dc9 Mon Sep 17 00:00:00 2001 From: hubwriter Date: Wed, 6 May 2026 10:31:33 +0100 Subject: [PATCH 09/13] Copilot CLI: Add rubber duck conceptual article (#60992) Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../agents/copilot-cli/about-custom-agents.md | 2 + .../copilot-cli/comparing-cli-features.md | 2 +- .../concepts/agents/copilot-cli/index.md | 1 + .../agents/copilot-cli/rubber-duck.md | 97 +++++++++++++++++++ content/copilot/how-tos/copilot-cli/index.md | 2 + .../copilot-cli/use-copilot-cli/overview.md | 14 ++- .../cli-command-reference.md | 2 +- 7 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 content/copilot/concepts/agents/copilot-cli/rubber-duck.md diff --git a/content/copilot/concepts/agents/copilot-cli/about-custom-agents.md b/content/copilot/concepts/agents/copilot-cli/about-custom-agents.md index 80eb99f5a364..2d0a9dd27737 100644 --- a/content/copilot/concepts/agents/copilot-cli/about-custom-agents.md +++ b/content/copilot/concepts/agents/copilot-cli/about-custom-agents.md @@ -33,6 +33,8 @@ In addition to the main {% data variables.product.prodname_copilot_short %} agen * **research** — This agent operates as a staff-level software engineer and research specialist. It provides exhaustive, meticulously researched answers about codebases, APIs, libraries, and software architecture. It uses {% data variables.product.github %} search/exploration tools, web fetch/search, and local tools. Unlike the other agents, the research agent can only be invoked by using the `/research` slash command. It cannot be automatically triggered by the main agent. +* **rubber-duck** — A constructive critic that gives {% data variables.product.prodname_copilot_short %} a second opinion on its own plans, code, and tests. It runs on a different model from the one driving your session, so it brings a complementary perspective. It is designed to review proposed changes, not to make file changes itself. For more information, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/rubber-duck). + ## Running agents as subagents One of the benefits of using custom agents you have defined yourself—or the built-in agents—is that the main {% data variables.product.prodname_copilot_short %} agent can run them as subagents with a separate context window. This means that your custom agent, or built-in agent, can focus on a specific subtask without cluttering the context window of the main agent. diff --git a/content/copilot/concepts/agents/copilot-cli/comparing-cli-features.md b/content/copilot/concepts/agents/copilot-cli/comparing-cli-features.md index 68cf236cd539..6f9f7ba7c228 100644 --- a/content/copilot/concepts/agents/copilot-cli/comparing-cli-features.md +++ b/content/copilot/concepts/agents/copilot-cli/comparing-cli-features.md @@ -320,7 +320,7 @@ Subagents help {% data variables.product.prodname_copilot_short %}: **Custom agents** provide {% data variables.product.prodname_copilot_short %} with specialist knowledge about a particular subject, and define a particular approach that {% data variables.product.prodname_copilot_short %} should use when working in that area. You can think of a custom agent as a "persona" that {% data variables.product.prodname_copilot_short %} can adopt when working on certain tasks. -{% data variables.copilot.copilot_cli_short %} has several built-in custom agents. For example, the `explore`, `task`, `research`, `code-review`, and `general-purpose` agents. You can also define your own custom agents, to meet your specific needs. +{% data variables.copilot.copilot_cli_short %} has several built-in custom agents. For example, the `explore`, `task`, `research`, `code-review`, `rubber-duck`, and `general-purpose` agents. You can also define your own custom agents, to meet your specific needs. You define a custom agent in a Markdown file with YAML frontmatter. The file contains: diff --git a/content/copilot/concepts/agents/copilot-cli/index.md b/content/copilot/concepts/agents/copilot-cli/index.md index 4fb6f7c59556..27249ba410c0 100644 --- a/content/copilot/concepts/agents/copilot-cli/index.md +++ b/content/copilot/concepts/agents/copilot-cli/index.md @@ -16,6 +16,7 @@ children: - /fleet - /research - /chronicle + - /rubber-duck - /lsp-servers - /context-management contentType: concepts diff --git a/content/copilot/concepts/agents/copilot-cli/rubber-duck.md b/content/copilot/concepts/agents/copilot-cli/rubber-duck.md new file mode 100644 index 000000000000..d958a5fb0fd4 --- /dev/null +++ b/content/copilot/concepts/agents/copilot-cli/rubber-duck.md @@ -0,0 +1,97 @@ +--- +title: About the rubber duck agent +shortTitle: About rubber duck +allowTitleToDifferFromFilename: true +intro: 'The rubber duck agent is a built-in critic that gives {% data variables.product.prodname_copilot_short %} a constructive second opinion on its own plans, code, and tests—using a different AI model from the one driving your session.' +product: '{% data reusables.gated-features.copilot-cli %}' +versions: + feature: copilot +contentType: concepts +category: + - Learn about Copilot # Copilot discovery page + - Learn about Copilot CLI # Copilot CLI bespoke page +docsTeamMetrics: + - copilot-cli +--- + +## Introduction + +Rubber duck is a built-in agent in {% data variables.copilot.copilot_cli %} that acts as a constructive critic. While working on a task, the main CLI agent for a session can pass its current plan, design, implementation, or tests over to the rubber duck agent for review. The rubber duck agent looks for blind spots, design flaws, and substantive issues, and reports back with concrete, actionable feedback. {% data variables.product.prodname_copilot_short %} then takes that critique into account before continuing. + +The rubber duck agent is designed to review proposed changes, not to make file changes itself. The main agent for the session decides what to do with the feedback. + +> [!NOTE] +> The rubber duck agent is currently only available if the main agent is using a Claude or GPT large language model. + +## Why "rubber duck"? + +The name comes from a long-standing technique in software engineering called **rubber ducking** in which you explain your code, or proposed solution, to an inanimate object—traditionally a rubber duck. The idea is that by articulating your thinking, you often uncover mistakes, misunderstandings, or logical flaws. + +The rubber duck agent applies a similar idea to {% data variables.product.prodname_copilot_short %}. Before moving ahead with a non-trivial change, {% data variables.product.prodname_copilot_short %} can stop, articulate its current thinking, and have it scrutinized by an independent reviewer. Unlike a real rubber duck, this one talks back: it returns a structured critique that {% data variables.product.prodname_copilot_short %} can act on. + +## Second opinion from another model + +A key design feature of the rubber duck agent is that it deliberately runs on a **different AI model from the one driving your session**. {% data variables.copilot.copilot_cli %} picks a critic model that contrasts with the current session model. For example, if you have chosen to use a Claude model for your session, the rubber duck agent may use a GPT model as the critic. {% data variables.copilot.copilot_cli_short %} only uses the rubber duck agent if a suitable model is available to provide a useful critique. + +The benefit of using a different model is that the critic is less likely to share the same blind spots, biases, or failure modes as the model that produced the work. You effectively get two independent perspectives on the same problem. + +The appropriate critic model is selected automatically each time the rubber duck agent is invoked, based on your current session model. If you switch session models mid-session (for example, with the `/model` command), the next invocation of the rubber duck agent picks the appropriate critic for the new session model. + +## What the rubber duck agent does + +When the rubber duck agent is consulted, it: + +1. **Reads the work in context.** It understands what the code, design, or proposal is trying to accomplish, how it integrates with the rest of the system, and what assumptions exist. +1. **Identifies real issues.** It looks for bugs, logic errors, security vulnerabilities, design flaws, anti-patterns, performance bottlenecks, and other problems that genuinely matter to the success of the task. +1. **Recommends specific fixes.** For each issue it finds, it states the issue, its impact, and a concrete suggested change. +1. **Categorizes its feedback** by severity: + * **Blocking issues**—must be fixed for the work to succeed. + * **Non-blocking issues**—should be fixed to improve quality, but won't prevent success. + * **Suggestions**—lower-priority improvements that still have a real impact on the outcome. +1. **Only reports findings that matter.** If it finds no issues, it says so explicitly. The rubber duck agent is configured not to comment on style, formatting, naming conventions, grammar in comments, minor refactors, or best practices that don't prevent actual problems. + +The rubber duck agent has read-only access to your codebase via the standard exploration tools. It cannot edit files or run commands that change your environment. + +## When {% data variables.product.prodname_copilot_short %} consults the rubber duck agent + +When the rubber duck agent is enabled, {% data variables.product.prodname_copilot_short %} is instructed to consult it at high-leverage moments rather than only when stuck. Typical situations include: + +* **After planning a non-trivial change, but before implementing it.** This is the highest-leverage moment to catch design flaws, while course corrections are still cheap. +* **Mid-implementation,** to check for blind spots in a complex piece of work. +* **After writing tests,** to validate that test coverage is comprehensive and that the behavior actually satisfies your original request. +* **Reactively, when {% data variables.product.prodname_copilot_short %} hits repeated failures or unexpected results,** to get an independent analysis of the problem rather than retrying the same approach. + +For small, well-understood changes {% data variables.product.prodname_copilot_short %} typically skips the rubber duck agent. + +When {% data variables.product.prodname_copilot_short %} consults the rubber duck agent, it summarizes the resulting critique for you in the timeline output rather than repeating it verbatim—for example, "The critique pointed out a blind spot in my plan around X, so I updated my plan to address that." + +## Manually invoking the rubber duck agent + +Typically {% data variables.copilot.copilot_cli_short %} consults the rubber duck agent automatically. You don't need to do anything. The timeline output shows when the main agent is getting a rubber duck critique. However, sometimes the CLI will not use the rubber duck agent. For example, it may decide that the changes are not extensive enough to warrant a critique. + +You can use a natural language prompt to explicitly ask {% data variables.product.prodname_copilot_short %} to get a second opinion. For example, after asking {% data variables.product.prodname_copilot_short %} to produce a plan of work, you could enter a prompt such as: + +```copilot +Rubber duck your plan. +``` + +Or part way through a series of changes, you could prompt: + +```copilot +Get a critique of the changes you've made so far. +``` + +## Benefits of using the rubber duck agent + +* **Catches issues early.** Most non-trivial tasks that fail have problems that a critique could have caught at the planning stage. Getting feedback before code is written is preferable to fixing problems later in the process. + + > [!NOTE] + > Consulting the rubber duck agent runs an additional reasoning pass on a separate model, so it adds some latency and involves additional model usage. The upside is that spending a little more time and resources up front can save you time and model usage overall by catching issues early and by reducing the number of failed attempts to complete a task. + +* **Reduces single-model blind spots.** Because the agent uses a model from a different family, it brings a genuinely different perspective rather than re-running the same reasoning that produced the original work. +* **Improves quality of complex changes.** Architectural decisions, multi-file changes, and unfamiliar codebases all benefit from a second opinion before {% data variables.product.prodname_copilot_short %} commits to an approach. +* **Stays out of the way for simple tasks.** {% data variables.product.prodname_copilot_short %} only consults the rubber duck agent when the work is non-trivial, so it doesn't slow down quick edits and obvious fixes. + +## Further reading + +* [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-custom-agents#built-in-agents) diff --git a/content/copilot/how-tos/copilot-cli/index.md b/content/copilot/how-tos/copilot-cli/index.md index 74170d029236..222aa795c285 100644 --- a/content/copilot/how-tos/copilot-cli/index.md +++ b/content/copilot/how-tos/copilot-cli/index.md @@ -27,6 +27,7 @@ children: - /content/copilot/concepts/agents/about-agent-skills - /content/copilot/concepts/agents/copilot-cli/about-cli-plugins - /content/copilot/concepts/agents/copilot-cli/about-copilot-cli + - /content/copilot/concepts/agents/copilot-cli/about-custom-agents - /content/copilot/concepts/agents/copilot-cli/about-remote-access - /content/copilot/concepts/agents/copilot-cli/autopilot - /content/copilot/concepts/agents/copilot-cli/cancel-and-roll-back @@ -36,6 +37,7 @@ children: - /content/copilot/concepts/agents/copilot-cli/fleet - /content/copilot/concepts/agents/copilot-cli/lsp-servers - /content/copilot/concepts/agents/copilot-cli/research + - /content/copilot/concepts/agents/copilot-cli/rubber-duck - /content/copilot/reference/copilot-cli-reference/acp-server - /content/copilot/reference/copilot-cli-reference/cli-command-reference - /content/copilot/reference/copilot-cli-reference/cli-plugin-reference diff --git a/content/copilot/how-tos/copilot-cli/use-copilot-cli/overview.md b/content/copilot/how-tos/copilot-cli/use-copilot-cli/overview.md index 6ca5cae91661..52431400eb7a 100644 --- a/content/copilot/how-tos/copilot-cli/use-copilot-cli/overview.md +++ b/content/copilot/how-tos/copilot-cli/use-copilot-cli/overview.md @@ -163,18 +163,28 @@ A {% data variables.copilot.copilot_custom_agent_short %} is a specialized versi Executes commands such as tests and builds, providing brief summaries on success and full output on failure. - General-purpose + General purpose Handles complex, multi-step tasks that require the full toolset and high-quality reasoning, running in a separate context to keep your main conversation clearly focused. - Code-review + Code review Reviews changes with a focus on surfacing only genuine issues, minimizing noise. + + Research + Performs deep research across your codebase, relevant repositories, and the web, producing a detailed report with citations. + + + Rubber duck + Acts as a constructive critic to provide feedback on some non-trivial tasks. Used automatically by {% data variables.copilot.copilot_cli_short %}. + The AI model being used by the CLI can choose to delegate a task to a subsidiary subagent process, that operates using a {% data variables.copilot.copilot_custom_agent_short %} with specific expertise, if it judges that this would result in the work being completed more effectively. The model may equally choose to handle the work directly in the main agent. +Some built-in {% data variables.copilot.custom_agents_short %}, such as the rubber duck agent, are consulted automatically by {% data variables.product.prodname_copilot_short %} on your behalf rather than invoked by you directly. You won't see them as separate options when you run `/agent`, but you may see {% data variables.product.prodname_copilot_short %} mention them as it works through a task. + You can define your own {% data variables.copilot.custom_agents_short %} using Markdown files, called {% data variables.copilot.agent_profiles %}, that specify what expertise the agent should have, what tools it can use, and any specific instructions for how it should respond. You can define {% data variables.copilot.custom_agents_short %} at the user, repository, or organization/enterprise level: diff --git a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md index a0450162490a..1d65433ffc1f 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md @@ -589,7 +589,7 @@ Custom agents are specialized AI agents defined in Markdown files. The filename | `explore` | claude-haiku-4.5 | Fast codebase exploration. Searches files, reads code, and answers questions. Returns focused answers under 300 words. Safe to run in parallel. | | `general-purpose` | claude-sonnet-4.5 | Full-capability agent for complex multi-step tasks. Runs in a separate context window. | | `research` | claude-sonnet-4.6 | Deep research agent. Generates a report based on information in your codebase, in relevant repositories, and on the web. | -| `rubber-duck` | complementary model | Use a complementary model to provide a constructive critique of proposals, designs, implementations, or tests. Identifies weak points and suggests improvements. When using Claude, it uses a GPT model; when using GPT, it uses Claude Opus 4.7. Never makes direct code changes. {% data reusables.copilot.experimental %} | +| `rubber-duck` | complementary model | Use a complementary model to provide a constructive critique of proposals, designs, implementations, or tests. Identifies weak points and suggests improvements. See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/rubber-duck). | | `task` | claude-haiku-4.5 | Command execution (tests, builds, lints). Returns brief summary on success, full output on failure. | ### Custom agent frontmatter fields From 848387d938ca8920c60bc2e62f57e5184d929231 Mon Sep 17 00:00:00 2001 From: Sophie <29382425+sophietheking@users.noreply.github.com> Date: Wed, 6 May 2026 14:25:30 +0200 Subject: [PATCH 10/13] Copilot Code Review Active and Passive User Counts [GA] (#61025) Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- .../concepts/copilot-usage-metrics/copilot-metrics.md | 3 ++- .../copilot-usage-metrics/copilot-usage-metrics.md | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/content/copilot/concepts/copilot-usage-metrics/copilot-metrics.md b/content/copilot/concepts/copilot-usage-metrics/copilot-metrics.md index f5903da666fd..34c665b495b0 100644 --- a/content/copilot/concepts/copilot-usage-metrics/copilot-metrics.md +++ b/content/copilot/concepts/copilot-usage-metrics/copilot-metrics.md @@ -98,7 +98,7 @@ You can expect data to be available within **two full days**. This means that da {% data variables.product.prodname_copilot_short %} usage metrics can be grouped into a few main categories: Adoption, engagement, acceptance rate, Lines of Code (LoC), and pull request lifecycle metrics. -**Adoption** measures how many licensed developers are actively using {% data variables.product.prodname_copilot_short %}. For example, daily active users (DAU) tells you how many unique users interacted with {% data variables.product.prodname_copilot_short %} on a given day. Ideally, you'll see a consistent upward trend in these metrics during rollout. +**Adoption** measures how many licensed developers are actively using {% data variables.product.prodname_copilot_short %}. For example, daily active users (DAU) tells you how many unique users interacted with {% data variables.product.prodname_copilot_short %} on a given day. Ideally, you'll see a consistent upward trend in these metrics during rollout. {% data variables.copilot.copilot_code-review_short %} adoption is tracked separately, with distinct active and passive user counts. Active users manually requested a review or applied a suggestion; passive users had {% data variables.copilot.copilot_code-review_short %} automatically assigned to review their pull request. When a user has both signals in the same period, they are counted as active only. **Engagement** measures describe how deeply developers use {% data variables.product.prodname_copilot_short %} once they’ve adopted it. Key engagement metrics show not only frequency of use but also breadth across features. For example, average chat requests per active user measures how often users open and interact with {% data variables.copilot.copilot_chat_short %}. You'd want to see regular and increasing chat use across languages and IDEs. @@ -127,6 +127,7 @@ These metrics can be used together to answer key questions about your teams' usa | Do developers trust {% data variables.product.prodname_copilot_short %}’s output? | Acceptance rate trends | | Are enablement efforts working? | Growth in adoption and engagement after training or communication campaigns | | Is {% data variables.product.prodname_copilot_short %} influencing delivery speed or pull request throughput? | Pull request merge counts and median time to merge | +| How is {% data variables.copilot.copilot_code-review_short %} being adopted? | Active versus passive code review user counts | Look for patterns across these signals rather than focusing on any single number. For example, a steady DAU paired with a rising acceptance rate indicates growing trust and value. diff --git a/content/copilot/reference/copilot-usage-metrics/copilot-usage-metrics.md b/content/copilot/reference/copilot-usage-metrics/copilot-usage-metrics.md index 9327ebbb7ed7..3e8fefea1828 100644 --- a/content/copilot/reference/copilot-usage-metrics/copilot-usage-metrics.md +++ b/content/copilot/reference/copilot-usage-metrics/copilot-usage-metrics.md @@ -92,6 +92,12 @@ For example schemas of the data returned by the APIs, see [AUTOTITLE](/copilot/r | `totals_by_model_feature` / `totals_by_language_model` | Model-specific breakdowns for chat activity (not completions). When {% data variables.copilot.copilot_auto_model_selection_short %} is enabled, activity is attributed to the actual model used rather than appearing as `Auto`. | | `last_known_ide_version` / `last_known_plugin_version` | The most recent IDE and {% data variables.copilot.copilot_chat_short %} extension version detected for each user. | | `daily_active_cli_users` | Number of unique users in the enterprise or organization who used {% data variables.product.prodname_copilot_short %} via the CLI on a given day. This field is **independent** of IDE active user counts and is **not** included in IDE-based active user definitions. Omitted for enterprises or organizations with no CLI usage on that day. | +| `daily_active_copilot_code_review_users` | Number of unique users who actively used {% data variables.copilot.copilot_code-review_short %} on a given day. Active usage means manually requesting a review or applying a suggestion. When a user has both active and passive signals in the same period, they are counted as active only. | +| `daily_passive_copilot_code_review_users` | Number of unique users who had {% data variables.copilot.copilot_code-review_short %} automatically assigned to review their pull request on a given day, with no active engagement. | +| `weekly_active_copilot_code_review_users` | Number of unique users who actively used {% data variables.copilot.copilot_code-review_short %} during a trailing seven-day window. When a user has both active and passive signals in the same period, they are counted as active only. | +| `weekly_passive_copilot_code_review_users` | Number of unique users who had {% data variables.copilot.copilot_code-review_short %} automatically assigned to review their pull request during a trailing seven-day window, with no active engagement. | +| `monthly_active_copilot_code_review_users` | Number of unique users who actively used {% data variables.copilot.copilot_code-review_short %} during a trailing 28-day window. When a user has both active and passive signals in the same period, they are counted as active only. | +| `monthly_passive_copilot_code_review_users` | Number of unique users who had {% data variables.copilot.copilot_code-review_short %} automatically assigned to review their pull request during a trailing 28-day window, with no active engagement. | | `totals_by_cli` | Breakdown of CLI-specific metrics for the enterprise, organization, or user on a given day. Independent of IDE metrics—CLI usage is **not** reflected in other fields such as `totals_by_ide` or `totals_by_feature`. Omitted when there's no CLI usage on that day. See [{% data variables.copilot.copilot_cli_short %} metrics fields](#copilot-cli-metrics-fields-api-only) below. | | `used_cli` | Captures whether the user has used {% data variables.copilot.copilot_cli_short %} that day. | | `used_agent` | Captures whether the user has used agent mode in the IDE that day. Does not include {% data variables.copilot.copilot_code-review_short %} activity, which is captured separately in `used_copilot_code_review_active` and `used_copilot_code_review_passive`. | From 64777314910579e2c90a744437c4f04121a31755 Mon Sep 17 00:00:00 2001 From: docs-bot <77750099+docs-bot@users.noreply.github.com> Date: Wed, 6 May 2026 05:56:43 -0700 Subject: [PATCH 11/13] Update OpenAPI Description (#61061) Co-authored-by: Tim Rogers Co-authored-by: Anne-Marie <102995847+am-stead@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- content/rest/actions/concurrency-groups.md | 14 + content/rest/actions/index.md | 1 + content/rest/agent-tasks/agent-tasks.md | 14 + content/rest/agent-tasks/index.md | 12 + content/rest/index.md | 1 + .../fine-grained-pat-permissions.json | 27 + .../data/fpt-2022-11-28/fine-grained-pat.json | 18 + .../server-to-server-permissions.json | 33 + .../fpt-2022-11-28/server-to-server-rest.json | 18 + .../fpt-2022-11-28/user-to-server-rest.json | 18 + .../fine-grained-pat-permissions.json | 27 + .../data/fpt-2026-03-10/fine-grained-pat.json | 18 + .../server-to-server-permissions.json | 33 + .../fpt-2026-03-10/server-to-server-rest.json | 18 + .../fpt-2026-03-10/user-to-server-rest.json | 18 + .../fine-grained-pat-permissions.json | 27 + .../ghec-2022-11-28/fine-grained-pat.json | 18 + .../server-to-server-permissions.json | 33 + .../server-to-server-rest.json | 18 + .../ghec-2022-11-28/user-to-server-rest.json | 18 + .../fine-grained-pat-permissions.json | 27 + .../ghec-2026-03-10/fine-grained-pat.json | 18 + .../server-to-server-permissions.json | 33 + .../server-to-server-rest.json | 18 + .../ghec-2026-03-10/user-to-server-rest.json | 18 + src/github-apps/lib/config.json | 2 +- .../lib/static/redirect-exceptions.txt | 5 - src/rest/data/fpt-2022-11-28/actions.json | 657 ++++++ src/rest/data/fpt-2022-11-28/agent-tasks.json | 1994 +++++++++++++++++ src/rest/data/fpt-2022-11-28/orgs.json | 8 +- .../fpt-2022-11-28/private-registries.json | 80 +- .../data/fpt-2022-11-28/secret-scanning.json | 22 + src/rest/data/fpt-2026-03-10/actions.json | 657 ++++++ src/rest/data/fpt-2026-03-10/agent-tasks.json | 1994 +++++++++++++++++ src/rest/data/fpt-2026-03-10/orgs.json | 8 +- .../fpt-2026-03-10/private-registries.json | 80 +- .../data/fpt-2026-03-10/secret-scanning.json | 22 + src/rest/data/ghec-2022-11-28/actions.json | 657 ++++++ .../data/ghec-2022-11-28/agent-tasks.json | 1994 +++++++++++++++++ src/rest/data/ghec-2022-11-28/orgs.json | 8 +- .../ghec-2022-11-28/private-registries.json | 80 +- .../data/ghec-2022-11-28/secret-scanning.json | 31 + src/rest/data/ghec-2026-03-10/actions.json | 657 ++++++ .../data/ghec-2026-03-10/agent-tasks.json | 1994 +++++++++++++++++ src/rest/data/ghec-2026-03-10/orgs.json | 8 +- .../ghec-2026-03-10/private-registries.json | 80 +- .../data/ghec-2026-03-10/secret-scanning.json | 31 + .../data/ghes-3.15-2022-11-28/actions.json | 6 + .../ghes-3.15-2022-11-28/secret-scanning.json | 4 + .../data/ghes-3.16-2022-11-28/actions.json | 6 + .../private-registries.json | 39 +- .../ghes-3.16-2022-11-28/secret-scanning.json | 4 + .../data/ghes-3.17-2022-11-28/actions.json | 6 + .../private-registries.json | 39 +- .../ghes-3.17-2022-11-28/secret-scanning.json | 4 + .../data/ghes-3.18-2022-11-28/actions.json | 6 + .../private-registries.json | 80 +- .../ghes-3.18-2022-11-28/secret-scanning.json | 4 + .../data/ghes-3.19-2022-11-28/actions.json | 6 + .../private-registries.json | 80 +- .../ghes-3.19-2022-11-28/secret-scanning.json | 4 + .../data/ghes-3.20-2022-11-28/actions.json | 6 + .../private-registries.json | 80 +- .../ghes-3.20-2022-11-28/secret-scanning.json | 4 + src/rest/lib/config.json | 2 +- src/webhooks/lib/config.json | 2 +- 66 files changed, 11838 insertions(+), 111 deletions(-) create mode 100644 content/rest/actions/concurrency-groups.md create mode 100644 content/rest/agent-tasks/agent-tasks.md create mode 100644 content/rest/agent-tasks/index.md create mode 100644 src/rest/data/fpt-2022-11-28/agent-tasks.json create mode 100644 src/rest/data/fpt-2026-03-10/agent-tasks.json create mode 100644 src/rest/data/ghec-2022-11-28/agent-tasks.json create mode 100644 src/rest/data/ghec-2026-03-10/agent-tasks.json diff --git a/content/rest/actions/concurrency-groups.md b/content/rest/actions/concurrency-groups.md new file mode 100644 index 000000000000..d245e5f0ab49 --- /dev/null +++ b/content/rest/actions/concurrency-groups.md @@ -0,0 +1,14 @@ +--- +title: REST API endpoints for Actions concurrency groups +shortTitle: Actions concurrency groups +intro: Use the REST API to view and manage concurrency groups for GitHub Actions workflows. +versions: # DO NOT MANUALLY EDIT. CHANGES WILL BE OVERWRITTEN BY A 🤖 + fpt: '*' + ghec: '*' +autogenerated: rest +allowTitleToDifferFromFilename: true +category: + - Automate CI/CD workflows +--- + + diff --git a/content/rest/actions/index.md b/content/rest/actions/index.md index d7cc7ac3ce31..4c9bd61341af 100644 --- a/content/rest/actions/index.md +++ b/content/rest/actions/index.md @@ -15,6 +15,7 @@ versions: children: - /artifacts - /cache + - /concurrency-groups - /hosted-runners - /oidc - /permissions diff --git a/content/rest/agent-tasks/agent-tasks.md b/content/rest/agent-tasks/agent-tasks.md new file mode 100644 index 000000000000..e5fe6c835765 --- /dev/null +++ b/content/rest/agent-tasks/agent-tasks.md @@ -0,0 +1,14 @@ +--- +title: REST API endpoints for agent tasks +shortTitle: Agent tasks +intro: Use the REST API to start and manage {% data variables.copilot.copilot_cloud_agent %} tasks +versions: # DO NOT MANUALLY EDIT. CHANGES WILL BE OVERWRITTEN BY A 🤖 + fpt: '*' + ghec: '*' +autogenerated: rest +allowTitleToDifferFromFilename: true +category: + - Use Copilot and AI services +--- + + diff --git a/content/rest/agent-tasks/index.md b/content/rest/agent-tasks/index.md new file mode 100644 index 000000000000..ae64798f7d74 --- /dev/null +++ b/content/rest/agent-tasks/index.md @@ -0,0 +1,12 @@ +--- +title: REST API endpoints for agent tasks +shortTitle: Agent tasks +autogenerated: rest +allowTitleToDifferFromFilename: true +children: + - /agent-tasks +versions: + fpt: '*' + ghec: '*' +--- + diff --git a/content/rest/index.md b/content/rest/index.md index 019daa3d7699..c48c155dd0d1 100644 --- a/content/rest/index.md +++ b/content/rest/index.md @@ -49,6 +49,7 @@ children: - /guides - /actions - /activity + - /agent-tasks - /announcement-banners - /apps - /billing 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 ec3f990cc4cd..4b097db480dc 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 @@ -3306,6 +3306,24 @@ "additional-permissions": false, "access": "write" }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "additional-permissions": false, + "access": "read" + }, + { + "category": "actions", + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "additional-permissions": false, + "access": "read" + }, { "category": "actions", "slug": "get-a-job-for-a-workflow-run", @@ -3441,6 +3459,15 @@ "additional-permissions": false, "access": "write" }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "additional-permissions": false, + "access": "read" + }, { "category": "actions", "slug": "force-cancel-a-workflow-run", diff --git a/src/github-apps/data/fpt-2022-11-28/fine-grained-pat.json b/src/github-apps/data/fpt-2022-11-28/fine-grained-pat.json index 5529b670de5f..666c87c9c771 100644 --- a/src/github-apps/data/fpt-2022-11-28/fine-grained-pat.json +++ b/src/github-apps/data/fpt-2022-11-28/fine-grained-pat.json @@ -630,6 +630,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -888,6 +900,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "force-cancel-a-workflow-run", "subcategory": "workflow-runs", 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 55279401e371..5ee6e1c47146 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 @@ -4347,6 +4347,28 @@ "server-to-server": true, "additional-permissions": false }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "actions", + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, { "category": "actions", "slug": "get-a-job-for-a-workflow-run", @@ -4512,6 +4534,17 @@ "server-to-server": true, "additional-permissions": false }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, { "category": "actions", "slug": "force-cancel-a-workflow-run", diff --git a/src/github-apps/data/fpt-2022-11-28/server-to-server-rest.json b/src/github-apps/data/fpt-2022-11-28/server-to-server-rest.json index 28a0b3c57ca6..0c0e60cf67f7 100644 --- a/src/github-apps/data/fpt-2022-11-28/server-to-server-rest.json +++ b/src/github-apps/data/fpt-2022-11-28/server-to-server-rest.json @@ -672,6 +672,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -930,6 +942,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "review-custom-deployment-protection-rules-for-a-workflow-run", "subcategory": "workflow-runs", diff --git a/src/github-apps/data/fpt-2022-11-28/user-to-server-rest.json b/src/github-apps/data/fpt-2022-11-28/user-to-server-rest.json index b489d58212b5..c60af9234b33 100644 --- a/src/github-apps/data/fpt-2022-11-28/user-to-server-rest.json +++ b/src/github-apps/data/fpt-2022-11-28/user-to-server-rest.json @@ -672,6 +672,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -930,6 +942,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "force-cancel-a-workflow-run", "subcategory": "workflow-runs", 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 ec3f990cc4cd..4b097db480dc 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 @@ -3306,6 +3306,24 @@ "additional-permissions": false, "access": "write" }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "additional-permissions": false, + "access": "read" + }, + { + "category": "actions", + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "additional-permissions": false, + "access": "read" + }, { "category": "actions", "slug": "get-a-job-for-a-workflow-run", @@ -3441,6 +3459,15 @@ "additional-permissions": false, "access": "write" }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "additional-permissions": false, + "access": "read" + }, { "category": "actions", "slug": "force-cancel-a-workflow-run", diff --git a/src/github-apps/data/fpt-2026-03-10/fine-grained-pat.json b/src/github-apps/data/fpt-2026-03-10/fine-grained-pat.json index 5529b670de5f..666c87c9c771 100644 --- a/src/github-apps/data/fpt-2026-03-10/fine-grained-pat.json +++ b/src/github-apps/data/fpt-2026-03-10/fine-grained-pat.json @@ -630,6 +630,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -888,6 +900,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "force-cancel-a-workflow-run", "subcategory": "workflow-runs", 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 55279401e371..5ee6e1c47146 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 @@ -4347,6 +4347,28 @@ "server-to-server": true, "additional-permissions": false }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "actions", + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, { "category": "actions", "slug": "get-a-job-for-a-workflow-run", @@ -4512,6 +4534,17 @@ "server-to-server": true, "additional-permissions": false }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, { "category": "actions", "slug": "force-cancel-a-workflow-run", diff --git a/src/github-apps/data/fpt-2026-03-10/server-to-server-rest.json b/src/github-apps/data/fpt-2026-03-10/server-to-server-rest.json index 28a0b3c57ca6..0c0e60cf67f7 100644 --- a/src/github-apps/data/fpt-2026-03-10/server-to-server-rest.json +++ b/src/github-apps/data/fpt-2026-03-10/server-to-server-rest.json @@ -672,6 +672,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -930,6 +942,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "review-custom-deployment-protection-rules-for-a-workflow-run", "subcategory": "workflow-runs", diff --git a/src/github-apps/data/fpt-2026-03-10/user-to-server-rest.json b/src/github-apps/data/fpt-2026-03-10/user-to-server-rest.json index b489d58212b5..c60af9234b33 100644 --- a/src/github-apps/data/fpt-2026-03-10/user-to-server-rest.json +++ b/src/github-apps/data/fpt-2026-03-10/user-to-server-rest.json @@ -672,6 +672,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -930,6 +942,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "force-cancel-a-workflow-run", "subcategory": "workflow-runs", 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 10f9dd3a85ca..6a4101ca8fa9 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 @@ -3843,6 +3843,24 @@ "additional-permissions": false, "access": "write" }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "additional-permissions": false, + "access": "read" + }, + { + "category": "actions", + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "additional-permissions": false, + "access": "read" + }, { "category": "actions", "slug": "get-a-job-for-a-workflow-run", @@ -3978,6 +3996,15 @@ "additional-permissions": false, "access": "write" }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "additional-permissions": false, + "access": "read" + }, { "category": "actions", "slug": "force-cancel-a-workflow-run", diff --git a/src/github-apps/data/ghec-2022-11-28/fine-grained-pat.json b/src/github-apps/data/ghec-2022-11-28/fine-grained-pat.json index 1442649db075..c671ba06b4e6 100644 --- a/src/github-apps/data/ghec-2022-11-28/fine-grained-pat.json +++ b/src/github-apps/data/ghec-2022-11-28/fine-grained-pat.json @@ -630,6 +630,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -888,6 +900,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "force-cancel-a-workflow-run", "subcategory": "workflow-runs", 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 e49590ecc6a9..d1ea0a96992b 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 @@ -5652,6 +5652,28 @@ "server-to-server": true, "additional-permissions": false }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "actions", + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, { "category": "actions", "slug": "get-a-job-for-a-workflow-run", @@ -5817,6 +5839,17 @@ "server-to-server": true, "additional-permissions": false }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, { "category": "actions", "slug": "force-cancel-a-workflow-run", diff --git a/src/github-apps/data/ghec-2022-11-28/server-to-server-rest.json b/src/github-apps/data/ghec-2022-11-28/server-to-server-rest.json index 6341e24319e3..b5d70af3d81e 100644 --- a/src/github-apps/data/ghec-2022-11-28/server-to-server-rest.json +++ b/src/github-apps/data/ghec-2022-11-28/server-to-server-rest.json @@ -684,6 +684,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -942,6 +954,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "review-custom-deployment-protection-rules-for-a-workflow-run", "subcategory": "workflow-runs", diff --git a/src/github-apps/data/ghec-2022-11-28/user-to-server-rest.json b/src/github-apps/data/ghec-2022-11-28/user-to-server-rest.json index 793f8b615901..ee0d4a4d7d81 100644 --- a/src/github-apps/data/ghec-2022-11-28/user-to-server-rest.json +++ b/src/github-apps/data/ghec-2022-11-28/user-to-server-rest.json @@ -684,6 +684,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -942,6 +954,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "force-cancel-a-workflow-run", "subcategory": "workflow-runs", 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 10f9dd3a85ca..6a4101ca8fa9 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 @@ -3843,6 +3843,24 @@ "additional-permissions": false, "access": "write" }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "additional-permissions": false, + "access": "read" + }, + { + "category": "actions", + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "additional-permissions": false, + "access": "read" + }, { "category": "actions", "slug": "get-a-job-for-a-workflow-run", @@ -3978,6 +3996,15 @@ "additional-permissions": false, "access": "write" }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "additional-permissions": false, + "access": "read" + }, { "category": "actions", "slug": "force-cancel-a-workflow-run", diff --git a/src/github-apps/data/ghec-2026-03-10/fine-grained-pat.json b/src/github-apps/data/ghec-2026-03-10/fine-grained-pat.json index 1442649db075..c671ba06b4e6 100644 --- a/src/github-apps/data/ghec-2026-03-10/fine-grained-pat.json +++ b/src/github-apps/data/ghec-2026-03-10/fine-grained-pat.json @@ -630,6 +630,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -888,6 +900,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "force-cancel-a-workflow-run", "subcategory": "workflow-runs", 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 e49590ecc6a9..d1ea0a96992b 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 @@ -5652,6 +5652,28 @@ "server-to-server": true, "additional-permissions": false }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "actions", + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, { "category": "actions", "slug": "get-a-job-for-a-workflow-run", @@ -5817,6 +5839,17 @@ "server-to-server": true, "additional-permissions": false }, + { + "category": "actions", + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, { "category": "actions", "slug": "force-cancel-a-workflow-run", diff --git a/src/github-apps/data/ghec-2026-03-10/server-to-server-rest.json b/src/github-apps/data/ghec-2026-03-10/server-to-server-rest.json index 6341e24319e3..b5d70af3d81e 100644 --- a/src/github-apps/data/ghec-2026-03-10/server-to-server-rest.json +++ b/src/github-apps/data/ghec-2026-03-10/server-to-server-rest.json @@ -684,6 +684,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -942,6 +954,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "review-custom-deployment-protection-rules-for-a-workflow-run", "subcategory": "workflow-runs", diff --git a/src/github-apps/data/ghec-2026-03-10/user-to-server-rest.json b/src/github-apps/data/ghec-2026-03-10/user-to-server-rest.json index 793f8b615901..ee0d4a4d7d81 100644 --- a/src/github-apps/data/ghec-2026-03-10/user-to-server-rest.json +++ b/src/github-apps/data/ghec-2026-03-10/user-to-server-rest.json @@ -684,6 +684,18 @@ "verb": "delete", "requestPath": "/repos/{owner}/{repo}/actions/caches/{cache_id}" }, + { + "slug": "list-concurrency-groups-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups" + }, + { + "slug": "get-a-concurrency-group-for-a-repository", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}" + }, { "slug": "get-a-job-for-a-workflow-run", "subcategory": "workflow-jobs", @@ -942,6 +954,12 @@ "verb": "post", "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel" }, + { + "slug": "list-concurrency-groups-for-a-workflow-run", + "subcategory": "concurrency-groups", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups" + }, { "slug": "force-cancel-a-workflow-run", "subcategory": "workflow-runs", diff --git a/src/github-apps/lib/config.json b/src/github-apps/lib/config.json index 2ec27eb13dc2..1ccc0c154967 100644 --- a/src/github-apps/lib/config.json +++ b/src/github-apps/lib/config.json @@ -60,5 +60,5 @@ "2022-11-28" ] }, - "sha": "d3a3c2a50bb45b5f437bdfd8e0c700091bb1fb7b" + "sha": "12330abe1a9651268439945b92312855bb071532" } \ No newline at end of file diff --git a/src/redirects/lib/static/redirect-exceptions.txt b/src/redirects/lib/static/redirect-exceptions.txt index 7bf99b7f62f6..9f7a56931291 100644 --- a/src/redirects/lib/static/redirect-exceptions.txt +++ b/src/redirects/lib/static/redirect-exceptions.txt @@ -48,8 +48,3 @@ - /github-ae@latest/admin/overview/about-data-residency - /github-ae@latest/admin/overview/deploying-github-ae - /github-ae@latest/admin/overview/initializing-github-ae - -# Agent tasks REST API was rolled back before launch -/rest -- /rest/agent-tasks -- /rest/agent-tasks/agent-tasks diff --git a/src/rest/data/fpt-2022-11-28/actions.json b/src/rest/data/fpt-2022-11-28/actions.json index 0a0b8005c020..18a98ba54ed3 100644 --- a/src/rest/data/fpt-2022-11-28/actions.json +++ b/src/rest/data/fpt-2022-11-28/actions.json @@ -2520,6 +2520,657 @@ } } ], + "concurrency-groups": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "title": "List concurrency groups for a repository", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "per_page", + "description": "

    The number of results per page (max 100). For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "schema": { + "type": "integer", + "default": 30 + } + }, + { + "name": "after", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Lists the active concurrency groups for a repository.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "last_acquired_at": "2026-01-15T16:14:23Z" + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build", + "last_acquired_at": "2026-01-15T16:13:55Z" + } + ] + }, + "schema": { + "title": "Concurrency Group List", + "description": "A list of active concurrency groups for a repository.", + "type": "object", + "required": [ + "total_count", + "concurrency_groups" + ], + "properties": { + "total_count": { + "type": "integer" + }, + "concurrency_groups": { + "type": "array", + "items": { + "type": "object", + "required": [ + "group_name", + "group_url", + "last_acquired_at" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group." + }, + "last_acquired_at": { + "type": [ + "string", + "null" + ], + "format": "date-time" + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "title": "Get a concurrency group for a repository", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "concurrency_group_name", + "description": "

    The name of the concurrency group.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ahead_of_run", + "description": "

    Filter to items ahead of this workflow run ID in the queue, plus the run itself.\nMatches workflow-level concurrency and reusable-workflow leases held on behalf of\nthe run. Mutually exclusive with ahead_of_job.

    ", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + }, + { + "name": "ahead_of_job", + "description": "

    Filter to items ahead of this job ID in the queue, plus the job itself.\nMatches job-level concurrency and reusable-workflow leases on the job's\nancestor paths. Mutually exclusive with ahead_of_run.

    ", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Gets a specific concurrency group for a repository, including all instances in the group's queue.\nReturns 404 if the group is inactive or does not exist.

    \n

    Optionally, pass ahead_of_run or ahead_of_job to filter the results to only the items\nahead of the specified workflow run or job in the queue, plus the specified item itself\n(returned as the last element). This is useful for determining what is blocking a particular\nrun or job. Returns 422 if the specified run or job is not in this concurrency group.

    \n

    When using ahead_of_run, this matches workflow-level concurrency and any reusable-workflow\nleases held on behalf of that run. Job-level leases within the run are not considered to\nblock the run as a whole. Use ahead_of_job to match job-level concurrency and reusable-workflow\nleases on the job's ancestor paths.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "concurrency_group_name": "CONCURRENCY_GROUP_NAME" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "total_count": 3, + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "in_progress" + }, + { + "run_id": 30433643, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433643", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433643", + "status": "pending" + }, + { + "run_id": 30433644, + "run_name": "Deploy hotfix", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433644", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433644", + "job_id": 798245260, + "job_name": "deploy", + "job_url": "https://api.github.com/repos/octocat/Hello-World/actions/jobs/798245260", + "job_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433644/job/798245260", + "status": "pending" + } + ] + }, + "schema": { + "title": "Concurrency Group", + "description": "A concurrency group with the workflow runs and jobs that are either currently holding\nor waiting for the concurrency group lease.", + "type": "object", + "required": [ + "group_name", + "group_url", + "total_count", + "group_members" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group." + }, + "total_count": { + "type": "integer" + }, + "group_members": { + "type": "array", + "items": { + "type": "object", + "required": [ + "run_id", + "run_name", + "run_url", + "run_html_url", + "status" + ], + "properties": { + "run_id": { + "type": "integer", + "description": "The ID of the workflow run." + }, + "run_name": { + "type": "string", + "description": "The name of the workflow run." + }, + "run_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the workflow run." + }, + "run_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the workflow run." + }, + "job_id": { + "type": "integer", + "description": "The ID of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_name": { + "type": "string", + "description": "The display name of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the job." + }, + "job_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the job." + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "pending" + ] + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "title": "List concurrency groups for a workflow run", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "run_id", + "description": "

    The unique identifier of the workflow run.

    ", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "per_page", + "description": "

    The number of results per page (max 100). For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "schema": { + "type": "integer", + "default": 30 + } + }, + { + "name": "before", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results before this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "after", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Lists all concurrency groups associated with a workflow run or its jobs.

    \n

    The set of groups is derived from the run's configuration, so a group is\nincluded even when the run no longer has any items currently holding or\nwaiting in it. In that case the group_members array will be empty.\ntotal_count reflects the number of groups the run participates in by\nconfiguration, not the number with active items.

    \n

    This differs from GET /repos/{owner}/{repo}/actions/concurrency_groups/{group_name},\nwhich returns 404 when a group has no active items. That endpoint reports\nthe live state of a group repo-wide, while this endpoint reports the\ngroups associated with a specific run by configuration.

    \n

    Results are sorted by group name and support cursor-based pagination via\nbefore and after. The after cursor paginates forward only and does\nnot emit a rel=\"prev\" Link; use before to page backward from a\nforward page's next cursor.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "run_id": "RUN_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "in_progress", + "position": 0, + "position_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod?ahead_of_run=30433642" + } + ] + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build", + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "pending", + "position": 2, + "position_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build?ahead_of_job=798245260", + "job_id": 798245260, + "job_name": "build", + "job_url": "https://api.github.com/repos/octocat/Hello-World/actions/jobs/798245260", + "job_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642/job/798245260" + } + ] + } + ] + }, + "schema": { + "title": "Concurrency Group Run List", + "description": "A list of concurrency groups associated with a workflow run.", + "type": "object", + "required": [ + "total_count", + "concurrency_groups" + ], + "properties": { + "total_count": { + "type": "integer", + "description": "The total number of concurrency groups this workflow run participates in,\nderived from the run's configuration. This count is not filtered by\nwhether the run currently holds or is waiting in each group, so it can\ninclude groups whose `group_members` array is empty (for example, when\nthe run has already released its lease in that group)." + }, + "concurrency_groups": { + "type": "array", + "items": { + "type": "object", + "required": [ + "group_name", + "group_url", + "group_members" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group. May return 404 if the group\nhas no active items at the time it is requested, since the\nget-by-name endpoint reports the live repo-wide state of a group\nwhile this endpoint lists groups associated with a run by\nconfiguration." + }, + "group_members": { + "type": "array", + "description": "Items belonging to this workflow run that are either currently holding or\nwaiting for the concurrency group lease. May be empty if the run no\nlonger has any active or queued items in this group.", + "items": { + "type": "object", + "required": [ + "run_id", + "run_name", + "run_url", + "run_html_url", + "status", + "position", + "position_url" + ], + "properties": { + "run_id": { + "type": "integer", + "description": "The ID of the workflow run." + }, + "run_name": { + "type": "string", + "description": "The name of the workflow run." + }, + "run_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the workflow run." + }, + "run_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the workflow run." + }, + "position": { + "type": "integer", + "description": "Queue position. 0 means the item holds the concurrency lease (in_progress), 1 or higher means queued (pending)." + }, + "position_url": { + "type": "string", + "format": "uri", + "description": "API URL to get items ahead of this item in the concurrency group." + }, + "job_id": { + "type": [ + "integer", + "null" + ], + "description": "The ID of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_name": { + "type": [ + "string", + "null" + ], + "description": "The display name of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the job." + }, + "job_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the job." + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "pending" + ] + } + } + } + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + } + ], "hosted-runners": [ { "serverUrl": "https://api.github.com", @@ -27008,6 +27659,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/fpt-2022-11-28/agent-tasks.json b/src/rest/data/fpt-2022-11-28/agent-tasks.json new file mode 100644 index 000000000000..2dcafcd7dd96 --- /dev/null +++ b/src/rest/data/fpt-2022-11-28/agent-tasks.json @@ -0,0 +1,1994 @@ +{ + "agent-tasks": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/repos/{owner}/{repo}/tasks", + "title": "List tasks for repository", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + }, + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 30, + "minimum": 1, + "maximum": 100 + }, + "description": "

    The number of results per page (max 100).

    " + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1, + "minimum": 1 + }, + "description": "

    The page number of the results to fetch.

    " + }, + { + "name": "sort", + "in": "query", + "schema": { + "type": "string", + "default": "updated_at", + "enum": [ + "updated_at", + "created_at" + ] + }, + "description": "

    The field to sort results by. Can be updated_at or created_at.

    " + }, + { + "name": "direction", + "in": "query", + "schema": { + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ] + }, + "description": "

    The direction to sort results. Can be asc or desc.

    " + }, + { + "name": "state", + "in": "query", + "schema": { + "type": "string" + }, + "description": "

    Comma-separated list of task states to filter by. Can be any combination of: queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, cancelled.

    " + }, + { + "name": "is_archived", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "

    Filter by archived status. When true, returns only archived tasks. When false or omitted, returns only non-archived tasks. Defaults to false.

    " + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "

    Only show tasks updated at or after this time (ISO 8601 timestamp)

    " + }, + { + "name": "creator_id", + "in": "query", + "schema": { + "type": "integer" + }, + "description": "

    Filter tasks by creator user ID

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a list of tasks for a specific repository

    \n

    Fine-grained access tokens for \"List tasks for repository\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Tasks retrieved successfully

    ", + "example": { + "tasks": [ + { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z" + } + ] + }, + "schema": { + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + "description": "List of tasks" + }, + "total_active_count": { + "type": "integer", + "format": "int32", + "description": "Total count of active (non-archived) tasks" + }, + "total_archived_count": { + "type": "integer", + "format": "int32", + "description": "Total count of archived tasks" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Tasks retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "post", + "requestPath": "/agents/repos/{owner}/{repo}/tasks", + "title": "Start a task", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + } + ], + "bodyParameters": [ + { + "type": "string", + "name": "prompt", + "description": "

    The user's prompt for the agent

    ", + "isRequired": true + }, + { + "type": "string", + "name": "model", + "description": "

    The model to use for this task. The allowed models may change over time and depend on the user's GitHub Copilot plan and organization policies. Currently supported values: claude-sonnet-4.6, claude-opus-4.6, gpt-5.2-codex, gpt-5.3-codex, gpt-5.4, claude-sonnet-4.5, claude-opus-4.5

    " + }, + { + "type": "boolean", + "name": "create_pull_request", + "description": "

    Whether to create a PR.

    ", + "default": false + }, + { + "type": "string", + "name": "base_ref", + "description": "

    Base ref for new branch/PR

    " + } + ], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Starts a new Copilot cloud agent task for a repository.

    \n

    This endpoint is only available to users with a Copilot Business or Copilot Enterprise subscription.

    \n

    Fine-grained access tokens for \"Start a task\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read and write)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "contentType": "application/json", + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "bodyParameters": { + "prompt": "Fix the login button on the homepage", + "base_ref": "main" + }, + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "201", + "contentType": "application/json", + "description": "

    Task created successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "queued", + "session_count": 1, + "artifacts": [], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z" + }, + "schema": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "201", + "description": "

    Task created successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Problems parsing JSON

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/repos/{owner}/{repo}/tasks/{task_id}", + "title": "Get a task by repo", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + }, + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The unique identifier of the task.

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a task by ID scoped to an owner/repo path

    \n

    Fine-grained access tokens for \"Get a task by repo\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "task_id": "TASK_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Task retrieved successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "sessions": [ + { + "id": "s1a2b3c4-d5e6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "user": { + "id": 1 + }, + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "state": "completed", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "completed_at": "2025-01-01T01:00:00Z", + "prompt": "Fix the login button on the homepage", + "head_ref": "copilot/fix-1", + "base_ref": "main", + "model": "claude-sonnet-4.6" + } + ] + }, + "schema": { + "allOf": [ + { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "type": "object", + "description": "Full session details within a task", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Session ID" + }, + "name": { + "type": "string", + "description": "Session name" + }, + "user": { + "description": "The user who created this session", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this session belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "task_id": { + "type": "string", + "description": "Task ID this session belongs to" + }, + "state": { + "type": "string", + "description": "Current state of a session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "Completion timestamp" + }, + "prompt": { + "type": "string", + "description": "Content of the triggering event" + }, + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + }, + "model": { + "type": "string", + "description": "Model used for this session" + }, + "error": { + "type": "object", + "description": "Error details for a failed session", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + } + }, + "description": "Sessions associated with this task" + } + } + } + ] + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Task retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/tasks", + "title": "List tasks", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 30, + "minimum": 1, + "maximum": 100 + }, + "description": "

    The number of results per page (max 100).

    " + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1, + "minimum": 1 + }, + "description": "

    The page number of the results to fetch.

    " + }, + { + "name": "sort", + "in": "query", + "schema": { + "type": "string", + "default": "updated_at", + "enum": [ + "updated_at", + "created_at" + ] + }, + "description": "

    The field to sort results by. Can be updated_at or created_at.

    " + }, + { + "name": "direction", + "in": "query", + "schema": { + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ] + }, + "description": "

    The direction to sort results. Can be asc or desc.

    " + }, + { + "name": "state", + "in": "query", + "schema": { + "type": "string" + }, + "description": "

    Comma-separated list of task states to filter by. Can be any combination of: queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, cancelled.

    " + }, + { + "name": "is_archived", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "

    Filter by archived status. When true, returns only archived tasks. When false or omitted, returns only non-archived tasks. Defaults to false.

    " + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "

    Only show tasks updated at or after this time (ISO 8601 timestamp)

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a list of tasks for the authenticated user

    \n

    Fine-grained access tokens for \"List tasks\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json" + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Tasks retrieved successfully

    ", + "example": { + "tasks": [ + { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z" + } + ] + }, + "schema": { + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + "description": "List of tasks" + }, + "total_active_count": { + "type": "integer", + "format": "int32", + "description": "Total count of active (non-archived) tasks" + }, + "total_archived_count": { + "type": "integer", + "format": "int32", + "description": "Total count of archived tasks" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Tasks retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/tasks/{task_id}", + "title": "Get a task by ID", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The unique identifier of the task.

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a task by ID with its associated sessions

    \n

    Fine-grained access tokens for \"Get a task by ID\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "task_id": "TASK_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Task retrieved successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "sessions": [ + { + "id": "s1a2b3c4-d5e6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "user": { + "id": 1 + }, + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "state": "completed", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "completed_at": "2025-01-01T01:00:00Z", + "prompt": "Fix the login button on the homepage", + "head_ref": "copilot/fix-1", + "base_ref": "main", + "model": "claude-sonnet-4.6" + } + ] + }, + "schema": { + "allOf": [ + { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "type": "object", + "description": "Full session details within a task", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Session ID" + }, + "name": { + "type": "string", + "description": "Session name" + }, + "user": { + "description": "The user who created this session", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this session belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "task_id": { + "type": "string", + "description": "Task ID this session belongs to" + }, + "state": { + "type": "string", + "description": "Current state of a session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "Completion timestamp" + }, + "prompt": { + "type": "string", + "description": "Content of the triggering event" + }, + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + }, + "model": { + "type": "string", + "description": "Model used for this session" + }, + "error": { + "type": "object", + "description": "Error details for a failed session", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + } + }, + "description": "Sessions associated with this task" + } + } + } + ] + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Task retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Problems parsing request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + } + ] +} \ No newline at end of file diff --git a/src/rest/data/fpt-2022-11-28/orgs.json b/src/rest/data/fpt-2022-11-28/orgs.json index 08510d45c578..d4b83b4bef45 100644 --- a/src/rest/data/fpt-2022-11-28/orgs.json +++ b/src/rest/data/fpt-2022-11-28/orgs.json @@ -5561,19 +5561,19 @@ { "type": "string", "name": "name", - "description": "

    The name of the artifact. Note that if multiple deployments have identical 'digest' parameter values,\nthe name parameter must also be identical across all entries.

    ", + "description": "

    The name of the artifact.

    ", "isRequired": true }, { "type": "string", "name": "digest", - "description": "

    The hex encoded digest of the artifact. Note that if multiple deployments have identical 'digest' parameter values,\nthe name and version parameters must also be identical across all entries.

    ", + "description": "

    The hex encoded digest of the artifact.

    ", "isRequired": true }, { "type": "string", "name": "version", - "description": "

    The artifact version. Note that if multiple deployments have identical 'digest' parameter values,\nthe version parameter must also be identical across all entries.

    " + "description": "

    The artifact version.

    " }, { "type": "string", @@ -5615,7 +5615,7 @@ "default": true } ], - "descriptionHTML": "

    Set deployment records for a given cluster.\nIf proposed records in the 'deployments' field have identical 'cluster', 'logical_environment',\n'physical_environment', and 'deployment_name' values as existing records, the existing records will be updated.\nIf no existing records match, new records will be created.

    ", + "descriptionHTML": "

    Set deployment records for a given cluster.\nIf proposed records in the 'deployments' field have identical 'cluster', 'logical_environment',\n'physical_environment', and 'deployment_name' values as existing records, the existing records will be updated.\nIf no existing records match, new records will be created.\nNote: Artifacts are uniquely identified by the combination of their repository and digest fields. If two entries in the deployments\narray resolve to the same repository and have identical digest fields but differing name and version fields, the endpoint will use\nthe artifact name and version from the record processed first, since a single artifact (identified by repository and digest) can\nonly have one name and version.

    ", "codeExamples": [ { "request": { diff --git a/src/rest/data/fpt-2022-11-28/private-registries.json b/src/rest/data/fpt-2022-11-28/private-registries.json index 4a2241ec4b4a..5fe0e8fe34cf 100644 --- a/src/rest/data/fpt-2022-11-28/private-registries.json +++ b/src/rest/data/fpt-2022-11-28/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -333,14 +342,15 @@ { "type": "string", "name": "auth_type", - "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith for OIDC authentication.

    ", + "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp for OIDC authentication.

    ", "enum": [ "token", "username_password", "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -386,7 +396,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -407,9 +417,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [ { "request": { @@ -483,7 +503,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -569,6 +590,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -659,7 +688,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -745,6 +775,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -959,7 +997,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -1041,6 +1080,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -1184,7 +1231,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -1230,7 +1278,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -1251,9 +1299,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/fpt-2022-11-28/secret-scanning.json b/src/rest/data/fpt-2022-11-28/secret-scanning.json index 44e82856f993..41d43d83102e 100644 --- a/src/rest/data/fpt-2022-11-28/secret-scanning.json +++ b/src/rest/data/fpt-2022-11-28/secret-scanning.json @@ -186,6 +186,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -2080,6 +2089,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -5851,6 +5869,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/fpt-2026-03-10/actions.json b/src/rest/data/fpt-2026-03-10/actions.json index 044ce0c19d67..73cb97a83062 100644 --- a/src/rest/data/fpt-2026-03-10/actions.json +++ b/src/rest/data/fpt-2026-03-10/actions.json @@ -2520,6 +2520,657 @@ } } ], + "concurrency-groups": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "title": "List concurrency groups for a repository", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "per_page", + "description": "

    The number of results per page (max 100). For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "schema": { + "type": "integer", + "default": 30 + } + }, + { + "name": "after", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Lists the active concurrency groups for a repository.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "last_acquired_at": "2026-01-15T16:14:23Z" + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build", + "last_acquired_at": "2026-01-15T16:13:55Z" + } + ] + }, + "schema": { + "title": "Concurrency Group List", + "description": "A list of active concurrency groups for a repository.", + "type": "object", + "required": [ + "total_count", + "concurrency_groups" + ], + "properties": { + "total_count": { + "type": "integer" + }, + "concurrency_groups": { + "type": "array", + "items": { + "type": "object", + "required": [ + "group_name", + "group_url", + "last_acquired_at" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group." + }, + "last_acquired_at": { + "type": [ + "string", + "null" + ], + "format": "date-time" + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "title": "Get a concurrency group for a repository", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "concurrency_group_name", + "description": "

    The name of the concurrency group.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ahead_of_run", + "description": "

    Filter to items ahead of this workflow run ID in the queue, plus the run itself.\nMatches workflow-level concurrency and reusable-workflow leases held on behalf of\nthe run. Mutually exclusive with ahead_of_job.

    ", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + }, + { + "name": "ahead_of_job", + "description": "

    Filter to items ahead of this job ID in the queue, plus the job itself.\nMatches job-level concurrency and reusable-workflow leases on the job's\nancestor paths. Mutually exclusive with ahead_of_run.

    ", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Gets a specific concurrency group for a repository, including all instances in the group's queue.\nReturns 404 if the group is inactive or does not exist.

    \n

    Optionally, pass ahead_of_run or ahead_of_job to filter the results to only the items\nahead of the specified workflow run or job in the queue, plus the specified item itself\n(returned as the last element). This is useful for determining what is blocking a particular\nrun or job. Returns 422 if the specified run or job is not in this concurrency group.

    \n

    When using ahead_of_run, this matches workflow-level concurrency and any reusable-workflow\nleases held on behalf of that run. Job-level leases within the run are not considered to\nblock the run as a whole. Use ahead_of_job to match job-level concurrency and reusable-workflow\nleases on the job's ancestor paths.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "concurrency_group_name": "CONCURRENCY_GROUP_NAME" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "total_count": 3, + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "in_progress" + }, + { + "run_id": 30433643, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433643", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433643", + "status": "pending" + }, + { + "run_id": 30433644, + "run_name": "Deploy hotfix", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433644", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433644", + "job_id": 798245260, + "job_name": "deploy", + "job_url": "https://api.github.com/repos/octocat/Hello-World/actions/jobs/798245260", + "job_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433644/job/798245260", + "status": "pending" + } + ] + }, + "schema": { + "title": "Concurrency Group", + "description": "A concurrency group with the workflow runs and jobs that are either currently holding\nor waiting for the concurrency group lease.", + "type": "object", + "required": [ + "group_name", + "group_url", + "total_count", + "group_members" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group." + }, + "total_count": { + "type": "integer" + }, + "group_members": { + "type": "array", + "items": { + "type": "object", + "required": [ + "run_id", + "run_name", + "run_url", + "run_html_url", + "status" + ], + "properties": { + "run_id": { + "type": "integer", + "description": "The ID of the workflow run." + }, + "run_name": { + "type": "string", + "description": "The name of the workflow run." + }, + "run_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the workflow run." + }, + "run_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the workflow run." + }, + "job_id": { + "type": "integer", + "description": "The ID of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_name": { + "type": "string", + "description": "The display name of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the job." + }, + "job_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the job." + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "pending" + ] + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "title": "List concurrency groups for a workflow run", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "run_id", + "description": "

    The unique identifier of the workflow run.

    ", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "per_page", + "description": "

    The number of results per page (max 100). For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "schema": { + "type": "integer", + "default": 30 + } + }, + { + "name": "before", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results before this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "after", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Lists all concurrency groups associated with a workflow run or its jobs.

    \n

    The set of groups is derived from the run's configuration, so a group is\nincluded even when the run no longer has any items currently holding or\nwaiting in it. In that case the group_members array will be empty.\ntotal_count reflects the number of groups the run participates in by\nconfiguration, not the number with active items.

    \n

    This differs from GET /repos/{owner}/{repo}/actions/concurrency_groups/{group_name},\nwhich returns 404 when a group has no active items. That endpoint reports\nthe live state of a group repo-wide, while this endpoint reports the\ngroups associated with a specific run by configuration.

    \n

    Results are sorted by group name and support cursor-based pagination via\nbefore and after. The after cursor paginates forward only and does\nnot emit a rel=\"prev\" Link; use before to page backward from a\nforward page's next cursor.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "run_id": "RUN_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "in_progress", + "position": 0, + "position_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod?ahead_of_run=30433642" + } + ] + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build", + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "pending", + "position": 2, + "position_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build?ahead_of_job=798245260", + "job_id": 798245260, + "job_name": "build", + "job_url": "https://api.github.com/repos/octocat/Hello-World/actions/jobs/798245260", + "job_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642/job/798245260" + } + ] + } + ] + }, + "schema": { + "title": "Concurrency Group Run List", + "description": "A list of concurrency groups associated with a workflow run.", + "type": "object", + "required": [ + "total_count", + "concurrency_groups" + ], + "properties": { + "total_count": { + "type": "integer", + "description": "The total number of concurrency groups this workflow run participates in,\nderived from the run's configuration. This count is not filtered by\nwhether the run currently holds or is waiting in each group, so it can\ninclude groups whose `group_members` array is empty (for example, when\nthe run has already released its lease in that group)." + }, + "concurrency_groups": { + "type": "array", + "items": { + "type": "object", + "required": [ + "group_name", + "group_url", + "group_members" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group. May return 404 if the group\nhas no active items at the time it is requested, since the\nget-by-name endpoint reports the live repo-wide state of a group\nwhile this endpoint lists groups associated with a run by\nconfiguration." + }, + "group_members": { + "type": "array", + "description": "Items belonging to this workflow run that are either currently holding or\nwaiting for the concurrency group lease. May be empty if the run no\nlonger has any active or queued items in this group.", + "items": { + "type": "object", + "required": [ + "run_id", + "run_name", + "run_url", + "run_html_url", + "status", + "position", + "position_url" + ], + "properties": { + "run_id": { + "type": "integer", + "description": "The ID of the workflow run." + }, + "run_name": { + "type": "string", + "description": "The name of the workflow run." + }, + "run_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the workflow run." + }, + "run_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the workflow run." + }, + "position": { + "type": "integer", + "description": "Queue position. 0 means the item holds the concurrency lease (in_progress), 1 or higher means queued (pending)." + }, + "position_url": { + "type": "string", + "format": "uri", + "description": "API URL to get items ahead of this item in the concurrency group." + }, + "job_id": { + "type": [ + "integer", + "null" + ], + "description": "The ID of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_name": { + "type": [ + "string", + "null" + ], + "description": "The display name of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the job." + }, + "job_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the job." + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "pending" + ] + } + } + } + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + } + ], "hosted-runners": [ { "serverUrl": "https://api.github.com", @@ -26903,6 +27554,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/fpt-2026-03-10/agent-tasks.json b/src/rest/data/fpt-2026-03-10/agent-tasks.json new file mode 100644 index 000000000000..2dcafcd7dd96 --- /dev/null +++ b/src/rest/data/fpt-2026-03-10/agent-tasks.json @@ -0,0 +1,1994 @@ +{ + "agent-tasks": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/repos/{owner}/{repo}/tasks", + "title": "List tasks for repository", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + }, + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 30, + "minimum": 1, + "maximum": 100 + }, + "description": "

    The number of results per page (max 100).

    " + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1, + "minimum": 1 + }, + "description": "

    The page number of the results to fetch.

    " + }, + { + "name": "sort", + "in": "query", + "schema": { + "type": "string", + "default": "updated_at", + "enum": [ + "updated_at", + "created_at" + ] + }, + "description": "

    The field to sort results by. Can be updated_at or created_at.

    " + }, + { + "name": "direction", + "in": "query", + "schema": { + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ] + }, + "description": "

    The direction to sort results. Can be asc or desc.

    " + }, + { + "name": "state", + "in": "query", + "schema": { + "type": "string" + }, + "description": "

    Comma-separated list of task states to filter by. Can be any combination of: queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, cancelled.

    " + }, + { + "name": "is_archived", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "

    Filter by archived status. When true, returns only archived tasks. When false or omitted, returns only non-archived tasks. Defaults to false.

    " + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "

    Only show tasks updated at or after this time (ISO 8601 timestamp)

    " + }, + { + "name": "creator_id", + "in": "query", + "schema": { + "type": "integer" + }, + "description": "

    Filter tasks by creator user ID

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a list of tasks for a specific repository

    \n

    Fine-grained access tokens for \"List tasks for repository\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Tasks retrieved successfully

    ", + "example": { + "tasks": [ + { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z" + } + ] + }, + "schema": { + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + "description": "List of tasks" + }, + "total_active_count": { + "type": "integer", + "format": "int32", + "description": "Total count of active (non-archived) tasks" + }, + "total_archived_count": { + "type": "integer", + "format": "int32", + "description": "Total count of archived tasks" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Tasks retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "post", + "requestPath": "/agents/repos/{owner}/{repo}/tasks", + "title": "Start a task", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + } + ], + "bodyParameters": [ + { + "type": "string", + "name": "prompt", + "description": "

    The user's prompt for the agent

    ", + "isRequired": true + }, + { + "type": "string", + "name": "model", + "description": "

    The model to use for this task. The allowed models may change over time and depend on the user's GitHub Copilot plan and organization policies. Currently supported values: claude-sonnet-4.6, claude-opus-4.6, gpt-5.2-codex, gpt-5.3-codex, gpt-5.4, claude-sonnet-4.5, claude-opus-4.5

    " + }, + { + "type": "boolean", + "name": "create_pull_request", + "description": "

    Whether to create a PR.

    ", + "default": false + }, + { + "type": "string", + "name": "base_ref", + "description": "

    Base ref for new branch/PR

    " + } + ], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Starts a new Copilot cloud agent task for a repository.

    \n

    This endpoint is only available to users with a Copilot Business or Copilot Enterprise subscription.

    \n

    Fine-grained access tokens for \"Start a task\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read and write)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "contentType": "application/json", + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "bodyParameters": { + "prompt": "Fix the login button on the homepage", + "base_ref": "main" + }, + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "201", + "contentType": "application/json", + "description": "

    Task created successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "queued", + "session_count": 1, + "artifacts": [], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z" + }, + "schema": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "201", + "description": "

    Task created successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Problems parsing JSON

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/repos/{owner}/{repo}/tasks/{task_id}", + "title": "Get a task by repo", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + }, + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The unique identifier of the task.

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a task by ID scoped to an owner/repo path

    \n

    Fine-grained access tokens for \"Get a task by repo\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "task_id": "TASK_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Task retrieved successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "sessions": [ + { + "id": "s1a2b3c4-d5e6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "user": { + "id": 1 + }, + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "state": "completed", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "completed_at": "2025-01-01T01:00:00Z", + "prompt": "Fix the login button on the homepage", + "head_ref": "copilot/fix-1", + "base_ref": "main", + "model": "claude-sonnet-4.6" + } + ] + }, + "schema": { + "allOf": [ + { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "type": "object", + "description": "Full session details within a task", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Session ID" + }, + "name": { + "type": "string", + "description": "Session name" + }, + "user": { + "description": "The user who created this session", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this session belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "task_id": { + "type": "string", + "description": "Task ID this session belongs to" + }, + "state": { + "type": "string", + "description": "Current state of a session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "Completion timestamp" + }, + "prompt": { + "type": "string", + "description": "Content of the triggering event" + }, + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + }, + "model": { + "type": "string", + "description": "Model used for this session" + }, + "error": { + "type": "object", + "description": "Error details for a failed session", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + } + }, + "description": "Sessions associated with this task" + } + } + } + ] + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Task retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/tasks", + "title": "List tasks", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 30, + "minimum": 1, + "maximum": 100 + }, + "description": "

    The number of results per page (max 100).

    " + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1, + "minimum": 1 + }, + "description": "

    The page number of the results to fetch.

    " + }, + { + "name": "sort", + "in": "query", + "schema": { + "type": "string", + "default": "updated_at", + "enum": [ + "updated_at", + "created_at" + ] + }, + "description": "

    The field to sort results by. Can be updated_at or created_at.

    " + }, + { + "name": "direction", + "in": "query", + "schema": { + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ] + }, + "description": "

    The direction to sort results. Can be asc or desc.

    " + }, + { + "name": "state", + "in": "query", + "schema": { + "type": "string" + }, + "description": "

    Comma-separated list of task states to filter by. Can be any combination of: queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, cancelled.

    " + }, + { + "name": "is_archived", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "

    Filter by archived status. When true, returns only archived tasks. When false or omitted, returns only non-archived tasks. Defaults to false.

    " + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "

    Only show tasks updated at or after this time (ISO 8601 timestamp)

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a list of tasks for the authenticated user

    \n

    Fine-grained access tokens for \"List tasks\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json" + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Tasks retrieved successfully

    ", + "example": { + "tasks": [ + { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z" + } + ] + }, + "schema": { + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + "description": "List of tasks" + }, + "total_active_count": { + "type": "integer", + "format": "int32", + "description": "Total count of active (non-archived) tasks" + }, + "total_archived_count": { + "type": "integer", + "format": "int32", + "description": "Total count of archived tasks" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Tasks retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/tasks/{task_id}", + "title": "Get a task by ID", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The unique identifier of the task.

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a task by ID with its associated sessions

    \n

    Fine-grained access tokens for \"Get a task by ID\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "task_id": "TASK_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Task retrieved successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "sessions": [ + { + "id": "s1a2b3c4-d5e6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "user": { + "id": 1 + }, + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "state": "completed", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "completed_at": "2025-01-01T01:00:00Z", + "prompt": "Fix the login button on the homepage", + "head_ref": "copilot/fix-1", + "base_ref": "main", + "model": "claude-sonnet-4.6" + } + ] + }, + "schema": { + "allOf": [ + { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "type": "object", + "description": "Full session details within a task", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Session ID" + }, + "name": { + "type": "string", + "description": "Session name" + }, + "user": { + "description": "The user who created this session", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this session belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "task_id": { + "type": "string", + "description": "Task ID this session belongs to" + }, + "state": { + "type": "string", + "description": "Current state of a session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "Completion timestamp" + }, + "prompt": { + "type": "string", + "description": "Content of the triggering event" + }, + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + }, + "model": { + "type": "string", + "description": "Model used for this session" + }, + "error": { + "type": "object", + "description": "Error details for a failed session", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + } + }, + "description": "Sessions associated with this task" + } + } + } + ] + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Task retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Problems parsing request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + } + ] +} \ No newline at end of file diff --git a/src/rest/data/fpt-2026-03-10/orgs.json b/src/rest/data/fpt-2026-03-10/orgs.json index 77e8e98d98b3..eaf051c33cdb 100644 --- a/src/rest/data/fpt-2026-03-10/orgs.json +++ b/src/rest/data/fpt-2026-03-10/orgs.json @@ -5547,19 +5547,19 @@ { "type": "string", "name": "name", - "description": "

    The name of the artifact. Note that if multiple deployments have identical 'digest' parameter values,\nthe name parameter must also be identical across all entries.

    ", + "description": "

    The name of the artifact.

    ", "isRequired": true }, { "type": "string", "name": "digest", - "description": "

    The hex encoded digest of the artifact. Note that if multiple deployments have identical 'digest' parameter values,\nthe name and version parameters must also be identical across all entries.

    ", + "description": "

    The hex encoded digest of the artifact.

    ", "isRequired": true }, { "type": "string", "name": "version", - "description": "

    The artifact version. Note that if multiple deployments have identical 'digest' parameter values,\nthe version parameter must also be identical across all entries.

    " + "description": "

    The artifact version.

    " }, { "type": "string", @@ -5601,7 +5601,7 @@ "default": true } ], - "descriptionHTML": "

    Set deployment records for a given cluster.\nIf proposed records in the 'deployments' field have identical 'cluster', 'logical_environment',\n'physical_environment', and 'deployment_name' values as existing records, the existing records will be updated.\nIf no existing records match, new records will be created.

    ", + "descriptionHTML": "

    Set deployment records for a given cluster.\nIf proposed records in the 'deployments' field have identical 'cluster', 'logical_environment',\n'physical_environment', and 'deployment_name' values as existing records, the existing records will be updated.\nIf no existing records match, new records will be created.\nNote: Artifacts are uniquely identified by the combination of their repository and digest fields. If two entries in the deployments\narray resolve to the same repository and have identical digest fields but differing name and version fields, the endpoint will use\nthe artifact name and version from the record processed first, since a single artifact (identified by repository and digest) can\nonly have one name and version.

    ", "codeExamples": [ { "request": { diff --git a/src/rest/data/fpt-2026-03-10/private-registries.json b/src/rest/data/fpt-2026-03-10/private-registries.json index 4a2241ec4b4a..5fe0e8fe34cf 100644 --- a/src/rest/data/fpt-2026-03-10/private-registries.json +++ b/src/rest/data/fpt-2026-03-10/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -333,14 +342,15 @@ { "type": "string", "name": "auth_type", - "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith for OIDC authentication.

    ", + "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp for OIDC authentication.

    ", "enum": [ "token", "username_password", "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -386,7 +396,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -407,9 +417,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [ { "request": { @@ -483,7 +503,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -569,6 +590,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -659,7 +688,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -745,6 +775,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -959,7 +997,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -1041,6 +1080,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -1184,7 +1231,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -1230,7 +1278,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -1251,9 +1299,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/fpt-2026-03-10/secret-scanning.json b/src/rest/data/fpt-2026-03-10/secret-scanning.json index 44e82856f993..41d43d83102e 100644 --- a/src/rest/data/fpt-2026-03-10/secret-scanning.json +++ b/src/rest/data/fpt-2026-03-10/secret-scanning.json @@ -186,6 +186,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -2080,6 +2089,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -5851,6 +5869,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/ghec-2022-11-28/actions.json b/src/rest/data/ghec-2022-11-28/actions.json index f20d151c5765..e779f5987e92 100644 --- a/src/rest/data/ghec-2022-11-28/actions.json +++ b/src/rest/data/ghec-2022-11-28/actions.json @@ -2596,6 +2596,657 @@ } } ], + "concurrency-groups": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "title": "List concurrency groups for a repository", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "per_page", + "description": "

    The number of results per page (max 100). For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "schema": { + "type": "integer", + "default": 30 + } + }, + { + "name": "after", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Lists the active concurrency groups for a repository.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "last_acquired_at": "2026-01-15T16:14:23Z" + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build", + "last_acquired_at": "2026-01-15T16:13:55Z" + } + ] + }, + "schema": { + "title": "Concurrency Group List", + "description": "A list of active concurrency groups for a repository.", + "type": "object", + "required": [ + "total_count", + "concurrency_groups" + ], + "properties": { + "total_count": { + "type": "integer" + }, + "concurrency_groups": { + "type": "array", + "items": { + "type": "object", + "required": [ + "group_name", + "group_url", + "last_acquired_at" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group." + }, + "last_acquired_at": { + "type": [ + "string", + "null" + ], + "format": "date-time" + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "title": "Get a concurrency group for a repository", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "concurrency_group_name", + "description": "

    The name of the concurrency group.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ahead_of_run", + "description": "

    Filter to items ahead of this workflow run ID in the queue, plus the run itself.\nMatches workflow-level concurrency and reusable-workflow leases held on behalf of\nthe run. Mutually exclusive with ahead_of_job.

    ", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + }, + { + "name": "ahead_of_job", + "description": "

    Filter to items ahead of this job ID in the queue, plus the job itself.\nMatches job-level concurrency and reusable-workflow leases on the job's\nancestor paths. Mutually exclusive with ahead_of_run.

    ", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Gets a specific concurrency group for a repository, including all instances in the group's queue.\nReturns 404 if the group is inactive or does not exist.

    \n

    Optionally, pass ahead_of_run or ahead_of_job to filter the results to only the items\nahead of the specified workflow run or job in the queue, plus the specified item itself\n(returned as the last element). This is useful for determining what is blocking a particular\nrun or job. Returns 422 if the specified run or job is not in this concurrency group.

    \n

    When using ahead_of_run, this matches workflow-level concurrency and any reusable-workflow\nleases held on behalf of that run. Job-level leases within the run are not considered to\nblock the run as a whole. Use ahead_of_job to match job-level concurrency and reusable-workflow\nleases on the job's ancestor paths.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "concurrency_group_name": "CONCURRENCY_GROUP_NAME" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "total_count": 3, + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "in_progress" + }, + { + "run_id": 30433643, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433643", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433643", + "status": "pending" + }, + { + "run_id": 30433644, + "run_name": "Deploy hotfix", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433644", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433644", + "job_id": 798245260, + "job_name": "deploy", + "job_url": "https://api.github.com/repos/octocat/Hello-World/actions/jobs/798245260", + "job_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433644/job/798245260", + "status": "pending" + } + ] + }, + "schema": { + "title": "Concurrency Group", + "description": "A concurrency group with the workflow runs and jobs that are either currently holding\nor waiting for the concurrency group lease.", + "type": "object", + "required": [ + "group_name", + "group_url", + "total_count", + "group_members" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group." + }, + "total_count": { + "type": "integer" + }, + "group_members": { + "type": "array", + "items": { + "type": "object", + "required": [ + "run_id", + "run_name", + "run_url", + "run_html_url", + "status" + ], + "properties": { + "run_id": { + "type": "integer", + "description": "The ID of the workflow run." + }, + "run_name": { + "type": "string", + "description": "The name of the workflow run." + }, + "run_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the workflow run." + }, + "run_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the workflow run." + }, + "job_id": { + "type": "integer", + "description": "The ID of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_name": { + "type": "string", + "description": "The display name of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the job." + }, + "job_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the job." + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "pending" + ] + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "title": "List concurrency groups for a workflow run", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "run_id", + "description": "

    The unique identifier of the workflow run.

    ", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "per_page", + "description": "

    The number of results per page (max 100). For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "schema": { + "type": "integer", + "default": 30 + } + }, + { + "name": "before", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results before this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "after", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Lists all concurrency groups associated with a workflow run or its jobs.

    \n

    The set of groups is derived from the run's configuration, so a group is\nincluded even when the run no longer has any items currently holding or\nwaiting in it. In that case the group_members array will be empty.\ntotal_count reflects the number of groups the run participates in by\nconfiguration, not the number with active items.

    \n

    This differs from GET /repos/{owner}/{repo}/actions/concurrency_groups/{group_name},\nwhich returns 404 when a group has no active items. That endpoint reports\nthe live state of a group repo-wide, while this endpoint reports the\ngroups associated with a specific run by configuration.

    \n

    Results are sorted by group name and support cursor-based pagination via\nbefore and after. The after cursor paginates forward only and does\nnot emit a rel=\"prev\" Link; use before to page backward from a\nforward page's next cursor.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "run_id": "RUN_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "in_progress", + "position": 0, + "position_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod?ahead_of_run=30433642" + } + ] + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build", + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "pending", + "position": 2, + "position_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build?ahead_of_job=798245260", + "job_id": 798245260, + "job_name": "build", + "job_url": "https://api.github.com/repos/octocat/Hello-World/actions/jobs/798245260", + "job_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642/job/798245260" + } + ] + } + ] + }, + "schema": { + "title": "Concurrency Group Run List", + "description": "A list of concurrency groups associated with a workflow run.", + "type": "object", + "required": [ + "total_count", + "concurrency_groups" + ], + "properties": { + "total_count": { + "type": "integer", + "description": "The total number of concurrency groups this workflow run participates in,\nderived from the run's configuration. This count is not filtered by\nwhether the run currently holds or is waiting in each group, so it can\ninclude groups whose `group_members` array is empty (for example, when\nthe run has already released its lease in that group)." + }, + "concurrency_groups": { + "type": "array", + "items": { + "type": "object", + "required": [ + "group_name", + "group_url", + "group_members" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group. May return 404 if the group\nhas no active items at the time it is requested, since the\nget-by-name endpoint reports the live repo-wide state of a group\nwhile this endpoint lists groups associated with a run by\nconfiguration." + }, + "group_members": { + "type": "array", + "description": "Items belonging to this workflow run that are either currently holding or\nwaiting for the concurrency group lease. May be empty if the run no\nlonger has any active or queued items in this group.", + "items": { + "type": "object", + "required": [ + "run_id", + "run_name", + "run_url", + "run_html_url", + "status", + "position", + "position_url" + ], + "properties": { + "run_id": { + "type": "integer", + "description": "The ID of the workflow run." + }, + "run_name": { + "type": "string", + "description": "The name of the workflow run." + }, + "run_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the workflow run." + }, + "run_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the workflow run." + }, + "position": { + "type": "integer", + "description": "Queue position. 0 means the item holds the concurrency lease (in_progress), 1 or higher means queued (pending)." + }, + "position_url": { + "type": "string", + "format": "uri", + "description": "API URL to get items ahead of this item in the concurrency group." + }, + "job_id": { + "type": [ + "integer", + "null" + ], + "description": "The ID of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_name": { + "type": [ + "string", + "null" + ], + "description": "The display name of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the job." + }, + "job_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the job." + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "pending" + ] + } + } + } + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + } + ], "hosted-runners": [ { "serverUrl": "https://api.github.com", @@ -35707,6 +36358,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/ghec-2022-11-28/agent-tasks.json b/src/rest/data/ghec-2022-11-28/agent-tasks.json new file mode 100644 index 000000000000..275cc3f86861 --- /dev/null +++ b/src/rest/data/ghec-2022-11-28/agent-tasks.json @@ -0,0 +1,1994 @@ +{ + "agent-tasks": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/repos/{owner}/{repo}/tasks", + "title": "List tasks for repository", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + }, + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 30, + "minimum": 1, + "maximum": 100 + }, + "description": "

    The number of results per page (max 100).

    " + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1, + "minimum": 1 + }, + "description": "

    The page number of the results to fetch.

    " + }, + { + "name": "sort", + "in": "query", + "schema": { + "type": "string", + "default": "updated_at", + "enum": [ + "updated_at", + "created_at" + ] + }, + "description": "

    The field to sort results by. Can be updated_at or created_at.

    " + }, + { + "name": "direction", + "in": "query", + "schema": { + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ] + }, + "description": "

    The direction to sort results. Can be asc or desc.

    " + }, + { + "name": "state", + "in": "query", + "schema": { + "type": "string" + }, + "description": "

    Comma-separated list of task states to filter by. Can be any combination of: queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, cancelled.

    " + }, + { + "name": "is_archived", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "

    Filter by archived status. When true, returns only archived tasks. When false or omitted, returns only non-archived tasks. Defaults to false.

    " + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "

    Only show tasks updated at or after this time (ISO 8601 timestamp)

    " + }, + { + "name": "creator_id", + "in": "query", + "schema": { + "type": "integer" + }, + "description": "

    Filter tasks by creator user ID

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a list of tasks for a specific repository

    \n

    Fine-grained access tokens for \"List tasks for repository\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Tasks retrieved successfully

    ", + "example": { + "tasks": [ + { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z" + } + ] + }, + "schema": { + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + "description": "List of tasks" + }, + "total_active_count": { + "type": "integer", + "format": "int32", + "description": "Total count of active (non-archived) tasks" + }, + "total_archived_count": { + "type": "integer", + "format": "int32", + "description": "Total count of archived tasks" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Tasks retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "post", + "requestPath": "/agents/repos/{owner}/{repo}/tasks", + "title": "Start a task", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + } + ], + "bodyParameters": [ + { + "type": "string", + "name": "prompt", + "description": "

    The user's prompt for the agent

    ", + "isRequired": true + }, + { + "type": "string", + "name": "model", + "description": "

    The model to use for this task. The allowed models may change over time and depend on the user's GitHub Copilot plan and organization policies. Currently supported values: claude-sonnet-4.6, claude-opus-4.6, gpt-5.2-codex, gpt-5.3-codex, gpt-5.4, claude-sonnet-4.5, claude-opus-4.5

    " + }, + { + "type": "boolean", + "name": "create_pull_request", + "description": "

    Whether to create a PR.

    ", + "default": false + }, + { + "type": "string", + "name": "base_ref", + "description": "

    Base ref for new branch/PR

    " + } + ], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Starts a new Copilot cloud agent task for a repository.

    \n

    This endpoint is only available to users with a Copilot Business or Copilot Enterprise subscription.

    \n

    Fine-grained access tokens for \"Start a task\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read and write)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "contentType": "application/json", + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "bodyParameters": { + "prompt": "Fix the login button on the homepage", + "base_ref": "main" + }, + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "201", + "contentType": "application/json", + "description": "

    Task created successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "queued", + "session_count": 1, + "artifacts": [], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z" + }, + "schema": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "201", + "description": "

    Task created successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Problems parsing JSON

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/repos/{owner}/{repo}/tasks/{task_id}", + "title": "Get a task by repo", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + }, + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The unique identifier of the task.

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a task by ID scoped to an owner/repo path

    \n

    Fine-grained access tokens for \"Get a task by repo\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "task_id": "TASK_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Task retrieved successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "sessions": [ + { + "id": "s1a2b3c4-d5e6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "user": { + "id": 1 + }, + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "state": "completed", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "completed_at": "2025-01-01T01:00:00Z", + "prompt": "Fix the login button on the homepage", + "head_ref": "copilot/fix-1", + "base_ref": "main", + "model": "claude-sonnet-4.6" + } + ] + }, + "schema": { + "allOf": [ + { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "type": "object", + "description": "Full session details within a task", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Session ID" + }, + "name": { + "type": "string", + "description": "Session name" + }, + "user": { + "description": "The user who created this session", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this session belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "task_id": { + "type": "string", + "description": "Task ID this session belongs to" + }, + "state": { + "type": "string", + "description": "Current state of a session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "Completion timestamp" + }, + "prompt": { + "type": "string", + "description": "Content of the triggering event" + }, + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + }, + "model": { + "type": "string", + "description": "Model used for this session" + }, + "error": { + "type": "object", + "description": "Error details for a failed session", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + } + }, + "description": "Sessions associated with this task" + } + } + } + ] + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Task retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/tasks", + "title": "List tasks", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 30, + "minimum": 1, + "maximum": 100 + }, + "description": "

    The number of results per page (max 100).

    " + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1, + "minimum": 1 + }, + "description": "

    The page number of the results to fetch.

    " + }, + { + "name": "sort", + "in": "query", + "schema": { + "type": "string", + "default": "updated_at", + "enum": [ + "updated_at", + "created_at" + ] + }, + "description": "

    The field to sort results by. Can be updated_at or created_at.

    " + }, + { + "name": "direction", + "in": "query", + "schema": { + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ] + }, + "description": "

    The direction to sort results. Can be asc or desc.

    " + }, + { + "name": "state", + "in": "query", + "schema": { + "type": "string" + }, + "description": "

    Comma-separated list of task states to filter by. Can be any combination of: queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, cancelled.

    " + }, + { + "name": "is_archived", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "

    Filter by archived status. When true, returns only archived tasks. When false or omitted, returns only non-archived tasks. Defaults to false.

    " + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "

    Only show tasks updated at or after this time (ISO 8601 timestamp)

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a list of tasks for the authenticated user

    \n

    Fine-grained access tokens for \"List tasks\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json" + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Tasks retrieved successfully

    ", + "example": { + "tasks": [ + { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z" + } + ] + }, + "schema": { + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + "description": "List of tasks" + }, + "total_active_count": { + "type": "integer", + "format": "int32", + "description": "Total count of active (non-archived) tasks" + }, + "total_archived_count": { + "type": "integer", + "format": "int32", + "description": "Total count of archived tasks" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Tasks retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/tasks/{task_id}", + "title": "Get a task by ID", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The unique identifier of the task.

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a task by ID with its associated sessions

    \n

    Fine-grained access tokens for \"Get a task by ID\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "task_id": "TASK_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Task retrieved successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "sessions": [ + { + "id": "s1a2b3c4-d5e6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "user": { + "id": 1 + }, + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "state": "completed", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "completed_at": "2025-01-01T01:00:00Z", + "prompt": "Fix the login button on the homepage", + "head_ref": "copilot/fix-1", + "base_ref": "main", + "model": "claude-sonnet-4.6" + } + ] + }, + "schema": { + "allOf": [ + { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "type": "object", + "description": "Full session details within a task", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Session ID" + }, + "name": { + "type": "string", + "description": "Session name" + }, + "user": { + "description": "The user who created this session", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this session belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "task_id": { + "type": "string", + "description": "Task ID this session belongs to" + }, + "state": { + "type": "string", + "description": "Current state of a session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "Completion timestamp" + }, + "prompt": { + "type": "string", + "description": "Content of the triggering event" + }, + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + }, + "model": { + "type": "string", + "description": "Model used for this session" + }, + "error": { + "type": "object", + "description": "Error details for a failed session", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + } + }, + "description": "Sessions associated with this task" + } + } + } + ] + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Task retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Problems parsing request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + } + ] +} \ No newline at end of file diff --git a/src/rest/data/ghec-2022-11-28/orgs.json b/src/rest/data/ghec-2022-11-28/orgs.json index 44ec1db1690c..01fb473e4fd4 100644 --- a/src/rest/data/ghec-2022-11-28/orgs.json +++ b/src/rest/data/ghec-2022-11-28/orgs.json @@ -6183,19 +6183,19 @@ { "type": "string", "name": "name", - "description": "

    The name of the artifact. Note that if multiple deployments have identical 'digest' parameter values,\nthe name parameter must also be identical across all entries.

    ", + "description": "

    The name of the artifact.

    ", "isRequired": true }, { "type": "string", "name": "digest", - "description": "

    The hex encoded digest of the artifact. Note that if multiple deployments have identical 'digest' parameter values,\nthe name and version parameters must also be identical across all entries.

    ", + "description": "

    The hex encoded digest of the artifact.

    ", "isRequired": true }, { "type": "string", "name": "version", - "description": "

    The artifact version. Note that if multiple deployments have identical 'digest' parameter values,\nthe version parameter must also be identical across all entries.

    " + "description": "

    The artifact version.

    " }, { "type": "string", @@ -6237,7 +6237,7 @@ "default": true } ], - "descriptionHTML": "

    Set deployment records for a given cluster.\nIf proposed records in the 'deployments' field have identical 'cluster', 'logical_environment',\n'physical_environment', and 'deployment_name' values as existing records, the existing records will be updated.\nIf no existing records match, new records will be created.

    ", + "descriptionHTML": "

    Set deployment records for a given cluster.\nIf proposed records in the 'deployments' field have identical 'cluster', 'logical_environment',\n'physical_environment', and 'deployment_name' values as existing records, the existing records will be updated.\nIf no existing records match, new records will be created.\nNote: Artifacts are uniquely identified by the combination of their repository and digest fields. If two entries in the deployments\narray resolve to the same repository and have identical digest fields but differing name and version fields, the endpoint will use\nthe artifact name and version from the record processed first, since a single artifact (identified by repository and digest) can\nonly have one name and version.

    ", "codeExamples": [ { "request": { diff --git a/src/rest/data/ghec-2022-11-28/private-registries.json b/src/rest/data/ghec-2022-11-28/private-registries.json index 7611ea603ce1..b7033ebf2b6d 100644 --- a/src/rest/data/ghec-2022-11-28/private-registries.json +++ b/src/rest/data/ghec-2022-11-28/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -333,14 +342,15 @@ { "type": "string", "name": "auth_type", - "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith for OIDC authentication.

    ", + "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp for OIDC authentication.

    ", "enum": [ "token", "username_password", "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -386,7 +396,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -407,9 +417,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [ { "request": { @@ -483,7 +503,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -569,6 +590,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -659,7 +688,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -745,6 +775,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -959,7 +997,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -1041,6 +1080,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -1184,7 +1231,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -1230,7 +1278,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -1251,9 +1299,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/ghec-2022-11-28/secret-scanning.json b/src/rest/data/ghec-2022-11-28/secret-scanning.json index b0fb3cfa896c..cc19dc55dbbd 100644 --- a/src/rest/data/ghec-2022-11-28/secret-scanning.json +++ b/src/rest/data/ghec-2022-11-28/secret-scanning.json @@ -177,6 +177,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -2058,6 +2067,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -3952,6 +3970,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -7723,6 +7750,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/ghec-2026-03-10/actions.json b/src/rest/data/ghec-2026-03-10/actions.json index 03b1abf38051..0a138046c195 100644 --- a/src/rest/data/ghec-2026-03-10/actions.json +++ b/src/rest/data/ghec-2026-03-10/actions.json @@ -2596,6 +2596,657 @@ } } ], + "concurrency-groups": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups", + "title": "List concurrency groups for a repository", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "per_page", + "description": "

    The number of results per page (max 100). For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "schema": { + "type": "integer", + "default": 30 + } + }, + { + "name": "after", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Lists the active concurrency groups for a repository.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "last_acquired_at": "2026-01-15T16:14:23Z" + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build", + "last_acquired_at": "2026-01-15T16:13:55Z" + } + ] + }, + "schema": { + "title": "Concurrency Group List", + "description": "A list of active concurrency groups for a repository.", + "type": "object", + "required": [ + "total_count", + "concurrency_groups" + ], + "properties": { + "total_count": { + "type": "integer" + }, + "concurrency_groups": { + "type": "array", + "items": { + "type": "object", + "required": [ + "group_name", + "group_url", + "last_acquired_at" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group." + }, + "last_acquired_at": { + "type": [ + "string", + "null" + ], + "format": "date-time" + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}", + "title": "Get a concurrency group for a repository", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "concurrency_group_name", + "description": "

    The name of the concurrency group.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ahead_of_run", + "description": "

    Filter to items ahead of this workflow run ID in the queue, plus the run itself.\nMatches workflow-level concurrency and reusable-workflow leases held on behalf of\nthe run. Mutually exclusive with ahead_of_job.

    ", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + }, + { + "name": "ahead_of_job", + "description": "

    Filter to items ahead of this job ID in the queue, plus the job itself.\nMatches job-level concurrency and reusable-workflow leases on the job's\nancestor paths. Mutually exclusive with ahead_of_run.

    ", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1 + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Gets a specific concurrency group for a repository, including all instances in the group's queue.\nReturns 404 if the group is inactive or does not exist.

    \n

    Optionally, pass ahead_of_run or ahead_of_job to filter the results to only the items\nahead of the specified workflow run or job in the queue, plus the specified item itself\n(returned as the last element). This is useful for determining what is blocking a particular\nrun or job. Returns 422 if the specified run or job is not in this concurrency group.

    \n

    When using ahead_of_run, this matches workflow-level concurrency and any reusable-workflow\nleases held on behalf of that run. Job-level leases within the run are not considered to\nblock the run as a whole. Use ahead_of_job to match job-level concurrency and reusable-workflow\nleases on the job's ancestor paths.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "concurrency_group_name": "CONCURRENCY_GROUP_NAME" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "total_count": 3, + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "in_progress" + }, + { + "run_id": 30433643, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433643", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433643", + "status": "pending" + }, + { + "run_id": 30433644, + "run_name": "Deploy hotfix", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433644", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433644", + "job_id": 798245260, + "job_name": "deploy", + "job_url": "https://api.github.com/repos/octocat/Hello-World/actions/jobs/798245260", + "job_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433644/job/798245260", + "status": "pending" + } + ] + }, + "schema": { + "title": "Concurrency Group", + "description": "A concurrency group with the workflow runs and jobs that are either currently holding\nor waiting for the concurrency group lease.", + "type": "object", + "required": [ + "group_name", + "group_url", + "total_count", + "group_members" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group." + }, + "total_count": { + "type": "integer" + }, + "group_members": { + "type": "array", + "items": { + "type": "object", + "required": [ + "run_id", + "run_name", + "run_url", + "run_html_url", + "status" + ], + "properties": { + "run_id": { + "type": "integer", + "description": "The ID of the workflow run." + }, + "run_name": { + "type": "string", + "description": "The name of the workflow run." + }, + "run_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the workflow run." + }, + "run_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the workflow run." + }, + "job_id": { + "type": "integer", + "description": "The ID of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_name": { + "type": "string", + "description": "The display name of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the job." + }, + "job_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the job." + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "pending" + ] + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups", + "title": "List concurrency groups for a workflow run", + "category": "actions", + "subcategory": "concurrency-groups", + "parameters": [ + { + "name": "owner", + "description": "

    The account owner of the repository. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "repo", + "description": "

    The name of the repository without the .git extension. The name is not case sensitive.

    ", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "run_id", + "description": "

    The unique identifier of the workflow run.

    ", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "per_page", + "description": "

    The number of results per page (max 100). For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "schema": { + "type": "integer", + "default": 30 + } + }, + { + "name": "before", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results before this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "after", + "description": "

    A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. For more information, see \"Using pagination in the REST API.\"

    ", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Lists all concurrency groups associated with a workflow run or its jobs.

    \n

    The set of groups is derived from the run's configuration, so a group is\nincluded even when the run no longer has any items currently holding or\nwaiting in it. In that case the group_members array will be empty.\ntotal_count reflects the number of groups the run participates in by\nconfiguration, not the number with active items.

    \n

    This differs from GET /repos/{owner}/{repo}/actions/concurrency_groups/{group_name},\nwhich returns 404 when a group has no active items. That endpoint reports\nthe live state of a group repo-wide, while this endpoint reports the\ngroups associated with a specific run by configuration.

    \n

    Results are sorted by group name and support cursor-based pagination via\nbefore and after. The after cursor paginates forward only and does\nnot emit a rel=\"prev\" Link; use before to page backward from a\nforward page's next cursor.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint with a private repository.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "run_id": "RUN_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Response

    ", + "example": { + "total_count": 2, + "concurrency_groups": [ + { + "group_name": "deploy-prod", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod", + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "in_progress", + "position": 0, + "position_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/deploy-prod?ahead_of_run=30433642" + } + ] + }, + { + "group_name": "ci-build", + "group_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build", + "group_members": [ + { + "run_id": 30433642, + "run_name": "Deploy to production", + "run_url": "https://api.github.com/repos/octocat/Hello-World/actions/runs/30433642", + "run_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642", + "status": "pending", + "position": 2, + "position_url": "https://api.github.com/repos/octocat/Hello-World/actions/concurrency_groups/ci-build?ahead_of_job=798245260", + "job_id": 798245260, + "job_name": "build", + "job_url": "https://api.github.com/repos/octocat/Hello-World/actions/jobs/798245260", + "job_html_url": "https://github.com/octocat/Hello-World/actions/runs/30433642/job/798245260" + } + ] + } + ] + }, + "schema": { + "title": "Concurrency Group Run List", + "description": "A list of concurrency groups associated with a workflow run.", + "type": "object", + "required": [ + "total_count", + "concurrency_groups" + ], + "properties": { + "total_count": { + "type": "integer", + "description": "The total number of concurrency groups this workflow run participates in,\nderived from the run's configuration. This count is not filtered by\nwhether the run currently holds or is waiting in each group, so it can\ninclude groups whose `group_members` array is empty (for example, when\nthe run has already released its lease in that group)." + }, + "concurrency_groups": { + "type": "array", + "items": { + "type": "object", + "required": [ + "group_name", + "group_url", + "group_members" + ], + "properties": { + "group_name": { + "type": "string", + "description": "The name of the concurrency group." + }, + "group_url": { + "type": "string", + "format": "uri", + "description": "API URL for this concurrency group. May return 404 if the group\nhas no active items at the time it is requested, since the\nget-by-name endpoint reports the live repo-wide state of a group\nwhile this endpoint lists groups associated with a run by\nconfiguration." + }, + "group_members": { + "type": "array", + "description": "Items belonging to this workflow run that are either currently holding or\nwaiting for the concurrency group lease. May be empty if the run no\nlonger has any active or queued items in this group.", + "items": { + "type": "object", + "required": [ + "run_id", + "run_name", + "run_url", + "run_html_url", + "status", + "position", + "position_url" + ], + "properties": { + "run_id": { + "type": "integer", + "description": "The ID of the workflow run." + }, + "run_name": { + "type": "string", + "description": "The name of the workflow run." + }, + "run_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the workflow run." + }, + "run_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the workflow run." + }, + "position": { + "type": "integer", + "description": "Queue position. 0 means the item holds the concurrency lease (in_progress), 1 or higher means queued (pending)." + }, + "position_url": { + "type": "string", + "format": "uri", + "description": "API URL to get items ahead of this item in the concurrency group." + }, + "job_id": { + "type": [ + "integer", + "null" + ], + "description": "The ID of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_name": { + "type": [ + "string", + "null" + ], + "description": "The display name of the job, when the item represents a job-level or reusable-workflow-level lease." + }, + "job_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "API URL for the job." + }, + "job_html_url": { + "type": [ + "string", + "null" + ], + "format": "uri", + "description": "Web URL for the job." + }, + "status": { + "type": "string", + "enum": [ + "in_progress", + "pending" + ] + } + } + } + } + } + } + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    OK

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation failed, or the endpoint has been spammed.

    " + } + ], + "previews": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Actions\" repository permissions": "read" + } + ], + "allowsPublicRead": true + } + } + ], "hosted-runners": [ { "serverUrl": "https://api.github.com", @@ -35570,6 +36221,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/ghec-2026-03-10/agent-tasks.json b/src/rest/data/ghec-2026-03-10/agent-tasks.json new file mode 100644 index 000000000000..275cc3f86861 --- /dev/null +++ b/src/rest/data/ghec-2026-03-10/agent-tasks.json @@ -0,0 +1,1994 @@ +{ + "agent-tasks": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/repos/{owner}/{repo}/tasks", + "title": "List tasks for repository", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + }, + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 30, + "minimum": 1, + "maximum": 100 + }, + "description": "

    The number of results per page (max 100).

    " + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1, + "minimum": 1 + }, + "description": "

    The page number of the results to fetch.

    " + }, + { + "name": "sort", + "in": "query", + "schema": { + "type": "string", + "default": "updated_at", + "enum": [ + "updated_at", + "created_at" + ] + }, + "description": "

    The field to sort results by. Can be updated_at or created_at.

    " + }, + { + "name": "direction", + "in": "query", + "schema": { + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ] + }, + "description": "

    The direction to sort results. Can be asc or desc.

    " + }, + { + "name": "state", + "in": "query", + "schema": { + "type": "string" + }, + "description": "

    Comma-separated list of task states to filter by. Can be any combination of: queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, cancelled.

    " + }, + { + "name": "is_archived", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "

    Filter by archived status. When true, returns only archived tasks. When false or omitted, returns only non-archived tasks. Defaults to false.

    " + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "

    Only show tasks updated at or after this time (ISO 8601 timestamp)

    " + }, + { + "name": "creator_id", + "in": "query", + "schema": { + "type": "integer" + }, + "description": "

    Filter tasks by creator user ID

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a list of tasks for a specific repository

    \n

    Fine-grained access tokens for \"List tasks for repository\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Tasks retrieved successfully

    ", + "example": { + "tasks": [ + { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z" + } + ] + }, + "schema": { + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + "description": "List of tasks" + }, + "total_active_count": { + "type": "integer", + "format": "int32", + "description": "Total count of active (non-archived) tasks" + }, + "total_archived_count": { + "type": "integer", + "format": "int32", + "description": "Total count of archived tasks" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Tasks retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "post", + "requestPath": "/agents/repos/{owner}/{repo}/tasks", + "title": "Start a task", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + } + ], + "bodyParameters": [ + { + "type": "string", + "name": "prompt", + "description": "

    The user's prompt for the agent

    ", + "isRequired": true + }, + { + "type": "string", + "name": "model", + "description": "

    The model to use for this task. The allowed models may change over time and depend on the user's GitHub Copilot plan and organization policies. Currently supported values: claude-sonnet-4.6, claude-opus-4.6, gpt-5.2-codex, gpt-5.3-codex, gpt-5.4, claude-sonnet-4.5, claude-opus-4.5

    " + }, + { + "type": "boolean", + "name": "create_pull_request", + "description": "

    Whether to create a PR.

    ", + "default": false + }, + { + "type": "string", + "name": "base_ref", + "description": "

    Base ref for new branch/PR

    " + } + ], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Starts a new Copilot cloud agent task for a repository.

    \n

    This endpoint is only available to users with a Copilot Business or Copilot Enterprise subscription.

    \n

    Fine-grained access tokens for \"Start a task\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read and write)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "contentType": "application/json", + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "bodyParameters": { + "prompt": "Fix the login button on the homepage", + "base_ref": "main" + }, + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "201", + "contentType": "application/json", + "description": "

    Task created successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "queued", + "session_count": 1, + "artifacts": [], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T00:00:00Z" + }, + "schema": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "201", + "description": "

    Task created successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Problems parsing JSON

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/repos/{owner}/{repo}/tasks/{task_id}", + "title": "Get a task by repo", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "owner", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The account owner of the repository. The name is not case sensitive.

    " + }, + { + "name": "repo", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The name of the repository. The name is not case sensitive.

    " + }, + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The unique identifier of the task.

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a task by ID scoped to an owner/repo path

    \n

    Fine-grained access tokens for \"Get a task by repo\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "task_id": "TASK_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Task retrieved successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "sessions": [ + { + "id": "s1a2b3c4-d5e6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "user": { + "id": 1 + }, + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "state": "completed", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "completed_at": "2025-01-01T01:00:00Z", + "prompt": "Fix the login button on the homepage", + "head_ref": "copilot/fix-1", + "base_ref": "main", + "model": "claude-sonnet-4.6" + } + ] + }, + "schema": { + "allOf": [ + { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "type": "object", + "description": "Full session details within a task", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Session ID" + }, + "name": { + "type": "string", + "description": "Session name" + }, + "user": { + "description": "The user who created this session", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this session belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "task_id": { + "type": "string", + "description": "Task ID this session belongs to" + }, + "state": { + "type": "string", + "description": "Current state of a session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "Completion timestamp" + }, + "prompt": { + "type": "string", + "description": "Content of the triggering event" + }, + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + }, + "model": { + "type": "string", + "description": "Model used for this session" + }, + "error": { + "type": "object", + "description": "Error details for a failed session", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + } + }, + "description": "Sessions associated with this task" + } + } + } + ] + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Task retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/tasks", + "title": "List tasks", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 30, + "minimum": 1, + "maximum": 100 + }, + "description": "

    The number of results per page (max 100).

    " + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1, + "minimum": 1 + }, + "description": "

    The page number of the results to fetch.

    " + }, + { + "name": "sort", + "in": "query", + "schema": { + "type": "string", + "default": "updated_at", + "enum": [ + "updated_at", + "created_at" + ] + }, + "description": "

    The field to sort results by. Can be updated_at or created_at.

    " + }, + { + "name": "direction", + "in": "query", + "schema": { + "type": "string", + "default": "desc", + "enum": [ + "asc", + "desc" + ] + }, + "description": "

    The direction to sort results. Can be asc or desc.

    " + }, + { + "name": "state", + "in": "query", + "schema": { + "type": "string" + }, + "description": "

    Comma-separated list of task states to filter by. Can be any combination of: queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, cancelled.

    " + }, + { + "name": "is_archived", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "

    Filter by archived status. When true, returns only archived tasks. When false or omitted, returns only non-archived tasks. Defaults to false.

    " + }, + { + "name": "since", + "in": "query", + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "

    Only show tasks updated at or after this time (ISO 8601 timestamp)

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a list of tasks for the authenticated user

    \n

    Fine-grained access tokens for \"List tasks\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json" + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Tasks retrieved successfully

    ", + "example": { + "tasks": [ + { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z" + } + ] + }, + "schema": { + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + "description": "List of tasks" + }, + "total_active_count": { + "type": "integer", + "format": "int32", + "description": "Total count of active (non-archived) tasks" + }, + "total_archived_count": { + "type": "integer", + "format": "int32", + "description": "Total count of archived tasks" + } + } + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Tasks retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Bad request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/agents/tasks/{task_id}", + "title": "Get a task by ID", + "category": "agent-tasks", + "subcategory": "agent-tasks", + "parameters": [ + { + "name": "task_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

    The unique identifier of the task.

    " + } + ], + "bodyParameters": [], + "descriptionHTML": "

    Note

    \n

    \nThis endpoint is in public preview and is subject to change.

    \n
    \n

    Returns a task by ID with its associated sessions

    \n

    Fine-grained access tokens for \"Get a task by ID\"

    \n

    This endpoint works with the following fine-grained token types:

    \n\n

    The fine-grained token must have the following permission set:

    \n
      \n
    • \"Agent tasks\" repository permissions (read)
    • \n
    \n

    GitHub App installation access tokens are not supported for this endpoint.

    ", + "codeExamples": [ + { + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "task_id": "TASK_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

    Task retrieved successfully

    ", + "example": { + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "url": "https://api.github.com/agents/repos/octocat/hello-world/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "html_url": "https://github.com/octocat/hello-world/copilot/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "creator": { + "id": 1 + }, + "creator_type": "user", + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "state": "completed", + "session_count": 1, + "artifacts": [ + { + "provider": "github", + "type": "pull", + "data": { + "id": 42 + } + } + ], + "archived_at": null, + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "sessions": [ + { + "id": "s1a2b3c4-d5e6-7890-abcd-ef1234567890", + "name": "Fix the login button on the homepage", + "user": { + "id": 1 + }, + "owner": { + "id": 1 + }, + "repository": { + "id": 1296269 + }, + "task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "state": "completed", + "created_at": "2025-01-01T00:00:00Z", + "updated_at": "2025-01-01T01:00:00Z", + "completed_at": "2025-01-01T01:00:00Z", + "prompt": "Fix the login button on the homepage", + "head_ref": "copilot/fix-1", + "base_ref": "main", + "model": "claude-sonnet-4.6" + } + ] + }, + "schema": { + "allOf": [ + { + "type": "object", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique task identifier" + }, + "url": { + "type": "string", + "description": "API URL for this task" + }, + "html_url": { + "type": "string", + "description": "Web URL for this task" + }, + "name": { + "type": "string", + "description": "Human-readable name derived from the task prompt" + }, + "creator": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + } + ], + "description": "The entity who created this task" + }, + "creator_type": { + "type": "string", + "description": "Type of the task creator", + "enum": [ + "user", + "organization" + ] + }, + "user_collaborators": { + "type": "array", + "items": { + "type": "object", + "description": "A GitHub user", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "description": "User objects of collaborators on this task", + "deprecated": true + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this task belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "state": { + "type": "string", + "description": "Current state of the task, derived from its most recent session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "session_count": { + "type": "integer", + "format": "int32", + "description": "Number of sessions in this task" + }, + "artifacts": { + "type": "array", + "items": { + "type": "object", + "description": "A resource generated by the task", + "required": [ + "provider", + "type", + "data" + ], + "properties": { + "provider": { + "type": "string", + "enum": [ + "github" + ], + "description": "Provider namespace" + }, + "type": { + "type": "string", + "enum": [ + "pull", + "branch" + ], + "description": "Type of artifact. Available Values: `pull`, `branch`.\n" + }, + "data": { + "oneOf": [ + { + "type": "object", + "description": "A GitHub resource (pull request, issue, etc.)", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "GitHub resource ID" + }, + "global_id": { + "type": "string", + "description": "GraphQL global ID" + } + } + }, + { + "type": "object", + "description": "A Git branch reference", + "required": [ + "head_ref", + "base_ref" + ], + "properties": { + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + } + } + } + ], + "description": "Resource data (shape depends on type)" + } + } + }, + "description": "Resources created by this task (PRs, branches, etc.)" + }, + "archived_at": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "description": "Timestamp when the task was archived, null if not archived" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the most recent update" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the task was created" + } + } + }, + { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "type": "object", + "description": "Full session details within a task", + "required": [ + "id", + "state", + "created_at" + ], + "properties": { + "id": { + "type": "string", + "description": "Session ID" + }, + "name": { + "type": "string", + "description": "Session name" + }, + "user": { + "description": "The user who created this session", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "owner": { + "description": "The owner of the repository", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the user" + } + } + }, + "repository": { + "description": "The repository this session belongs to", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the repository" + } + } + }, + "task_id": { + "type": "string", + "description": "Task ID this session belongs to" + }, + "state": { + "type": "string", + "description": "Current state of a session", + "enum": [ + "queued", + "in_progress", + "completed", + "failed", + "idle", + "waiting_for_user", + "timed_out", + "cancelled" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "description": "Completion timestamp" + }, + "prompt": { + "type": "string", + "description": "Content of the triggering event" + }, + "head_ref": { + "type": "string", + "description": "Head branch name" + }, + "base_ref": { + "type": "string", + "description": "Base branch name" + }, + "model": { + "type": "string", + "description": "Model used for this session" + }, + "error": { + "type": "object", + "description": "Error details for a failed session", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + } + }, + "description": "Sessions associated with this task" + } + } + } + ] + } + } + } + ], + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

    Task retrieved successfully

    " + }, + { + "httpStatusCode": "400", + "description": "

    Problems parsing request

    " + }, + { + "httpStatusCode": "401", + "description": "

    Authentication required

    " + }, + { + "httpStatusCode": "403", + "description": "

    Insufficient permissions

    " + }, + { + "httpStatusCode": "404", + "description": "

    Resource not found

    " + }, + { + "httpStatusCode": "422", + "description": "

    Validation Failed

    " + } + ], + "previews": [] + } + ] +} \ No newline at end of file diff --git a/src/rest/data/ghec-2026-03-10/orgs.json b/src/rest/data/ghec-2026-03-10/orgs.json index caec43e1968e..4e9746ff155e 100644 --- a/src/rest/data/ghec-2026-03-10/orgs.json +++ b/src/rest/data/ghec-2026-03-10/orgs.json @@ -6169,19 +6169,19 @@ { "type": "string", "name": "name", - "description": "

    The name of the artifact. Note that if multiple deployments have identical 'digest' parameter values,\nthe name parameter must also be identical across all entries.

    ", + "description": "

    The name of the artifact.

    ", "isRequired": true }, { "type": "string", "name": "digest", - "description": "

    The hex encoded digest of the artifact. Note that if multiple deployments have identical 'digest' parameter values,\nthe name and version parameters must also be identical across all entries.

    ", + "description": "

    The hex encoded digest of the artifact.

    ", "isRequired": true }, { "type": "string", "name": "version", - "description": "

    The artifact version. Note that if multiple deployments have identical 'digest' parameter values,\nthe version parameter must also be identical across all entries.

    " + "description": "

    The artifact version.

    " }, { "type": "string", @@ -6223,7 +6223,7 @@ "default": true } ], - "descriptionHTML": "

    Set deployment records for a given cluster.\nIf proposed records in the 'deployments' field have identical 'cluster', 'logical_environment',\n'physical_environment', and 'deployment_name' values as existing records, the existing records will be updated.\nIf no existing records match, new records will be created.

    ", + "descriptionHTML": "

    Set deployment records for a given cluster.\nIf proposed records in the 'deployments' field have identical 'cluster', 'logical_environment',\n'physical_environment', and 'deployment_name' values as existing records, the existing records will be updated.\nIf no existing records match, new records will be created.\nNote: Artifacts are uniquely identified by the combination of their repository and digest fields. If two entries in the deployments\narray resolve to the same repository and have identical digest fields but differing name and version fields, the endpoint will use\nthe artifact name and version from the record processed first, since a single artifact (identified by repository and digest) can\nonly have one name and version.

    ", "codeExamples": [ { "request": { diff --git a/src/rest/data/ghec-2026-03-10/private-registries.json b/src/rest/data/ghec-2026-03-10/private-registries.json index 7611ea603ce1..b7033ebf2b6d 100644 --- a/src/rest/data/ghec-2026-03-10/private-registries.json +++ b/src/rest/data/ghec-2026-03-10/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -333,14 +342,15 @@ { "type": "string", "name": "auth_type", - "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith for OIDC authentication.

    ", + "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp for OIDC authentication.

    ", "enum": [ "token", "username_password", "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -386,7 +396,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -407,9 +417,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [ { "request": { @@ -483,7 +503,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -569,6 +590,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -659,7 +688,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -745,6 +775,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -959,7 +997,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -1041,6 +1080,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -1184,7 +1231,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -1230,7 +1278,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -1251,9 +1299,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/ghec-2026-03-10/secret-scanning.json b/src/rest/data/ghec-2026-03-10/secret-scanning.json index b0fb3cfa896c..cc19dc55dbbd 100644 --- a/src/rest/data/ghec-2026-03-10/secret-scanning.json +++ b/src/rest/data/ghec-2026-03-10/secret-scanning.json @@ -177,6 +177,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -2058,6 +2067,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -3952,6 +3970,15 @@ "type": "boolean", "default": false } + }, + { + "name": "is_bypassed", + "in": "query", + "description": "

    A boolean value (true or false) indicating whether to filter alerts by their push protection bypass status. When set to true, only alerts that were created because a push protection rule was bypassed will be returned. When set to false, only alerts that were not caused by a push protection bypass will be returned.

    ", + "required": false, + "schema": { + "type": "boolean" + } } ], "bodyParameters": [], @@ -7723,6 +7750,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/ghes-3.15-2022-11-28/actions.json b/src/rest/data/ghes-3.15-2022-11-28/actions.json index da2482025b1c..3b9dc3fa3543 100644 --- a/src/rest/data/ghes-3.15-2022-11-28/actions.json +++ b/src/rest/data/ghes-3.15-2022-11-28/actions.json @@ -25625,6 +25625,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/ghes-3.15-2022-11-28/secret-scanning.json b/src/rest/data/ghes-3.15-2022-11-28/secret-scanning.json index 9798c0330494..3d8257e2c6d6 100644 --- a/src/rest/data/ghes-3.15-2022-11-28/secret-scanning.json +++ b/src/rest/data/ghes-3.15-2022-11-28/secret-scanning.json @@ -3828,6 +3828,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/ghes-3.16-2022-11-28/actions.json b/src/rest/data/ghes-3.16-2022-11-28/actions.json index 525b26282ac5..a988b072655f 100644 --- a/src/rest/data/ghes-3.16-2022-11-28/actions.json +++ b/src/rest/data/ghes-3.16-2022-11-28/actions.json @@ -25625,6 +25625,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/ghes-3.16-2022-11-28/private-registries.json b/src/rest/data/ghes-3.16-2022-11-28/private-registries.json index dc7883f478ce..b9db362dae0e 100644 --- a/src/rest/data/ghes-3.16-2022-11-28/private-registries.json +++ b/src/rest/data/ghes-3.16-2022-11-28/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -413,7 +422,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -495,6 +505,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -638,7 +656,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -684,7 +703,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -705,9 +724,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/ghes-3.16-2022-11-28/secret-scanning.json b/src/rest/data/ghes-3.16-2022-11-28/secret-scanning.json index be8a3d5415d9..34c0dda99b29 100644 --- a/src/rest/data/ghes-3.16-2022-11-28/secret-scanning.json +++ b/src/rest/data/ghes-3.16-2022-11-28/secret-scanning.json @@ -4637,6 +4637,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/ghes-3.17-2022-11-28/actions.json b/src/rest/data/ghes-3.17-2022-11-28/actions.json index 08c47567fef2..c8232b0609f5 100644 --- a/src/rest/data/ghes-3.17-2022-11-28/actions.json +++ b/src/rest/data/ghes-3.17-2022-11-28/actions.json @@ -25661,6 +25661,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/ghes-3.17-2022-11-28/private-registries.json b/src/rest/data/ghes-3.17-2022-11-28/private-registries.json index 79ce74a3cc3b..137a81a91c4f 100644 --- a/src/rest/data/ghes-3.17-2022-11-28/private-registries.json +++ b/src/rest/data/ghes-3.17-2022-11-28/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -413,7 +422,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -495,6 +505,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -638,7 +656,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -684,7 +703,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -705,9 +724,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/ghes-3.17-2022-11-28/secret-scanning.json b/src/rest/data/ghes-3.17-2022-11-28/secret-scanning.json index 6a1db159cecd..6ab1a592e856 100644 --- a/src/rest/data/ghes-3.17-2022-11-28/secret-scanning.json +++ b/src/rest/data/ghes-3.17-2022-11-28/secret-scanning.json @@ -4672,6 +4672,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/ghes-3.18-2022-11-28/actions.json b/src/rest/data/ghes-3.18-2022-11-28/actions.json index fdda87e8e3a3..2df66c9d0f35 100644 --- a/src/rest/data/ghes-3.18-2022-11-28/actions.json +++ b/src/rest/data/ghes-3.18-2022-11-28/actions.json @@ -25676,6 +25676,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/ghes-3.18-2022-11-28/private-registries.json b/src/rest/data/ghes-3.18-2022-11-28/private-registries.json index bb0a894f2913..6f11945f5a79 100644 --- a/src/rest/data/ghes-3.18-2022-11-28/private-registries.json +++ b/src/rest/data/ghes-3.18-2022-11-28/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -333,14 +342,15 @@ { "type": "string", "name": "auth_type", - "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith for OIDC authentication.

    ", + "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp for OIDC authentication.

    ", "enum": [ "token", "username_password", "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -386,7 +396,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -407,9 +417,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [ { "request": { @@ -483,7 +503,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -569,6 +590,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -659,7 +688,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -745,6 +775,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -959,7 +997,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -1041,6 +1080,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -1184,7 +1231,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -1230,7 +1278,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -1251,9 +1299,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/ghes-3.18-2022-11-28/secret-scanning.json b/src/rest/data/ghes-3.18-2022-11-28/secret-scanning.json index ea9f8a1ab3b0..261613b60178 100644 --- a/src/rest/data/ghes-3.18-2022-11-28/secret-scanning.json +++ b/src/rest/data/ghes-3.18-2022-11-28/secret-scanning.json @@ -4569,6 +4569,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/ghes-3.19-2022-11-28/actions.json b/src/rest/data/ghes-3.19-2022-11-28/actions.json index c842c4ca1e23..09b6b0bd56fa 100644 --- a/src/rest/data/ghes-3.19-2022-11-28/actions.json +++ b/src/rest/data/ghes-3.19-2022-11-28/actions.json @@ -28679,6 +28679,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/ghes-3.19-2022-11-28/private-registries.json b/src/rest/data/ghes-3.19-2022-11-28/private-registries.json index 7bb905aeefff..ff94823dd05a 100644 --- a/src/rest/data/ghes-3.19-2022-11-28/private-registries.json +++ b/src/rest/data/ghes-3.19-2022-11-28/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -333,14 +342,15 @@ { "type": "string", "name": "auth_type", - "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith for OIDC authentication.

    ", + "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp for OIDC authentication.

    ", "enum": [ "token", "username_password", "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -386,7 +396,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -407,9 +417,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [ { "request": { @@ -483,7 +503,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -569,6 +590,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -659,7 +688,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -745,6 +775,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -959,7 +997,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -1041,6 +1080,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -1184,7 +1231,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -1230,7 +1278,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -1251,9 +1299,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/ghes-3.19-2022-11-28/secret-scanning.json b/src/rest/data/ghes-3.19-2022-11-28/secret-scanning.json index 2390aaa71ced..216d61e9fa53 100644 --- a/src/rest/data/ghes-3.19-2022-11-28/secret-scanning.json +++ b/src/rest/data/ghes-3.19-2022-11-28/secret-scanning.json @@ -6572,6 +6572,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/data/ghes-3.20-2022-11-28/actions.json b/src/rest/data/ghes-3.20-2022-11-28/actions.json index b1a1bc857131..6a209c612d32 100644 --- a/src/rest/data/ghes-3.20-2022-11-28/actions.json +++ b/src/rest/data/ghes-3.20-2022-11-28/actions.json @@ -28679,6 +28679,12 @@ "name": "enable_debug_logging", "description": "

    Whether to enable debug logging for the re-run.

    ", "default": false + }, + { + "type": "boolean", + "name": "enable_debugger", + "description": "

    Whether to enable the debugger for the re-run of this job.

    ", + "default": false } ], "descriptionHTML": "

    Re-run a job and its dependent jobs in a workflow run.

    \n

    OAuth app tokens and personal access tokens (classic) need the repo scope to use this endpoint.

    ", diff --git a/src/rest/data/ghes-3.20-2022-11-28/private-registries.json b/src/rest/data/ghes-3.20-2022-11-28/private-registries.json index 9de494597695..13602cb21ca1 100644 --- a/src/rest/data/ghes-3.20-2022-11-28/private-registries.json +++ b/src/rest/data/ghes-3.20-2022-11-28/private-registries.json @@ -114,7 +114,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -196,6 +197,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -333,14 +342,15 @@ { "type": "string", "name": "auth_type", - "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith for OIDC authentication.

    ", + "description": "

    The authentication type for the private registry. Defaults to token if not specified. Use oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp for OIDC authentication.

    ", "enum": [ "token", "username_password", "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -386,7 +396,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -407,9 +417,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Creates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [ { "request": { @@ -483,7 +503,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -569,6 +590,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -659,7 +688,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -745,6 +775,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -959,7 +997,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ], "type": "string" }, @@ -1041,6 +1080,14 @@ "description": "The Cloudsmith API host.", "type": "string" }, + "workload_identity_provider": { + "description": "The full resource name of the GCP Workload Identity Provider (e.g. `projects//locations/global/workloadIdentityPools//providers/`).", + "type": "string" + }, + "service_account": { + "description": "The GCP service account email to impersonate. If omitted, the federated token is used directly (direct WIF).", + "type": "string" + }, "created_at": { "type": "string", "format": "date-time" @@ -1184,7 +1231,8 @@ "oidc_azure", "oidc_aws", "oidc_jfrog", - "oidc_cloudsmith" + "oidc_cloudsmith", + "oidc_gcp" ] }, { @@ -1230,7 +1278,7 @@ { "type": "string", "name": "audience", - "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and required for oidc_cloudsmith auth types.

    " + "description": "

    The OIDC audience. Optional for oidc_aws, oidc_jfrog, and oidc_gcp, and required for oidc_cloudsmith auth types.

    " }, { "type": "string", @@ -1251,9 +1299,19 @@ "type": "string", "name": "api_host", "description": "

    The Cloudsmith API host. Optional for oidc_cloudsmith auth type. If omitted, api.cloudsmith.io is used by default.

    " + }, + { + "type": "string", + "name": "workload_identity_provider", + "description": "

    The full resource name of the GCP Workload Identity Provider (e.g. projects/<NUM>/locations/global/workloadIdentityPools/<POOL>/providers/<PROVIDER>). Required when auth_type is oidc_gcp.

    " + }, + { + "type": "string", + "name": "service_account", + "description": "

    The GCP service account email to impersonate. Optional for oidc_gcp auth type. If omitted, the federated token is used directly (direct WIF).

    " } ], - "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, or oidc_cloudsmith), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", + "descriptionHTML": "

    Updates a private registry configuration with an encrypted value for an organization. Encrypt your secret using LibSodium. For more information, see \"Encrypting secrets for the REST API.\"\nFor OIDC-based registries (oidc_azure, oidc_aws, oidc_jfrog, oidc_cloudsmith, or oidc_gcp), the encrypted_value and key_id fields should be omitted.

    \n

    OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint.

    ", "codeExamples": [], "statusCodes": [ { diff --git a/src/rest/data/ghes-3.20-2022-11-28/secret-scanning.json b/src/rest/data/ghes-3.20-2022-11-28/secret-scanning.json index b10d80021bee..80a4e2aa54ca 100644 --- a/src/rest/data/ghes-3.20-2022-11-28/secret-scanning.json +++ b/src/rest/data/ghes-3.20-2022-11-28/secret-scanning.json @@ -6624,6 +6624,10 @@ "httpStatusCode": "400", "description": "

    Bad request, resolution comment is invalid or the resolution was not changed.

    " }, + { + "httpStatusCode": "403", + "description": "

    Delegated alert dismissal is enabled and the authenticated user is not a valid reviewer.

    " + }, { "httpStatusCode": "404", "description": "

    Repository is public, or secret scanning is disabled for the repository, or the resource is not found

    " diff --git a/src/rest/lib/config.json b/src/rest/lib/config.json index f38c5a72271d..2412fd4706dd 100644 --- a/src/rest/lib/config.json +++ b/src/rest/lib/config.json @@ -52,5 +52,5 @@ ] } }, - "sha": "d3a3c2a50bb45b5f437bdfd8e0c700091bb1fb7b" + "sha": "12330abe1a9651268439945b92312855bb071532" } \ No newline at end of file diff --git a/src/webhooks/lib/config.json b/src/webhooks/lib/config.json index 7b9bdef0a537..28574f6f1461 100644 --- a/src/webhooks/lib/config.json +++ b/src/webhooks/lib/config.json @@ -1,3 +1,3 @@ { - "sha": "d3a3c2a50bb45b5f437bdfd8e0c700091bb1fb7b" + "sha": "12330abe1a9651268439945b92312855bb071532" } \ No newline at end of file From 1e38a7841a45779818cb1f59e1f3615e38547719 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 6 May 2026 15:01:30 +0200 Subject: [PATCH 12/13] Rename procedural-content-type.md to how-to-content-type.md (#60310) Co-authored-by: Thom Wong <101249231+supergranular@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Melanie Yarbrough <11952755+myarb@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../contents-of-a-github-docs-article.md | 4 ++-- .../best-practices-for-github-docs.md | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/content/contributing/style-guide-and-content-model/contents-of-a-github-docs-article.md b/content/contributing/style-guide-and-content-model/contents-of-a-github-docs-article.md index 569e1bd4e752..1605745ec623 100644 --- a/content/contributing/style-guide-and-content-model/contents-of-a-github-docs-article.md +++ b/content/contributing/style-guide-and-content-model/contents-of-a-github-docs-article.md @@ -140,9 +140,9 @@ Prerequisites are information that people need to know before proceeding with a * [AUTOTITLE](/enterprise-server@latest/admin/installation/installing-github-enterprise-server-on-aws) * [AUTOTITLE](/enterprise-server@latest/admin/configuration/enabling-subdomain-isolation) -## Procedural content +## How-to content -Procedural content helps people complete tasks. For more information, see [AUTOTITLE](/contributing/style-guide-and-content-model/procedural-content-type) in the content model. +How-to content helps people complete tasks. For more information, see [AUTOTITLE](/contributing/style-guide-and-content-model/how-to-content-type) in the content model. ## Troubleshooting content diff --git a/content/contributing/writing-for-github-docs/best-practices-for-github-docs.md b/content/contributing/writing-for-github-docs/best-practices-for-github-docs.md index d8f2136d3048..4707b88524bc 100644 --- a/content/contributing/writing-for-github-docs/best-practices-for-github-docs.md +++ b/content/contributing/writing-for-github-docs/best-practices-for-github-docs.md @@ -47,12 +47,12 @@ Before you begin, it’s important to understand who you’re writing for, what Determine which type of content you will write, based on the intended audience and the core purpose of the content. {% data variables.product.prodname_docs %} use the following content types: -* [Conceptual content](/contributing/style-guide-and-content-model/conceptual-content-type) -* [Referential content](/contributing/style-guide-and-content-model/referential-content-type) -* [Procedural content](/contributing/style-guide-and-content-model/procedural-content-type) -* [Troubleshooting content](/contributing/style-guide-and-content-model/troubleshooting-content-type) -* [Quickstart](/contributing/style-guide-and-content-model/quickstart-content-type) -* [Tutorial](/contributing/style-guide-and-content-model/tutorial-content-type) +* [AUTOTITLE](/contributing/style-guide-and-content-model/conceptual-content-type) +* [AUTOTITLE](/contributing/style-guide-and-content-model/referential-content-type) +* [AUTOTITLE](/contributing/style-guide-and-content-model/how-to-content-type) +* [AUTOTITLE](/contributing/style-guide-and-content-model/troubleshooting-content-type) +* [AUTOTITLE](/contributing/style-guide-and-content-model/quickstart-content-type) +* [AUTOTITLE](/contributing/style-guide-and-content-model/tutorial-content-type) For example, use the conceptual content type to help readers understand the basics of a feature or topic and how it can help them accomplish their goals. Use the procedural content type to help people complete a specific task from start to finish. From aa7ef35bf5d2f2748f86b59f3becb718c0eb2846 Mon Sep 17 00:00:00 2001 From: hubwriter Date: Wed, 6 May 2026 15:51:11 +0100 Subject: [PATCH 13/13] [2026-05-04] GitHub Mobile & GitHub.com: Remote Control - view and steer CLI sessions [GA] (#60961) Co-authored-by: Joe Clark <31087804+jc-clark@users.noreply.github.com> --- .../agents/copilot-cli/about-remote-access.md | 91 ------------------- .../copilot-cli/about-remote-control.md | 80 ++++++++++++++++ .../concepts/agents/copilot-cli/index.md | 2 +- content/copilot/how-tos/copilot-cli/index.md | 2 +- .../use-copilot-cli/steer-remotely.md | 76 +++++++++------- .../cli-command-reference.md | 2 +- .../cli/remote-access-reconnection.md | 1 + 7 files changed, 125 insertions(+), 129 deletions(-) delete mode 100644 content/copilot/concepts/agents/copilot-cli/about-remote-access.md create mode 100644 content/copilot/concepts/agents/copilot-cli/about-remote-control.md create mode 100644 data/reusables/cli/remote-access-reconnection.md diff --git a/content/copilot/concepts/agents/copilot-cli/about-remote-access.md b/content/copilot/concepts/agents/copilot-cli/about-remote-access.md deleted file mode 100644 index 5ba7f361ee8e..000000000000 --- a/content/copilot/concepts/agents/copilot-cli/about-remote-access.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: About remote access to {% data variables.copilot.copilot_cli %} sessions -shortTitle: About remote access -intro: 'Access a running {% data variables.copilot.copilot_cli_short %} session from {% data variables.product.prodname_dotcom_the_website %} or {% data variables.product.prodname_mobile %} to monitor and steer the session when you are away from the machine where the session is running.' -versions: - feature: copilot -contentType: concepts -category: - - Learn about Copilot # Copilot discovery page - - Learn about Copilot CLI # Copilot CLI bespoke page -docsTeamMetrics: - - copilot-cli ---- - -This article explains the concepts around remote access to {% data variables.copilot.copilot_cli_short %} sessions. For instructions on how to enable remote access, see [AUTOTITLE](/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely). - -## Introduction - -When you start a {% data variables.copilot.copilot_cli %} session on your local machine, the session is normally only accessible from the terminal where you started it. However, you can enable remote access to the session from {% data variables.product.prodname_dotcom_the_website %} and {% data variables.product.prodname_mobile %}, allowing you to view the progress of a task that {% data variables.product.prodname_copilot_short %} is working on, and respond to prompts for more information, or requests for permissions. - -This is useful in scenarios such as: - -* **Leaving your workstation**: You started a session on your laptop and were then called away, or you finished work for the day, but you want to continue interacting with {% data variables.product.prodname_copilot_short %} without having to return to the machine. - -* **Monitoring a long-running task**: You started a complex task that will take time to complete, but didn't give {% data variables.product.prodname_copilot_short %} full permission to carry out every action. You need to periodically assess and respond to permission requests to allow a task to continue. - - To ensure the stability of the remote access feature there is a 60 MB limit on size of session output that is passed to the remote interface. As a result, very long-running sessions that generate large amounts of output may experience reduced performance in the remote interface. The local terminal session is unaffected. - -* **Quick access from a mobile device**: You're working on something else now but you're using {% data variables.product.prodname_mobile %} to provide an at-a-glance view of progress on a task you started in {% data variables.copilot.copilot_cli_short %}. - -{% data reusables.cli.public-preview-remote-access %} - -## Prerequisites - -Remote access requires: - -* **Policy enablement**: For users who have a {% data variables.product.prodname_copilot_short %} seat from an organization, remote access access is governed by policies set at the organization and enterprise level. The "Remote Control" policy is off by default but can be enabled by an enterprise or organization owner. See [Administering remote access](#administering-remote-access). -* **A {% data variables.product.github %} repository**: The working directory where you started the CLI must contain a Git repository hosted on {% data variables.product.prodname_dotcom_the_website %}. If you attempt to enable remote access outside of a {% data variables.product.prodname_dotcom %} repository, the CLI displays the message: "Remote session disabled: not in a {% data variables.product.github %} repository" -* **The machine must be online**: The CLI session must be actively running in a terminal on a machine with an internet connection. If the machine goes to sleep or loses its connection, remote access is unavailable until the machine is back online. See [Reconnection](#reconnection) later in this article. -* **An interactive session**: Remote access is only available for interactive sessions. It is not available when you use the CLI programmatically with the `--prompt` command-line option, for example when you use the CLI in a script. - -## Accessing a session remotely - -When you enable remote access for a {% data variables.copilot.copilot_cli_short %} session, you can go to {% data variables.product.prodname_dotcom_the_website %} or {% data variables.product.prodname_mobile %} and find the session in the list of your recent agent sessions. The remote interface is updated in real time, allowing you to monitor ongoing output from the session and respond to prompts and permission requests as they come in. - -Both the local terminal and the remote interface are active at the same time. You can enter commands in either interface. {% data variables.copilot.copilot_cli_short %} uses the first response it receives to any prompt or permission request. - -Your session continues to run on your local machine. The remote interface provides a way to interact with the session, but the CLI itself—and all the tools, shell commands, and file operations it runs—remain on the machine where you started the session. - -## What you can do remotely - -When connected to a session remotely from {% data variables.product.prodname_dotcom_the_website %} or {% data variables.product.prodname_mobile %}, you can: - -* **Respond to permission requests**: Approve or deny tool, file path, and URL permission requests. -* **Respond to questions**: Answer when {% data variables.product.prodname_copilot_short %} asks you to supply more information or make a decision. -* **Approve or reject plans**: Respond to plan approval prompts when {% data variables.product.prodname_copilot_short %} is in plan mode. -* **Submit new prompts**: Enter questions or instructions, just as you would in the terminal. -* **Switch modes**: Change the session mode—for example, between interactive and plan mode. -* **End the current operation**: Cancel the agent's current work. - -{% data reusables.cli.remote-access-slash-commands %} - -## Reconnection - -If the connection between your local machine and {% data variables.product.prodname_dotcom %} is temporarily lost—for example, due to a network interruption—you can continue using the session remotely as soon as the connection is restored. - -You can use the `/keep-alive` slash command to prevent your machine from going to sleep. See [Preventing your machine from going to sleep](/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely#preventing-your-machine-from-going-to-sleep). - -If you closed a session that had remote access enabled, when you resume the session—either using `copilot --continue` or `copilot --resume=ID`—you must re-enable remote access. For more information, see [AUTOTITLE](/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely#resuming-a-session-with-remote-access). - -## Visibility of remote access sessions - -Remote access is only available to you—the person who is signed in to {% data variables.product.prodname_dotcom %} with the same account that started the CLI session. No one else can view or interact with your session remotely. - -### Points to note - -When you enable remote access: - -* Session events are sent from your local machine to {% data variables.product.prodname_dotcom %}. This includes conversation messages, tool execution events, and permission requests. -* Remote commands are polled by {% data variables.copilot.copilot_cli_short %} from {% data variables.product.prodname_dotcom %} and injected into your local session. -* The CLI itself continues to run locally. All shell commands, file operations, and tool executions happen on your machine—remote access does not grant any direct access to your local machine beyond what the CLI agent can do within the session. - -The remote session link (displayed in the CLI when you enable remote access) points to a session-specific URL on {% data variables.product.prodname_dotcom_the_website %}. Only authenticated users with the correct account can access this URL. - -## Administering remote access - -The ability for users enable remote access to their {% data variables.copilot.copilot_cli_short %} sessions can be controlled by policies in the enterprise or organization settings. Users who get {% data variables.product.prodname_copilot_short %} from an organization will not be able to use remote access if it has been disabled at the organization or enterprise level. - -The "Remote Control" policy is off by default, so it must be enabled by an enterprise or organization owner before users can start monitoring and steering their CLI sessions remotely. - -For more information about setting policies for your enterprise or organization, see [AUTOTITLE](/copilot/how-tos/administer-copilot/manage-for-organization/manage-policies) and [AUTOTITLE](/copilot/how-tos/copilot-cli/administer-copilot-cli-for-your-enterprise). diff --git a/content/copilot/concepts/agents/copilot-cli/about-remote-control.md b/content/copilot/concepts/agents/copilot-cli/about-remote-control.md new file mode 100644 index 000000000000..b781f9240643 --- /dev/null +++ b/content/copilot/concepts/agents/copilot-cli/about-remote-control.md @@ -0,0 +1,80 @@ +--- +title: About remote control of {% data variables.copilot.copilot_cli %} sessions +shortTitle: About remote control +intro: 'Remote control lets you monitor and steer a {% data variables.copilot.copilot_cli_short %} session from {% data variables.product.prodname_dotcom_the_website %} or {% data variables.product.prodname_mobile %}, even after you''ve stepped away from your machine.' +versions: + feature: copilot +redirect_from: + - /copilot/concepts/agents/copilot-cli/about-remote-access +contentType: concepts +category: + - Learn about Copilot # Copilot discovery page + - Learn about Copilot CLI # Copilot CLI bespoke page +docsTeamMetrics: + - copilot-cli +--- + +This article explains the concepts around remote control of {% data variables.copilot.copilot_cli_short %} sessions. For instructions on how to enable remote control, see [AUTOTITLE](/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely). + +## When remote control helps + +By default, {% data variables.copilot.copilot_cli %} sessions are only steerable from your local machine. However, you can enable remote control of the session. Remote control is useful when you want to view progress or respond to prompts and permission requests, without having to remain at the machine where the session is running. For example: + +* **You step away from your workstation**: Keep interacting with {% data variables.product.prodname_copilot_short %} from your phone or another device, without returning to the machine where the session is running. +* **A long-running task needs your input**: Approve permission requests and answer questions as they come up, so the task isn't blocked while you're away. +* **You want a quick status check**: Glance at session progress from {% data variables.product.prodname_mobile %} while you work on something else. + +## Prerequisites + +Remote control requires: + +* **Policy enablement**: If your {% data variables.product.prodname_copilot_short %} seat comes from an organization, an enterprise or organization owner must enable the "Remote Control" policy (off by default). See [Administering remote control](#administering-remote-control) later in this article. +* **The machine must be online**: The CLI session must be actively running in a terminal on a machine with an internet connection. If the machine goes to sleep or loses its connection, remote control is unavailable until the machine is back online. See [Reconnection](#reconnection) later in this article. +* **An interactive session**: Remote access is only available for interactive sessions. It is not available when you use the CLI programmatically with the `--prompt` command-line option, for example when you use the CLI in a script. + +## Accessing a session remotely + +When you enable remote control for a {% data variables.copilot.copilot_cli_short %} session, you can go to {% data variables.product.prodname_dotcom_the_website %} or {% data variables.product.prodname_mobile %} and find the session in the list of your recent agent sessions. The remote interface is updated in real time, allowing you to monitor ongoing output from the session and respond to prompts and permission requests as they come in. + +Both the local terminal and the remote interface are active at the same time. You can enter commands in either interface. {% data variables.copilot.copilot_cli_short %} uses the first response it receives to any prompt or permission request. + +Your session continues to run on your local machine. The remote interface provides a way to interact with the session, but the CLI itself—and all the tools, shell commands, and file operations it runs—remain on the machine where you started the session. + +## What you can do remotely + +When connected to a session remotely from {% data variables.product.prodname_dotcom_the_website %} or {% data variables.product.prodname_mobile %}, you can: + +* **Respond to permission requests**: Approve or deny tool, file path, and URL permission requests. +* **Respond to questions**: Answer when {% data variables.product.prodname_copilot_short %} asks you to supply more information or make a decision. +* **Approve or reject plans**: Respond to plan approval prompts when {% data variables.product.prodname_copilot_short %} is in plan mode. +* **Submit new prompts**: Enter questions or instructions, just as you would in the terminal. +* **Switch modes**: Change the session mode—for example, between interactive and plan mode. +* **End the current operation**: Cancel the agent's current work. + +{% data reusables.cli.remote-access-slash-commands %} + +## Reconnection + +If the connection between your local machine and {% data variables.product.prodname_dotcom %} is temporarily lost—for example, due to a network interruption—you can continue using the session remotely as soon as the connection is restored. + +You can use the `/keep-alive` slash command to prevent your machine from going to sleep. See [Preventing your machine from going to sleep](/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely#preventing-your-machine-from-going-to-sleep). + +{% data reusables.cli.remote-access-reconnection %} + +## Security and privacy + +Remote control is only available to you — the person signed in to {% data variables.product.prodname_dotcom %} with the same account that started the CLI session. No one else can view or interact with your sessions remotely. The session URL displayed in the CLI is session-specific and only accessible to authenticated users with the correct account. + +When remote control is enabled: + +* Session events (conversation messages, tool execution events, and permission requests) are sent from your local machine to {% data variables.product.prodname_dotcom %}. +* Remote commands are polled by {% data variables.copilot.copilot_cli_short %} from {% data variables.product.prodname_dotcom %} and injected into your local session. +* The CLI continues to run locally — all shell commands, file operations, and tool executions happen on your machine. Remote control does not grant direct access to your machine beyond what the CLI agent can do within the session. + +The remote session link (displayed in the CLI when you enable remote control) points to a session-specific URL on {% data variables.product.prodname_dotcom_the_website %}. Only authenticated users with the correct account can access this URL. + +## Administering remote control + +Enterprise and organization owners control whether users can enable remote control, using the "Remote Control" policy. This policy is off by default. + +For more information, see [AUTOTITLE](/copilot/how-tos/administer-copilot/manage-for-organization/manage-policies) and [AUTOTITLE](/copilot/how-tos/copilot-cli/administer-copilot-cli-for-your-enterprise). diff --git a/content/copilot/concepts/agents/copilot-cli/index.md b/content/copilot/concepts/agents/copilot-cli/index.md index 27249ba410c0..74da9aca65d8 100644 --- a/content/copilot/concepts/agents/copilot-cli/index.md +++ b/content/copilot/concepts/agents/copilot-cli/index.md @@ -9,7 +9,7 @@ children: - /about-copilot-cli - /comparing-cli-features - /cancel-and-roll-back - - /about-remote-access + - /about-remote-control - /about-custom-agents - /about-cli-plugins - /autopilot diff --git a/content/copilot/how-tos/copilot-cli/index.md b/content/copilot/how-tos/copilot-cli/index.md index 222aa795c285..76ef7c09f1a4 100644 --- a/content/copilot/how-tos/copilot-cli/index.md +++ b/content/copilot/how-tos/copilot-cli/index.md @@ -28,7 +28,7 @@ children: - /content/copilot/concepts/agents/copilot-cli/about-cli-plugins - /content/copilot/concepts/agents/copilot-cli/about-copilot-cli - /content/copilot/concepts/agents/copilot-cli/about-custom-agents - - /content/copilot/concepts/agents/copilot-cli/about-remote-access + - /content/copilot/concepts/agents/copilot-cli/about-remote-control - /content/copilot/concepts/agents/copilot-cli/autopilot - /content/copilot/concepts/agents/copilot-cli/cancel-and-roll-back - /content/copilot/concepts/agents/copilot-cli/chronicle diff --git a/content/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely.md b/content/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely.md index 5ee4f8ae4b56..2844aee0dcce 100644 --- a/content/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely.md +++ b/content/copilot/how-tos/copilot-cli/use-copilot-cli/steer-remotely.md @@ -2,7 +2,7 @@ title: Steering a {% data variables.copilot.copilot_cli %} session from another device shortTitle: Steer a session remotely allowTitleToDifferFromFilename: true -intro: 'Enable remote access to a {% data variables.copilot.copilot_cli_short %} session so you can monitor progress, respond to prompts, and continue working from {% data variables.product.prodname_dotcom_the_website %} or {% data variables.product.prodname_mobile %}.' +intro: 'Enable remote control for a {% data variables.copilot.copilot_cli_short %} session so you can monitor progress, respond to prompts, and continue working from {% data variables.product.prodname_dotcom_the_website %} or {% data variables.product.prodname_mobile %}.' versions: feature: copilot contentType: how-tos @@ -15,11 +15,9 @@ docsTeamMetrics: - copilot-cli --- -Remote access lets you connect to a running {% data variables.copilot.copilot_cli_short %} session from any browser or from {% data variables.product.prodname_mobile %}. You can view session output, respond to permission requests, and continue working in the session without being at the machine where the session is running. +Remote control lets you connect to a running {% data variables.copilot.copilot_cli_short %} session from any browser or from {% data variables.product.prodname_mobile %}. You can view session output, respond to permission requests, and continue working in the session without being at the machine where the session is running. -This article explains how to enable and use remote access. For more conceptual information, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-remote-access). - -{% data reusables.cli.public-preview-remote-access %} +This article explains how to enable and use remote control. For more conceptual information, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-remote-control). ## Prerequisites @@ -30,24 +28,26 @@ This article explains how to enable and use remote access. For more conceptual i * The working directory must contain a Git repository hosted on {% data variables.product.prodname_dotcom_the_website %}. If you are not in a {% data variables.product.prodname_dotcom %} repository, the CLI displays: "Remote session disabled: not in a {% data variables.product.github %} repository." -## Enabling remote access for a session +## Enabling remote control for a session -You can enable remote access in three ways: +You can enable remote control in three ways: * With a slash command during an interactive session. * With a command-line option when you start {% data variables.copilot.copilot_cli_short %}. -* By configuring the CLI to enable remote access by default for all interactive sessions. +* By configuring the CLI to enable remote control by default for all interactive sessions. ### Using the `/remote` slash command -If you are already in an interactive session and want to enable remote access, enter: +If you are already in an interactive session and want to enable remote control, enter: ```copilot copy -/remote +/remote on ``` The CLI connects to {% data variables.product.prodname_dotcom_the_website %} and displays details for accessing the session remotely—see [Accessing a session from {% data variables.product.prodname_dotcom_the_website %}](#accessing-a-session-from-githubcom) and [Accessing a session from {% data variables.product.prodname_mobile %}](#accessing-a-session-from-github-mobile) later in this article. +You can use the `/remote` slash command without an argument to check the current remote control status, or to redisplay the remote access details if remote control is currently enabled. If you want to end the remote connection for the current session, enter `/remote off`. + ### Using the `--remote` command-line option If you think you may want to access a session remotely, you can start the CLI with the `--remote` command-line option. This avoids the need to remember to use the `/remote` slash command during the session. @@ -58,9 +58,9 @@ copilot --remote Details for accessing the session remotely are displayed when the interactive session starts and can be displayed again at any time by using the `/remote` slash command. -### Configuring remote access to always be enabled +### Configuring remote control to always be enabled -If you always want your interactive CLI sessions to be remotely accessible, add the following to your {% data variables.product.prodname_copilot_short %} configuration file (typically located at `~/.copilot/settings.json`): +If you always want your interactive CLI sessions to be remotely accessible, add the following to your {% data variables.product.prodname_copilot_short %} settings file (typically located at `~/.copilot/settings.json`): ```json copy { @@ -75,30 +75,33 @@ copilot --no-remote ``` > [!NOTE] -> The command-line options `--remote` and `--no-remote` always take precedence over the `remoteSessions` setting in the configuration file. +> The command-line options `--remote` and `--no-remote` always take precedence over the `remoteSessions` setting in the settings file. ## Accessing a session from {% data variables.product.prodname_dotcom_the_website %} -When remote access is enabled, the CLI displays a link in the format: +When you enable remote control, the CLI displays a link to the session on {% data variables.product.prodname_dotcom_the_website %}. -```text -https://github.com/OWNER/REPO/tasks/TASK_ID -``` +Use the link to access the session in your default web browser. You must be signed in to {% data variables.product.prodname_dotcom %} with the same account that started the CLI session. -Use this link to access the session in a web browser. You must be signed in to {% data variables.product.prodname_dotcom %} with the same account that started the CLI session. - -You can also access the session from your list of recent agent sessions on {% data variables.product.prodname_dotcom_the_website %}: +You can also access the session without the link: +1. Log on to {% data variables.product.prodname_dotcom_the_website %} on any computer. 1. In the top-left corner of {% data variables.product.prodname_dotcom %}, click {% octicon "three-bars" aria-label="Open menu" %}. 1. Click **{% octicon "copilot" aria-hidden="true" aria-label="copilot" %} {% data variables.product.prodname_copilot_short %}**. -1. Under "Recent agent sessions", click your {% data variables.copilot.copilot_cli_short %} session to open it. + + Your CLI session is listed under "Recent agent sessions." + +1. Optionally, use the **Type** filter at the top right of the list to show only {% data variables.copilot.copilot_cli_short %} sessions. +1. Click your {% data variables.copilot.copilot_cli_short %} session to open it. + +If you started the session from a local copy of a {% data variables.product.github %} repository, you can also access the session from the **Agents** tab of that repository on {% data variables.product.prodname_dotcom_the_website %}. > [!IMPORTANT] -> Sessions are user-specific: you can only access your own {% data variables.copilot.copilot_cli_short %} sessions. Other {% data variables.product.github %} users cannot access your sessions. +> Remotely accessible sessions are user-specific: you can only access your own {% data variables.copilot.copilot_cli_short %} sessions. Other {% data variables.product.github %} users cannot access your sessions. ## Accessing a session from {% data variables.product.prodname_mobile %} -A {% data variables.copilot.copilot_cli_short %} session is available in {% data variables.product.prodname_mobile %} as soon as you enable remote access. To find your session in {% data variables.product.prodname_mobile %}: +A {% data variables.copilot.copilot_cli_short %} session is available in {% data variables.product.prodname_mobile %} as soon as you enable remote control. To find your session in {% data variables.product.prodname_mobile %}: 1. Tap the **{% octicon "copilot" aria-hidden="true" aria-label="copilot" %} {% data variables.product.prodname_copilot_short %}** button in the bottom right corner of the screen. @@ -129,23 +132,26 @@ In an interactive session, enter `/keep-alive OPTION`, where `OPTION` is one of: Without passing an `OPTION`, the `/keep-alive` command displays the current keep-alive status. -## Resuming a session with remote access +## Reviewing previous sessions -When you shut down a session that has remote access enabled, the CLI displays a resume command that includes `--remote`: +You can view old {% data variables.copilot.copilot_cli_short %} sessions on {% data variables.product.prodname_dotcom_the_website %} or in {% data variables.product.prodname_mobile %}. -```bash -copilot --resume=SESSION_ID --remote -``` +1. Go to your list of recent agent sessions on {% data variables.product.prodname_dotcom_the_website %} or in {% data variables.product.prodname_mobile %}. See [Accessing a session from github.com](#accessing-a-session-from-githubcom) and [Accessing a session from GitHub Mobile](#accessing-a-session-from-github-mobile) earlier in this article. +1. Click or tap the session you want to review. + +On {% data variables.product.prodname_dotcom_the_website %}, a message tells you the `copilot --resume` command to use if you want to resume the session. Enter this command in your terminal on the machine where you ran that session. + +## Resuming a session -Use this command to restart the session with remote access enabled. +{% data reusables.cli.remote-access-reconnection %} -Similarly, adding `--remote` to a `copilot --continue` command resumes the most recent session with remote access enabled. +## Preventing remote control -If you have `"remoteSessions": true` in your {% data variables.product.prodname_copilot_short %} configuration file, resumed sessions will have remote access enabled automatically and you do not need to use the `--remote` option. +Remote control is disabled by default, but may be enabled in your {% data variables.product.prodname_copilot_short %} settings file (typically `~/.copilot/settings.json`). You can ensure a session is not remotely controllable by: -## Preventing remote access +* **For a single session**: Start the CLI with `--no-remote` to prevent remote control for that session, regardless of your settings file value. +* **Permanently**: Remove the `"remoteSessions": true` setting from `~/.copilot/settings.json` (or set it to `false`). -Remote access is disabled by default, but may be enabled in your {% data variables.product.prodname_copilot_short %} configuration file. You can ensure a session is not remotely accessible by: +## Further reading -* **For a single session**: Start the CLI with `--no-remote` to prevent remote access for that session, regardless of your configuration file setting. -* **Permanently**: Remove the `"remoteSessions": true` setting from your {% data variables.product.prodname_copilot_short %} configuration file (or set it to `false`). +* [{% data variables.copilot.copilot_cli_short %} sessions in {% data variables.product.prodname_vscode %}](https://code.visualstudio.com/docs/copilot/agents/copilot-cli) in the {% data variables.product.prodname_vscode_shortname %} documentation. diff --git a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md index 1d65433ffc1f..f39fd1ccca96 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md @@ -163,7 +163,7 @@ copilot completion fish > ~/.config/fish/completions/copilot.fish | `/ide` | Connect to an IDE workspace. See [AUTOTITLE](/copilot/how-tos/copilot-cli/use-copilot-cli/connecting-vs-code#managing-the-connection-with-the-ide-slash-command). | | `/init` | Initialize {% data variables.product.prodname_copilot_short %} custom instructions and agentic features for this repository. See [Project initialization for {% data variables.product.prodname_copilot_short %}](#project-initialization-for-copilot). | | `/instructions` | View and toggle custom instruction files. | -| `/keep-alive [on\|busy\|NUMBERm\|NUMBERh]` | Prevent the machine from going to sleep: while a CLI session is active, while the agent is busy, or for a defined length of time. {% data reusables.copilot.experimental %} | +| `/keep-alive [on\|busy\|NUMBERm\|NUMBERh]` | Prevent the machine from going to sleep: while a CLI session is active, while the agent is busy, or for a defined length of time. | | `/list-dirs` | Display all of the directories for which file access has been allowed. | | `/login` | Log in to {% data variables.product.prodname_copilot_short %}. | | `/logout` | Log out of {% data variables.product.prodname_copilot_short %}. | diff --git a/data/reusables/cli/remote-access-reconnection.md b/data/reusables/cli/remote-access-reconnection.md new file mode 100644 index 000000000000..b57ff8ad4572 --- /dev/null +++ b/data/reusables/cli/remote-access-reconnection.md @@ -0,0 +1 @@ +When you use `copilot --continue` or `copilot --resume` to resume a CLI session for which remote control was enabled, remote control is automatically re-enabled.