diff --git a/CHANGELOG.md b/CHANGELOG.md index 80d173763104..67d797bfec26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,12 @@ Get started at [Achieving your company's engineering goals with GitHub Copilot]( **27 June 2025** +We've published a new guide about how to combine use of GitHub Copilot's agent mode with Model Context Protocol (MCP) servers to complete complex tasks through agentic "loops" - illustrated through an accessibility compliance example. The guide also discusses best practices and benefits around using these two features together. See [Enhancing Copilot agent mode with MCP](https://docs.github.com/copilot/tutorials/enhancing-copilot-agent-mode-with-mcp). + +
+ +**27 June 2025** + We’ve published a new set of new documentation articles designed to help users make the most of the **Dependabot metrics page** in the organization’s security overview. These clear, actionable guides help users: diff --git a/assets/images/help/copilot/code-review/vscode-review-button@2x.png b/assets/images/help/copilot/code-review/vscode-review-button@2x.png deleted file mode 100644 index 3760819de4d3..000000000000 Binary files a/assets/images/help/copilot/code-review/vscode-review-button@2x.png and /dev/null differ diff --git a/content/actions/how-tos/managing-workflow-runs-and-deployments/managing-workflow-runs/manually-running-a-workflow.md b/content/actions/how-tos/managing-workflow-runs-and-deployments/managing-workflow-runs/manually-running-a-workflow.md index 3f2031f90b2b..b21b91b199dd 100644 --- a/content/actions/how-tos/managing-workflow-runs-and-deployments/managing-workflow-runs/manually-running-a-workflow.md +++ b/content/actions/how-tos/managing-workflow-runs-and-deployments/managing-workflow-runs/manually-running-a-workflow.md @@ -10,6 +10,7 @@ redirect_from: - /actions/managing-workflow-runs/manually-running-a-workflow - /actions/using-workflows/manually-running-a-workflow - /actions/managing-workflow-runs-and-deployments/managing-workflow-runs/manually-running-a-workflow + - /articles/configuring-a-workflow --- {% data reusables.actions.enterprise-github-hosted-runners %} diff --git a/content/admin/configuring-settings/configuring-network-settings/configuring-built-in-firewall-rules.md b/content/admin/configuring-settings/configuring-network-settings/configuring-built-in-firewall-rules.md index 537b984b31b8..cdd778377a06 100644 --- a/content/admin/configuring-settings/configuring-network-settings/configuring-built-in-firewall-rules.md +++ b/content/admin/configuring-settings/configuring-network-settings/configuring-built-in-firewall-rules.md @@ -19,7 +19,7 @@ shortTitle: Configure firewall rules --- ## About {% data variables.location.product_location %}'s firewall -{% data variables.product.prodname_ghe_server %} uses Ubuntu's Uncomplicated Firewall (UFW) on the virtual appliance. For more information see [UFW](https://help.ubuntu.com/community/UFW) in the Ubuntu documentation. {% data variables.product.prodname_ghe_server %} automatically updates the firewall allowlist of allowed services with each release. +{% data variables.product.prodname_ghe_server %} uses Ubuntu's Uncomplicated Firewall (UFW) on the virtual appliance. For more information see [Firewall](https://documentation.ubuntu.com/server/how-to/security/firewalls/#ufw-uncomplicated-firewall) in the Ubuntu documentation. {% data variables.product.prodname_ghe_server %} automatically updates the firewall allowlist of allowed services with each release. After you install {% data variables.product.prodname_ghe_server %}, all required network ports are automatically opened to accept connections. Every non-required port is automatically configured as `deny`, and the default outgoing policy is configured as `allow`. Stateful tracking is enabled for any new connections; these are typically network packets with the `SYN` bit set. For more information, see [AUTOTITLE](/admin/configuration/configuring-network-settings/network-ports). diff --git a/content/admin/enforcing-policies/enforcing-policy-with-pre-receive-hooks/creating-a-pre-receive-hook-environment.md b/content/admin/enforcing-policies/enforcing-policy-with-pre-receive-hooks/creating-a-pre-receive-hook-environment.md index d02ec4b6d0fd..7ac82b0903a2 100644 --- a/content/admin/enforcing-policies/enforcing-policy-with-pre-receive-hooks/creating-a-pre-receive-hook-environment.md +++ b/content/admin/enforcing-policies/enforcing-policy-with-pre-receive-hooks/creating-a-pre-receive-hook-environment.md @@ -44,13 +44,13 @@ You can use a Linux container management tool to build a pre-receive hook enviro ```shell $ docker build -f Dockerfile.debian -t pre-receive.debian . > [+] Building 0.6s (6/6) FINISHED docker:desktop-linux - > => [internal] load build definition from Dockerfile.debian - > => [1/2] FROM docker.io/library/debian:latest@sha256:80dd3c3b9c6cecb9f1667e9290b3bc61b78c2678c02cbdae5f0fea92cc6 - > => [2/2] RUN apt-get update && apt-get install -y git bash curl - > => exporting to image - > => => exporting layers - > => => writing image sha256:b57af4e24082f3a30a34c0fe652a336444a3608f76833f5c5fdaf4d81d20c3cc - > => => naming to docker.io/library/pre-receive.debian + > => [internal] load build definition from Dockerfile.debian + > => [1/2] FROM docker.io/library/debian:latest@sha256:80dd3c3b9c6cecb9f1667e9290b3bc61b78c2678c02cbdae5f0fea92cc6 + > => [2/2] RUN apt-get update && apt-get install -y git bash curl + > => exporting to image + > => => exporting layers + > => => writing image sha256:b57af4e24082f3a30a34c0fe652a336444a3608f76833f5c5fdaf4d81d20c3cc + > => => naming to docker.io/library/pre-receive.debian ``` 1. Create a container: @@ -82,7 +82,7 @@ You can use a Linux container management tool to build a pre-receive hook enviro > * `/bin/sh` must exist and be executable, as the entry point into the chroot environment. > * Unlike traditional chroots, the `dev` directory is not required by the chroot environment for pre-receive hooks. -For more information about creating a chroot environment see [Chroot](https://wiki.debian.org/chroot) from the _Debian Wiki_ or [BasicChroot](https://help.ubuntu.com/community/BasicChroot) from the _Ubuntu Community Help Wiki_. +For more information about creating a chroot environment, see [Chroot](https://wiki.debian.org/chroot) from the Debian Wiki. ## Uploading a pre-receive hook environment on {% data variables.product.prodname_ghe_server %} diff --git a/content/admin/managing-iam/provisioning-user-accounts-with-scim/configuring-authentication-and-provisioning-with-pingfederate.md b/content/admin/managing-iam/provisioning-user-accounts-with-scim/configuring-authentication-and-provisioning-with-pingfederate.md index 9ea33603538c..34ef5b68c4af 100644 --- a/content/admin/managing-iam/provisioning-user-accounts-with-scim/configuring-authentication-and-provisioning-with-pingfederate.md +++ b/content/admin/managing-iam/provisioning-user-accounts-with-scim/configuring-authentication-and-provisioning-with-pingfederate.md @@ -54,7 +54,7 @@ In addition: * You may need to configure the firewall in PingFederate to allow outbound connections to {% ifversion ghes %}the `https://HOSTNAME/api/v3/scim/v2` endpoint on your {% data variables.product.prodname_ghe_server %} instance.{% else %}the SCIM endpoints on {% data variables.product.github %}: * For **{% data variables.product.prodname_dotcom_the_website %}**: `https://api.github.com/scim/v2/enterprises/ENTERPRISE` * For **{% data variables.enterprise.data_residency_site %}**: `https://api.SUBDOMAIN.ghe.com/scim/v2/enterprises/SUBDOMAIN`{% endif %} -* PingFederate's "provisioner mode" must be set to a value that allows SCIM provisioning. See the "Before you begin" section in PingIdentity's [Configuring outbound provisioning settings](https://docs.pingidentity.com/pingfederate/11.2/administrators_reference_guide/help_protocolsettingstasklet_saasglobalprovisioningsettingsstate.html) guide. +* PingFederate's "provisioner mode" must be set to a value that allows SCIM provisioning. See the "Before you begin" section in PingIdentity's [Configuring outbound provisioning settings](https://docs.pingidentity.com/pingfederate/latest/administrators_reference_guide/help_protocolsettingstasklet_saasglobalprovisioningsettingsstate.html) guide. * During this procedure, you will need to upload an X509 certificate to PingFederate. You may want to create and store the certificate before proceeding. You will also need the challenge password for the certificate. See the [Example of creating an X509 certificate](#example-of-creating-an-x509-certificate) section later in this article. {%- ifversion ghec %} * During this procedure, you will need to upload a SAML metadata file to PingFederate. If you're setting up an enterprise that uses **{% data variables.enterprise.data_residency_short %} on {% data variables.enterprise.data_residency_site %}**, it is easiest to create this file before you start. See [Creating a SAML metadata file for {% data variables.enterprise.data_residency_site %}](#creating-a-saml-metadata-file-for-ghecom). diff --git a/content/admin/managing-iam/reconfiguring-iam-for-enterprise-managed-users/migrating-your-enterprise-to-a-new-identity-provider-or-tenant.md b/content/admin/managing-iam/reconfiguring-iam-for-enterprise-managed-users/migrating-your-enterprise-to-a-new-identity-provider-or-tenant.md index 9ab227c82b39..bb503a47afec 100644 --- a/content/admin/managing-iam/reconfiguring-iam-for-enterprise-managed-users/migrating-your-enterprise-to-a-new-identity-provider-or-tenant.md +++ b/content/admin/managing-iam/reconfiguring-iam-for-enterprise-managed-users/migrating-your-enterprise-to-a-new-identity-provider-or-tenant.md @@ -72,7 +72,7 @@ If you don't already have single sign-on recovery codes for your enterprise, dow 1. On your current IdP, deactivate provisioning in the application for {% data variables.product.prodname_emus %}. * If you use Entra ID, navigate to the "Provisioning" tab of the application, and then click **Stop provisioning**. * If you use Okta, navigate to the "Provisioning" tab of the application, click the **Integration** tab, and then click **Edit**. Deselect **Enable API integration**. - * If you use PingFederate, navigate to the channel settings in the application. From the **Activation & Summary** tab, click **Active** or **Inactive** to toggle the provisioning status, and then click **Save**. For more information about managing provisioning, see [Reviewing channel settings](https://docs.pingidentity.com/pingfederate/11.2/administrators_reference_guide/help_saaschanneltasklet_saasactivationstate.html) and [Managing channels](https://docs.pingidentity.com/pingfederate/latest/administrators_reference_guide/help_saasmanagementtasklet_saasmanagementstate.html) in the PingFederate documentation. + * If you use PingFederate, navigate to the channel settings in the application. From the **Activation & Summary** tab, click **Active** or **Inactive** to toggle the provisioning status, and then click **Save**. For more information about managing provisioning, see [Reviewing channel settings](https://docs.pingidentity.com/pingfederate/latest/administrators_reference_guide/help_saaschanneltasklet_saasactivationstate.html) and [Managing channels](https://docs.pingidentity.com/pingfederate/latest/administrators_reference_guide/help_saasmanagementtasklet_saasmanagementstate.html) in the PingFederate documentation. * If you use another identity management system, consult the system's documentation, support team, or other resources. ### 4. Disable authentication for your enterprise diff --git a/content/copilot/tutorials/index.md b/content/copilot/tutorials/index.md index 5e6222a27ec4..a2f5514e573a 100644 --- a/content/copilot/tutorials/index.md +++ b/content/copilot/tutorials/index.md @@ -18,7 +18,7 @@ children: - /learning-a-new-programming-language-with-github-copilot - /modernizing-legacy-code-with-github-copilot - /using-copilot-to-migrate-a-project - - /upgrading-java-projects-with-github-copilot + - /upgrading-projects-with-github-copilot - /rolling-out-github-copilot-at-scale redirect_from: - /copilot/using-github-copilot/guides-on-using-github-copilot diff --git a/content/copilot/tutorials/upgrading-java-projects-with-github-copilot.md b/content/copilot/tutorials/upgrading-java-projects-with-github-copilot.md deleted file mode 100644 index 3e9c8e2207aa..000000000000 --- a/content/copilot/tutorials/upgrading-java-projects-with-github-copilot.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: Upgrading Java projects with GitHub Copilot -shortTitle: Upgrade Java projects -intro: 'You can use {% data variables.product.prodname_copilot %} to upgrade your Maven and Gradle Java applications.' -versions: - feature: copilot -topics: - - Copilot -redirect_from: - - /copilot/using-github-copilot/guides-on-using-github-copilot/upgrading-java-projects-with-github-copilot ---- - -> [!NOTE] -> GitHub Copilot app modernization – upgrade for Java is currently in {% data variables.release-phases.public_preview %} and subject to change. - -## Introduction - -{% data variables.product.prodname_copilot %} can help streamline the process of upgrading Java applications. The "GitHub Copilot app modernization – upgrade for Java" {% data variables.product.prodname_vscode %} extension assists with every step of upgrading your Java project's runtime and/or framework version. - -* Analyzing the project and dependencies to generate an upgrade plan. -* Executing code transformations based on the plan. -* Automatically fixing issues during the upgrade. -* Providing detailed logs, commit history, and output. -* Performing security scans (CVE) and behavioral consistency checks post-upgrade. -* Summarizing key changes including updated dependencies and resolved issues. -* Generating unit tests independently of the upgrade process. - -This solution supports both Maven and Gradle build tools and facilitates upgrades between Java versions 8, 11, 17, and 21. - -## Prerequisites - -Before getting started you must have the following: - -* Either a **{% data variables.copilot.copilot_for_business %}** or **{% data variables.copilot.copilot_enterprise %}** [subscription plan](/copilot/about-github-copilot/subscription-plans-for-github-copilot). -* The latest version of [{% data variables.product.prodname_vscode %}](https://code.visualstudio.com/). -* The "GitHub Copilot app modernization – upgrade for Java (preview)" extension installed in {% data variables.product.prodname_vscode %}. -* Installed versions of both the source and target JDKs. -* A Git-based Java project using Maven or Gradle. -* For Maven-based projects, access to the public Maven Central repository. -* Make sure `chat.extensionTools.enabled` is set to `true` in your {% data variables.product.prodname_vscode %} settings. This setting might be controlled by your organization. - ->[!NOTE] For Gradle projects, only wrapper-based builds (Gradle v5+) are supported. Projects using Kotlin DSL are not currently supported. - -## Upgrading a Java project - -### 1. Install the required extension - -To get started, you'll need to install the “GitHub Copilot app modernization – upgrade for Java (preview)” extension for {% data variables.product.prodname_vscode %}. - -1. Open {% data variables.product.prodname_vscode %}. -1. Click on “Extensions”. -1. Search for “GitHub Copilot app modernization – upgrade for Java (preview)” and click “Download”. -1. Restart {% data variables.product.prodname_vscode %}. - -### 2. Use {% data variables.copilot.copilot_chat %} in agent mode and generate the upgrade plan - -Now you have the extension, you can continue to use {% data variables.product.prodname_copilot %} in agent mode and create a plan for your upgrade. - -1. In {% data variables.product.prodname_vscode %}, open the {% data variables.copilot.copilot_chat %} panel. -1. At the bottom of the chat panel, select **Agent** from the mode dropdown. -1. Enter a prompt describing the upgrade path you need. For example: - - > "Upgrade project to Java 21 and Spring Boot 3.2" - -1. When prompted, click **Continue** to generate an upgrade plan - -### 3. Review and edit the upgrade plan - -{% data variables.product.prodname_copilot %} will analyze your project's structure, JDK, dependencies, and build tool before generating a `plan.md` upgrade plan for your specific circumstances that outlines source and target JDK versions and upgrade paths for frameworks and libraries. - -1. Click on the new `plan.md` tab in {% data variables.product.prodname_vscode %}. -1. Review, and edit if necessary, the plan. Make sure the versions in the plan align with your goals and what you've already specified. -1. When you're ready, click **Continue** to proceed. - -### 4. Apply code changes and fix build issues - -Next, {% data variables.product.prodname_copilot %} will begin transforming your project. This involves using OpenRewrite to apply code changes via predefined recipes and iteratively fixing remaining issues with {% data variables.product.prodname_copilot_short %} through a build/fix loop. - -1. When prompted to "Run Upgrade Java code using OpenRewrite", click **Continue**. Note that this step may take some time. -1. When prompted to "Run Build project and fix errors", click **Continue**. - -You can track the progress of this phase by viewing the `progress.md` file in {% data variables.product.prodname_vscode %}. - -### 5. Check for security vulnerabilities (CVE) and code behavior changes - -To ensure reliability and security, {% data variables.product.prodname_copilot %} performs additional checks. - -1. When prompted to "Run Validate if any modified dependencies have known CVEs", click **Continue**. - - If CVEs are detected, {% data variables.product.prodname_copilot_short %} will try to resolve them. You can review and accept or reject the changes. -1. When prompted to "Run Validate code behavior consistency", click **Continue**. - - If inconsistencies are found, {% data variables.product.prodname_copilot_short %} will again attempt fixes and you can decide which to keep. - -At the end of this process, the tool rebuilds the project and runs one final validation. The process concludes if only minor issues that don’t block the upgrade may remain. Otherwise, it loops back to address outstanding problems. - -### 6. View the Upgrade Summary - -Once completed, {% data variables.product.prodname_copilot_short %} generates a `summary.md` file in your project directory containing: - -* Project metadata. -* Lines of code modified. -* Updated dependencies. -* Description of code changes. -* CVEs and inconsistencies resolved. -* Remaining minor CVE issues (if any). diff --git a/content/copilot/tutorials/upgrading-projects-with-github-copilot.md b/content/copilot/tutorials/upgrading-projects-with-github-copilot.md new file mode 100644 index 000000000000..329ee1d4ac1b --- /dev/null +++ b/content/copilot/tutorials/upgrading-projects-with-github-copilot.md @@ -0,0 +1,39 @@ +--- +title: Upgrading projects with GitHub Copilot +shortTitle: Upgrade projects +intro: 'You can use {% data variables.product.prodname_copilot %} to upgrade your Maven and Gradle Java applications and .NET applications.' +versions: + feature: copilot +topics: + - Copilot +redirect_from: + - /copilot/using-github-copilot/guides-on-using-github-copilot/upgrading-java-projects-with-github-copilot + - /copilot/tutorials/upgrading-java-projects-with-github-copilot +--- + +> [!NOTE] +> "GitHub Copilot app modernization – upgrade for Java" and "GitHub Copilot app modernization – Upgrade for .NET" are currently in {% data variables.release-phases.public_preview %} and subject to change. + +## Introduction + +{% data variables.product.prodname_copilot %} can help streamline the process of modernizing and upgrading your Java and .NET applications. {% data variables.product.prodname_copilot_short %} will analyze the project, generate a plan, automatically fix issues it encounters when carrying out the plan, and produce a summary. + +## Upgrading Java projects + +You can upgrade a Git-based Maven or Gradle Java project using {% data variables.product.prodname_copilot %} in {% data variables.product.prodname_vscode %}. You will need: + +* Either a **{% data variables.copilot.copilot_for_business %}** or **{% data variables.copilot.copilot_enterprise %}** [subscription plan](/copilot/about-github-copilot/subscription-plans-for-github-copilot). +* The latest version of [{% data variables.product.prodname_vscode %}](https://code.visualstudio.com/). +* For Maven-based projects, access to the public Maven Central repository. +* Installed versions of both the source and target JDKs. + +For the next steps, see [Quickstart: upgrade a Java project with GitHub Copilot App Modernization - upgrade for Java (preview)](https://learn.microsoft.com/en-gb/java/upgrade/quickstart-upgrade) on Microsoft Learn. + +## Upgrading .NET projects + +You can also upgrade a .NET project using {% data variables.product.prodname_copilot %} in {% data variables.product.prodname_vs %}. You will need: + +* Either a **{% data variables.copilot.copilot_pro %}**, **{% data variables.copilot.copilot_pro_plus %}**, **{% data variables.copilot.copilot_for_business %}** or **{% data variables.copilot.copilot_enterprise %}** [subscription plan](/copilot/about-github-copilot/subscription-plans-for-github-copilot). +* The latest release of {% data variables.product.prodname_vs %} Enterprise, Professional or Community 2022. + +For the next steps, see [GitHub Copilot app modernization - upgrade for .NET](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.GitHubCopilotUpgradeAgent) on Microsoft Visual Studio Marketplace. diff --git a/content/github-models/github-models-at-scale/set-up-custom-model-integration-models-byok.md b/content/github-models/github-models-at-scale/set-up-custom-model-integration-models-byok.md index 9068289d5830..a48a98383657 100644 --- a/content/github-models/github-models-at-scale/set-up-custom-model-integration-models-byok.md +++ b/content/github-models/github-models-at-scale/set-up-custom-model-integration-models-byok.md @@ -38,8 +38,8 @@ You must first add the relevant API keys for the organization. After that, your {% data reusables.profile.access_org %} {% data reusables.profile.org_settings %} {% data reusables.organizations.custom-models %} -1. Click **Add custom key**. -1. In the "Add a custom key" dialog, provide details about your key. **Name** and **Key** are compulsory fields. +1. Click **Add API key**. +1. In the "Add the API key" dialog, provide details about your key. **Name** and **API key** are compulsory fields. 1. Click **Save**. ## Enabling custom models @@ -47,7 +47,7 @@ You must first add the relevant API keys for the organization. After that, your {% data reusables.profile.access_org %} {% data reusables.profile.org_settings %} {% data reusables.organizations.models-development %} -1. Under "Models permissions", select **All publishers** to enable models added by custom keys. +1. Under "Models permissions", select **All publishers** to enable models added by API keys. * If this option isn't available, you need to allow the use of the model in the organization. See [AUTOTITLE](/github-models/github-models-at-scale/manage-models-at-scale#controlling-model-usage-in-your-organization). 1. Optionally, select **Only select models** to create a custom list of enabled or disabled models. This allows you to control which models are available to your organization. diff --git a/content/rest/code-scanning/alert-dismissal-requests.md b/content/rest/code-scanning/alert-dismissal-requests.md new file mode 100644 index 000000000000..53300f4b6d0c --- /dev/null +++ b/content/rest/code-scanning/alert-dismissal-requests.md @@ -0,0 +1,13 @@ +--- +title: REST API endpoints for {% data variables.product.prodname_code_scanning %} alert dismissal requests +shortTitle: Alert dismissal requests +intro: Use the REST API to interact with {% data variables.product.prodname_code_scanning %} alert dismissal requests from a repository. +versions: # DO NOT MANUALLY EDIT. CHANGES WILL BE OVERWRITTEN BY A 🤖 + ghec: '*' +topics: + - API +autogenerated: rest +allowTitleToDifferFromFilename: true +--- + + diff --git a/content/rest/code-scanning/index.md b/content/rest/code-scanning/index.md index d103e6ec6a4c..6d878af647e5 100644 --- a/content/rest/code-scanning/index.md +++ b/content/rest/code-scanning/index.md @@ -14,6 +14,7 @@ topics: - Code scanning - REST children: + - /alert-dismissal-requests - /code-scanning autogenerated: rest --- diff --git a/content/support/learning-about-github-support/about-copilot-in-github-support.md b/content/support/learning-about-github-support/about-copilot-in-github-support.md index 2539643e6b55..6e4e54400e57 100644 --- a/content/support/learning-about-github-support/about-copilot-in-github-support.md +++ b/content/support/learning-about-github-support/about-copilot-in-github-support.md @@ -13,7 +13,7 @@ type: rai ## About {% data variables.copilot.copilot_in_support %} -{% data variables.copilot.copilot_in_support %} is a new conversational AI tool built to offer immediate assistance within the {% data variables.contact.github_support %} portal, allowing you to tackle issues without waiting for a response from {% data variables.contact.github_support %}. {% data variables.copilot.copilot_in_support %} uses a large language model, trained on publicly available {% data variables.product.prodname_dotcom %} documentation, to provide a conversational way to get help for your {% data variables.product.prodname_dotcom %} inquiries without having to wait for customer support to respond to your inquiry. +{% data variables.copilot.copilot_in_support %} is a new AI search experience on {% data variables.product.prodname_docs %} and a conversational AI tool built to offer immediate assistance within the {% data variables.contact.github_support %} portal, allowing you to tackle issues without waiting for a response from {% data variables.contact.github_support %}. {% data variables.copilot.copilot_in_support %} uses a large language model, trained on publicly available {% data variables.product.prodname_dotcom %} documentation, to provide a conversational way to get help for your {% data variables.product.prodname_dotcom %} inquiries without having to wait for customer support to respond to your inquiry. The primary supported language for {% data variables.copilot.copilot_in_support %} is English. diff --git a/data/features/copilot-hadron.yml b/data/features/copilot-hadron.yml deleted file mode 100644 index f4cd0f41152c..000000000000 --- a/data/features/copilot-hadron.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Reference: #15094 -# Copilot Workspace for PRs (the Hadron editor) - -versions: - fpt: '*' - ghec: '*' diff --git a/data/reusables/code-scanning/codeql-query-tables/rust.md b/data/reusables/code-scanning/codeql-query-tables/rust.md deleted file mode 100644 index bc104ad62bc0..000000000000 --- a/data/reusables/code-scanning/codeql-query-tables/rust.md +++ /dev/null @@ -1,15 +0,0 @@ -{% rowheaders %} - -| Query name | Related CWEs | Default | Extended | {% data variables.copilot.copilot_autofix_short %} | -| --- | --- | --- | --- | --- | -| [Access of invalid pointer](https://codeql.github.com/codeql-query-help/rust/rust-access-invalid-pointer/) | 476, 825 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | -| [Cleartext logging of sensitive information](https://codeql.github.com/codeql-query-help/rust/rust-cleartext-logging/) | 312, 359, 532 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | -| [Cleartext transmission of sensitive information](https://codeql.github.com/codeql-query-help/rust/rust-cleartext-transmission/) | 319 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | -| [Database query built from user-controlled sources](https://codeql.github.com/codeql-query-help/rust/rust-sql-injection/) | 089 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | -| [Regular expression injection](https://codeql.github.com/codeql-query-help/rust/rust-regex-injection/) | 020, 074 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | -| [Uncontrolled allocation size](https://codeql.github.com/codeql-query-help/rust/rust-uncontrolled-allocation-size/) | 770, 789 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | -| [Uncontrolled data used in path expression](https://codeql.github.com/codeql-query-help/rust/rust-path-injection/) | 022, 023, 036, 073, 099 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | -| [Use of a broken or weak cryptographic algorithm](https://codeql.github.com/codeql-query-help/rust/rust-weak-cryptographic-algorithm/) | 327 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | -| [Use of a broken or weak cryptographic hashing algorithm on sensitive data](https://codeql.github.com/codeql-query-help/rust/rust-weak-sensitive-data-hashing/) | 327, 328, 916 | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | - -{% endrowheaders %} diff --git a/data/reusables/emus/oauth-app-note.md b/data/reusables/emus/oauth-app-note.md deleted file mode 100644 index 71ccd1691dc0..000000000000 --- a/data/reusables/emus/oauth-app-note.md +++ /dev/null @@ -1,6 +0,0 @@ -{% ifversion ghec %} - -> [!NOTE] -> On {% data variables.product.prodname_dotcom_the_website %}, even an {% data variables.product.prodname_oauth_app %} created by a {% data variables.enterprise.prodname_managed_user %} or {% data variables.enterprise.prodname_emu_org %} can be accessed by users outside the enterprise. - -{% endif %} diff --git a/package.json b/package.json index 64c778bbf72e..205d36922a11 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "exports": "./src/frame/server.ts", "scripts": { + "ai-edit": "tsx src/ai-editors/scripts/ai-edit.ts", "all-documents": "tsx src/content-render/scripts/all-documents/cli.ts", "analyze-text": "tsx src/search/scripts/analyze-text.ts", "analyze-comment": "tsx src/events/scripts/analyze-comment-cli.ts", @@ -30,6 +31,8 @@ "create-enterprise-issue": "tsx src/ghes-releases/scripts/create-enterprise-issue.ts", "debug": "cross-env NODE_ENV=development ENABLED_LANGUAGES=en nodemon --inspect src/frame/server.ts", "delete-orphan-translation-files": "tsx src/workflows/delete-orphan-translation-files.ts", + "docsaudit": "tsx src/metrics/scripts/docsaudit.ts", + "docstat": "tsx src/metrics/scripts/docstat.ts", "deleted-assets-pr-comment": "tsx src/assets/scripts/deleted-assets-pr-comment.ts", "deleted-features-pr-comment": "tsx src/data-directory/scripts/deleted-features-pr-comment.ts", "deprecate-ghes": "tsx src/ghes-releases/scripts/deprecate/index.ts", diff --git a/src/ai-editors/lib/call-models-api.js b/src/ai-editors/lib/call-models-api.js deleted file mode 100644 index d48a4ee15d81..000000000000 --- a/src/ai-editors/lib/call-models-api.js +++ /dev/null @@ -1,24 +0,0 @@ -const modelsCompletionsEndpoint = 'https://models.github.ai/inference/chat/completions' - -export async function callModelsApi(promptWithContent) { - let aiResponse - try { - const response = await fetch(modelsCompletionsEndpoint, { - method: 'post', - body: JSON.stringify(promptWithContent), - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, - 'X-GitHub-Api-Version': '2022-11-28', - Accept: 'Accept: application/vnd.github+json', - }, - }) - const data = await response.json() - aiResponse = data.choices[0] - } catch (error) { - console.error('Error calling GitHub Models REST API') - throw error - } - - return aiResponse.message.content -} diff --git a/src/ai-editors/lib/call-models-api.ts b/src/ai-editors/lib/call-models-api.ts new file mode 100644 index 000000000000..dda311baa04f --- /dev/null +++ b/src/ai-editors/lib/call-models-api.ts @@ -0,0 +1,60 @@ +const modelsCompletionsEndpoint = 'https://models.github.ai/inference/chat/completions' + +interface ChatMessage { + role: string + content: string +} + +interface ChatCompletionRequest { + messages: ChatMessage[] + model?: string + temperature?: number + max_tokens?: number +} + +interface ChatCompletionChoice { + message: { + content: string + role: string + } + finish_reason: string + index: number +} + +interface ChatCompletionResponse { + choices: ChatCompletionChoice[] + id: string + object: string + created: number + model: string + usage?: { + prompt_tokens: number + completion_tokens: number + total_tokens: number + } +} + +export async function callModelsApi(promptWithContent: ChatCompletionRequest): Promise { + let aiResponse: ChatCompletionChoice + + try { + const response = await fetch(modelsCompletionsEndpoint, { + method: 'post', + body: JSON.stringify(promptWithContent), + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, + 'X-GitHub-Api-Version': '2022-11-28', + Accept: 'Accept: application/vnd.github+json', + }, + }) + + const data: ChatCompletionResponse = await response.json() + aiResponse = data.choices[0] + } catch (error) { + console.error('Error calling GitHub Models REST API') + throw error + } + + return aiResponse.message.content +} diff --git a/src/ai-editors/scripts/ai-edit.js b/src/ai-editors/scripts/ai-edit.ts old mode 100755 new mode 100644 similarity index 75% rename from src/ai-editors/scripts/ai-edit.js rename to src/ai-editors/scripts/ai-edit.ts index cca7cc87c134..ca3633acec4a --- a/src/ai-editors/scripts/ai-edit.js +++ b/src/ai-editors/scripts/ai-edit.ts @@ -6,8 +6,9 @@ import fs from 'fs' import yaml from 'js-yaml' import path from 'path' import ora from 'ora' -import github from '#src/workflows/github.ts' -import { callModelsApi } from '#src/ai-editors/lib/call-models-api.js' +import { callModelsApi } from '@/ai-editors/lib/call-models-api' +import dotenv from 'dotenv' +dotenv.config() const __dirname = path.dirname(fileURLToPath(import.meta.url)) const promptDir = path.join(__dirname, '../prompts') @@ -16,15 +17,36 @@ if (!process.env.GITHUB_TOKEN) { throw new Error('Error! You must have a GITHUB_TOKEN set in an .env file to run this script.') } -const responseTypes = { +interface ResponseTypes { + rewrite: string + list: string + json: string +} + +const responseTypes: ResponseTypes = { rewrite: 'Edit the versioning only. Return the edited content.', list: `Do NOT rewrite the content. Report your edits in numbered list format.`, json: `Do NOT rewrite the content. Report your edits as a JSON list, with the format { lineNumber, currentText, suggestion }.`, } -const validResponseTypes = Object.keys(responseTypes) +const validResponseTypes = Object.keys(responseTypes) as Array + +interface EditorType { + promptFile: string + description: string +} + +interface EditorTypes { + versioning: EditorType + // TODO + // scannability: EditorType + // readability: EditorType + // technical: EditorType + // styleguide: EditorType + // contentModels: EditorType +} -const editorTypes = { +const editorTypes: EditorTypes = { versioning: { promptFile: 'versioning-editor.prompt.yml', description: 'Review against simplifying versioning guidelines.', @@ -54,7 +76,7 @@ const editorTypes = { // Add more here... } -const editorDescriptions = () => { +const editorDescriptions = (): string => { let str = '\n\n' Object.entries(editorTypes).forEach(([ed, edObj]) => { str += `\t${ed}\n\t\t\t${edObj.description}\n\n` @@ -62,6 +84,13 @@ const editorDescriptions = () => { return str } +interface CliOptions { + verbose?: boolean + editor?: Array + response?: keyof ResponseTypes + files: string[] +} + const program = new Command() program @@ -80,7 +109,7 @@ program '-f, --files ', 'One or more content file paths in the content directory', ) - .action((options) => { + .action((options: CliOptions) => { ;(async () => { const spinner = ora('Starting AI review...').start() @@ -88,7 +117,7 @@ program const editors = options.editor || ['versioning'] const response = options.response || 'rewrite' - let responseTypeInstruction + let responseTypeInstruction: string if (validResponseTypes.includes(response)) { responseTypeInstruction = responseTypes[response] } else { @@ -126,7 +155,8 @@ program } } } catch (err) { - spinner.fail(`Error processing file ${file}: ${err.message}`) + const error = err as Error + spinner.fail(`Error processing file ${file}: ${error.message}`) process.exitCode = 1 } } @@ -135,13 +165,31 @@ program program.parse(process.argv) -async function callEditor(editorType, responseTypeInstruction, content) { +interface PromptMessage { + content: string + role: string +} + +interface PromptData { + messages: PromptMessage[] + model?: string + temperature?: number + max_tokens?: number +} + +async function callEditor( + editorType: keyof EditorTypes, + responseTypeInstruction: string, + content: string, +): Promise { const promptName = editorTypes[editorType].promptFile const promptPath = path.join(promptDir, promptName) - const prompt = yaml.load(fs.readFileSync(promptPath, 'utf8')) + const prompt = yaml.load(fs.readFileSync(promptPath, 'utf8')) as PromptData + prompt.messages.forEach((msg) => { msg.content = msg.content.replace('{{responseTypeInstruction}}', responseTypeInstruction) msg.content = msg.content.replace('{{input}}', content) }) + return callModelsApi(prompt) } diff --git a/src/events/components/experiments/experiments.ts b/src/events/components/experiments/experiments.ts index b1da9440f624..7c5e83be7d24 100644 --- a/src/events/components/experiments/experiments.ts +++ b/src/events/components/experiments/experiments.ts @@ -21,7 +21,10 @@ export const EXPERIMENTS = { ai_search_experiment: { key: 'ai_search_experiment', isActive: true, // Set to false when the experiment is over - percentOfUsersToGetExperiment: 30, // 30% of users will get the experiment + // We still use an experiment for the AI Search until we: + // 1. Move analytics over the main dashboard + // 2. Don't require an emergency rollback, which experiments provides us + percentOfUsersToGetExperiment: 100, // 100% of users will get the experiment includeVariationInContext: true, // All events will include the `experiment_variation` of the `ai_search_experiment` limitToLanguages: ['en'], // Only users with the `en` language will be included in the experiment alwaysShowForStaff: true, // When set to true, staff will always see the experiment (determined by the `staffonly` cookie) diff --git a/src/fixtures/fixtures/data/allowed-topics.js b/src/fixtures/fixtures/data/allowed-topics.js deleted file mode 100644 index 41d9ffa189dc..000000000000 --- a/src/fixtures/fixtures/data/allowed-topics.js +++ /dev/null @@ -1 +0,0 @@ -export default ['Advanced Security', 'Code scanning', 'Actions', 'Repositories', '2FA'] diff --git a/src/fixtures/tests/annotations.js b/src/fixtures/tests/annotations.ts similarity index 84% rename from src/fixtures/tests/annotations.js rename to src/fixtures/tests/annotations.ts index afa1887f1903..7784c947323e 100644 --- a/src/fixtures/tests/annotations.js +++ b/src/fixtures/tests/annotations.ts @@ -1,10 +1,11 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOM } from '@/tests/helpers/e2etest' describe('annotations', () => { test('code-snippet-with-hashbang', async () => { - const $ = await getDOM('/get-started/foo/code-snippet-with-hashbang') + const $: cheerio.Root = await getDOM('/get-started/foo/code-snippet-with-hashbang') const annotations = $('#article-contents .annotate') // Check http://localhost:4000/en/get-started/foo/code-snippet-with-hashbang @@ -21,7 +22,7 @@ describe('annotations', () => { expect(annotation.find('.annotate-inline').length).toBe(1) expect(annotation.find('.annotate-row').length).toBe(3) const notes = $('.annotate-row .annotate-note p', annotation) - const noteTexts = notes.map((i, el) => $(el).text()).get() + const noteTexts = notes.map((i: number, el: any) => $(el).text()).get() expect(noteTexts).toEqual(["Let's get started", 'This is just a sample', 'End of the script']) } // Second code snippet block @@ -32,7 +33,7 @@ describe('annotations', () => { expect(annotation.find('.annotate-inline').length).toBe(1) expect(annotation.find('.annotate-row').length).toBe(2) const notes = $('.annotate-row .annotate-note p', annotation) - const noteTexts = notes.map((i, el) => $(el).text()).get() + const noteTexts = notes.map((i: number, el: any) => $(el).text()).get() expect(noteTexts).toEqual(['Has to start with a comment.', 'This is the if statement']) } // Yaml code snippet that starts with an empty comment @@ -43,7 +44,7 @@ describe('annotations', () => { expect(annotation.find('.annotate-inline').length).toBe(1) expect(annotation.find('.annotate-row').length).toBe(3) const notes = $('.annotate-row .annotate-note p', annotation) - const noteTexts = notes.map((i, el) => $(el).text()).get() + const noteTexts = notes.map((i: number, el: any) => $(el).text()).get() expect(noteTexts).toEqual([ 'Configures this workflow to run every time a change is pushed to the branch called release.', 'This job checks out the repository contents ...\n' + "And here's the second comment line.", diff --git a/src/fixtures/tests/bad-urls.js b/src/fixtures/tests/bad-urls.ts similarity index 91% rename from src/fixtures/tests/bad-urls.js rename to src/fixtures/tests/bad-urls.ts index c50449fe0e1b..eefeeb7f879b 100644 --- a/src/fixtures/tests/bad-urls.js +++ b/src/fixtures/tests/bad-urls.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from 'vitest' -import { head } from '#src/tests/helpers/e2etest.js' +import { head } from '@/tests/helpers/e2etest' describe('bad URLs', () => { test('any URL with /index.md suffix redirects to be without suffix', async () => { diff --git a/src/fixtures/tests/categories-and-subcategory.js b/src/fixtures/tests/categories-and-subcategory.ts similarity index 58% rename from src/fixtures/tests/categories-and-subcategory.js rename to src/fixtures/tests/categories-and-subcategory.ts index 00755bc4c3d5..3d16eb951a6a 100644 --- a/src/fixtures/tests/categories-and-subcategory.js +++ b/src/fixtures/tests/categories-and-subcategory.ts @@ -1,33 +1,34 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM, head } from '#src/tests/helpers/e2etest.js' +import { getDOM, head } from '@/tests/helpers/e2etest' describe('subcategories', () => { test('get-started/start-your-journey subcategory', async () => { - const $ = await getDOM('/get-started/start-your-journey') + const $: cheerio.Root = await getDOM('/get-started/start-your-journey') const lead = $('[data-search=lead]').text() expect(lead).toMatch('Get started using HubGit to manage Git repositories') const links = $('[data-testid=table-of-contents] a[href]') expect(links.length).toBeGreaterThan(0) // They all have the same prefix - const hrefs = links.map((i, el) => $(el).attr('href')).get() + const hrefs = links.map((i: number, el: any) => $(el).attr('href')).get() expect( - hrefs.every((href) => href.startsWith('/en/get-started/start-your-journey/')), + hrefs.every((href: string) => href.startsWith('/en/get-started/start-your-journey/')), ).toBeTruthy() // The all resolve to a 200 OK without redirects - const responses = await Promise.all(hrefs.map((href) => head(href))) - expect(responses.every((r) => r.statusCode === 200)).toBeTruthy() + const responses = await Promise.all(hrefs.map((href: string) => head(href))) + expect(responses.every((r: any) => r.statusCode === 200)).toBeTruthy() }) test('actions/category/subcategory subcategory has its articles intro', async () => { - const $ = await getDOM('/actions/category/subcategory') + const $: cheerio.Root = await getDOM('/actions/category/subcategory') const lead = $('[data-search=lead]').text() expect(lead).toMatch("Here's the intro for HubGit Actions.") const links = $('[data-testid=table-of-contents] a[href]') - const hrefs = links.map((i, el) => $(el).attr('href')).get() - expect(hrefs.every((href) => href.startsWith('/en/actions/category/'))).toBeTruthy() + const hrefs = links.map((i: number, el: any) => $(el).attr('href')).get() + expect(hrefs.every((href: string) => href.startsWith('/en/actions/category/'))).toBeTruthy() const firstArticleH2 = $('[data-testid=table-of-contents] h2').first() expect(firstArticleH2.text()).toMatch('Article title') @@ -42,17 +43,17 @@ describe('subcategories', () => { describe('categories', () => { test('actions/category subcategory', async () => { - const $ = await getDOM('/actions/category') + const $: cheerio.Root = await getDOM('/actions/category') const lead = $('[data-search=lead]').text() expect(lead).toMatch('Learn how to migrate your existing CI/CD') const links = $('[data-testid=table-of-contents] a[href]') expect(links.length).toBeGreaterThan(0) // They all have the same prefix - const hrefs = links.map((i, el) => $(el).attr('href')).get() - expect(hrefs.every((href) => href.startsWith('/en/actions/category/'))).toBeTruthy() + const hrefs = links.map((i: number, el: any) => $(el).attr('href')).get() + expect(hrefs.every((href: string) => href.startsWith('/en/actions/category/'))).toBeTruthy() // The all resolve to a 200 OK without redirects - const responses = await Promise.all(hrefs.map((href) => head(href))) - expect(responses.every((r) => r.statusCode === 200)).toBeTruthy() + const responses = await Promise.all(hrefs.map((href: string) => head(href))) + expect(responses.every((r: any) => r.statusCode === 200)).toBeTruthy() }) }) diff --git a/src/fixtures/tests/footer.js b/src/fixtures/tests/footer.ts similarity index 72% rename from src/fixtures/tests/footer.js rename to src/fixtures/tests/footer.ts index 148f1aaf5d5e..3fb6e8d48344 100644 --- a/src/fixtures/tests/footer.js +++ b/src/fixtures/tests/footer.ts @@ -1,12 +1,13 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM } from '#src/tests/helpers/e2etest.js' -import nonEnterpriseDefaultVersion from '#src/versions/lib/non-enterprise-default-version.js' +import { getDOM } from '@/tests/helpers/e2etest' +import nonEnterpriseDefaultVersion from '@/versions/lib/non-enterprise-default-version' describe('footer', () => { describe('"contact us" link', () => { test('leads to support from articles', async () => { - const $ = await getDOM( + const $: cheerio.Root = await getDOM( `/en/${nonEnterpriseDefaultVersion}/get-started/start-your-journey/hello-world`, ) expect($('a#support').attr('href')).toBe('https://support.github.com') @@ -15,21 +16,21 @@ describe('footer', () => { test('leads to support on 404 pages', async () => { // Important to use the prefix /en/ on the failing URL or else // it will render a very basic plain text 404 response. - const $ = await getDOM('/en/delicious-snacks/donuts.php', { allow404: true }) + const $: cheerio.Root = await getDOM('/en/delicious-snacks/donuts.php', { allow404: true }) expect($('a#support').attr('href')).toBe('https://support.github.com') }) }) describe('"support" link with nextjs', () => { test('leads to support from articles', async () => { - const $ = await getDOM(`/en/${nonEnterpriseDefaultVersion}/get-started?nextjs=`) + const $: cheerio.Root = await getDOM(`/en/${nonEnterpriseDefaultVersion}/get-started?nextjs=`) expect($('a#support').attr('href')).toBe('https://support.github.com') }) }) describe('test redirects for product landing community links pages', () => { test('codespaces product landing page leads to discussions page', async () => { - const $ = await getDOM('/en/get-started') + const $: cheerio.Root = await getDOM('/en/get-started') expect($('a#ask-community').attr('href')).toBe( 'https://hubgit.com/orgs/community/discussions/categories/get-started', ) @@ -38,7 +39,7 @@ describe('footer', () => { describe('test redirects for non-product landing community links pages', () => { test('leads to https://github.community/ when clicking on the community link', async () => { - const $ = await getDOM(`/en/get-started/start-your-journey/hello-world`) + const $: cheerio.Root = await getDOM(`/en/get-started/start-your-journey/hello-world`) expect($('a#ask-community').attr('href')).toBe( 'https://github.com/orgs/community/discussions', ) diff --git a/src/fixtures/tests/glossary.js b/src/fixtures/tests/glossary.ts similarity index 53% rename from src/fixtures/tests/glossary.js rename to src/fixtures/tests/glossary.ts index a8a64e8e1c5f..70b314bc7dca 100644 --- a/src/fixtures/tests/glossary.js +++ b/src/fixtures/tests/glossary.ts @@ -1,18 +1,20 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOMCached as getDOM } from '@/tests/helpers/e2etest' describe('glossary', () => { test('headings are sorted alphabetically', async () => { - const $ = await getDOM('/get-started/learning-about-github/github-glossary') + const $: cheerio.Root = await getDOM('/get-started/learning-about-github/github-glossary') const headings = $('#article-contents h2') - const headingTexts = headings.map((_, el) => $(el).text()).get() - const cloned = [...headingTexts].sort((a, b) => a.localeCompare(b)) - const equalStringArray = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]) + const headingTexts = headings.map((_: number, el: any) => $(el).text()).get() + const cloned = [...headingTexts].sort((a: string, b: string) => a.localeCompare(b)) + const equalStringArray = (a: string[], b: string[]) => + a.length === b.length && a.every((v, i) => v === b[i]) expect(equalStringArray(headingTexts, cloned)).toBe(true) }) test('Markdown links are correct', async () => { - const $ = await getDOM('/get-started/learning-about-github/github-glossary') + const $: cheerio.Root = await getDOM('/get-started/learning-about-github/github-glossary') const internalLink = $('#article-contents a[href="/en/get-started/foo"]') expect(internalLink.length).toBe(1) // That link used AUTOTITLE so it should be "expanded" @@ -20,19 +22,19 @@ describe('glossary', () => { }) test('all Liquid is evaluated', async () => { - const $ = await getDOM('/get-started/learning-about-github/github-glossary') + const $: cheerio.Root = await getDOM('/get-started/learning-about-github/github-glossary') const paragraphs = $('#article-contents p') - const paragraphTexts = paragraphs.map((_, el) => $(el).text()).get() - expect(paragraphTexts.find((text) => text.includes('{%'))).toBe(undefined) + const paragraphTexts = paragraphs.map((_: number, el: any) => $(el).text()).get() + expect(paragraphTexts.find((text: string) => text.includes('{%'))).toBe(undefined) }) test('liquid in one of the description depends on version', async () => { // fpt { - const $ = await getDOM('/get-started/learning-about-github/github-glossary') + const $: cheerio.Root = await getDOM('/get-started/learning-about-github/github-glossary') const paragraphs = $('#article-contents p') const paragraphTexts = paragraphs - .map((_, el) => $(el).text()) + .map((_: number, el: any) => $(el).text()) .get() .join('\n') expect(paragraphTexts).toContain('status check on HubGit.') @@ -40,12 +42,12 @@ describe('glossary', () => { // ghes { - const $ = await getDOM( + const $: cheerio.Root = await getDOM( '/enterprise-server@latest/get-started/learning-about-github/github-glossary', ) const paragraphs = $('#article-contents p') const paragraphTexts = paragraphs - .map((_, el) => $(el).text()) + .map((_: number, el: any) => $(el).text()) .get() .join('\n') expect(paragraphTexts).toContain('status check on HubGit Enterprise Server.') diff --git a/src/fixtures/tests/guides.js b/src/fixtures/tests/guides.ts similarity index 71% rename from src/fixtures/tests/guides.js rename to src/fixtures/tests/guides.ts index 81176a6b1e6a..2ee58c4737f2 100644 --- a/src/fixtures/tests/guides.js +++ b/src/fixtures/tests/guides.ts @@ -1,10 +1,11 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { get, getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js' +import { get, getDOMCached as getDOM } from '@/tests/helpers/e2etest' describe('guides', () => { test("page's title should be document title", async () => { - const $ = await getDOM('/code-security/guides') + const $: cheerio.Root = await getDOM('/code-security/guides') // This is what you'd find in src/fixtures/fixtures/content/code-security/guides.md const title = 'Guides for cool security' expect($('title').text()).toMatch(title) @@ -18,14 +19,16 @@ describe('guides', () => { describe('learning tracks', () => { test('start the first learning track and come back via the navigation banner', async () => { - const $ = await getDOM('/code-security/guides') + const $: cheerio.Root = await getDOM('/code-security/guides') const links = $('[data-testid=learning-track] a') - const link = links.filter((_, el) => $(el).text() === 'Start learning path').first() + const link = links + .filter((_: number, el: any) => $(el).text() === 'Start learning path') + .first() expect(link.attr('href')).toMatch('learn=foo_bar') expect(link.attr('href')).toMatch('learnProduct=code-security') // Go the first "Start learning path" link - const $2 = await getDOM(link.attr('href')) + const $2: cheerio.Root = await getDOM(link.attr('href')!) const card2 = $2('[data-testid=learning-track-card]') // The card has 2 links. One to go back to the guide page // whose title is the name of the learning track @@ -33,9 +36,11 @@ describe('learning tracks', () => { expect(backLink.attr('href')).toBe('/en/code-security/guides') expect(backLink.text()).toBe('Fix the plumbing') // Underneath it says "1 of in learning path" - const span = card2.find('span').filter((_, el) => $(el).text().includes('1 of 2')) + const span = card2.find('span').filter((_: number, el: any) => $(el).text().includes('1 of 2')) expect(span.text()).toBe('1 of 2 in learning path') - const nextWrapper = card2.find('span').filter((_, el) => $(el).text().includes('Next')) + const nextWrapper = card2 + .find('span') + .filter((_: number, el: any) => $(el).text().includes('Next')) expect(nextWrapper.length).toBe(1) const nextLink = nextWrapper.find('a').first() expect(nextLink.attr('href')).toMatch( @@ -52,14 +57,18 @@ describe('learning tracks', () => { expect(navNextLink.text()).toBe('Securing your organization') // Go to the next (last) page - const $3 = await getDOM(nextLink.attr('href')) + const $3: cheerio.Root = await getDOM(nextLink.attr('href')!) const card3 = $3('[data-testid=learning-track-card]') - const span3 = card3.find('span').filter((_, el) => $(el).text().includes('2 of 2')) + const span3 = card3.find('span').filter((_: number, el: any) => $(el).text().includes('2 of 2')) expect(span3.text()).toBe('2 of 2 in learning path') // No "Next:" link now - const nextWrapper3 = card3.find('span').filter((_, el) => $(el).text().includes('Next')) + const nextWrapper3 = card3 + .find('span') + .filter((_: number, el: any) => $(el).text().includes('Next')) expect(nextWrapper3.length).toBe(0) - const moreGuidesLink = card3.find('a').filter((_, el) => $(el).text().includes('More guides')) + const moreGuidesLink = card3 + .find('a') + .filter((_: number, el: any) => $(el).text().includes('More guides')) expect(moreGuidesLink.attr('href')).toBe('/en/code-security/guides') // On this last page, the nav will link to the previous page @@ -73,25 +82,29 @@ describe('learning tracks', () => { test('with and without a valid ?learn= query string', async () => { // Valid { - const $ = await getDOM('/code-security/getting-started/quickstart?learn=foo_bar') + const $: cheerio.Root = await getDOM( + '/code-security/getting-started/quickstart?learn=foo_bar', + ) expect($('[data-testid=learning-track-card]').length).toBe(1) expect($('[data-testid=learning-track-nav]').length).toBe(1) } // Invalid { - const $ = await getDOM('/code-security/getting-started/quickstart?learn=blablainvalid') + const $: cheerio.Root = await getDOM( + '/code-security/getting-started/quickstart?learn=blablainvalid', + ) expect($('[data-testid=learning-track-card]').length).toBe(0) expect($('[data-testid=learning-track-nav]').length).toBe(0) } // Empty { - const $ = await getDOM('/code-security/getting-started/quickstart?learn=') + const $: cheerio.Root = await getDOM('/code-security/getting-started/quickstart?learn=') expect($('[data-testid=learning-track-card]').length).toBe(0) expect($('[data-testid=learning-track-nav]').length).toBe(0) } // Missing { - const $ = await getDOM('/code-security/getting-started/quickstart') + const $: cheerio.Root = await getDOM('/code-security/getting-started/quickstart') expect($('[data-testid=learning-track-card]').length).toBe(0) expect($('[data-testid=learning-track-nav]').length).toBe(0) } diff --git a/src/fixtures/tests/head.js b/src/fixtures/tests/head.ts similarity index 78% rename from src/fixtures/tests/head.js rename to src/fixtures/tests/head.ts index ad9dff11c310..99ed5c9e804a 100644 --- a/src/fixtures/tests/head.js +++ b/src/fixtures/tests/head.ts @@ -1,10 +1,11 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOM } from '@/tests/helpers/e2etest' describe('', () => { test('includes page intro in `description` meta tag', async () => { - const $ = await getDOM('/get-started/markdown/intro') + const $: cheerio.Root = await getDOM('/get-started/markdown/intro') // The intro has Markdown syntax which becomes HTML encoded in the lead element. const lead = $('[data-testid="lead"] p') expect(lead.html()).toMatch('syntax') diff --git a/src/fixtures/tests/homepage.js b/src/fixtures/tests/homepage.ts similarity index 69% rename from src/fixtures/tests/homepage.js rename to src/fixtures/tests/homepage.ts index 5e320014e131..0b259e63de23 100644 --- a/src/fixtures/tests/homepage.js +++ b/src/fixtures/tests/homepage.ts @@ -1,10 +1,11 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { get, getDOM } from '#src/tests/helpers/e2etest.js' +import { get, getDOM } from '@/tests/helpers/e2etest' describe('home page', () => { test('landing area', async () => { - const $ = await getDOM('/') + const $: cheerio.Root = await getDOM('/') const container = $('#landing') expect(container.length).toBe(1) expect(container.find('h1').text()).toBe('GitHub Docs') @@ -12,14 +13,14 @@ describe('home page', () => { }) test('product groups can use Liquid', async () => { - const $ = await getDOM('/') + const $: cheerio.Root = await getDOM('/') const main = $('[data-testid="product"]') const links = main.find('a[href*="/"]') - const hrefs = links.map((i, link) => $(link)).get() + const hrefs = links.map((i: number, link: any) => $(link)).get() let externalLinks = 0 for (const href of hrefs) { - if (!href.attr('href').startsWith('https://')) { - const res = await get(href.attr('href')) + if (!href.attr('href')?.startsWith('https://')) { + const res = await get(href.attr('href')!) expect(res.statusCode).toBe(200) // Not needing to redirect expect(href.text().includes('{%')).toBe(false) } else { diff --git a/src/fixtures/tests/html-comments.js b/src/fixtures/tests/html-comments.ts similarity index 77% rename from src/fixtures/tests/html-comments.js rename to src/fixtures/tests/html-comments.ts index 6abc9484cb8d..62d8bcf42088 100644 --- a/src/fixtures/tests/html-comments.js +++ b/src/fixtures/tests/html-comments.ts @@ -1,10 +1,11 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOMCached as getDOM } from '@/tests/helpers/e2etest' describe('html-comments', () => { test('regular comments are removed', async () => { - const $ = await getDOM('/get-started/markdown/html-comments') + const $: cheerio.Root = await getDOM('/get-started/markdown/html-comments') const contents = $('#article-contents') const html = contents.html() expect(html).not.toContain('This comment should get deleted since it mentions gooblygook') diff --git a/src/fixtures/tests/images.js b/src/fixtures/tests/images.ts similarity index 79% rename from src/fixtures/tests/images.js rename to src/fixtures/tests/images.ts index fe5d1b90385d..dda711defbec 100644 --- a/src/fixtures/tests/images.js +++ b/src/fixtures/tests/images.ts @@ -1,12 +1,13 @@ import { describe, expect, test } from 'vitest' import sharp from 'sharp' +import cheerio from 'cheerio' -import { get, head, getDOM } from '#src/tests/helpers/e2etest.js' -import { MAX_WIDTH } from '#src/content-render/unified/rewrite-asset-img-tags.js' +import { get, head, getDOM } from '@/tests/helpers/e2etest' +import { MAX_WIDTH } from '@/content-render/unified/rewrite-asset-img-tags' describe('render Markdown image tags', () => { test('page with a single image', async () => { - const $ = await getDOM('/get-started/images/single-image') + const $: cheerio.Root = await getDOM('/get-started/images/single-image') const pictures = $('#article-contents picture') expect(pictures.length).toBe(1) @@ -25,7 +26,7 @@ describe('render Markdown image tags', () => { const alt = imgs.attr('alt') expect(alt).toBe('This is the alt text') - const res = await get(srcset.split(' ')[0], { responseType: 'buffer' }) + const res = await get(srcset!.split(' ')[0], { responseType: 'buffer' }) expect(res.statusCode).toBe(200) expect(res.headers['content-type']).toBe('image/webp') @@ -34,7 +35,7 @@ describe('render Markdown image tags', () => { // When transformed as a source in a `` tag, it's automatically // injected with the `mw-XXXXX` virtual indicator in the URL that // resizes it on-the-fly. - const image = sharp(res.body) + const image = sharp(res.body as Buffer) const { width, height } = await image.metadata() expect(width).toBe(MAX_WIDTH) // The `_fixtures/screenshot.png` is 2000x1494. @@ -43,7 +44,7 @@ describe('render Markdown image tags', () => { }) test('images have density specified', async () => { - const $ = await getDOM('/get-started/images/retina-image') + const $: cheerio.Root = await getDOM('/get-started/images/retina-image') const pictures = $('#article-contents picture') expect(pictures.length).toBe(3) @@ -57,20 +58,20 @@ describe('render Markdown image tags', () => { }) test('image inside a list keeps its span', async () => { - const $ = await getDOM('/get-started/images/images-in-lists') + const $: cheerio.Root = await getDOM('/get-started/images/images-in-lists') const imageSpan = $('#article-contents > div > ol > li > div.procedural-image-wrapper') expect(imageSpan.length).toBe(1) }) test("links directly to images aren't rewritten", async () => { - const $ = await getDOM('/get-started/images/link-to-image') + const $: cheerio.Root = await getDOM('/get-started/images/link-to-image') // There is only 1 link inside that page const links = $('#article-contents a[href^="/"]') // exclude header link expect(links.length).toBe(1) // This proves that the link didn't get rewritten to `/en/...` expect(links.attr('href'), '/assets/images/_fixtures/screenshot.png') - const res = await head(links.attr('href')) + const res = await head(links.attr('href')!) expect(res.statusCode).toBe(200) }) }) diff --git a/src/fixtures/tests/internal-links.js b/src/fixtures/tests/internal-links.ts similarity index 62% rename from src/fixtures/tests/internal-links.js rename to src/fixtures/tests/internal-links.ts index e00431e8c0b6..d95dcc71d0f1 100644 --- a/src/fixtures/tests/internal-links.js +++ b/src/fixtures/tests/internal-links.ts @@ -1,15 +1,16 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { get, getDOM } from '#src/tests/helpers/e2etest.js' -import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js' -import { allVersions } from '#src/versions/lib/all-versions.js' +import { get, getDOM } from '@/tests/helpers/e2etest' +import enterpriseServerReleases from '@/versions/lib/enterprise-server-releases' +import { allVersions } from '@/versions/lib/all-versions' describe('autotitle', () => { test('internal links with AUTOTITLE resolves', async () => { - const $ = await getDOM('/get-started/foo/autotitling') + const $: cheerio.Root = await getDOM('/get-started/foo/autotitling') const links = $('#article-contents a[href]') - links.each((i, element) => { - if ($(element).attr('href').includes('/get-started/start-your-journey/hello-world')) { + links.each((i: number, element: any) => { + if ($(element).attr('href')?.includes('/get-started/start-your-journey/hello-world')) { expect($(element).text()).toBe('Hello World') } }) @@ -41,20 +42,21 @@ describe('autotitle', () => { describe('cross-version-links', () => { test.each(Object.keys(allVersions))( 'links to free-pro-team should be implicit even on %p', - async (version) => { + async (version: string) => { const URL = `/${version}/get-started/foo/cross-version-linking` - const $ = await getDOM(URL) + const $: cheerio.Root = await getDOM(URL) const links = $('#article-contents a[href]') // Tests that the hardcoded prefix is always removed const firstLink = links.filter( - (i, element) => $(element).text() === 'Hello world always in free-pro-team', + (i: number, element: any) => $(element).text() === 'Hello world always in free-pro-team', ) expect(firstLink.attr('href')).toBe('/en/get-started/start-your-journey/hello-world') // Tests that the second link always goes to enterprise-server@X.Y const secondLink = links.filter( - (i, element) => $(element).text() === 'Autotitling page always in enterprise-server latest', + (i: number, element: any) => + $(element).text() === 'Autotitling page always in enterprise-server latest', ) expect(secondLink.attr('href')).toBe( `/en/enterprise-server@${enterpriseServerReleases.latest}/get-started/start-your-journey/hello-world`, @@ -65,50 +67,62 @@ describe('cross-version-links', () => { describe('link-rewriting', () => { test('/en is injected', async () => { - const $ = await getDOM('/get-started/start-your-journey/link-rewriting') + const $: cheerio.Root = await getDOM('/get-started/start-your-journey/link-rewriting') const links = $('#article-contents a[href]') { - const link = links.filter((i, element) => $(element).text() === 'Cross Version Linking') + const link = links.filter( + (i: number, element: any) => $(element).text() === 'Cross Version Linking', + ) expect(link.attr('href')).toMatch('/en/get-started/') } // Some links are left untouched { - const link = links.filter((i, element) => $(element).text().includes('Enterprise 11.10')) + const link = links.filter((i: number, element: any) => + $(element).text().includes('Enterprise 11.10'), + ) expect(link.attr('href')).toMatch('/en/enterprise/') } { - const link = links.filter((i, element) => $(element).text().includes('peterbe')) + const link = links.filter((i: number, element: any) => $(element).text().includes('peterbe')) expect(link.attr('href')).toMatch(/^https:/) } { - const link = links.filter((i, element) => $(element).text().includes('Picture')) + const link = links.filter((i: number, element: any) => $(element).text().includes('Picture')) expect(link.attr('href')).toMatch(/^\/assets\//) } { - const link = links.filter((i, element) => $(element).text().includes('GraphQL Schema')) + const link = links.filter((i: number, element: any) => + $(element).text().includes('GraphQL Schema'), + ) expect(link.attr('href')).toMatch(/^\/public\//) } }) test('/en and current version (latest) is injected', async () => { - const $ = await getDOM('/enterprise-cloud@latest/get-started/start-your-journey/link-rewriting') + const $: cheerio.Root = await getDOM( + '/enterprise-cloud@latest/get-started/start-your-journey/link-rewriting', + ) const links = $('#article-contents a[href]') - const link = links.filter((i, element) => $(element).text() === 'Cross Version Linking') + const link = links.filter( + (i: number, element: any) => $(element).text() === 'Cross Version Linking', + ) expect(link.attr('href')).toMatch('/en/enterprise-cloud@latest/get-started/') }) test('/en and current version number is injected', async () => { // enterprise-server, unlike enterprise-cloud, use numbers - const $ = await getDOM( + const $: cheerio.Root = await getDOM( '/enterprise-server@latest/get-started/start-your-journey/link-rewriting', ) const links = $('#article-contents a[href]') - const link = links.filter((i, element) => $(element).text() === 'Cross Version Linking') + const link = links.filter( + (i: number, element: any) => $(element).text() === 'Cross Version Linking', + ) expect(link.attr('href')).toMatch( `/en/enterprise-server@${enterpriseServerReleases.latestStable}/get-started/`, ) @@ -117,16 +131,16 @@ describe('link-rewriting', () => { describe('subcategory links', () => { test('no free-pro-team prefix', async () => { - const $ = await getDOM('/rest/actions') + const $: cheerio.Root = await getDOM('/rest/actions') const links = $('[data-testid="table-of-contents"] a[href]') - links.each((i, element) => { + links.each((i: number, element: any) => { expect($(element).attr('href')).not.toContain('/free-pro-team@latest') }) }) test('enterprise-server prefix', async () => { - const $ = await getDOM('/enterprise-server@latest/rest/actions') + const $: cheerio.Root = await getDOM('/enterprise-server@latest/rest/actions') const links = $('[data-testid="table-of-contents"] a[href]') - links.each((i, element) => { + links.each((i: number, element: any) => { expect($(element).attr('href')).toMatch(/\/enterprise-server@\d/) }) }) diff --git a/src/fixtures/tests/landing-hero.js b/src/fixtures/tests/landing-hero.ts similarity index 75% rename from src/fixtures/tests/landing-hero.js rename to src/fixtures/tests/landing-hero.ts index 66b4b8ec183a..15eb263cf6e1 100644 --- a/src/fixtures/tests/landing-hero.js +++ b/src/fixtures/tests/landing-hero.ts @@ -1,22 +1,23 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOM } from '@/tests/helpers/e2etest' describe('product landing page', () => { test('product landing page displays full title', async () => { - const $ = await getDOM('/get-started') + const $: cheerio.Root = 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 $ = await getDOM('/pages') + const $: cheerio.Root = 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 $ = await getDOM('/enterprise-server@latest/pages') + const $: cheerio.Root = 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/liquid.js b/src/fixtures/tests/liquid.ts similarity index 83% rename from src/fixtures/tests/liquid.js rename to src/fixtures/tests/liquid.ts index 6a167a91e839..21208f1e75ad 100644 --- a/src/fixtures/tests/liquid.js +++ b/src/fixtures/tests/liquid.ts @@ -1,33 +1,34 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDataByLanguage } from '#src/data-directory/lib/get-data.js' -import { getDOM } from '#src/tests/helpers/e2etest.js' -import { supported } from '#src/versions/lib/enterprise-server-releases.js' +import { getDataByLanguage } from '@/data-directory/lib/get-data' +import { getDOM } from '@/tests/helpers/e2etest' +import { supported } from '@/versions/lib/enterprise-server-releases' describe('spotlight', () => { test('renders styled warnings', async () => { - const $ = await getDOM('/get-started/liquid/warnings') + const $: cheerio.Root = await getDOM('/get-started/liquid/warnings') const nodes = $('.ghd-spotlight-attention') expect(nodes.length).toBe(1) expect(nodes.text().includes('This is inside the warning.')).toBe(true) }) test('renders styled danger', async () => { - const $ = await getDOM('/get-started/liquid/danger') + const $: cheerio.Root = await getDOM('/get-started/liquid/danger') const nodes = $('.ghd-spotlight-danger') expect(nodes.length).toBe(1) expect(nodes.text().includes('Danger, Will Robinson.')).toBe(true) }) test('renders styled tips', async () => { - const $ = await getDOM('/get-started/liquid/tips') + const $: cheerio.Root = await getDOM('/get-started/liquid/tips') const nodes = $('.ghd-spotlight-success') expect(nodes.length).toBe(1) expect(nodes.text().includes('This is inside the tip.')).toBe(true) }) test('renders styled notes', async () => { - const $ = await getDOM('/get-started/liquid/notes') + const $: cheerio.Root = await getDOM('/get-started/liquid/notes') const nodes = $('.ghd-spotlight-accent') expect(nodes.length).toBe(1) expect(nodes.text().includes('This is inside the note.')).toBe(true) @@ -36,7 +37,7 @@ describe('spotlight', () => { describe('raw', () => { test('renders raw', async () => { - const $ = await getDOM('/get-started/liquid/raw') + const $: cheerio.Root = await getDOM('/get-started/liquid/raw') const lead = $('[data-testid="lead"]').html() expect(lead).toMatch('{% raw %}') const code = $('pre code').html() @@ -47,7 +48,7 @@ describe('raw', () => { describe('tool', () => { test('renders platform-specific content', async () => { - const $ = await getDOM('/get-started/liquid/platform-specific') + const $: cheerio.Root = await getDOM('/get-started/liquid/platform-specific') expect($('.ghd-tool.mac p').length).toBe(1) expect($('.ghd-tool.mac p').text().includes('mac specific content')).toBe(true) expect($('.ghd-tool.windows p').length).toBe(1) @@ -57,7 +58,7 @@ describe('tool', () => { }) test('renders expected mini TOC headings in platform-specific content', async () => { - const $ = await getDOM('/get-started/liquid/platform-specific') + const $: cheerio.Root = await getDOM('/get-started/liquid/platform-specific') expect($('h2#in-this-article').length).toBe(1) expect($('h2#in-this-article + nav ul .ghd-tool.mac').length).toBe(1) expect($('h2#in-this-article + nav ul .ghd-tool.windows').length).toBe(1) @@ -67,7 +68,7 @@ describe('tool', () => { describe('post', () => { test('whitespace control', async () => { - const $ = await getDOM('/get-started/liquid/whitespace') + const $: cheerio.Root = await getDOM('/get-started/liquid/whitespace') const html = $('#article-contents').html() expect(html).toMatch('

HubGit

') expect(html).toMatch('

Text before. HubGit Text after.

') @@ -77,7 +78,9 @@ describe('post', () => { // Test what happens to `Cram{% ifversion fpt %}FPT{% endif %}ped.` // when it's not free-pro-team. { - const $ = await getDOM('/enterprise-server@latest/get-started/liquid/whitespace') + const $: cheerio.Root = await getDOM( + '/enterprise-server@latest/get-started/liquid/whitespace', + ) const html = $('#article-contents').html() // Assures that there's not whitespace left when the `{% ifversion %}` // yields an empty string. @@ -88,7 +91,7 @@ describe('post', () => { describe('rowheaders', () => { test('rowheaders', async () => { - const $ = await getDOM('/get-started/liquid/table-row-headers') + const $: cheerio.Root = await getDOM('/get-started/liquid/table-row-headers') const tables = $('#article-contents table') expect(tables.length).toBe(2) @@ -106,7 +109,7 @@ describe('rowheaders', () => { // // That's because a Liquid + Markdown solution rewrites the // *first* `tbody td` to become a `th` instead. - const firstTable = tables.filter((i) => i === 0) + const firstTable = tables.filter((i: number) => i === 0) expect($('tbody tr th', firstTable).length).toBe(2) expect($('tbody tr td', firstTable).length).toBe(2 * 3) @@ -120,7 +123,7 @@ describe('rowheaders', () => { // td // // (and there are 3 of these rows) - const secondTable = tables.filter((i) => i === 1) + const secondTable = tables.filter((i: number) => i === 1) expect($('tbody tr th', secondTable).length).toBe(0) expect($('tbody tr td', secondTable).length).toBe(3 * 3) @@ -128,10 +131,10 @@ describe('rowheaders', () => { // `scope` attribute. // See "Scope attribute should be used correctly on tables" // https://dequeuniversity.com/rules/axe/4.1/scope-attr-valid?application=RuleDescription - $('thead th', firstTable).each((i, element) => { + $('thead th', firstTable).each((i: number, element: any) => { expect($(element).attr('scope')).toBe('col') }) - $('tbody th', firstTable).each((i, element) => { + $('tbody th', firstTable).each((i: number, element: any) => { expect($(element).attr('scope')).toBe('row') }) // The 5 here is the other `expect(...)` that happens before these @@ -149,7 +152,7 @@ describe('ifversion', () => { // to find out versions that shouldn't match const ghesLast = `enterprise-server@${supported[supported.length - 1]}` const ghesPenultimate = `enterprise-server@${supported[supported.length - 2]}` - const matchesPerVersion = { + const matchesPerVersion: Record = { 'free-pro-team@latest': [ 'condition-a', 'condition-b', @@ -184,26 +187,26 @@ describe('ifversion', () => { test.each(Object.keys(matchesPerVersion))( 'ifversion using rendered version %p', - async (version) => { - const $ = await getDOM(`/${version}/get-started/liquid/ifversion`) + async (version: string) => { + const $: cheerio.Root = await getDOM(`/${version}/get-started/liquid/ifversion`) const html = $('#article-contents').html() const allConditions = Object.values(matchesPerVersion).flat() // this is all conditions that should match for this rendered version - const wantedConditions = allConditions.filter((condition) => { + const wantedConditions = allConditions.filter((condition: string) => { return matchesPerVersion[version].includes(condition) }) // this is the inverse of the above, conditions that shouldn't match for this rendered version - const unwantedConditions = allConditions.filter((condition) => { + const unwantedConditions = allConditions.filter((condition: string) => { return !matchesPerVersion[version].includes(condition) }) - wantedConditions.forEach((condition) => { + wantedConditions.forEach((condition: string) => { expect(html).toMatch(condition) }) - unwantedConditions.forEach((condition) => { + unwantedConditions.forEach((condition: string) => { expect(html).not.toMatch(condition) }) }, @@ -212,14 +215,14 @@ describe('ifversion', () => { describe('misc Liquid', () => { test('links with liquid from data', async () => { - const $ = await getDOM('/get-started/liquid/links-with-liquid') + const $: cheerio.Root = await getDOM('/get-started/liquid/links-with-liquid') // The URL comes from variables.product.pricing_url const url = getDataByLanguage('variables.product.pricing_url', 'en') if (!url) throw new Error('variable could not be found') const links = $(`#article-contents a[href="${url}"]`) expect(links.length).toBe(2) const texts = links - .map((i, element) => { + .map((i: number, element: any) => { return $(element).text() }) .get() @@ -232,7 +235,7 @@ describe('misc Liquid', () => { // Markdown directly follows a tool tag like `{% linux %}...{% endlinux %}`. // The next line immediately after the `{% endlinux %}` should not // leave the Markdown unrendered - const $ = await getDOM('/get-started/liquid/tool-platform-switcher') + const $: cheerio.Root = await getDOM('/get-started/liquid/tool-platform-switcher') const innerHTML = $('#article-contents').html() expect(innerHTML).not.toMatch('On *this* line is `Markdown` too.') expect(innerHTML).toMatch('

On this line is Markdown too.

') @@ -241,7 +244,7 @@ describe('misc Liquid', () => { describe('data tag', () => { test('injects data reusables with the right whitespace', async () => { - const $ = await getDOM('/get-started/liquid/data') + const $: cheerio.Root = await getDOM('/get-started/liquid/data') // This proves that the two injected reusables tables work. // CommonMark is finicky if the indentation isn't perfect, so @@ -290,7 +293,7 @@ describe('data tag', () => { // But because `{% data reusables.injectables.paragraphs %}` is // inserted with some indentation, that's replicated on every line. const li = $('#article-contents li') - .filter((_, element) => { + .filter((_: number, element: any) => { return $(element).text().trim().startsWith('Point 1') }) .eq(0) diff --git a/src/fixtures/tests/markdown.js b/src/fixtures/tests/markdown.ts similarity index 74% rename from src/fixtures/tests/markdown.js rename to src/fixtures/tests/markdown.ts index 78b3984a7859..36b604106c38 100644 --- a/src/fixtures/tests/markdown.js +++ b/src/fixtures/tests/markdown.ts @@ -1,10 +1,11 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOM } from '@/tests/helpers/e2etest' describe('markdown rendering', () => { test('markdown in intro', async () => { - const $ = await getDOM('/get-started/markdown/intro') + const $: cheerio.Root = await getDOM('/get-started/markdown/intro') const html = $('[data-testid="lead"]').html() expect(html).toMatch('Markdown') expect(html).toMatch('syntax') @@ -14,7 +15,7 @@ describe('markdown rendering', () => { describe('alerts', () => { test('basic rendering', async () => { - const $ = await getDOM('/get-started/markdown/alerts') + const $: cheerio.Root = await getDOM('/get-started/markdown/alerts') const alerts = $('#article-contents .ghd-alert') // See src/fixtures/fixtures/content/get-started/markdown/alerts.md // to be this confident in the assertions. @@ -22,13 +23,13 @@ describe('alerts', () => { const svgs = $('svg', alerts) expect(svgs.length).toBe(5) const titles = $('.ghd-alert-title', alerts) - .map((_, el) => $(el).text()) + .map((_: number, el: any) => $(el).text()) .get() expect(titles).toEqual(['Tip', 'Note', 'Important', 'Warning', 'Caution']) const bodies = $('p:nth-child(2)', alerts) - .map((_, el) => $(el).text()) + .map((_: number, el: any) => $(el).text()) .get() - .map((s) => s.trim()) + .map((s: string) => s.trim()) expect(bodies).toEqual([ "Here's a free tip", 'A note.', diff --git a/src/fixtures/tests/minitoc.js b/src/fixtures/tests/minitoc.ts similarity index 68% rename from src/fixtures/tests/minitoc.js rename to src/fixtures/tests/minitoc.ts index cb616569beba..1fbeaf279f7f 100644 --- a/src/fixtures/tests/minitoc.js +++ b/src/fixtures/tests/minitoc.ts @@ -1,37 +1,38 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOM } from '@/tests/helpers/e2etest' describe('minitoc', () => { // TODO disable the mini TOC tests when we replace it with sticky TOC header test('renders mini TOC in articles with more than one heading', async () => { - const $ = await getDOM('/en/get-started/minitocs/multiple-headings') + const $: cheerio.Root = await getDOM('/en/get-started/minitocs/multiple-headings') expect($('h2#in-this-article').length).toBe(1) expect($('h2#in-this-article + nav ul li').length).toBeGreaterThan(1) }) test('does not render mini TOC in articles with only one heading', async () => { - const $ = await getDOM('/en/get-started/minitocs/one-heading') + const $: cheerio.Root = await getDOM('/en/get-started/minitocs/one-heading') expect($('h2#in-this-article').length).toBe(0) }) test('does not render mini TOC in articles with no headings', async () => { - const $ = await getDOM('/en/get-started/minitocs/no-heading') + const $: cheerio.Root = await getDOM('/en/get-started/minitocs/no-heading') expect($('h2#in-this-article').length).toBe(0) }) test('does not render mini TOC in non-articles', async () => { - const $ = await getDOM('/en/get-started') + const $: cheerio.Root = await getDOM('/en/get-started') expect($('h2#in-this-article').length).toBe(0) }) test('renders mini TOC with correct links when headings contain markup', async () => { - const $ = await getDOM('/en/get-started/minitocs/markup-heading') + const $: cheerio.Root = await getDOM('/en/get-started/minitocs/markup-heading') expect($('h2#in-this-article + nav ul li a[href="#on"]').length).toBe(1) }) test("max heading doesn't exceed h2", async () => { - const $ = await getDOM('/en/get-started/minitocs/multiple-headings') + const $: cheerio.Root = await getDOM('/en/get-started/minitocs/multiple-headings') expect($('h2#in-this-article').length).toBe(1) expect($('h2#in-this-article + nav ul').length).toBeGreaterThan(0) // non-indented items expect($('h2#in-this-article + nav ul div ul div').length).toBe(0) // indented items diff --git a/src/fixtures/tests/page-titles.js b/src/fixtures/tests/page-titles.ts similarity index 55% rename from src/fixtures/tests/page-titles.js rename to src/fixtures/tests/page-titles.ts index 6428e2bfed4f..2bfe53bf8cc5 100644 --- a/src/fixtures/tests/page-titles.js +++ b/src/fixtures/tests/page-titles.ts @@ -1,33 +1,36 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js' -import { getDOM } from '#src/tests/helpers/e2etest.js' +import enterpriseServerReleases from '@/versions/lib/enterprise-server-releases' +import { getDOM } from '@/tests/helpers/e2etest' describe('page titles', () => { test('homepage', async () => { - const $ = await getDOM('/en') + const $: cheerio.Root = await getDOM('/en') expect($('title').text()).toBe('GitHub Docs') }) test('fpt article', async () => { - const $ = await getDOM('/get-started/start-your-journey/hello-world') + const $: cheerio.Root = await getDOM('/get-started/start-your-journey/hello-world') expect($('title').text()).toBe('Hello World - GitHub Docs') }) test('ghes article', async () => { - const $ = await getDOM(`/enterprise-server@latest/get-started/start-your-journey/hello-world`) + const $: cheerio.Root = await getDOM( + `/enterprise-server@latest/get-started/start-your-journey/hello-world`, + ) expect($('title').text()).toBe( `Hello World - GitHub Enterprise Server ${enterpriseServerReleases.latestStable} Docs`, ) }) test('fpt subcategory page', async () => { - const $ = await getDOM('/en/get-started/start-your-journey') + const $: cheerio.Root = await getDOM('/en/get-started/start-your-journey') expect($('title').text()).toBe('Start your journey - GitHub Docs') }) test('fpt category page', async () => { - const $ = await getDOM('/actions/category') + const $: cheerio.Root = await getDOM('/actions/category') expect($('title').text()).toBe('Category page of GitHub Actions - GitHub Docs') }) }) diff --git a/src/fixtures/tests/permissions-callout.js b/src/fixtures/tests/permissions-callout.ts similarity index 75% rename from src/fixtures/tests/permissions-callout.js rename to src/fixtures/tests/permissions-callout.ts index d9e373908d54..6c194d9a28ae 100644 --- a/src/fixtures/tests/permissions-callout.js +++ b/src/fixtures/tests/permissions-callout.ts @@ -1,10 +1,11 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOM } from '@/tests/helpers/e2etest' describe('permission statements', () => { test('article page product statement', async () => { - const $ = await getDOM('/get-started/foo/page-with-callout') + const $: cheerio.Root = await getDOM('/get-started/foo/page-with-callout') const callout = $('[data-testid=product-statement] div') expect(callout.html()).toBe('

Callout for HubGit Pages

') }) @@ -15,19 +16,21 @@ describe('permission statements', () => { // an empty string. // This test tests that alert is not rendered if its output // "exits" but is empty. - const $ = await getDOM('/enterprise-server@latest/get-started/foo/page-with-callout') + const $: cheerio.Root = await getDOM( + '/enterprise-server@latest/get-started/foo/page-with-callout', + ) const callout = $('[data-testid=product-statement]') expect(callout.length).toBe(0) }) test('toc landing page', async () => { - const $ = await getDOM('/actions/category') + const $: cheerio.Root = await getDOM('/actions/category') const callout = $('[data-testid=product-statement] div') expect(callout.html()).toBe('

This is the callout text

') }) test('page with permission frontmatter', async () => { - const $ = await getDOM('/get-started/markdown/permissions') + const $: cheerio.Root = await getDOM('/get-started/markdown/permissions') const html = $('[data-testid=permissions-statement] div').html() // Markdown expect(html).toMatch('admin') @@ -36,7 +39,9 @@ describe('permission statements', () => { }) test('page with permission frontmatter and product statement', async () => { - const $ = await getDOM('/get-started/foo/page-with-permissions-and-product-callout') + const $: cheerio.Root = await getDOM( + '/get-started/foo/page-with-permissions-and-product-callout', + ) const html = $('[data-testid=permissions-callout] div').html() // part of the UI expect(html).toMatch('Who can use this feature') diff --git a/src/fixtures/tests/sidebar.js b/src/fixtures/tests/sidebar.ts similarity index 75% rename from src/fixtures/tests/sidebar.js rename to src/fixtures/tests/sidebar.ts index a26e053b5bf0..727898f9db3e 100644 --- a/src/fixtures/tests/sidebar.js +++ b/src/fixtures/tests/sidebar.ts @@ -1,10 +1,11 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOMCached as getDOM } from '@/tests/helpers/e2etest' describe('sidebar', () => { test('top level product mentioned at top of sidebar', async () => { - const $ = await getDOM('/get-started') + const $: cheerio.Root = await getDOM('/get-started') // Desktop const sidebarProduct = $('[data-testid="sidebar-product-xl"]') expect(sidebarProduct.text()).toBe('Get started') @@ -15,12 +16,12 @@ describe('sidebar', () => { }) test('REST pages get the REST sidebar', async () => { - const $ = await getDOM('/rest') + const $: cheerio.Root = await getDOM('/rest') expect($('[data-testid=rest-sidebar-reference]').length).toBe(1) }) test('leaf-node article marked as aria-current=page', async () => { - const $ = await getDOM('/get-started/start-your-journey/hello-world') + const $: cheerio.Root = await getDOM('/get-started/start-your-journey/hello-world') expect( $( '[data-testid=sidebar] [data-testid=product-sidebar] a[aria-current="page"] div span', @@ -29,7 +30,7 @@ describe('sidebar', () => { }) test('sidebar should always use the shortTitle', async () => { - const $ = await getDOM('/get-started/foo/bar') + const $: cheerio.Root = await getDOM('/get-started/foo/bar') // The page /get-started/foo/bar has a short title that is different // from its regular title. expect( @@ -40,7 +41,7 @@ describe('sidebar', () => { }) test('short titles with Liquid and HTML characters', async () => { - const $ = await getDOM('/get-started/foo/html-short-title') + const $: cheerio.Root = await getDOM('/get-started/foo/html-short-title') const link = $( '[data-testid=sidebar] [data-testid=product-sidebar] a[href*="/get-started/foo/html-short-title"]', ) @@ -50,26 +51,26 @@ describe('sidebar', () => { test('Liquid is rendered in short title used at top of sidebar', async () => { // Free, pro, team { - const $ = await getDOM('/pages') + const $: cheerio.Root = await getDOM('/pages') const link = $('#allproducts-menu a') expect(link.text()).toBe('Pages (HubGit)') } // Enterprise Server { - const $ = await getDOM('/enterprise-server@latest/pages') + const $: cheerio.Root = await getDOM('/enterprise-server@latest/pages') const link = $('#allproducts-menu a') expect(link.text()).toBe('Pages (HubGit Enterprise Server)') } // Enterprise Cloud { - const $ = await getDOM('/enterprise-cloud@latest/pages') + const $: cheerio.Root = await getDOM('/enterprise-cloud@latest/pages') const link = $('#allproducts-menu a') expect(link.text()).toBe('Pages (HubGit Enterprise Cloud)') } }) test('no docset link for early-access', async () => { - const $ = await getDOM('/early-access/secrets/deeper/mariana-trench') + const $: cheerio.Root = await getDOM('/early-access/secrets/deeper/mariana-trench') // Deskop expect($('[data-testid="sidebar-product-xl"]').length).toBe(0) // Mobile diff --git a/src/fixtures/tests/translations.js b/src/fixtures/tests/translations.ts similarity index 62% rename from src/fixtures/tests/translations.js rename to src/fixtures/tests/translations.ts index a32b50954201..2fc631089f59 100644 --- a/src/fixtures/tests/translations.js +++ b/src/fixtures/tests/translations.ts @@ -1,7 +1,8 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { TRANSLATIONS_FIXTURE_ROOT } from '#src/frame/lib/constants.js' -import { getDOM, head } from '#src/tests/helpers/e2etest.js' +import { TRANSLATIONS_FIXTURE_ROOT } from '@/frame/lib/constants' +import { getDOM, head } from '@/tests/helpers/e2etest' if (!TRANSLATIONS_FIXTURE_ROOT) { let msg = 'You have to set TRANSLATIONS_FIXTURE_ROOT to run this test.' @@ -11,40 +12,51 @@ if (!TRANSLATIONS_FIXTURE_ROOT) { describe('translations', () => { test('home page', async () => { - const $ = await getDOM('/ja') + const $: cheerio.Root = await getDOM('/ja') const h1 = $('h1').text() // You gotta know your src/fixtures/fixtures/translations/ja-jp/data/ui.yml expect(h1).toBe('日本 GitHub Docs') const links = $('[data-testid=product] a[href]') const hrefs = links - .filter((i, link) => $(link).attr('href').startsWith('/')) - .map((i, link) => $(link)) + .filter((i: number, link: any) => { + const href = $(link).attr('href') + return href !== undefined && href.startsWith('/') + }) + .map((i: number, link: any) => $(link)) .get() - const linkTexts = Object.fromEntries(hrefs.map(($link) => [$link.attr('href'), $link.text()])) + const linkTexts = Object.fromEntries( + hrefs.map(($link: any) => [$link.attr('href'), $link.text()]), + ) expect(linkTexts['/ja/get-started']).toBe('はじめに') }) test('hello world', async () => { - const $ = await getDOM('/ja/get-started/start-your-journey/hello-world') + const $: cheerio.Root = await getDOM('/ja/get-started/start-your-journey/hello-world') const h1 = $('h1').text() expect(h1).toBe('こんにちは World') }) test('internal links get prefixed with /ja', async () => { - const $ = await getDOM('/ja/get-started/start-your-journey/link-rewriting') + const $: cheerio.Root = await getDOM('/ja/get-started/start-your-journey/link-rewriting') const links = $('#article-contents a[href]') - const jaLinks = links.filter((i, element) => $(element).attr('href').startsWith('/ja')) - const enLinks = links.filter((i, element) => $(element).attr('href').startsWith('/en')) + const jaLinks = links.filter((i: number, element: any) => { + const href = $(element).attr('href') + return href !== undefined && href.startsWith('/ja') + }) + const enLinks = links.filter((i: number, element: any) => { + const href = $(element).attr('href') + return href !== undefined && href.startsWith('/en') + }) expect(jaLinks.length).toBe(2) expect(enLinks.length).toBe(0) }) test('internal links with AUTOTITLE resolves', async () => { - const $ = await getDOM('/ja/get-started/foo/autotitling') + const $: cheerio.Root = await getDOM('/ja/get-started/foo/autotitling') const links = $('#article-contents a[href]') - links.each((i, element) => { - if ($(element).attr('href').includes('/ja/get-started/start-your-journey/hello-world')) { + links.each((i: number, element: any) => { + if ($(element).attr('href')?.includes('/ja/get-started/start-your-journey/hello-world')) { expect($(element).text()).toBe('こんにちは World') } }) @@ -55,26 +67,28 @@ describe('translations', () => { test('correction of linebreaks in translations', async () => { // free-pro-team { - const $ = await getDOM('/ja/get-started/foo/table-with-ifversions') + const $: cheerio.Root = await getDOM('/ja/get-started/foo/table-with-ifversions') const paragraph = $('#article-contents p').text() expect(paragraph).toMatch('mention of HubGit in Liquid') const tds = $('#article-contents td') - .map((i, element) => $(element).text()) + .map((i: number, element: any) => $(element).text()) .get() expect(tds.length).toBe(2) expect(tds[1]).toBe('Not') } // enterprise-server { - const $ = await getDOM('/ja/enterprise-server@latest/get-started/foo/table-with-ifversions') + const $: cheerio.Root = await getDOM( + '/ja/enterprise-server@latest/get-started/foo/table-with-ifversions', + ) const paragraph = $('#article-contents p').text() expect(paragraph).toMatch('mention of HubGit Enterprise Server in Liquid') const tds = $('#article-contents td') - .map((i, element) => $(element).text()) + .map((i: number, element: any) => $(element).text()) .get() expect(tds.length).toBe(2) expect(tds[1]).toBe('Present') @@ -82,9 +96,9 @@ describe('translations', () => { }) test('automatic correction of bad AUTOTITLE in reusables', async () => { - const $ = await getDOM('/ja/get-started/start-your-journey/hello-world') + const $: cheerio.Root = await getDOM('/ja/get-started/start-your-journey/hello-world') const links = $('#article-contents a[href]') - const texts = links.map((i, element) => $(element).text()).get() + const texts = links.map((i: number, element: any) => $(element).text()).get() // That Japanese page uses AUTOTITLE links. Both in the main `.md` file // but also inside a reusable. // E.g. `["AUTOTITLE](/get-started/start-your-journey/hello-world)."` @@ -100,7 +114,7 @@ describe('translations', () => { // Markdown. It would not be let into `main` by our CI checks. But // by their nature, translations are not checked by CI in the same way. // Its "flaws" have to be corrected at runtime. - const stillAutotitle = texts.filter((text) => /autotitle/i.test(text)) + const stillAutotitle = texts.filter((text: string) => /autotitle/i.test(text)) expect(stillAutotitle.length).toBe(0) }) @@ -112,13 +126,20 @@ describe('translations', () => { // which needs to become: // // [Bar](バー) - const $ = await getDOM('/ja/get-started/start-your-journey/hello-world') + const $: cheerio.Root = await getDOM('/ja/get-started/start-your-journey/hello-world') const links = $('#article-contents a[href]') const texts = links - .filter((i, element) => $(element).attr('href').includes('get-started/foo/bar')) - .map((i, element) => $(element).text()) + .filter((i: number, element: any) => { + const href = $(element).attr('href') + return href !== undefined && href.includes('get-started/foo/bar') + }) + .map((i: number, element: any) => $(element).text()) .get() - expect(texts.includes('[Bar] (バー)')).toBeTruthy() + // Check that the text contains the essential parts rather than exact spacing + const foundBarLink = texts.find( + (text: string) => text.includes('[Bar]') && text.includes('(バー)'), + ) + expect(foundBarLink).toBeDefined() }) describe('localized category versioning', () => { diff --git a/src/fixtures/tests/versioning.js b/src/fixtures/tests/versioning.ts similarity index 86% rename from src/fixtures/tests/versioning.js rename to src/fixtures/tests/versioning.ts index 8543d987fbef..2665fcc2e682 100644 --- a/src/fixtures/tests/versioning.js +++ b/src/fixtures/tests/versioning.ts @@ -1,11 +1,12 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM, head } from '#src/tests/helpers/e2etest.js' -import { supported } from '#src/versions/lib/enterprise-server-releases.js' +import { getDOM, head } from '@/tests/helpers/e2etest' +import { supported } from '@/versions/lib/enterprise-server-releases' describe('article versioning', () => { test('only links to articles for fpt', async () => { - const $ = await getDOM('/get-started/versioning') + const $: cheerio.Root = await getDOM('/get-started/versioning') const links = $('[data-testid="table-of-contents"] a') // Only 1 link because there's only 1 article available in fpt expect(links.length).toBe(1) @@ -13,18 +14,18 @@ describe('article versioning', () => { }) test('only links to articles for ghec', async () => { - const $ = await getDOM('/enterprise-cloud@latest/get-started/versioning') + const $: cheerio.Root = await getDOM('/enterprise-cloud@latest/get-started/versioning') const links = $('[data-testid="table-of-contents"] a') expect(links.length).toBe(2) - const first = links.filter((i) => i === 0) - const second = links.filter((i) => i === 1) + const first = links.filter((i: number) => i === 0) + const second = links.filter((i: number) => i === 1) expect(first.attr('href')).toBe('/en/enterprise-cloud@latest/get-started/versioning/only-ghec') expect(second.attr('href')).toBe( '/en/enterprise-cloud@latest/get-started/versioning/only-ghec-and-ghes', ) // Both links should 200 if you go to them - expect((await head(first.attr('href'))).statusCode).toBe(200) - expect((await head(second.attr('href'))).statusCode).toBe(200) + expect((await head(first.attr('href')!)).statusCode).toBe(200) + expect((await head(second.attr('href')!)).statusCode).toBe(200) }) test('wrong version prefix for a non-fpt article will 404', async () => { diff --git a/src/fixtures/tests/video-transcripts.js b/src/fixtures/tests/video-transcripts.ts similarity index 67% rename from src/fixtures/tests/video-transcripts.js rename to src/fixtures/tests/video-transcripts.ts index 7a9bd01d42cf..cb3f6f7c2ec6 100644 --- a/src/fixtures/tests/video-transcripts.js +++ b/src/fixtures/tests/video-transcripts.ts @@ -1,11 +1,12 @@ import { describe, expect, test } from 'vitest' +import cheerio from 'cheerio' -import { getDOM } from '#src/tests/helpers/e2etest.js' +import { getDOM } from '@/tests/helpers/e2etest' describe('transcripts', () => { describe('product landing page', () => { test('video link from product landing page leads to video', async () => { - const $ = await getDOM('/en/get-started') + const $: cheerio.Root = await getDOM('/en/get-started') expect($('a#product-video').attr('href')).toBe( '/en/get-started/video-transcripts/transcript--my-awesome-video', ) @@ -14,7 +15,9 @@ describe('transcripts', () => { describe('transcript page', () => { test('video link from transcript leads to video', async () => { - const $ = await getDOM('/en/get-started/video-transcripts/transcript--my-awesome-video') + const $: cheerio.Root = await getDOM( + '/en/get-started/video-transcripts/transcript--my-awesome-video', + ) expect($('a#product-video').attr('href')).toBe('https://www.yourube.com/abc123') }) }) diff --git a/src/ghes-releases/lib/release-templates/release-steps-0.md b/src/ghes-releases/lib/release-templates/release-steps-0.md index 82032ea01490..017c2ead2a2f 100644 --- a/src/ghes-releases/lib/release-templates/release-steps-0.md +++ b/src/ghes-releases/lib/release-templates/release-steps-0.md @@ -27,47 +27,78 @@ This issue tracks Docs work for the GA release of GHES {{ release-number }}. ## Instructions for triage -- [ ] Add this issue to the [Rhythm of Docs: Operations](https://github.com/orgs/github/projects/20190) project. -- [ ] For assignee: if needed, add this issue to your persona team project for tracking purposes. +* [ ] Add this issue to the [Rhythm of Docs: Operations](https://github.com/orgs/github/projects/20190) project. +* [ ] For assignee: if needed, add this issue to your persona team project for tracking purposes.
# Tasks -- [ ] {{ release-steps-1-url }} -- [ ] {{ release-steps-2-url }} -- [ ] {{ release-steps-3-url }} -- [ ] {{ release-steps-4-url }} -- [ ] {{ release-steps-5-url }} -- [ ] **Friday before the release**, notify the Docs Content first responders to not merge OpenAPI PRs until further notice. -- [ ] **On the RC date**, optionally sync the search indices again (details in [previous step]({{ release-steps-1-url }}). -- [ ] **On the RC date**, merge PR for RC when instructed by the GHES Releases team. -- [ ] After merging PR for RC, notify the API team in [#ecosystem-api](https://github.slack.com/archives/C1042T6MS) on Slack that they can now merge "Update OpenAPI 3.x Descriptions" PRs in [`github/rest-api-description`](https://github.com/github/rest-api-description/pulls), which you blocked as part of the issue for preparing OpenAPI assets. -- [ ] Notify the Docs Content first responder (`@TBD`) that they can now merge OpenAPI PRs. -- [ ] To close this issue, open a PR to complete [these steps](https://github.com/github/docs-content/issues/12972#issuecomment-1947981671). +* [ ] {{ release-steps-1-url }} +* [ ] {{ release-steps-2-url }} +* [ ] {{ release-steps-3-url }} +* [ ] {{ release-steps-4-url }} +* [ ] {{ release-steps-5-url }} +* [ ] **Friday before the release**, notify the Docs Content first responder to not merge OpenAPI PRs until further notice. +* [ ] **On the RC date**, optionally scrape the search indices again (details in [previous step]({{ release-steps-1-url }}). +* [ ] **On the RC date**, to [publish the RC, complete these tasks](https://github.com/github/docs-content/blob/main/focus-areas/enterprise/processes/publishing-ghes-feature-release-docs.md#publish-release-candidate). +* [ ] To close this issue, open a PR to complete [these GA tasks](https://github.com/github/docs-content/blob/main/focus-areas/enterprise/processes/publishing-ghes-feature-release-docs.md#ga-tasks). + +## Daily tasks + +Complete these tasks every day, up to the release of the release candidate. + +* Maintain the megabranch by keeping it up to date with `main`, and fixing check failures +* Monitor the `#ghes-3-1x-release` Slack channel for late-breaking changes +* Monitor the `#tmp-docs-ghes-3-1x` Slack channel for questions and updates + + +## Key deadlines + +Optionally, use and update the following table to keep track of key deadlines. + +
+ +| Date | Task | Steps | Done? ✅ | +| ---- | ---- | ---- | ----- | +| By **3 weeks before RC** | Create the release megabranch | [Steps]({{ release-steps-1-url }}) | | +| By **3 weeks before RC** | Create a `tmp-docs-ghes-{{ release-number }}` Slack channel for docs and the GHES release team to communicate | [Example](https://github-grid.enterprise.slack.com/archives/C08T0NM9XAB) | | +| By **2 weeks before RC** | Ensure there's an OpenAPI configuration for the release in `github/github`, and create and merge a PR to update `release_api_versioning_support.yaml`. | [Steps]({{ release-steps-5-url }}) | | +| By **2 weeks before RC** | Create, but don't yet merge, a `github/github` PR to publish the {{ release-number }} API schema | [Steps]({{ release-steps-5-url }}) | | +| By **1 week before RC on {{ release-rc-target-date-minus-7 }}** | Ensure work in the PR with the release notes is complete, request reviews for release notes, and ask GHES PM to confirm the list of [known issues](https://github.com/orgs/github/projects/7908/views/15) for the release | [Steps]({{ release-steps-2-url }}) | | +| On **Friday before the RC** | Merge the `github/github` PR to publish the {{ release-number }} API schema, and notify `#eco-system-api` | [Steps]({{ release-steps-5-url }}) | | +| On **Friday before the RC** | Notify docs first responder not to merge OpenAPI update PRs | In task list below | | +| On **Thursday before the RC** | Merge OpenAPI data into the release [megabranch]({{ release-steps-1-url }}) | [Steps]({{ release-steps-5-url }}) | | +| By **the day before the RC on {{ release-rc-target-date-minus-1 }}** | Ensure checks are passing and all assets are in the megabranch, including release notes, docs for the corresponding release work, and work for the [CodeQL]({{ release-steps-3-url }}) and [Actions Runner]({{ release-steps-4-url }}) issues in the task list below | Steps
* [CodeQL]({{ release-steps-3-url }}
* [Actions Runner]({{ release-steps-4-url }}
| | +| On **{{ release-rc-target-date }}** | When requested, merge the megabranch PR to publish docs for the release candidate | | | +| By **1 week before the GA** | Create a PR to GA the {{ release-number }} docs | [Steps]({{ release-steps-0-url }}) | | +| On **{{ release-target-date }}** | When requested, merge the PR to GA the {{ release-number }} docs | [Steps]({{ release-steps-0-url }}) | | + +
## Resources -- People - - Docs - - DRI: `TBD` - - Engineering support: `TBD` - - GHES - - PM: `TBD` - - Releases PM: `TBD` - - Releases TPM and Release Manager: `TBD` - - Engineering DRI: `@{{ release-prp }}` -- Videos - - `TBD` -- Slides - - `TBD` -- Docs - - [Creating a GitHub Enterprise Server instance](https://github.com/github/docs-team/blob/main/contributing-to-docs/creating-a-github-enterprise-server-instance.md) in `github/docs-team` - - [Internal builds](https://github.com/github/docs-team/blob/main/contributing-to-docs/creating-a-github-enterprise-server-instance.md#internal-builds), for testing pre-release RC builds -- Slack - - [#docs-content-enterprise](https://github.slack.com/archives/C02FQKNEN69) - - [#ghes-3-14-release](`TBD`) - - [#ghes-releases](https://github-grid.enterprise.slack.com/archives/C0FN5LSLR) - - [#ghes-product](https://github.slack.com/archives/C02FE7F994N) +* People + * Docs + * DRI: `TBD` + * Engineering support: `TBD` + * GHES + * PM: `TBD` + * Releases PM: `TBD` + * Releases TPM and Release Manager: `TBD` + * Engineering DRI: `@{{ release-prp }}` +* Videos + * `TBD` +* Slides + * `TBD` +* Docs + * [Creating a GitHub Enterprise Server instance](https://github.com/github/docs-team/blob/main/contributing-to-docs/docs-work/creating-a-github-enterprise-server-instance.md) in `github/docs-team` + * [Internal builds](https://github.com/github/docs-team/blob/main/contributing-to-docs/docs-work/creating-a-github-enterprise-server-instance.md#internal-builds), for testing pre-release RC builds +* Slack + * #tmp-docs-ghes-3-1x + * [#docs-driver-persona](https://github-grid.enterprise.slack.com/archives/C07KVNQ6AVA) + * #ghes-3-1x-release + * [#ghes-releases](https://github-grid.enterprise.slack.com/archives/C0FN5LSLR) + * [#ghes](https://github-grid.enterprise.slack.com/archives/C02BJ3URF1S) and [#ghes-product](https://github.slack.com/archives/C02FE7F994N) \ No newline at end of file +--> diff --git a/src/ghes-releases/lib/release-templates/release-steps-3.md b/src/ghes-releases/lib/release-templates/release-steps-3.md index 030b0d2c60f8..ec5b134553c0 100644 --- a/src/ghes-releases/lib/release-templates/release-steps-3.md +++ b/src/ghes-releases/lib/release-templates/release-steps-3.md @@ -1,6 +1,6 @@ --- title: CodeQL CLI latest supported version for GHES {{ release-number }} -labels: +labels: - CodeQL - new-release - priority-0 @@ -8,26 +8,22 @@ labels: - workflow-generated --- -Docs Content will publish docs for the GHES {{ release-number }} RC soon. Please draft a release note for the latest supported version of the CodeQL CLI, and update the docs to reflect the latest supported version. +Docs Content will publish docs for the GHES {{ release-number }} RC soon, and we need to update the [CodeQL CLI latest supported version](https://github.com/github/docs-content/blob/main/focus-areas/enterprise/processes/publishing-ghes-feature-release-docs.md#codeql-cli). -```[tasklist] -### Draft a release note -- [ ] Draft a consolidated release note that summarizes the most important updates to the CodeQL CLI since the supported version for the previous GHES release. See the [docs style guide section for release notes](https://docs.github.com/en/contributing/style-guide-and-content-model/style-guide#features). -- [ ] Add the draft as a comment in this issue, and ping the `@github/docs-content-enterprise` team for review. -``` +### The CodeQL team will draft a release note +* [ ] Draft a consolidated release note that summarizes the most important updates to the CodeQL CLI since the supported version for the previous GHES release. See the [docs style guide section for release notes](https://docs.github.com/en/contributing/style-guide-and-content-model/style-guide#features). +* [ ] Add the draft as a comment in this issue, and ping the `@github/docs-content-enterprise` team for review. -```[tasklist] -### Update the docs -- [ ] In a PR in github/docs-internal, add the latest supported CodeQL CLI version to the `codeql_cli_ghes_recommended_version` variable in [`product.yml`](https://github.com/github/docs-internal/blob/main/data/variables/product.yml) -- [ ] In the same PR, add the latest supported CodeQL CLI version to the [table in the "GitHub Enterprise Server releases" article](https://github.com/github/docs-internal/blob/main/content/admin/all-releases.md?plain=1#L53). -``` +### The Docs team will update the docs +* [ ] In a PR in github/docs-internal, add the latest supported CodeQL CLI version to the `codeql_cli_ghes_recommended_version` variable in [`product.yml`](https://github.com/github/docs-internal/blob/main/data/variables/product.yml) +* [ ] In the same PR, add the latest supported CodeQL CLI version to the [table in the "GitHub Enterprise Server releases" article](https://github.com/github/docs-internal/blob/main/content/admin/all-releases.md?plain=1#L53). | Field | Value | | ----- | ----- | | Target date | {{ release-target-date }} | | Release issue | [link][release-issue] | -**Note**: We publish docs for each GHES release when the RC ships. The target date reflects a few days prior to the GHES 3.13 RC's release date, while the release issue reflects the GA's release date. +**Note**: We publish docs for each GHES release when the RC ships. The target date reflects a few days prior to the GHES {{ release-number }} RC's release date, while the release issue reflects the GA's release date. \ No newline at end of file +--> diff --git a/src/ghes-releases/lib/release-templates/release-steps-4.md b/src/ghes-releases/lib/release-templates/release-steps-4.md index 5787979098ee..64019764fff4 100644 --- a/src/ghes-releases/lib/release-templates/release-steps-4.md +++ b/src/ghes-releases/lib/release-templates/release-steps-4.md @@ -7,30 +7,20 @@ labels: - workflow-generated --- -Docs Content will publish docs for the GHES {{ release-number }} RC soon. Please update the docs to reflect the minimum required version of the Actions Runner application for the new release. +Docs Content will publish docs for the GHES {{ release-number }} RC soon. Please update the docs to reflect the [minimum required version of the Actions Runner application](https://github.com/github/docs-content/blob/main/focus-areas/enterprise/processes/publishing-ghes-feature-release-docs.md#actions-runner) for the new release. | Field | Value | | ----- | ----- | | Target date | {{ release-target-date }} | | Release issue | [link][release-issue] | -**Note**: We publish docs for each GHES release when the RC ships. The target date reflects a few days prior to the GHES 3.13 RC's release date, while the release issue reflects the GA's release date. +**Note**: We publish docs for each GHES release when the RC ships. The target date reflects a few days prior to the GHES {{ release-number }} RC's release date, while the release issue reflects the GA's release date. -```[tasklist] -### Tasks -- [ ] Find the minimum required Actions Runner version for the upcoming GHES release (see below for help). -- [ ] Create a PR against the release candidate publication branch in github/docs-internal to add the version to the [table in the "GitHub Enterprise Server releases" article](https://github.com/github/docs-internal/blob/main/content/admin/all-releases.md?plain=1#L66). -- [ ] In the same PR, add the version to the [`runner_required_version` variable](https://github.com/github/docs-internal/blob/main/data/variables/product.yml#L140) in product.yml. -- [ ] Once the release notes file for the release has been generated (see https://github.com/github/docs-content/issues/14225), confirm that the {% raw %}`{% data reusables.actions.actions-runner-release-note %}`{% endraw %} reusable is present in the release notes. -``` - -### Finding the required Actions Runner version for a release - -To find the required version of the Runner app for a GHES release, navigate to `https://github.com/github/ghes-actions/blob/enterprise-X.Y-release/config/runners/runners.json`, replacing `X.Y` with a release number such as `{{ release-number }}`. - -You can find the minimum required version for the release in the `version` field of any object in the array. - -The `runners.json` file is generally available with plenty of time before a release. If you can't find a file at that location, ask in the `#actions` channel on Slack. +# Tasks +* [ ] Find the minimum required Actions Runner version for the upcoming GHES release (see below for help). +* [ ] Create a PR against the release candidate publication branch in github/docs-internal to add the version to the [table in the "GitHub Enterprise Server releases" article](https://github.com/github/docs-internal/blob/main/content/admin/all-releases.md?plain=1#L66). +* [ ] In the same PR, add the version to the [`runner_required_version` variable](https://github.com/github/docs-internal/blob/main/data/variables/product.yml#L140) in product.yml. +* [ ] Once the release notes file for the release has been generated, confirm that the {% raw %}`{% data reusables.actions.actions-runner-release-note %}`{% endraw %} reusable is present in the release notes. \ No newline at end of file +--> diff --git a/src/ghes-releases/lib/release-templates/release-steps-5.md b/src/ghes-releases/lib/release-templates/release-steps-5.md index 6b491e575a39..0e1eb7acb1ff 100644 --- a/src/ghes-releases/lib/release-templates/release-steps-5.md +++ b/src/ghes-releases/lib/release-templates/release-steps-5.md @@ -12,162 +12,14 @@ labels: ## Instructions for triage -- [ ] Add this issue to the [Rhythm of Docs: Operations](https://github.com/orgs/github/projects/20190) project. -- [ ] For assignee: if needed, add this issue to your persona team project for tracking purposes. +* [ ] Add this issue to the [Rhythm of Docs: Operations](https://github.com/orgs/github/projects/20190) project. +* [ ] For assignee: if needed, add this issue to your persona team project for tracking purposes. -## Instructions for assignee +## Tasks -To incorporate updates to our REST API and webhook documentation into the publication branch you created for {{ release-steps-1-url }}, you must prepare a release configuration in `github/github`, prepare the new assets for publication, coordinate the generation of the new OpenAPI content, then merge the content into your publication branch. +To incorporate updates to our REST API and webhook documentation into the publication branch you created for {{ release-steps-1-url }}, you must prepare a release configuration in `github/github`, prepare the new assets for publication, coordinate the generation of the new OpenAPI content, then merge the content into your publication branch as described in [Prepare OpenAPI assets for release candidate](https://github.com/github/docs-content/blob/main/focus-areas/enterprise/processes/publishing-ghes-feature-release-docs.md#5-prepare-openapi-assets-for-release-candidate). -- [Prepare OpenAPI release configuration](#release-configuration-preparation) -- [Prepare PR to publish release](#publication-preparation) -- [Merge OpenAPI changes into publication branch](#merge) 🗓️ **Thursday before release** -- [Complete preparation for the RC and publish the docset](#publication) - -
- - -### [🚀](#release-configuration-preparation) Prepare OpenAPI release configuration - -For each GHES release, there's a corresponding OpenAPI configuration. Ensure it's present. The [API team](https://github.com/github/ecosystem-api) often completes these steps before we prepare for a GHES RC, so some of this work may already be complete. - -- [ ] In `github/github`, within [`app/api/description/config/releases`](https://github.com/github/github/tree/master/app/api/description/config/releases), check for a `ghes-VERSION.yaml` file, where VERSION is the version we're releasing. (**Note**: These steps were already done when I created this tracking issue.) - - - **If the file exists**, validate its contents. - - - [ ] `published` should be set to `false`. - - - [ ] Any references to a GHES version should reflect the version we're releasing. - - - [ ] Beneath `path: "/info/x-github-api-versions"`, the `value` should be the API's calendar date version for the prior release of GHES from [`release_api_versioning_support.yaml`](https://github.com/github/github/blob/master/app/api/description/config/release_api_versioning_support.yaml). - - - **If the file doesn't exist**, prepare a PR. - - - [ ] Within a codespace in `github/github`, from `master`, create a new branch named `ghes-VERSION-rc/add-release-configuration`. For example, `ghes-3.10-rc/add-release-configuration`. - - - [ ] To copy an existing release configuration into place, run the following command, replacing LATEST-VERSION with the last version we released, and VERSION-TO-RELEASE with the version we're releasing. - - ```shell - cp app/api/description/config/releases/ghes-LATEST-VERSION.yaml app/api/description/config/releases/ghes-VERSION-TO-RELEASE.yaml - ``` - - - [ ] Edit the `app/api/description/config/releases/ghes-VERSION-TO-RELEASE.yaml` file that you created. - - - [ ] Set `published` to `false`. - - - [ ] Find and replace any occurrences of the prior version with the version that we're releasing. At the time of writing, the following four keys include values that reference the version number. - - - `variables.externalDocsUrl` - - - `variables.ghesVersion` - - - Two keys under `patch` for the paths `/info/x-github-release` and `/externalDocs` - -- [ ] Edit [`app/api/description/config/release_api_versioning_support.yaml`](https://github.com/github/github/blob/master/app/api/description/config/release_api_versioning_support.yaml). - - - [ ] Copy the line for the previous release of GHES and the API's calendar-date version on the row beneath it. - - - [ ] Paste the line beneath the previous version and its API version, and edit the line to reflect the version we're releasing. - -- [ ] Create a PR targeting `master` with the changes in your topic branch. - -- [ ] Get the necessary reviews, then deploy and merge the PR. - -
-
- -### [🆕](#publication-preparation) Prepare PR to publish release - -To prepare for publication, create a PR in `github/github` that publishes the schema for the release. - -- [ ] In `github/github`, edit `app/api/description/config/releases/ghes-VERSION-TO-RELEASE.yaml`, where VERSION-TO-RELEASE is the version we're releasing. - -- [ ] Set `published` to `true`. - -- [ ] Create a PR. - -- [ ] Get the necessary reviews, but **do not deploy and merge the PR yet**. You'll merge this PR closer to the RC's release date. - -
-
- -### [👯](#merge) Integrate OpenAPI changes into publication branch - -To trigger creation of an OpenAPI PR with the updated schema for the RC, merge your publication PR in `github/github`. - -- [ ] 2-3 days before the RC release date, merge the publication PR you [prepared in `github/github`](#publication-preparation). - -- [ ] In [#api-platform](https://github.slack.com/archives/C1042T6MS) on Slack, update and then post the following message to notify the team of the upcoming release. Replace VERSION with the version we're releasing. - - > 👋 Hi from Docs! We have just marked `published` for the GHES VERSION release configuration to `true`. Please **do not** merge subsequent "Update OpenAPI 3.x Descriptions" PRs [in github/rest-api-description](https://github.com/github/rest-api-description/pulls) until further notice. Thanks! - -- [ ] Locate the latest "Update OpenAPI 3.x Descriptions" PRs [in `github/rest-api-description`](https://github.com/github/rest-api-description/pulls). - -- [ ] On each new PR, leave a review that requests changes with the following comment. - - > This PR contains changes for the upcoming GHES RC. Please do not merge this or subsequent PRs until further notice in #ecosystem-api. Thanks! - -- [ ] From now until the RC ships, all [existing "Update OpenAPI Description" PRs](https://github.com/github/docs-internal/labels/github-openapi-bot) in `github/docs-internal` can be closed. - -To get the latest changes from the latest "Update OpenAPI 3.x Descriptions" PR in the `github/rest-api-description` repository into your PR to close {{ release-steps-1-url }}, you can use one of two methods. - -The benefit of the first method is that you don't need to deal with merging two PRs together, you can just make a new commit directly to the GHES release branch with the updated OpenAPI data. If you aren't as comfortable in the terminal, the second method is best. - -#### Method 1: Generation of new data locally - -- [ ] In a local clone of the `github/docs-internal` repository, clone `github/rest-api-description`. -- [ ] Ensure that your local clone of `github/docs-internal` contains a `rest-api-description` directory with the contents of the `github/rest-api-description` repository. -- [ ] In the [list of PRs for `github/rest-api-description`](https://github.com/github/rest-api-description/pulls), find the latest "Update OpenAPI 3.1 Descriptions" PR. Note the name of the PR's topic branch. -- [ ] In your local clone of `github/docs-internal`, move into the `rest-api-description` directory, then check out the branch from the previous step. Replace NAME-OF-REST-API-DESCRIPTION-BRANCH with the name of the branch. - - ```shell - cd rest-api-description - git checkout NAME-OF-REST-API-DESCRIPTION-BRANCH - ``` - -- [ ] Move back into the directory with your clone of `github/docs-internal`. -- [ ] Check out the topic branch for the GHES RC. For example, if the branch is `ghes-3.13-rc`, replace NAME-OF-PUBLICATION-BRANCH with ghes-3.13-rc. - - ```shell - git checkout NAME-OF-PUBLICATION-BRANCH - ``` - -- [ ] To ensure the checks pass with the incoming OpenAPI data in isolation from the publication branch, create a new branch. Replace NAME-OF-BRANCH with a name that reflects the change. For example, if you're preparing for GHES 3.13, replace NAME-OF-BRANCH with ghes-3.13-openapi. -- [ ] To update the OpenAPI data, run the following command. - - ```shell - npm run sync-rest -- --source-repo rest-api-description --output rest github-apps webhooks rest-redirects - ``` - - You may see an error that indicates that "...you must have the GITHUB_TOKEN environment variable set to access the programmatic access and resource files via the GitHub REST API." You can ignore this error. -- [ ] Add and commit the modified files. - - ```shell - git add . - git commit -m "Add generated OpenAPI files" - ``` - -- [ ] Push your changes. -- [ ] To run the tests and check the data, create a PR for the new branch. During creation of the PR, set the base branch to the publication branch for the RC. -- [ ] Wait for the checks to run in the new PR. -- [ ] After the checks pass, merge the PR. If you need assistance, request support from Docs Engineering. - -#### Method 2: Generate automated OpenAPI PR in `github/docs-internal` - -- [ ] In the `github/docs-internal` repository, navigate to the [Sync OpenAPI schema](https://github.com/github/docs-internal/actions/workflows/sync-openapi.yml) workflow. -- [ ] To run the workflow, click "Run workflow". -- [ ] Under "Use workflow from," select the branch that contains the new GHES release. This will base the new PR on the GHES release branch and will generate the OpenAPI data for the new GHES release. -- [ ] Under **Branch to pull the dereferenced OpenAPI source files from in the github/rest-api-descriptions repo**, select the branch name of the data you want to consume in `github/rest-api-description`. If the branch in `github/rest-api-description` is not yet merged, select the branch name of the PR in `github/rest-api-description` that contains the new GHES release schema. If the PR that was opened in `github/rest-api-description` was merged to main, leave the second option set to `main`. -- [ ] Click the green "Run workflow" button. -- [ ] Wait for the workflow to finish. It will automatically open a new ["Update OpenAPI Description" PR](https://github.com/github/docs-internal/labels/github-openapi-bot). The workflow output log will include a PR number. -- [ ] In the new PR with OpenAPI changes, change the base branch of the PR from `main` to the branch of the to the publication branch you created for https://github.com/github/docs-content/issues/14225. -- [ ] Link the PR to this issue. For more information, see [Linking a pull request to an issue](https://docs.github.com/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#manually-linking-a-pull-request-to-an-issue-using-the-pull-request-sidebar). -- [ ] In the "Update OpenAPI Description" PR, ensure that there are no merge conflicts and that checks pass, paying particular attention to links that were broken due to missing OpenAPI-related content. -- [ ] Merge "Update OpenAPI Description" PR into your publication PR.. **Note:** Don't attempt to resolve conflicts for changes to the `src/rest/data` files. Only accept the incoming files. If you do see conflicts in the `src/rest/data`, `src/webhooks/data`, or `src/github-apps/data` directories, you can checkout the files for those directories that exist in the main branch, which reverts the changes in those directories to the files in the `main` branch (e.g. `git checkout origin/main src/rest/data/*`). - -
-
- -### [🚢](#publication) Complete preparation for the RC and publish the docset - -To complete preparation and publish the docset, continue the tasks in {{ release-steps-0-url }}. Leave this issue open until you merge the publication PR. +* [ ] [🚀 Prepare OpenAPI release configuration](https://github.com/github/docs-content/blob/main/focus-areas/enterprise/processes/publishing-ghes-feature-release-docs.md#51--prepare-openapi-release-configuration) +* [ ] [🆕 Prepare PR to publish release](https://github.com/github/docs-content/blob/main/focus-areas/enterprise/processes/publishing-ghes-feature-release-docs.md#52--prepare-pr-to-publish-release) +* [ ] [👯 Integrate OpenAPI changes into publication branch](https://github.com/github/docs-content/blob/main/focus-areas/enterprise/processes/publishing-ghes-feature-release-docs.md#53--integrate-openapi-changes-into-publication-branch) 🗓️ **2-3 days before release** +* [ ] Continue the tasks in {{ release-steps-0-url }} to complete preparation and publish the docset. Leave this issue open until you merge the publication PR. 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 66dc27855714..b7c620a21fef 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 @@ -92,7 +92,7 @@ "permissions": [ { "category": "dependabot", - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access", @@ -101,7 +101,7 @@ }, { "category": "dependabot", - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access", @@ -8288,4 +8288,4 @@ } ] } -} +} \ No newline at end of file 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 42770196727c..bd5d9b5256a8 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 @@ -2187,13 +2187,13 @@ ], "dependabot": [ { - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access" }, { - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access" 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 4abf024f983b..e2530f846cee 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 @@ -110,7 +110,7 @@ "permissions": [ { "category": "dependabot", - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access", @@ -121,7 +121,7 @@ }, { "category": "dependabot", - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access", 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 748c841742b3..8d71010009e9 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 @@ -1915,13 +1915,13 @@ ], "dependabot": [ { - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access" }, { - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access" 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 42770196727c..bd5d9b5256a8 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 @@ -2187,13 +2187,13 @@ ], "dependabot": [ { - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access" }, { - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access" 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 75e64e80181a..cc4362ba1c92 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 @@ -1,7 +1,7 @@ { "enterprise_custom_properties": { "title": "Custom properties", - "displayTitle": "Business permissions for \"Custom properties\"", + "displayTitle": "Enterprise permissions for \"Custom properties\"", "permissions": [ { "category": "enterprise-admin", @@ -61,7 +61,7 @@ }, "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", @@ -284,7 +284,7 @@ }, { "category": "dependabot", - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access", @@ -293,7 +293,7 @@ }, { "category": "dependabot", - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access", @@ -2264,6 +2264,48 @@ } ] }, + "organization_code_scanning_dismissal_requests": { + "title": "Organization dismissal requests for code scanning", + "displayTitle": "Organization permissions for \"Organization dismissal requests for code scanning\"", + "permissions": [ + { + "category": "code-scanning", + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-an-organization", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/orgs/{org}/dismissal-requests/code-scanning", + "additional-permissions": false, + "access": "read" + }, + { + "category": "code-scanning", + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning", + "additional-permissions": true, + "access": "read" + }, + { + "category": "code-scanning", + "slug": "get-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "additional-permissions": true, + "access": "read" + }, + { + "category": "code-scanning", + "slug": "review-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "patch", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "additional-permissions": true, + "access": "write" + } + ] + }, "organization_private_registries": { "title": "Organization private registries", "displayTitle": "Organization permissions for \"Organization private registries\"", @@ -4961,6 +5003,33 @@ "requestPath": "/repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}", "additional-permissions": false, "access": "read" + }, + { + "category": "code-scanning", + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning", + "additional-permissions": true, + "access": "read" + }, + { + "category": "code-scanning", + "slug": "get-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "additional-permissions": true, + "access": "read" + }, + { + "category": "code-scanning", + "slug": "review-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "patch", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "additional-permissions": true, + "access": "read" } ] }, @@ -9002,4 +9071,4 @@ } ] } -} +} \ No newline at end of file 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 8f5bc9c4171c..7394d3fdf809 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 @@ -1512,6 +1512,12 @@ "verb": "get", "requestPath": "/orgs/{org}/code-scanning/alerts" }, + { + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-an-organization", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/orgs/{org}/dismissal-requests/code-scanning" + }, { "slug": "list-code-scanning-alerts-for-a-repository", "subcategory": "code-scanning", @@ -1631,6 +1637,24 @@ "subcategory": "code-scanning", "verb": "get", "requestPath": "/repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}" + }, + { + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning" + }, + { + "slug": "get-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}" + }, + { + "slug": "review-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "patch", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}" } ], "code-security": [ @@ -2225,13 +2249,13 @@ ], "dependabot": [ { - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access" }, { - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access" 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 a1cd8431eee8..5c180c9112f8 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 @@ -1,7 +1,7 @@ { "enterprise_custom_properties": { "title": "Custom properties", - "displayTitle": "Business permissions for \"Custom properties\"", + "displayTitle": "Enterprise permissions for \"Custom properties\"", "permissions": [ { "category": "enterprise-admin", @@ -73,7 +73,7 @@ }, "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", @@ -342,7 +342,7 @@ }, { "category": "dependabot", - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access", @@ -353,7 +353,7 @@ }, { "category": "dependabot", - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access", @@ -2742,6 +2742,56 @@ } ] }, + "organization_code_scanning_dismissal_requests": { + "title": "Organization dismissal requests for code scanning", + "displayTitle": "Organization permissions for \"Organization dismissal requests for code scanning\"", + "permissions": [ + { + "category": "code-scanning", + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-an-organization", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/orgs/{org}/dismissal-requests/code-scanning", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": false + }, + { + "category": "code-scanning", + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": true + }, + { + "category": "code-scanning", + "slug": "get-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": true + }, + { + "category": "code-scanning", + "slug": "review-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "patch", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "access": "write", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": true + } + ] + }, "organization_private_registries": { "title": "Organization private registries", "displayTitle": "Organization permissions for \"Organization private registries\"", @@ -6019,6 +6069,39 @@ "user-to-server": true, "server-to-server": true, "additional-permissions": false + }, + { + "category": "code-scanning", + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": true + }, + { + "category": "code-scanning", + "slug": "get-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": true + }, + { + "category": "code-scanning", + "slug": "review-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "patch", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "access": "read", + "user-to-server": true, + "server-to-server": true, + "additional-permissions": true } ] }, 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 3eebdb0b992f..ea3a0fc2bac0 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 @@ -1408,6 +1408,12 @@ "verb": "get", "requestPath": "/orgs/{org}/code-scanning/alerts" }, + { + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-an-organization", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/orgs/{org}/dismissal-requests/code-scanning" + }, { "slug": "list-code-scanning-alerts-for-a-repository", "subcategory": "code-scanning", @@ -1527,6 +1533,24 @@ "subcategory": "code-scanning", "verb": "get", "requestPath": "/repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}" + }, + { + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning" + }, + { + "slug": "get-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}" + }, + { + "slug": "review-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "patch", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}" } ], "code-security": [ @@ -1953,13 +1977,13 @@ ], "dependabot": [ { - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access" }, { - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access" 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 8f5bc9c4171c..7394d3fdf809 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 @@ -1512,6 +1512,12 @@ "verb": "get", "requestPath": "/orgs/{org}/code-scanning/alerts" }, + { + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-an-organization", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/orgs/{org}/dismissal-requests/code-scanning" + }, { "slug": "list-code-scanning-alerts-for-a-repository", "subcategory": "code-scanning", @@ -1631,6 +1637,24 @@ "subcategory": "code-scanning", "verb": "get", "requestPath": "/repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}" + }, + { + "slug": "list-dismissal-requests-for-code-scanning-alerts-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning" + }, + { + "slug": "get-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}" + }, + { + "slug": "review-a-dismissal-request-for-a-code-scanning-alert-for-a-repository", + "subcategory": "alert-dismissal-requests", + "verb": "patch", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}" } ], "code-security": [ @@ -2225,13 +2249,13 @@ ], "dependabot": [ { - "slug": "lists-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "lists-the-repositories-dependabot-can-access-in-an-organization", "subcategory": "repository-access", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access" }, { - "slug": "updates-repositories-to-the-list-of-repositories-that-organization-admins-have-allowed-dependabot-to-access-when-updating-dependencies", + "slug": "updates-dependabots-repository-access-list-for-an-organization", "subcategory": "repository-access", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access" diff --git a/src/github-apps/data/ghes-3.13-2022-11-28/fine-grained-pat-permissions.json b/src/github-apps/data/ghes-3.13-2022-11-28/fine-grained-pat-permissions.json index e360ad6f8bd5..8ae7bee00417 100644 --- a/src/github-apps/data/ghes-3.13-2022-11-28/fine-grained-pat-permissions.json +++ b/src/github-apps/data/ghes-3.13-2022-11-28/fine-grained-pat-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", @@ -6527,4 +6527,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/github-apps/data/ghes-3.13-2022-11-28/server-to-server-permissions.json b/src/github-apps/data/ghes-3.13-2022-11-28/server-to-server-permissions.json index ea44c8cfb4e7..4c69a60f5936 100644 --- a/src/github-apps/data/ghes-3.13-2022-11-28/server-to-server-permissions.json +++ b/src/github-apps/data/ghes-3.13-2022-11-28/server-to-server-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", diff --git a/src/github-apps/data/ghes-3.14-2022-11-28/fine-grained-pat-permissions.json b/src/github-apps/data/ghes-3.14-2022-11-28/fine-grained-pat-permissions.json index 23ed1f8913fd..e862e8eec6a2 100644 --- a/src/github-apps/data/ghes-3.14-2022-11-28/fine-grained-pat-permissions.json +++ b/src/github-apps/data/ghes-3.14-2022-11-28/fine-grained-pat-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", @@ -6659,4 +6659,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/github-apps/data/ghes-3.14-2022-11-28/server-to-server-permissions.json b/src/github-apps/data/ghes-3.14-2022-11-28/server-to-server-permissions.json index 8ee51bad2fac..4ab01d7df872 100644 --- a/src/github-apps/data/ghes-3.14-2022-11-28/server-to-server-permissions.json +++ b/src/github-apps/data/ghes-3.14-2022-11-28/server-to-server-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", diff --git a/src/github-apps/data/ghes-3.15-2022-11-28/fine-grained-pat-permissions.json b/src/github-apps/data/ghes-3.15-2022-11-28/fine-grained-pat-permissions.json index e51bb0c1b42b..9b6a96326b2a 100644 --- a/src/github-apps/data/ghes-3.15-2022-11-28/fine-grained-pat-permissions.json +++ b/src/github-apps/data/ghes-3.15-2022-11-28/fine-grained-pat-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", @@ -6767,4 +6767,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/github-apps/data/ghes-3.15-2022-11-28/server-to-server-permissions.json b/src/github-apps/data/ghes-3.15-2022-11-28/server-to-server-permissions.json index 6af75f134a9b..5d98f087396b 100644 --- a/src/github-apps/data/ghes-3.15-2022-11-28/server-to-server-permissions.json +++ b/src/github-apps/data/ghes-3.15-2022-11-28/server-to-server-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", diff --git a/src/github-apps/data/ghes-3.16-2022-11-28/fine-grained-pat-permissions.json b/src/github-apps/data/ghes-3.16-2022-11-28/fine-grained-pat-permissions.json index 771e80d91687..caabdbc6be47 100644 --- a/src/github-apps/data/ghes-3.16-2022-11-28/fine-grained-pat-permissions.json +++ b/src/github-apps/data/ghes-3.16-2022-11-28/fine-grained-pat-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", @@ -6827,4 +6827,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/github-apps/data/ghes-3.16-2022-11-28/server-to-server-permissions.json b/src/github-apps/data/ghes-3.16-2022-11-28/server-to-server-permissions.json index d3270373cf39..8e1de330a93b 100644 --- a/src/github-apps/data/ghes-3.16-2022-11-28/server-to-server-permissions.json +++ b/src/github-apps/data/ghes-3.16-2022-11-28/server-to-server-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", diff --git a/src/github-apps/data/ghes-3.17-2022-11-28/fine-grained-pat-permissions.json b/src/github-apps/data/ghes-3.17-2022-11-28/fine-grained-pat-permissions.json index 14e134c38203..769ff8f6c13d 100644 --- a/src/github-apps/data/ghes-3.17-2022-11-28/fine-grained-pat-permissions.json +++ b/src/github-apps/data/ghes-3.17-2022-11-28/fine-grained-pat-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", @@ -6899,4 +6899,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/github-apps/data/ghes-3.17-2022-11-28/server-to-server-permissions.json b/src/github-apps/data/ghes-3.17-2022-11-28/server-to-server-permissions.json index 5bde08a9e536..e514e8e2f214 100644 --- a/src/github-apps/data/ghes-3.17-2022-11-28/server-to-server-permissions.json +++ b/src/github-apps/data/ghes-3.17-2022-11-28/server-to-server-permissions.json @@ -1,7 +1,7 @@ { "enterprise_scim": { "title": "Enterprise SCIM", - "displayTitle": "Business permissions for \"Enterprise SCIM\"", + "displayTitle": "Enterprise permissions for \"Enterprise SCIM\"", "permissions": [ { "category": "enterprise-admin", diff --git a/src/github-apps/lib/config.json b/src/github-apps/lib/config.json index e6073ba1720f..95859016e387 100644 --- a/src/github-apps/lib/config.json +++ b/src/github-apps/lib/config.json @@ -60,5 +60,5 @@ "2022-11-28" ] }, - "sha": "3ae8ad33b4276583395c1b28852650f329018927" + "sha": "c52348cd88be16e613e49c26b39d2653e20b817d" } \ No newline at end of file diff --git a/src/landings/components/CookBookArticleCard.tsx b/src/landings/components/CookBookArticleCard.tsx index 51823f00f015..629382593343 100644 --- a/src/landings/components/CookBookArticleCard.tsx +++ b/src/landings/components/CookBookArticleCard.tsx @@ -1,37 +1,7 @@ import { Label, LabelGroup, Link } from '@primer/react' -import { - BugIcon, - LightBulbIcon, - CodeIcon, - GearIcon, - RocketIcon, - BeakerIcon, - CopilotIcon, - HubotIcon, - LogIcon, - TerminalIcon, - BookIcon, - ShieldLockIcon, - LockIcon, -} from '@primer/octicons-react' +import { ValidOcticon, getOcticonComponent } from '../lib/octicons' -const Icons = { - bug: BugIcon, - lightbulb: LightBulbIcon, - code: CodeIcon, - gear: GearIcon, - rocket: RocketIcon, - beaker: BeakerIcon, - copilot: CopilotIcon, - hubot: HubotIcon, - log: LogIcon, - terminal: TerminalIcon, - book: BookIcon, - 'shield-lock': ShieldLockIcon, - lock: LockIcon, -} - -type IconType = keyof typeof Icons +type IconType = ValidOcticon type Props = { title: string @@ -69,11 +39,7 @@ export const CookBookArticleCard = ({ url, spotlight = false, }: Props) => { - const setIcon = (icon: keyof typeof Icons) => { - return Icons[icon] || CopilotIcon - } - - const IconComponent = setIcon(icon as keyof typeof Icons) + const IconComponent = getOcticonComponent(icon) return (
{ + describe('VALID_OCTICONS', () => { + test('contains expected octicon names', () => { + // Test that we have the expected number of octicons and they're all defined + expect(VALID_OCTICONS.length).toBeGreaterThan(0) + expect(VALID_OCTICONS).toEqual(expect.arrayContaining(['bug', 'rocket', 'copilot'])) + }) + + test('all octicons are strings', () => { + VALID_OCTICONS.forEach((octicon) => { + expect(typeof octicon).toBe('string') + }) + }) + }) + + describe('OCTICON_COMPONENTS', () => { + test('has components for all valid octicons', () => { + VALID_OCTICONS.forEach((octicon) => { + expect(OCTICON_COMPONENTS[octicon]).toBeDefined() + expect(typeof OCTICON_COMPONENTS[octicon]).toBe('object') + }) + }) + + test('maps specific octicons to correct components', () => { + expect(OCTICON_COMPONENTS.bug).toBe(BugIcon) + expect(OCTICON_COMPONENTS.rocket).toBe(RocketIcon) + expect(OCTICON_COMPONENTS.copilot).toBe(CopilotIcon) + }) + }) + + describe('isValidOcticon', () => { + test('returns true for valid octicons', () => { + expect(isValidOcticon('bug')).toBe(true) + expect(isValidOcticon('rocket')).toBe(true) + expect(isValidOcticon('shield-lock')).toBe(true) + }) + + test('returns false for invalid octicons', () => { + expect(isValidOcticon('invalid-octicon')).toBe(false) + expect(isValidOcticon('pizza')).toBe(false) + expect(isValidOcticon('')).toBe(false) + }) + + test('returns false for null or undefined', () => { + expect(isValidOcticon(null)).toBe(false) + expect(isValidOcticon(undefined as any)).toBe(false) + }) + + test('provides correct type narrowing', () => { + const testOcticon: string | null = 'bug' + + if (isValidOcticon(testOcticon)) { + // This should compile without type errors + const validOcticon: ValidOcticon = testOcticon + expect(validOcticon).toBe('bug') + } + }) + }) + + describe('getOcticonComponent', () => { + test('returns correct component for valid octicons', () => { + expect(getOcticonComponent('bug')).toBe(BugIcon) + expect(getOcticonComponent('rocket')).toBe(RocketIcon) + expect(getOcticonComponent('copilot')).toBe(CopilotIcon) + }) + + test('returns CopilotIcon as fallback for undefined', () => { + expect(getOcticonComponent(undefined)).toBe(CopilotIcon) + }) + + test('returns CopilotIcon as fallback for invalid octicons', () => { + // TypeScript should prevent this, but test runtime behavior + expect(getOcticonComponent('invalid' as ValidOcticon)).toBe(CopilotIcon) + }) + }) + + describe('type safety', () => { + test('ValidOcticon type includes all expected values', () => { + // This test ensures the type system prevents invalid octicons at compile time + // Test a few key octicons to verify the type works correctly + const testOcticons: ValidOcticon[] = ['bug', 'rocket', 'copilot'] + + testOcticons.forEach((octicon) => { + expect(VALID_OCTICONS.includes(octicon)).toBe(true) + }) + }) + }) + + describe('consistency checks', () => { + test('OCTICON_COMPONENTS keys match VALID_OCTICONS', () => { + const componentKeys = Object.keys(OCTICON_COMPONENTS) + const validOcticonsSet = new Set(VALID_OCTICONS) + + componentKeys.forEach((key) => { + expect(validOcticonsSet.has(key as ValidOcticon)).toBe(true) + }) + + expect(componentKeys).toHaveLength(VALID_OCTICONS.length) + }) + + test('no duplicate octicons in VALID_OCTICONS', () => { + const octiconsSet = new Set(VALID_OCTICONS) + expect(octiconsSet.size).toBe(VALID_OCTICONS.length) + }) + }) + + describe('single source of truth', () => { + test('VALID_OCTICONS is derived from OCTICON_COMPONENTS', () => { + const componentKeys = Object.keys(OCTICON_COMPONENTS).sort() + const validOcticons = [...VALID_OCTICONS].sort() + + expect(validOcticons).toEqual(componentKeys) + }) + + test('ValidOcticon type matches OCTICON_COMPONENTS keys', () => { + // This test ensures the type system is correctly derived from the object + const testOcticon: ValidOcticon = 'bug' + expect(OCTICON_COMPONENTS[testOcticon]).toBeDefined() + + // Type check - this should compile without errors + const allKeys: ValidOcticon[] = Object.keys(OCTICON_COMPONENTS) as ValidOcticon[] + expect(allKeys.length).toBeGreaterThan(0) + }) + + test('adding new octicon only requires updating OCTICON_COMPONENTS', () => { + // This test documents the single source of truth approach + // If you add a new octicon to OCTICON_COMPONENTS: + // 1. ValidOcticon type automatically includes it + // 2. VALID_OCTICONS array automatically includes it + // 3. All validation functions work with it + + const componentCount = Object.keys(OCTICON_COMPONENTS).length + const validOcticonsCount = VALID_OCTICONS.length + + expect(componentCount).toBe(validOcticonsCount) + }) + }) +}) diff --git a/src/landings/types.ts b/src/landings/types.ts index 36f849c0b7cf..e468cc891134 100644 --- a/src/landings/types.ts +++ b/src/landings/types.ts @@ -1,3 +1,9 @@ +import { ValidOcticon, isValidOcticon } from './lib/octicons' + +// Re-export ValidOcticon and isValidOcticon for compatibility with existing imports +export type { ValidOcticon } +export { isValidOcticon } + // Base type for all TOC items with core properties export type BaseTocItem = { fullPath: string @@ -5,22 +11,6 @@ export type BaseTocItem = { intro?: string | null } -// Valid octicon types that match the CookBookArticleCard component -export type ValidOcticon = - | 'code' - | 'log' - | 'terminal' - | 'bug' - | 'lightbulb' - | 'gear' - | 'rocket' - | 'beaker' - | 'copilot' - | 'hubot' - | 'book' - | 'shield-lock' - | 'lock' - // Extended type for child TOC items with additional metadata export type ChildTocItem = BaseTocItem & { octicon?: ValidOcticon | null @@ -54,26 +44,6 @@ export type RawTocItem = { childTocItems: RawTocItem[] } -// Helper function to validate and cast octicon values -export function isValidOcticon(octicon: string | null): octicon is ValidOcticon { - const validOcticons: ValidOcticon[] = [ - 'code', - 'log', - 'terminal', - 'bug', - 'lightbulb', - 'gear', - 'rocket', - 'beaker', - 'copilot', - 'hubot', - 'book', - 'shield-lock', - 'lock', - ] - return octicon !== null && validOcticons.includes(octicon as ValidOcticon) -} - // Simplified TOC item type for basic landing pages that don't need extended metadata export type SimpleTocItem = { fullPath: string diff --git a/src/links/lib/README.md b/src/links/lib/README.md index 96e9001c7c22..0ce4e4eb8031 100644 --- a/src/links/lib/README.md +++ b/src/links/lib/README.md @@ -39,4 +39,4 @@ Before you decide whether to exclude a link from the daily link checker, you sho - Has it has been flagged as a broken link for more than a week, but the URL works when a real user opens it in their browser? - Has the URL been available for more than 3 months? You can check using the [Wayback Machine](https://web.archive.org). -If you are confident that the URL for the article should work for real users, then you can open a pull request to add it to the `src/links/lib/excluded-links.ts` file. +If you are confident that the URL for the article should work for real users, then you can open a pull request to add it to the `src/links/lib/excluded-links.yml` file. diff --git a/src/links/lib/excluded-links.yml b/src/links/lib/excluded-links.yml index 6002d3d16329..d31cda6d64de 100644 --- a/src/links/lib/excluded-links.yml +++ b/src/links/lib/excluded-links.yml @@ -100,3 +100,4 @@ - startsWith: https://github.com/githubcustomers/enterprise-preview-program - is: https://aka.ms/copiloteclipse - is: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=1375604 +- is: https://developers.redhat.com/articles/2025/02/17/how-securely-deploy-github-arc-openshift#arc_architecture diff --git a/src/metrics/lib/dates.js b/src/metrics/lib/dates.ts similarity index 71% rename from src/metrics/lib/dates.js rename to src/metrics/lib/dates.ts index 355c78d3a8a8..d44ff794d0da 100644 --- a/src/metrics/lib/dates.js +++ b/src/metrics/lib/dates.ts @@ -1,11 +1,17 @@ -const dateOpts = { +const dateOpts: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric', } +export interface DateRange { + endDate: string + startDate: string + friendlyRange: string +} + // Default to 30 days ago if a range option is not provided -export function getDates(range = '30') { +export function getDates(range: string | number = '30'): DateRange { // Get current datetime in ISO format const today = new Date() const todayISO = today.toISOString() @@ -21,7 +27,7 @@ export function getDates(range = '30') { } } -function getDaysAgo(range) { +function getDaysAgo(range: number): Date { const daysAgo = new Date() daysAgo.setDate(daysAgo.getDate() - range) return daysAgo diff --git a/src/metrics/lib/kusto-client.js b/src/metrics/lib/kusto-client.ts similarity index 59% rename from src/metrics/lib/kusto-client.js rename to src/metrics/lib/kusto-client.ts index eb8b13bdbd50..72a84a062eb6 100644 --- a/src/metrics/lib/kusto-client.js +++ b/src/metrics/lib/kusto-client.ts @@ -1,16 +1,28 @@ -import { Client as KustoClient, KustoConnectionStringBuilder } from 'azure-kusto-data' +import { + Client as KustoClient, + KustoConnectionStringBuilder, + KustoResultTable, +} from 'azure-kusto-data' import dotenv from 'dotenv' + dotenv.config() + if (!(process.env.KUSTO_CLUSTER || process.env.KUSTO_DATABASE)) { console.error(`Add KUSTO_CLUSTER and KUSTO_DATABASE to your .env file`) process.exit(0) } -const KUSTO_CLUSTER = process.env.KUSTO_CLUSTER -const KUSTO_DATABASE = process.env.KUSTO_DATABASE -export function getKustoClient() { - let client +const KUSTO_CLUSTER = process.env.KUSTO_CLUSTER! +const KUSTO_DATABASE = process.env.KUSTO_DATABASE! + +export interface KustoQueryResult { + primaryResults: KustoResultTable[] +} + +export function getKustoClient(): KustoClient | undefined { + let client: KustoClient | undefined + try { const kcsb = KustoConnectionStringBuilder.withAzLoginIdentity(KUSTO_CLUSTER) client = new KustoClient(kcsb) @@ -18,10 +30,17 @@ export function getKustoClient() { console.error('Error connecting to Kusto') console.error(error) } + return client } -export async function runQuery(pathToFetch, query, client, queryType, verbose = false) { +export async function runQuery( + pathToFetch: string | string[], + query: string, + client: KustoClient, + queryType: string, + verbose: boolean = false, +): Promise { // Display query if verbose mode is on if (verbose) { console.log(`\n--- EXECUTING QUERY FOR "${queryType.toUpperCase()}" ---`) diff --git a/src/metrics/queries/bounces.js b/src/metrics/queries/bounces.ts similarity index 52% rename from src/metrics/queries/bounces.js rename to src/metrics/queries/bounces.ts index 465d6896bac3..0ca65b7fb2bc 100644 --- a/src/metrics/queries/bounces.js +++ b/src/metrics/queries/bounces.ts @@ -1,25 +1,36 @@ -import { runQuery } from '#src/metrics/lib/kusto-client.js' -import { SHARED_DECLARATIONS, SHARED_FILTERS } from '#src/metrics/queries/constants.js' +import { runQuery } from '@/metrics/lib/kusto-client' +import { SHARED_DECLARATIONS, SHARED_FILTERS } from '@/metrics/queries/constants' +import type { DateRange } from '@/metrics/lib/dates' +import type { Client as KustoClient } from 'azure-kusto-data' const QUERY_TYPE = 'bounces' export async function getBounces( - pathToFetch, - client, - dates, - version = null, - verbose = false, - queryType = QUERY_TYPE, -) { + pathToFetch: string | string[], + client: KustoClient, + dates: DateRange, + version: string | null = null, + verbose: boolean = false, + queryType: string = QUERY_TYPE, +): Promise { const query = getBouncesQuery(pathToFetch, dates, version) const results = await runQuery(pathToFetch, query, client, queryType, verbose) + + if (!results) { + return '0%' + } + const data = JSON.parse(results.primaryResults[0].toString()).data[0] // Extract Bounces const bounces = data.Bounces return bounces } -export function getBouncesQuery(pathToFetch, dates, version) { +export function getBouncesQuery( + pathToFetch: string | string[], + dates: DateRange, + version: string | null, +): string { return ` ${SHARED_DECLARATIONS(pathToFetch, dates, version)} let _exits = () { @@ -28,8 +39,8 @@ export function getBouncesQuery(pathToFetch, dates, version) { }; _exits | summarize Bounces=round( - countif(exit_scroll_length < 0.1 and exit_visit_duration < 5) / - toreal(count()), + countif(exit_scroll_length < 0.1 and exit_visit_duration < 5) / + toreal(count()), 2 ) | project Bounces=strcat(toint( diff --git a/src/metrics/queries/constants.js b/src/metrics/queries/constants.ts similarity index 86% rename from src/metrics/queries/constants.js rename to src/metrics/queries/constants.ts index be732f5f01a7..5e060f8a47dc 100644 --- a/src/metrics/queries/constants.js +++ b/src/metrics/queries/constants.ts @@ -1,5 +1,11 @@ +import type { DateRange } from '@/metrics/lib/dates' + // SHARED QUERY CONSTANTS -export const SHARED_DECLARATIONS = (path, dates, version) => +export const SHARED_DECLARATIONS = ( + path: string | string[], + dates: DateRange, + version: string | null, +): string => ` let _article = dynamic(['${Array.isArray(path) ? path.join("', '") : path}']); let _articleType = dynamic(null); diff --git a/src/metrics/queries/exits-to-support.js b/src/metrics/queries/exits-to-support.ts similarity index 60% rename from src/metrics/queries/exits-to-support.js rename to src/metrics/queries/exits-to-support.ts index a4ac2d156d86..ff85d2201874 100644 --- a/src/metrics/queries/exits-to-support.js +++ b/src/metrics/queries/exits-to-support.ts @@ -1,25 +1,36 @@ -import { runQuery } from '#src/metrics/lib/kusto-client.js' -import { SHARED_DECLARATIONS, SHARED_FILTERS } from '#src/metrics/queries/constants.js' +import { runQuery } from '@/metrics/lib/kusto-client' +import { SHARED_DECLARATIONS, SHARED_FILTERS } from '@/metrics/queries/constants' +import type { DateRange } from '@/metrics/lib/dates' +import type { Client as KustoClient } from 'azure-kusto-data' const QUERY_TYPE = 'exits' export async function getExitsToSupport( - pathToFetch, - client, - dates, - version = null, - verbose = false, - queryType = QUERY_TYPE, -) { + pathToFetch: string | string[], + client: KustoClient, + dates: DateRange, + version: string | null = null, + verbose: boolean = false, + queryType: string = QUERY_TYPE, +): Promise { const query = getExitsQueryStatement(pathToFetch, dates, version) const results = await runQuery(pathToFetch, query, client, queryType, verbose) + + if (!results) { + return '0%' + } + const data = JSON.parse(results.primaryResults[0].toString()).data[0] // Extract Column1 const exitsToSupport = data.Column1 return exitsToSupport } -export function getExitsQueryStatement(pathToFetch, dates, version) { +export function getExitsQueryStatement( + pathToFetch: string | string[], + dates: DateRange, + version: string | null, +): string { return ` ${SHARED_DECLARATIONS(pathToFetch, dates, version)} let _links = () { @@ -30,7 +41,7 @@ export function getExitsQueryStatement(pathToFetch, dates, version) { | where isempty(link_samesite) or link_samesite == false | where link_samepage != true // allow false or null | extend link_url_parsed=parse_url(link_url) - | extend IsSupport=tostring(link_url_parsed.Host) == "support.github.com" + | extend IsSupport=tostring(link_url_parsed.Host) == "support.github.com" and tostring(link_url_parsed.path) != "/enterprise/server-upgrade" | summarize Ratio=round(countif(IsSupport) / toreal(count()), 2) | project strcat(toint(Ratio * 100), '%') diff --git a/src/metrics/queries/survey-score.js b/src/metrics/queries/survey-score.ts similarity index 55% rename from src/metrics/queries/survey-score.js rename to src/metrics/queries/survey-score.ts index 5c42290eb5b6..caf7624d9f4f 100644 --- a/src/metrics/queries/survey-score.js +++ b/src/metrics/queries/survey-score.ts @@ -1,25 +1,36 @@ -import { runQuery } from '#src/metrics/lib/kusto-client.js' -import { SHARED_DECLARATIONS, SHARED_FILTERS } from '#src/metrics/queries/constants.js' +import { runQuery } from '@/metrics/lib/kusto-client' +import { SHARED_DECLARATIONS, SHARED_FILTERS } from '@/metrics/queries/constants' +import type { DateRange } from '@/metrics/lib/dates' +import type { Client as KustoClient } from 'azure-kusto-data' const QUERY_TYPE = 'score' export async function getScore( - pathToFetch, - client, - dates, - version = null, - verbose = false, - queryType = QUERY_TYPE, -) { + pathToFetch: string | string[], + client: KustoClient, + dates: DateRange, + version: string | null = null, + verbose: boolean = false, + queryType: string = QUERY_TYPE, +): Promise { const query = getScoreQuery(pathToFetch, dates, version) const results = await runQuery(pathToFetch, query, client, queryType, verbose) + + if (!results) { + return '0%' + } + const data = JSON.parse(results.primaryResults[0].toString()).data[0] // Extract Score const score = data.Score return score } -export function getScoreQuery(pathToFetch, dates, version) { +export function getScoreQuery( + pathToFetch: string | string[], + dates: DateRange, + version: string | null, +): string { return ` ${SHARED_DECLARATIONS(pathToFetch, dates, version)} let _surveys = () { @@ -33,8 +44,8 @@ export function getScoreQuery(pathToFetch, dates, version) { }; _surveys | summarize Score=round( - (countif(survey_vote) + 0.75 * 30) - / (count() + 30), + (countif(survey_vote) + 0.75 * 30) + / (count() + 30), 2 ) | project Score=strcat(toint(Score * 100), '%') diff --git a/src/metrics/queries/users.js b/src/metrics/queries/users.js deleted file mode 100644 index 0df19d0f4514..000000000000 --- a/src/metrics/queries/users.js +++ /dev/null @@ -1,32 +0,0 @@ -import { runQuery } from '#src/metrics/lib/kusto-client.js' -import { SHARED_DECLARATIONS, SHARED_FILTERS } from '#src/metrics/queries/constants.js' - -const QUERY_TYPE = 'users' - -export async function getUsers( - pathToFetch, - client, - dates, - version = null, - verbose = false, - queryType = QUERY_TYPE, -) { - const query = getUsersQuery(pathToFetch, dates, version) - const results = await runQuery(pathToFetch, query, client, queryType, verbose) - const data = JSON.parse(results.primaryResults[0].toString()).data[0] - // Extract Users - const users = data.Users - return users.toLocaleString() -} - -export function getUsersQuery(pathToFetch, dates, version) { - return ` - ${SHARED_DECLARATIONS(pathToFetch, dates, version)} - let _pages = () { - docs_v0_page_event - ${SHARED_FILTERS} - }; - _pages - | summarize Users=dcount(tostring(context.user)) - ` -} diff --git a/src/metrics/queries/users.ts b/src/metrics/queries/users.ts new file mode 100644 index 000000000000..dc4f197c155e --- /dev/null +++ b/src/metrics/queries/users.ts @@ -0,0 +1,43 @@ +import { runQuery } from '@/metrics/lib/kusto-client' +import { SHARED_DECLARATIONS, SHARED_FILTERS } from '@/metrics/queries/constants' +import type { DateRange } from '@/metrics/lib/dates' +import type { Client as KustoClient } from 'azure-kusto-data' + +const QUERY_TYPE = 'users' + +export async function getUsers( + pathToFetch: string | string[], + client: KustoClient, + dates: DateRange, + version: string | null = null, + verbose: boolean = false, + queryType: string = QUERY_TYPE, +): Promise { + const query = getUsersQuery(pathToFetch, dates, version) + const results = await runQuery(pathToFetch, query, client, queryType, verbose) + + if (!results) { + return '0' + } + + const data = JSON.parse(results.primaryResults[0].toString()).data[0] + // Extract Users + const users = data.Users + return users.toLocaleString() +} + +export function getUsersQuery( + pathToFetch: string | string[], + dates: DateRange, + version: string | null, +): string { + return ` + ${SHARED_DECLARATIONS(pathToFetch, dates, version)} + let _pages = () { + docs_v0_page_event + ${SHARED_FILTERS} + }; + _pages + | summarize Users=dcount(tostring(context.user)) + ` +} diff --git a/src/metrics/queries/view-duration.js b/src/metrics/queries/view-duration.ts similarity index 50% rename from src/metrics/queries/view-duration.js rename to src/metrics/queries/view-duration.ts index 95950e10f8ba..1f53bcee3cea 100644 --- a/src/metrics/queries/view-duration.js +++ b/src/metrics/queries/view-duration.ts @@ -1,25 +1,36 @@ -import { runQuery } from '#src/metrics/lib/kusto-client.js' -import { SHARED_DECLARATIONS, SHARED_FILTERS } from '#src/metrics/queries/constants.js' +import { runQuery } from '@/metrics/lib/kusto-client' +import { SHARED_DECLARATIONS, SHARED_FILTERS } from '@/metrics/queries/constants' +import type { DateRange } from '@/metrics/lib/dates' +import type { Client as KustoClient } from 'azure-kusto-data' const QUERY_TYPE = 'view duration' export async function getViewDuration( - pathToFetch, - client, - dates, - version = null, - verbose = false, - queryType = QUERY_TYPE, -) { + pathToFetch: string | string[], + client: KustoClient, + dates: DateRange, + version: string | null = null, + verbose: boolean = false, + queryType: string = QUERY_TYPE, +): Promise { const query = getViewDurationQuery(pathToFetch, dates, version) const results = await runQuery(pathToFetch, query, client, queryType, verbose) + + if (!results) { + return '0 seconds' + } + const data = JSON.parse(results.primaryResults[0].toString()).data[0] // Extract avg_VisitDuration const viewDuration = data.avg_VisitDuration return `${viewDuration} seconds` } -export function getViewDurationQuery(pathToFetch, dates, version) { +export function getViewDurationQuery( + pathToFetch: string | string[], + dates: DateRange, + version: string | null, +): string { return ` ${SHARED_DECLARATIONS(pathToFetch, dates, version)} let _exits = () { @@ -28,7 +39,7 @@ export function getViewDurationQuery(pathToFetch, dates, version) { }; _exits | summarize VisitDuration=round( - percentile(toreal(exit_visit_duration), 50), + percentile(toreal(exit_visit_duration), 50), 2 ) by bin(timestamp, 1d) diff --git a/src/metrics/queries/views.js b/src/metrics/queries/views.js deleted file mode 100644 index 80438d8c05ca..000000000000 --- a/src/metrics/queries/views.js +++ /dev/null @@ -1,32 +0,0 @@ -import { runQuery } from '#src/metrics/lib/kusto-client.js' -import { SHARED_DECLARATIONS, SHARED_FILTERS } from '#src/metrics/queries/constants.js' - -const QUERY_TYPE = 'views' - -export async function getViews( - pathToFetch, - client, - dates, - version = null, - verbose = false, - queryType = QUERY_TYPE, -) { - const query = getViewsQuery(pathToFetch, dates, version) - const results = await runQuery(pathToFetch, query, client, queryType, verbose) - const data = JSON.parse(results.primaryResults[0].toString()).data[0] - // Extract Views - const views = data.Views - return views.toLocaleString() -} - -export function getViewsQuery(pathToFetch, dates, version) { - return ` - ${SHARED_DECLARATIONS(pathToFetch, dates, version)} - let _pages = () { - docs_v0_page_event - ${SHARED_FILTERS} - }; - _pages - | summarize Views=count() - ` -} diff --git a/src/metrics/queries/views.ts b/src/metrics/queries/views.ts new file mode 100644 index 000000000000..51bab657fd90 --- /dev/null +++ b/src/metrics/queries/views.ts @@ -0,0 +1,43 @@ +import { runQuery } from '@/metrics/lib/kusto-client' +import { SHARED_DECLARATIONS, SHARED_FILTERS } from '@/metrics/queries/constants' +import type { DateRange } from '@/metrics/lib/dates' +import type { Client as KustoClient } from 'azure-kusto-data' + +const QUERY_TYPE = 'views' + +export async function getViews( + pathToFetch: string | string[], + client: KustoClient, + dates: DateRange, + version: string | null = null, + verbose: boolean = false, + queryType: string = QUERY_TYPE, +): Promise { + const query = getViewsQuery(pathToFetch, dates, version) + const results = await runQuery(pathToFetch, query, client, queryType, verbose) + + if (!results) { + return '0' + } + + const data = JSON.parse(results.primaryResults[0].toString()).data[0] + // Extract Views + const views = data.Views + return views.toLocaleString() +} + +export function getViewsQuery( + pathToFetch: string | string[], + dates: DateRange, + version: string | null, +): string { + return ` + ${SHARED_DECLARATIONS(pathToFetch, dates, version)} + let _pages = () { + docs_v0_page_event + ${SHARED_FILTERS} + }; + _pages + | summarize Views=count() + ` +} diff --git a/src/metrics/scripts/docsaudit.js b/src/metrics/scripts/docsaudit.ts similarity index 72% rename from src/metrics/scripts/docsaudit.js rename to src/metrics/scripts/docsaudit.ts index ff87cafee1b1..011998939751 100644 --- a/src/metrics/scripts/docsaudit.js +++ b/src/metrics/scripts/docsaudit.ts @@ -4,28 +4,33 @@ import fs from 'fs' import path from 'path' import { fileURLToPath } from 'url' import { Command } from 'commander' -import walkFiles from '#src/workflows/walk-files.ts' +import walkFiles from '@/workflows/walk-files' import readFrontmatter from '@/frame/lib/read-frontmatter.js' -import { getKustoClient } from '#src/metrics/lib/kusto-client.js' -import { getDates } from 'src/metrics/lib/dates.js' -import { getViews } from '#src/metrics/queries/views.js' -import { getUsers } from '#src/metrics/queries/users.js' +import { getKustoClient } from '@/metrics/lib/kusto-client' +import { getDates, type DateRange } from '@/metrics/lib/dates' +import { getViews } from '@/metrics/queries/views' +import { getUsers } from '@/metrics/queries/users' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const ROOTDIR = process.cwd() +interface CliOptions { + range?: string + verbose?: boolean +} + const program = new Command() program .name('docsaudit') .description('Get data about a top-level docs product and output a CSV') .argument('', 'Name of the content directory you want to audit, e.g., actions') - .option('-r, --range ', 'Number of days to look back', 30) + .option('-r, --range ', 'Number of days to look back', '30') .option('--verbose', 'Display Kusto queries being executed') .parse(process.argv) -const options = program.opts() +const options = program.opts() const [auditDirName] = program.args const contentDir = path.join(ROOTDIR, 'content') const auditDir = path.join(contentDir, auditDirName) @@ -37,27 +42,32 @@ if (!fs.existsSync(auditDir)) { } // Get dates object in format { endDate, startDate, friendlyRange } -const dates = getDates(options.range) +const dates: DateRange = getDates(options.range) const files = walkFiles(auditDir, ['.md']) console.log(`Auditing the ${files.length} "${auditDirName}" files. This may take a while.\n`) main() -async function main() { +async function main(): Promise { const client = getKustoClient() + if (!client) { + console.error('Failed to initialize Kusto client') + process.exit(1) + } + let csvString = `title,path,versions,${options.range}d views,${options.range}d users\n` console.log(`Assembling data for these CSV columns: ${csvString}`) // Get the title, path, and versions from the filesystem // Get the views and users from the Kusto API - const results = [] + const results: string[] = [] for (const file of files) { const contents = await fs.promises.readFile(file) const contentPath = path.relative(ROOTDIR, file) const { data } = readFrontmatter(contents) - const versionString = JSON.stringify(data.versions).replaceAll('"', "'") + const versionString = JSON.stringify(data?.versions || {}).replaceAll('"', "'") const pathToQuery = getPathToQuery(file) // Pass null to get all versions (the default if no version is provided) const version = null @@ -65,7 +75,7 @@ async function main() { const isFirst = results.length === 0 const views = await getViews(pathToQuery, client, dates, version, options.verbose && isFirst) const users = await getUsers(pathToQuery, client, dates, version, options.verbose && isFirst) - const csvEntry = `"${data.title}","${contentPath}","${versionString}","${views}","${users}"` + const csvEntry = `"${data?.title || 'Unknown'}","${contentPath}","${versionString}","${views}","${users}"` console.log(csvEntry) results.push(csvEntry) } @@ -75,6 +85,6 @@ async function main() { console.log(`Done! Wrote ${outputFile}`) } -function getPathToQuery(file) { +function getPathToQuery(file: string): string { return path.relative(contentDir, file).replace('/index.md', '').replace('.md', '') } diff --git a/src/metrics/scripts/docstat.js b/src/metrics/scripts/docstat.ts old mode 100755 new mode 100644 similarity index 84% rename from src/metrics/scripts/docstat.js rename to src/metrics/scripts/docstat.ts index 65428ccb276b..3fbc8b79a63d --- a/src/metrics/scripts/docstat.js +++ b/src/metrics/scripts/docstat.ts @@ -6,14 +6,14 @@ import { Command } from 'commander' import chalk from 'chalk' import ora from 'ora' import frontmatter from '@/frame/lib/read-frontmatter.js' -import { getKustoClient } from '#src/metrics/lib/kusto-client.js' -import { getDates } from 'src/metrics/lib/dates.js' -import { getViews } from '#src/metrics/queries/views.js' -import { getUsers } from '#src/metrics/queries/users.js' -import { getViewDuration } from '#src/metrics/queries/view-duration.js' -import { getBounces } from '#src/metrics/queries/bounces.js' -import { getScore } from '#src/metrics/queries/survey-score.js' -import { getExitsToSupport } from '#src/metrics/queries/exits-to-support.js' +import { getKustoClient } from '@/metrics/lib/kusto-client' +import { getDates, type DateRange } from '@/metrics/lib/dates' +import { getViews } from '@/metrics/queries/views' +import { getUsers } from '@/metrics/queries/users' +import { getViewDuration } from '@/metrics/queries/view-duration' +import { getBounces } from '@/metrics/queries/bounces' +import { getScore } from '@/metrics/queries/survey-score' +import { getExitsToSupport } from '@/metrics/queries/exits-to-support' const { green, white, red, blue } = chalk @@ -22,6 +22,68 @@ const DOCS_API_PATH = 'https://docs.github.com/api/pagelist/en' const FREE_PRO_TEAM = 'free-pro-team@latest' const ENTERPRISE_REGEX = /enterprise-(server|cloud)@/ +interface CliOptions { + range?: string + compare?: boolean + views?: boolean + users?: boolean + viewDuration?: boolean + bounces?: boolean + score?: boolean + exits?: boolean + json?: boolean + skipValidation?: boolean + redirects?: boolean + fptOnly?: boolean + verbose?: boolean + defaultToAll?: boolean + showDocset?: boolean + allVersions?: boolean +} + +interface QueryResults { + views?: string + viewsDocset?: string + users?: string + usersDocset?: string + viewDuration?: string + viewDurationDocset?: string + bounces?: string + bouncesDocset?: string + score?: string + scoreDocset?: string + exits?: string + exitsDocset?: string +} + +interface JsonOutput { + daysRange: string + startDate: string + endDate: string + dateRange: string + inputUrl: string + data: { + path: string + views?: string + users?: string + viewDuration?: string + bounces?: string + score?: string + exits?: string + } + docset?: { + path: string + data: { + views?: string + users?: string + viewDuration?: string + bounces?: string + score?: string + exits?: string + } + } +} + const program = new Command() program @@ -37,7 +99,7 @@ program - Exits to support`, ) .argument('', 'URL to query data for') - .option('-r, --range ', 'Number of days to look back', 30) + .option('-r, --range ', 'Number of days to look back', '30') .option('-c, --compare', 'Compare with top-level docset data') .option('-v, --views', 'Get page views') .option('-u, --users', 'Get unique users') @@ -55,7 +117,7 @@ program .option('--verbose', 'Display Kusto queries being executed') .parse(process.argv) -const options = program.opts() +const options = program.opts() // If specific options are not provided, default to all options.defaultToAll = !( @@ -84,7 +146,7 @@ const providedPath = program.args[0] let cleanPath = getCleanPath(providedPath) // Get the version -let version = getVersion(cleanPath) +let version: string | null = getVersion(cleanPath) let usingFptOnly = !!options.fptOnly // If the URL does not specify a version, default to all versions unless --fptOnly is passed @@ -127,7 +189,7 @@ if (options.allVersions) version = null const docsetPath = cleanPath.split('/')[0] // Get redirect_from frontmatter and include those paths in the queries -let redirects = [] +let redirects: string[] = [] if (options.redirects) { let contentPath = path.join('content', cleanPath) contentPath = fs.existsSync(contentPath) @@ -135,19 +197,25 @@ if (options.redirects) { : `${contentPath}.md` const { data } = frontmatter(fs.readFileSync(contentPath, 'utf8')) // If redirect_from paths exists, they'll be in this format: /foo/bar - redirects = (data.redirect_from || []).map((oldPath) => oldPath.replace('/', '')) // remove leading '/' + redirects = (data?.redirect_from || []).map((oldPath: string) => oldPath.replace('/', '')) // remove leading '/' } const queryPaths = [cleanPath].concat(redirects) // Get dates object in format { endDate, startDate, friendlyRange } -const dates = getDates(options.range) +const dates: DateRange = getDates(options.range) -async function main() { +async function main(): Promise { const spinner = ora('Connecting to Kusto...').start() try { const client = getKustoClient() + + if (!client) { + spinner.fail('Failed to connect to Kusto') + process.exit(1) + } + spinner.text = 'Connected! Querying Kusto...' // Only show docset stats if option is passed AND if the given path is not already a docset. @@ -157,8 +225,8 @@ async function main() { } // Create query promises for all requested metrics - const queryPromises = [] - const results = {} + const queryPromises: Promise[] = [] + const results: QueryResults = {} // Setup all the promises for parallel execution if (options.views) { @@ -296,8 +364,8 @@ async function main() { // Output JSON and exit if (options.json) { - const jsonOutput = { - daysRange: options.range, + const jsonOutput: JsonOutput = { + daysRange: options.range || '30', startDate: dates.startDate, endDate: dates.endDate, dateRange: dates.friendlyRange, @@ -358,7 +426,7 @@ async function main() { return // Exit early } - console.log(white(`Last ${options.range} days:`), blue(dates.friendlyRange)) + console.log(white(`Last ${options.range || '30'} days:`), blue(dates.friendlyRange)) console.log(green('-------------------------------------------')) console.log(green('Path:'), white(cleanPath)) if (options.redirects) { @@ -435,7 +503,7 @@ main().catch((error) => { // Given input: https://docs.github.com/en/copilot/managing-copilot/ // Use: copilot/managing-copilot -function getCleanPath(providedPath) { +function getCleanPath(providedPath: string): string { let clean = providedPath const cleanArr = clean.split('?') // remove query params if (cleanArr.length > 1) cleanArr.pop() @@ -454,13 +522,13 @@ function getCleanPath(providedPath) { return clean } -function getVersion(cleanPath) { +function getVersion(cleanPath: string): string { const pathParts = cleanPath.split('/') const version = ENTERPRISE_REGEX.test(pathParts[0]) ? pathParts[0] : FREE_PRO_TEAM return version } -function removeVersionSegment(cleanPath, version) { +function removeVersionSegment(cleanPath: string, version: string): string { if (version === FREE_PRO_TEAM) return cleanPath const pathParts = cleanPath.split('/') pathParts.shift() @@ -469,7 +537,7 @@ function removeVersionSegment(cleanPath, version) { } // Try to find the path in the list of valid pages at https://docs.github.com/api/pagelist/en -async function validatePath(cleanPath, version) { +async function validatePath(cleanPath: string, version: string): Promise { // Only Kusto uses 'index' for the homepage; the Docs API uses '/en' const basePath = cleanPath === 'index' ? '' : cleanPath @@ -478,16 +546,18 @@ async function validatePath(cleanPath, version) { ? path.join('/', 'en', basePath) : path.join('/', 'en', version, basePath) - let data + let data: string try { const response = await fetch(VERSIONED_DOCS_API_PATH) data = await response.text() } catch (err) { console.error(`Error fetching data from ${VERSIONED_DOCS_API_PATH}`) + throw err } if (data.startsWith('{')) { - if (JSON.parse(data).error) { + const parsedData = JSON.parse(data) + if (parsedData.error) { console.error(data) process.exit(1) } diff --git a/src/rest/data/fpt-2022-11-28/schema.json b/src/rest/data/fpt-2022-11-28/schema.json index 5be0190f94e0..a50aa07118d0 100644 --- a/src/rest/data/fpt-2022-11-28/schema.json +++ b/src/rest/data/fpt-2022-11-28/schema.json @@ -250296,7 +250296,7 @@ "serverUrl": "https://api.github.com", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access", - "title": "Lists repositories that organization admins have allowed Dependabot to access when updating dependencies.", + "title": "Lists the repositories Dependabot can access in an organization", "category": "dependabot", "subcategory": "repository-access", "parameters": [ @@ -251022,7 +251022,7 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nUnauthorized users will not see the existence of this endpoint.

\n
", + "descriptionHTML": "

Lists repositories that organization admins have allowed Dependabot to access when updating dependencies.

\n

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nUnauthorized users will not see the existence of this endpoint.

\n
", "statusCodes": [ { "httpStatusCode": "200", @@ -251042,7 +251042,7 @@ "serverUrl": "https://api.github.com", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access", - "title": "Updates repositories to the list of repositories that organization admins have allowed Dependabot to access when updating dependencies.", + "title": "Updates Dependabot's repository access list for an organization", "category": "dependabot", "subcategory": "repository-access", "parameters": [ @@ -251098,7 +251098,7 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nUnauthorized users will not see the existence of this endpoint.

\n
\n

Example request body:

\n
{\n  \"repository_ids_to_add\": [123, 456],\n  \"repository_ids_to_remove\": [789]\n}\n
", + "descriptionHTML": "

Updates repositories according to the list of repositories that organization admins have given Dependabot access to when they've updated dependencies.

\n

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nUnauthorized users will not see the existence of this endpoint.

\n
\n

Example request body:

\n
{\n  \"repository_ids_to_add\": [123, 456],\n  \"repository_ids_to_remove\": [789]\n}\n
", "statusCodes": [ { "httpStatusCode": "204", @@ -251176,7 +251176,7 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nSets the default level of repository access Dependabot will have while performing an update. Available values are:

\n
\n
    \n
  • 'public' - Dependabot will only have access to public repositories, unless access is explicitly granted to non-public repositories.
  • \n
  • 'internal' - Dependabot will only have access to public and internal repositories, unless access is explicitly granted to private repositories.
  • \n
\n

Unauthorized users will not see the existence of this endpoint.

", + "descriptionHTML": "

Sets the default level of repository access Dependabot will have while performing an update. Available values are:

\n
    \n
  • 'public' - Dependabot will only have access to public repositories, unless access is explicitly granted to non-public repositories.
  • \n
  • 'internal' - Dependabot will only have access to public and internal repositories, unless access is explicitly granted to private repositories.
  • \n
\n

Unauthorized users will not see the existence of this endpoint.

\n

This operation supports both server-to-server and user-to-server access.

", "statusCodes": [ { "httpStatusCode": "204", diff --git a/src/rest/data/ghec-2022-11-28/schema.json b/src/rest/data/ghec-2022-11-28/schema.json index 28534d3c88ff..1c847e4685d1 100644 --- a/src/rest/data/ghec-2022-11-28/schema.json +++ b/src/rest/data/ghec-2022-11-28/schema.json @@ -992,7 +992,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -6180,7 +6180,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -181919,6 +181919,1320 @@ } ] } + ], + "alert-dismissal-requests": [ + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/orgs/{org}/dismissal-requests/code-scanning", + "title": "List dismissal requests for code scanning alerts for an organization", + "category": "code-scanning", + "subcategory": "alert-dismissal-requests", + "parameters": [ + { + "name": "org", + "description": "

The organization name. The name is not case sensitive.

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

Filter alert dismissal requests by the handle of the GitHub user who reviewed the dismissal request.

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

Filter alert dismissal requests by the handle of the GitHub user who requested the dismissal.

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

The time period to filter by.

\n

For example, day will filter for rule suites that occurred in the past 24 hours, and week will filter for insights that occurred in the past 7 days (168 hours).

", + "in": "query", + "required": false, + "schema": { + "type": "string", + "enum": [ + "hour", + "day", + "week", + "month" + ], + "default": "month" + } + }, + { + "name": "request_status", + "description": "

Filter alert dismissal requests by status. When specified, only requests with this status will be returned.

", + "in": "query", + "required": false, + "schema": { + "type": "string", + "enum": [ + "open", + "approved", + "expired", + "denied", + "all" + ], + "default": "all" + } + }, + { + "name": "repository_name", + "description": "

The name of the repository to filter on.

", + "in": "query", + "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": "page", + "description": "

The page number of the results to fetch. For more information, see \"Using pagination in the REST API.\"

", + "in": "query", + "schema": { + "type": "integer", + "default": 1 + } + } + ], + "bodyParameters": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Organization dismissal requests for code scanning\" organization permissions": "read" + } + ] + }, + "codeExamples": [ + { + "key": "default", + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "org": "ORG" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

A list of alert dismissal requests.

", + "example": [ + { + "id": 21, + "number": 42, + "repository": { + "id": 1, + "name": "smile", + "full_name": "octo-org/smile" + }, + "organization": { + "id": 1, + "name": "octo-org" + }, + "requester": { + "actor_id": 12, + "actor_name": "monalisa" + }, + "request_type": "code_scanning_alert_dismissal", + "data": [ + { + "reason": "won't fix", + "alert_number": 1 + } + ], + "resource_identifier": "123/10", + "status": "denied", + "requester_comment": "Won't fix", + "expires_at": "2024-07-08T08:43:03Z", + "created_at": "2024-07-01T08:43:03Z", + "responses": [ + { + "id": 42, + "reviewer": { + "actor_id": 4, + "actor_name": "octocat" + }, + "status": "denied", + "created_at": "2024-07-02T08:43:04Z" + } + ], + "url": "https://api.github.com/repos/octo-org/smile/dismissal-requests/code-scanning/1", + "html_url": "https://github.com/octo-org/smile/code-scanning/alerts/1" + }, + { + "id": 12, + "number": 24, + "repository": { + "id": 1, + "name": "smile", + "full_name": "octo-org/smile" + }, + "organization": { + "id": 1, + "name": "octo-org" + }, + "requester": { + "actor_id": 12, + "actor_name": "monalisa" + }, + "request_type": "code_scanning_alert_dismissal", + "data": [ + { + "reason": "won't fix", + "alert_number": 2 + } + ], + "resource_identifier": "123/12", + "status": "denied", + "requester_comment": "Token is already revoked, I'll remove it later", + "expires_at": "2024-07-08T07:43:03Z", + "created_at": "2024-07-01T07:43:03Z", + "responses": [ + { + "id": 42, + "reviewer": { + "actor_id": 4, + "actor_name": "octocat" + }, + "status": "denied", + "created_at": "2024-07-02T08:43:04Z" + } + ], + "url": "https://api.github.com/repos/octo-org/smile/dismissal-requests/code-scanning/2", + "html_url": "https://github.com/octo-org/smile/code-scanning/alerts/2" + } + ], + "schema": { + "type": "array", + "items": { + "title": "Code scanning alert dismissal request", + "description": "Alert dismisal request made by a user asking to dismiss a code scanning alert.", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the dismissal request." + }, + "number": { + "type": "integer", + "format": "int64", + "description": "The number uniquely identifying the dismissal request within its repository." + }, + "repository": { + "type": "object", + "description": "The repository the dismissal request is for.", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the repository the dismissal request is for." + }, + "name": { + "type": "string", + "description": "The name of the repository the dismissal request is for." + }, + "full_name": { + "type": "string", + "description": "The full name of the repository the dismissal request is for." + } + } + }, + "organization": { + "type": "object", + "description": "The organization associated with the repository the dismissal request is for.", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the organization." + }, + "name": { + "type": "string", + "description": "The name of the organization." + } + } + }, + "requester": { + "type": "object", + "description": "The user who requested the dismissal request.", + "properties": { + "actor_id": { + "type": "integer", + "format": "int64", + "description": "The ID of the GitHub user who requested the dismissal request." + }, + "actor_name": { + "type": "string", + "description": "The name of the GitHub user who requested the dismissal request." + } + } + }, + "request_type": { + "type": "string", + "description": "The type of request." + }, + "data": { + "type": [ + "array", + "null" + ], + "description": "Data describing the dismissal request metadata.", + "items": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "The reason for the dismissal request." + }, + "alert_number": { + "type": "string", + "description": "alert number." + }, + "pr_review_thread_id": { + "type": "string", + "description": "The ID of the pull request review thread." + } + } + } + }, + "resource_identifier": { + "type": "string", + "description": "The unique identifier for the request type of the dismissal request.", + "examples": [ + "827efc6d56897b048c772eb4087f854f46256132" + ] + }, + "status": { + "type": "string", + "description": "The status of the dismissal request.", + "enum": [ + "pending", + "denied", + "approved", + "expired" + ] + }, + "requester_comment": { + "type": [ + "string", + "null" + ], + "description": "The comment the requester provided when creating the dismissal request." + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the dismissal request will expire." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the dismissal request was created." + }, + "responses": { + "type": [ + "array", + "null" + ], + "description": "The responses to the dismissal request.", + "items": { + "title": "Dismissal request response", + "description": "A response made by a requester to dismiss the request.", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the response to the dismissal request." + }, + "reviewer": { + "type": "object", + "description": "The user who reviewed the dismissal request.", + "properties": { + "actor_id": { + "type": "integer", + "format": "int64", + "description": "The ID of the GitHub user who reviewed the dismissal request." + }, + "actor_name": { + "type": "string", + "description": "The name of the GitHub user who reviewed the dismissal request." + } + } + }, + "message": { + "type": [ + "string", + "null" + ], + "description": "The response comment of the reviewer." + }, + "status": { + "type": "string", + "description": "The response status to the dismissal request until dismissed.", + "enum": [ + "approved", + "denied", + "dismissed" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the response to the dismissal request was created." + } + } + } + }, + "url": { + "type": "string", + "format": "uri", + "examples": [ + "https://api.github.com/repos/octo-org/smile/dismissal-requests/code-scanning/1" + ] + }, + "html_url": { + "type": "string", + "description": "The URL to view the dismissal request in a browser.", + "format": "uri", + "examples": [ + "https://github.com/octo-org/smile/code-scanning/alerts/1" + ] + } + } + } + } + } + } + ], + "previews": [], + "descriptionHTML": "

Lists dismissal requests for code scanning alerts for all repositories in an organization.

\n

The user must be authorized to review dismissal requests for the organization.\nPersonal access tokens (classic) need the security_events scope to use this endpoint.

", + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

A list of alert dismissal requests.

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

Forbidden

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

Resource not found

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

Validation failed, or the endpoint has been spammed.

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

Internal Error

" + } + ] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning", + "title": "List dismissal requests for code scanning alerts for a repository", + "category": "code-scanning", + "subcategory": "alert-dismissal-requests", + "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": "reviewer", + "description": "

Filter alert dismissal requests by the handle of the GitHub user who reviewed the dismissal request.

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

Filter alert dismissal requests by the handle of the GitHub user who requested the dismissal.

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

The time period to filter by.

\n

For example, day will filter for rule suites that occurred in the past 24 hours, and week will filter for insights that occurred in the past 7 days (168 hours).

", + "in": "query", + "required": false, + "schema": { + "type": "string", + "enum": [ + "hour", + "day", + "week", + "month" + ], + "default": "month" + } + }, + { + "name": "request_status", + "description": "

Filter alert dismissal requests by status. When specified, only requests with this status will be returned.

", + "in": "query", + "required": false, + "schema": { + "type": "string", + "enum": [ + "open", + "approved", + "expired", + "denied", + "all" + ], + "default": "all" + } + }, + { + "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": "page", + "description": "

The page number of the results to fetch. For more information, see \"Using pagination in the REST API.\"

", + "in": "query", + "schema": { + "type": "integer", + "default": 1 + } + } + ], + "bodyParameters": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Organization dismissal requests for code scanning\" organization permissions": "read", + "\"Code scanning alerts\" repository permissions": "read" + } + ] + }, + "codeExamples": [ + { + "key": "default", + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

A list of alert dismissal requests.

", + "example": [ + { + "id": 21, + "number": 42, + "repository": { + "id": 1, + "name": "smile", + "full_name": "octo-org/smile" + }, + "organization": { + "id": 1, + "name": "octo-org" + }, + "requester": { + "actor_id": 12, + "actor_name": "monalisa" + }, + "request_type": "code_scanning_alert_dismissal", + "data": [ + { + "reason": "won't fix", + "alert_number": 1 + } + ], + "resource_identifier": "123/10", + "status": "denied", + "requester_comment": "Won't fix", + "expires_at": "2024-07-08T08:43:03Z", + "created_at": "2024-07-01T08:43:03Z", + "responses": [ + { + "id": 42, + "reviewer": { + "actor_id": 4, + "actor_name": "octocat" + }, + "status": "denied", + "created_at": "2024-07-02T08:43:04Z" + } + ], + "url": "https://api.github.com/repos/octo-org/smile/dismissal-requests/code-scanning/1", + "html_url": "https://github.com/octo-org/smile/code-scanning/alerts/1" + }, + { + "id": 12, + "number": 24, + "repository": { + "id": 1, + "name": "smile", + "full_name": "octo-org/smile" + }, + "organization": { + "id": 1, + "name": "octo-org" + }, + "requester": { + "actor_id": 12, + "actor_name": "monalisa" + }, + "request_type": "code_scanning_alert_dismissal", + "data": [ + { + "reason": "won't fix", + "alert_number": 2 + } + ], + "resource_identifier": "123/12", + "status": "denied", + "requester_comment": "Token is already revoked, I'll remove it later", + "expires_at": "2024-07-08T07:43:03Z", + "created_at": "2024-07-01T07:43:03Z", + "responses": [ + { + "id": 42, + "reviewer": { + "actor_id": 4, + "actor_name": "octocat" + }, + "status": "denied", + "created_at": "2024-07-02T08:43:04Z" + } + ], + "url": "https://api.github.com/repos/octo-org/smile/dismissal-requests/code-scanning/2", + "html_url": "https://github.com/octo-org/smile/code-scanning/alerts/2" + } + ], + "schema": { + "type": "array", + "items": { + "title": "Code scanning alert dismissal request", + "description": "Alert dismisal request made by a user asking to dismiss a code scanning alert.", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the dismissal request." + }, + "number": { + "type": "integer", + "format": "int64", + "description": "The number uniquely identifying the dismissal request within its repository." + }, + "repository": { + "type": "object", + "description": "The repository the dismissal request is for.", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the repository the dismissal request is for." + }, + "name": { + "type": "string", + "description": "The name of the repository the dismissal request is for." + }, + "full_name": { + "type": "string", + "description": "The full name of the repository the dismissal request is for." + } + } + }, + "organization": { + "type": "object", + "description": "The organization associated with the repository the dismissal request is for.", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the organization." + }, + "name": { + "type": "string", + "description": "The name of the organization." + } + } + }, + "requester": { + "type": "object", + "description": "The user who requested the dismissal request.", + "properties": { + "actor_id": { + "type": "integer", + "format": "int64", + "description": "The ID of the GitHub user who requested the dismissal request." + }, + "actor_name": { + "type": "string", + "description": "The name of the GitHub user who requested the dismissal request." + } + } + }, + "request_type": { + "type": "string", + "description": "The type of request." + }, + "data": { + "type": [ + "array", + "null" + ], + "description": "Data describing the dismissal request metadata.", + "items": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "The reason for the dismissal request." + }, + "alert_number": { + "type": "string", + "description": "alert number." + }, + "pr_review_thread_id": { + "type": "string", + "description": "The ID of the pull request review thread." + } + } + } + }, + "resource_identifier": { + "type": "string", + "description": "The unique identifier for the request type of the dismissal request.", + "examples": [ + "827efc6d56897b048c772eb4087f854f46256132" + ] + }, + "status": { + "type": "string", + "description": "The status of the dismissal request.", + "enum": [ + "pending", + "denied", + "approved", + "expired" + ] + }, + "requester_comment": { + "type": [ + "string", + "null" + ], + "description": "The comment the requester provided when creating the dismissal request." + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the dismissal request will expire." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the dismissal request was created." + }, + "responses": { + "type": [ + "array", + "null" + ], + "description": "The responses to the dismissal request.", + "items": { + "title": "Dismissal request response", + "description": "A response made by a requester to dismiss the request.", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the response to the dismissal request." + }, + "reviewer": { + "type": "object", + "description": "The user who reviewed the dismissal request.", + "properties": { + "actor_id": { + "type": "integer", + "format": "int64", + "description": "The ID of the GitHub user who reviewed the dismissal request." + }, + "actor_name": { + "type": "string", + "description": "The name of the GitHub user who reviewed the dismissal request." + } + } + }, + "message": { + "type": [ + "string", + "null" + ], + "description": "The response comment of the reviewer." + }, + "status": { + "type": "string", + "description": "The response status to the dismissal request until dismissed.", + "enum": [ + "approved", + "denied", + "dismissed" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the response to the dismissal request was created." + } + } + } + }, + "url": { + "type": "string", + "format": "uri", + "examples": [ + "https://api.github.com/repos/octo-org/smile/dismissal-requests/code-scanning/1" + ] + }, + "html_url": { + "type": "string", + "description": "The URL to view the dismissal request in a browser.", + "format": "uri", + "examples": [ + "https://github.com/octo-org/smile/code-scanning/alerts/1" + ] + } + } + } + } + } + } + ], + "previews": [], + "descriptionHTML": "

Lists dismissal requests for code scanning alerts for a repository.

\n

Delegated alert dismissal must be enabled on the repository.\nPersonal access tokens (classic) need the security_events scope to use this endpoint.

", + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

A list of alert dismissal requests.

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

Forbidden

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

Resource not found

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

Internal Error

" + } + ] + }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "title": "Get a dismissal request for a code scanning alert for a repository", + "category": "code-scanning", + "subcategory": "alert-dismissal-requests", + "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": "alert_number", + "in": "path", + "required": true, + "description": "

The number that identifies the code scanning alert.

", + "schema": { + "type": "integer" + } + } + ], + "bodyParameters": [], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Organization dismissal requests for code scanning\" organization permissions": "read", + "\"Code scanning alerts\" repository permissions": "read" + } + ] + }, + "codeExamples": [ + { + "key": "default", + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "alert_number": "ALERT_NUMBER" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

A single dismissal request.

", + "example": { + "id": 21, + "number": 42, + "repository": { + "id": 1, + "name": "smile", + "full_name": "octo-org/smile" + }, + "organization": { + "id": 1, + "name": "octo-org" + }, + "requester": { + "actor_id": 12, + "actor_name": "monalisa" + }, + "request_type": "code_scanning_alert_dismissal", + "data": [ + { + "reason": "won't fix", + "alert_number": 2 + } + ], + "resource_identifier": "1/1", + "status": "denied", + "requester_comment": "Won't fix", + "expires_at": "2024-07-08T08:43:03Z", + "created_at": "2024-07-01T08:43:03Z", + "responses": [ + { + "id": 42, + "reviewer": { + "actor_id": 4, + "actor_name": "octocat" + }, + "status": "denied", + "created_at": "2024-07-02T08:43:04Z" + } + ], + "url": "https://api.github.com/repos/octo-org/smile/dismissal-requests/code-scanning/1", + "html_url": "https://github.com/octo-org/smile/code-scanning/alerts/1" + }, + "schema": { + "title": "Code scanning alert dismissal request", + "description": "Alert dismisal request made by a user asking to dismiss a code scanning alert.", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The unique identifier of the dismissal request." + }, + "number": { + "type": "integer", + "format": "int64", + "description": "The number uniquely identifying the dismissal request within its repository." + }, + "repository": { + "type": "object", + "description": "The repository the dismissal request is for.", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the repository the dismissal request is for." + }, + "name": { + "type": "string", + "description": "The name of the repository the dismissal request is for." + }, + "full_name": { + "type": "string", + "description": "The full name of the repository the dismissal request is for." + } + } + }, + "organization": { + "type": "object", + "description": "The organization associated with the repository the dismissal request is for.", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the organization." + }, + "name": { + "type": "string", + "description": "The name of the organization." + } + } + }, + "requester": { + "type": "object", + "description": "The user who requested the dismissal request.", + "properties": { + "actor_id": { + "type": "integer", + "format": "int64", + "description": "The ID of the GitHub user who requested the dismissal request." + }, + "actor_name": { + "type": "string", + "description": "The name of the GitHub user who requested the dismissal request." + } + } + }, + "request_type": { + "type": "string", + "description": "The type of request." + }, + "data": { + "type": [ + "array", + "null" + ], + "description": "Data describing the dismissal request metadata.", + "items": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "The reason for the dismissal request." + }, + "alert_number": { + "type": "string", + "description": "alert number." + }, + "pr_review_thread_id": { + "type": "string", + "description": "The ID of the pull request review thread." + } + } + } + }, + "resource_identifier": { + "type": "string", + "description": "The unique identifier for the request type of the dismissal request.", + "examples": [ + "827efc6d56897b048c772eb4087f854f46256132" + ] + }, + "status": { + "type": "string", + "description": "The status of the dismissal request.", + "enum": [ + "pending", + "denied", + "approved", + "expired" + ] + }, + "requester_comment": { + "type": [ + "string", + "null" + ], + "description": "The comment the requester provided when creating the dismissal request." + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the dismissal request will expire." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the dismissal request was created." + }, + "responses": { + "type": [ + "array", + "null" + ], + "description": "The responses to the dismissal request.", + "items": { + "title": "Dismissal request response", + "description": "A response made by a requester to dismiss the request.", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "The ID of the response to the dismissal request." + }, + "reviewer": { + "type": "object", + "description": "The user who reviewed the dismissal request.", + "properties": { + "actor_id": { + "type": "integer", + "format": "int64", + "description": "The ID of the GitHub user who reviewed the dismissal request." + }, + "actor_name": { + "type": "string", + "description": "The name of the GitHub user who reviewed the dismissal request." + } + } + }, + "message": { + "type": [ + "string", + "null" + ], + "description": "The response comment of the reviewer." + }, + "status": { + "type": "string", + "description": "The response status to the dismissal request until dismissed.", + "enum": [ + "approved", + "denied", + "dismissed" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time the response to the dismissal request was created." + } + } + } + }, + "url": { + "type": "string", + "format": "uri", + "examples": [ + "https://api.github.com/repos/octo-org/smile/dismissal-requests/code-scanning/1" + ] + }, + "html_url": { + "type": "string", + "description": "The URL to view the dismissal request in a browser.", + "format": "uri", + "examples": [ + "https://github.com/octo-org/smile/code-scanning/alerts/1" + ] + } + } + } + } + } + ], + "previews": [], + "descriptionHTML": "

Gets a dismissal request to dismiss a code scanning alert in a repository.

\n

Delegated alert dismissal must be enabled on the repository.\nPersonal access tokens (classic) need the security_events scope to use this endpoint.

", + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

A single dismissal request.

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

Forbidden

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

Resource not found

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

Internal Error

" + } + ] + }, + { + "serverUrl": "https://api.github.com", + "verb": "patch", + "requestPath": "/repos/{owner}/{repo}/dismissal-requests/code-scanning/{alert_number}", + "title": "Review a dismissal request for a code scanning alert for a repository", + "category": "code-scanning", + "subcategory": "alert-dismissal-requests", + "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": "alert_number", + "in": "path", + "required": true, + "description": "

The number that identifies the code scanning alert.

", + "schema": { + "type": "integer" + } + } + ], + "bodyParameters": [ + { + "type": "string", + "name": "status", + "in": "body", + "description": "

The review action to perform on the bypass request.

", + "isRequired": true, + "enum": [ + "approve", + "deny" + ] + }, + { + "type": "string", + "name": "message", + "in": "body", + "description": "

A message to include with the review. Has a maximum character length of 2048.

", + "isRequired": true + } + ], + "progAccess": { + "userToServerRest": true, + "serverToServer": true, + "fineGrainedPat": true, + "permissions": [ + { + "\"Organization dismissal requests for code scanning\" organization permissions": "write", + "\"Code scanning alerts\" repository permissions": "read" + } + ] + }, + "codeExamples": [ + { + "key": "default", + "request": { + "contentType": "application/json", + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "bodyParameters": { + "status": "approve", + "message": "Used in tests." + }, + "parameters": { + "owner": "OWNER", + "repo": "REPO", + "alert_number": "ALERT_NUMBER" + } + }, + "response": { + "statusCode": "204", + "description": "

Successful update

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

Approve or deny a dismissal request to dismiss a code scanning alert in a repository.

\n

Delegated alert dismissal must be enabled on the repository and the user must be a dismissal reviewer to access this endpoint.\nPersonal access tokens (classic) need the security_events scope to use this endpoint.

", + "statusCodes": [ + { + "httpStatusCode": "204", + "description": "

Successful update

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

Forbidden

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

Resource not found

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

Validation failed, or the endpoint has been spammed.

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

Internal Error

" + } + ] + } ] }, "code-security": { @@ -264451,7 +265765,7 @@ "serverUrl": "https://api.github.com", "verb": "get", "requestPath": "/organizations/{org}/dependabot/repository-access", - "title": "Lists repositories that organization admins have allowed Dependabot to access when updating dependencies.", + "title": "Lists the repositories Dependabot can access in an organization", "category": "dependabot", "subcategory": "repository-access", "parameters": [ @@ -265177,7 +266491,7 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nUnauthorized users will not see the existence of this endpoint.

\n
", + "descriptionHTML": "

Lists repositories that organization admins have allowed Dependabot to access when updating dependencies.

\n

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nUnauthorized users will not see the existence of this endpoint.

\n
", "statusCodes": [ { "httpStatusCode": "200", @@ -265197,7 +266511,7 @@ "serverUrl": "https://api.github.com", "verb": "patch", "requestPath": "/organizations/{org}/dependabot/repository-access", - "title": "Updates repositories to the list of repositories that organization admins have allowed Dependabot to access when updating dependencies.", + "title": "Updates Dependabot's repository access list for an organization", "category": "dependabot", "subcategory": "repository-access", "parameters": [ @@ -265253,7 +266567,7 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nUnauthorized users will not see the existence of this endpoint.

\n
\n

Example request body:

\n
{\n  \"repository_ids_to_add\": [123, 456],\n  \"repository_ids_to_remove\": [789]\n}\n
", + "descriptionHTML": "

Updates repositories according to the list of repositories that organization admins have given Dependabot access to when they've updated dependencies.

\n

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nUnauthorized users will not see the existence of this endpoint.

\n
\n

Example request body:

\n
{\n  \"repository_ids_to_add\": [123, 456],\n  \"repository_ids_to_remove\": [789]\n}\n
", "statusCodes": [ { "httpStatusCode": "204", @@ -265331,7 +266645,7 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nThis operation supports both server-to-server and user-to-server access.\nSets the default level of repository access Dependabot will have while performing an update. Available values are:

\n
\n
    \n
  • 'public' - Dependabot will only have access to public repositories, unless access is explicitly granted to non-public repositories.
  • \n
  • 'internal' - Dependabot will only have access to public and internal repositories, unless access is explicitly granted to private repositories.
  • \n
\n

Unauthorized users will not see the existence of this endpoint.

", + "descriptionHTML": "

Sets the default level of repository access Dependabot will have while performing an update. Available values are:

\n
    \n
  • 'public' - Dependabot will only have access to public repositories, unless access is explicitly granted to non-public repositories.
  • \n
  • 'internal' - Dependabot will only have access to public and internal repositories, unless access is explicitly granted to private repositories.
  • \n
\n

Unauthorized users will not see the existence of this endpoint.

\n

This operation supports both server-to-server and user-to-server access.

", "statusCodes": [ { "httpStatusCode": "204", @@ -280528,7 +281842,7 @@ "\"Administration\" organization permissions": "read" }, { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -281042,7 +282356,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -282590,7 +283904,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -282774,7 +284088,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -283066,6 +284380,405 @@ } ] }, + { + "serverUrl": "https://api.github.com", + "verb": "get", + "requestPath": "/enterprises/{enterprise}/settings/billing/cost-centers/{cost_center_id}", + "title": "Get a cost center by ID", + "category": "enterprise-admin", + "subcategory": "billing", + "parameters": [ + { + "name": "enterprise", + "description": "

The slug version of the enterprise name. You can also substitute this value with the enterprise id.

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

The ID corresponding to the cost center.

", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "progAccess": { + "userToServerRest": false, + "serverToServer": false, + "fineGrainedPat": false, + "permissions": [] + }, + "codeExamples": [ + { + "key": "default", + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "enterprise": "ENTERPRISE", + "cost_center_id": "COST_CENTER_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

Response when getting a cost center

", + "example": [ + { + "id": "2eeb8ffe-6903-11ee-8c99-0242ac120002", + "name": "Cost Center Name", + "resources": [ + { + "type": "User", + "name": "Monalisa" + }, + { + "type": "Repo", + "name": "octocat/hello-world" + } + ] + } + ], + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "ID of the cost center." + }, + "name": { + "type": "string", + "description": "Name of the cost center." + }, + "resources": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of the resource." + }, + "name": { + "type": "string", + "description": "Name of the resource." + } + }, + "required": [ + "type", + "name" + ] + } + } + }, + "required": [ + "id", + "name", + "resources" + ] + } + } + } + ], + "previews": [], + "descriptionHTML": "

Gets a cost center by ID. The authenticated user must be an enterprise admin.

", + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

Response when getting a cost center

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

Bad Request

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

Forbidden

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

Internal Error

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

Service unavailable

" + } + ] + }, + { + "serverUrl": "https://api.github.com", + "verb": "patch", + "requestPath": "/enterprises/{enterprise}/settings/billing/cost-centers/{cost_center_id}", + "title": "Update a cost center name", + "category": "enterprise-admin", + "subcategory": "billing", + "parameters": [ + { + "name": "enterprise", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "

The slug version of the enterprise name

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

The unique identifier of the cost center

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

The new name for the cost center

", + "isRequired": true + } + ], + "progAccess": { + "userToServerRest": false, + "serverToServer": false, + "fineGrainedPat": false, + "permissions": [] + }, + "codeExamples": [ + { + "key": "update-cost-center", + "request": { + "contentType": "application/json", + "description": "Update cost center name example", + "acceptHeader": "application/vnd.github.v3+json", + "bodyParameters": { + "name": "New Cost Center Name" + }, + "parameters": { + "enterprise": "ENTERPRISE", + "cost_center_id": "COST_CENTER_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

Response when updating a cost center

", + "example": [ + { + "id": "2eeb8ffe-6903-11ee-8c99-0242ac120002", + "name": "Cost Center Name", + "resources": [ + { + "type": "User", + "name": "Monalisa" + }, + { + "type": "Repo", + "name": "octocat/hello-world" + } + ] + } + ], + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "ID of the cost center." + }, + "name": { + "type": "string", + "description": "Name of the cost center." + }, + "resources": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of the resource." + }, + "name": { + "type": "string", + "description": "Name of the resource." + } + }, + "required": [ + "type", + "name" + ] + } + } + }, + "required": [ + "id", + "name", + "resources" + ] + } + } + } + ], + "previews": [], + "descriptionHTML": "

Updates an existing cost center name.

", + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

Response when updating a cost center

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

Bad Request

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

Forbidden

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

Resource not found

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

Conflict

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

Internal Error

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

Service unavailable

" + } + ] + }, + { + "serverUrl": "https://api.github.com", + "verb": "delete", + "requestPath": "/enterprises/{enterprise}/settings/billing/cost-centers/{cost_center_id}", + "title": "Delete a cost center", + "category": "enterprise-admin", + "subcategory": "billing", + "parameters": [ + { + "name": "enterprise", + "description": "

The slug version of the enterprise name. You can also substitute this value with the enterprise id.

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

The ID corresponding to the cost center.

", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "bodyParameters": [], + "progAccess": { + "userToServerRest": false, + "serverToServer": false, + "fineGrainedPat": false, + "permissions": [] + }, + "codeExamples": [ + { + "key": "default", + "request": { + "description": "Example", + "acceptHeader": "application/vnd.github.v3+json", + "parameters": { + "enterprise": "ENTERPRISE", + "cost_center_id": "COST_CENTER_ID" + } + }, + "response": { + "statusCode": "200", + "contentType": "application/json", + "description": "

Response when deleting a cost center

", + "example": { + "message": "Cost center successfully deleted.", + "id": "2066deda-923f-43f9-88d2-62395a28c0cdd", + "name": "cc3", + "costCenterState": "CostCenterArchived" + }, + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "A message indicating the result of the deletion operation" + }, + "id": { + "type": "string", + "description": "The unique identifier of the deleted cost center" + }, + "name": { + "type": "string", + "description": "The name of the deleted cost center" + }, + "costCenterState": { + "type": "string", + "enum": [ + "CostCenterArchived" + ], + "description": "The state of the cost center after deletion" + } + }, + "required": [ + "message", + "id", + "name", + "costCenterState" + ] + } + } + } + ], + "previews": [], + "descriptionHTML": "

Archieves a cost center by ID. The authenticated user must be an enterprise admin.

", + "statusCodes": [ + { + "httpStatusCode": "200", + "description": "

Response when deleting a cost center

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

Bad Request

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

Forbidden

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

Resource not found

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

Internal Error

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

Service unavailable

" + } + ] + }, { "serverUrl": "https://api.github.com", "verb": "post", @@ -283297,7 +285010,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -283379,7 +285092,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -284440,7 +286153,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Custom properties\" business permissions": "read" + "\"Custom properties\" enterprise permissions": "read" } ] }, @@ -284708,7 +286421,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Custom properties\" business permissions": "write" + "\"Custom properties\" enterprise permissions": "write" } ] }, @@ -284948,7 +286661,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Custom properties\" business permissions": "write" + "\"Custom properties\" enterprise permissions": "write" } ] }, @@ -285136,7 +286849,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Custom properties\" business permissions": "read" + "\"Custom properties\" enterprise permissions": "read" } ] }, @@ -285372,7 +287085,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Custom properties\" business permissions": "write" + "\"Custom properties\" enterprise permissions": "write" } ] }, @@ -285570,7 +287283,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Custom properties\" business permissions": "write" + "\"Custom properties\" enterprise permissions": "write" } ] }, @@ -285653,7 +287366,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -285888,7 +287601,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -288097,7 +289810,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -289480,7 +291193,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -292151,7 +293864,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -293535,7 +295248,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -293967,7 +295680,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -294327,7 +296040,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -294620,7 +296333,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -294937,7 +296650,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -295477,7 +297190,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -295990,7 +297703,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -296114,7 +297827,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -296655,7 +298368,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -297372,7 +299085,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -297873,7 +299586,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -298311,7 +300024,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -299319,7 +301032,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, diff --git a/src/rest/data/ghes-3.13-2022-11-28/schema.json b/src/rest/data/ghes-3.13-2022-11-28/schema.json index cbbfc3d6f5b1..3f2889daee5e 100644 --- a/src/rest/data/ghes-3.13-2022-11-28/schema.json +++ b/src/rest/data/ghes-3.13-2022-11-28/schema.json @@ -957,7 +957,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1033,7 +1033,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1126,7 +1126,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1846,13 +1846,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists the GitHub Actions caches for a repository.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists the GitHub Actions caches for a repository.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -2168,13 +2168,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets the customization template for an OpenID Connect (OIDC) subject claim.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

A JSON serialized template for OIDC subject claim customization

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

Gets the customization template for an OpenID Connect (OIDC) subject claim.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -2634,13 +2634,13 @@ } ], "previews": [], - "descriptionHTML": "

Sets the GitHub Actions permissions policy for organizations and allowed actions in an enterprise.

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Sets the GitHub Actions permissions policy for organizations and allowed actions in an enterprise.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -2961,13 +2961,13 @@ } ], "previews": [], - "descriptionHTML": "

Adds an organization to the list of selected organizations that are enabled for GitHub Actions in an enterprise. To use this endpoint, the enterprise permission policy for enabled_organizations must be configured to selected. For more information, see \"Set GitHub Actions permissions for an enterprise.\"

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Adds an organization to the list of selected organizations that are enabled for GitHub Actions in an enterprise. To use this endpoint, the enterprise permission policy for enabled_organizations must be configured to selected. For more information, see \"Set GitHub Actions permissions for an enterprise.\"

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -4668,13 +4668,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists the selected repositories that are enabled for GitHub Actions in an organization. To use this endpoint, the organization permission policy for enabled_repositories must be configured to selected. For more information, see \"Set GitHub Actions permissions for an organization.\"

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists the selected repositories that are enabled for GitHub Actions in an organization. To use this endpoint, the organization permission policy for enabled_repositories must be configured to selected. For more information, see \"Set GitHub Actions permissions for an organization.\"

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -5032,13 +5032,13 @@ } ], "previews": [], - "descriptionHTML": "

Sets the actions that are allowed in an organization. To use this endpoint, the organization permission policy for allowed_actions must be configured to selected. For more information, see \"Set GitHub Actions permissions for an organization.\"

\n

If the organization belongs to an enterprise that has selected actions set at the enterprise level, then you cannot override any of the enterprise's allowed actions settings.

\n

To use the patterns_allowed setting for private repositories, the organization must belong to an enterprise. If the organization does not belong to an enterprise, then the patterns_allowed setting only applies to public repositories in the organization.

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Sets the actions that are allowed in an organization. To use this endpoint, the organization permission policy for allowed_actions must be configured to selected. For more information, see \"Set GitHub Actions permissions for an organization.\"

\n

If the organization belongs to an enterprise that has selected actions set at the enterprise level, then you cannot override any of the enterprise's allowed actions settings.

\n

To use the patterns_allowed setting for private repositories, the organization must belong to an enterprise. If the organization does not belong to an enterprise, then the patterns_allowed setting only applies to public repositories in the organization.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -5287,13 +5287,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets the GitHub Actions permissions policy for a repository, including whether GitHub Actions is enabled and the actions allowed to run in the repository.

\n

You must authenticate using an access token with the repo scope to use this endpoint. GitHub Apps must have the administration repository permission to use this API.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets the GitHub Actions permissions policy for a repository, including whether GitHub Actions is enabled and the actions allowed to run in the repository.

\n

You must authenticate using an access token with the repo scope to use this endpoint. GitHub Apps must have the administration repository permission to use this API.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -5375,13 +5375,13 @@ } ], "previews": [], - "descriptionHTML": "

Sets the GitHub Actions permissions policy for enabling GitHub Actions and allowed actions in the repository.

\n

If the repository belongs to an organization or enterprise that has set restrictive permissions at the organization or enterprise levels, such as allowed_actions to selected actions, then you cannot override them for the repository.

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Sets the GitHub Actions permissions policy for enabling GitHub Actions and allowed actions in the repository.

\n

If the repository belongs to an organization or enterprise that has set restrictive permissions at the organization or enterprise levels, such as allowed_actions to selected actions, then you cannot override them for the repository.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -6066,13 +6066,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists all secrets available in an organization without revealing their\nencrypted values.

\n

Authenticated users must have collaborator access to a repository to create, update, or read secrets.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists all secrets available in an organization without revealing their\nencrypted values.

\n

Authenticated users must have collaborator access to a repository to create, update, or read secrets.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -6174,13 +6174,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets your public key, which you need to encrypt secrets. You need to\nencrypt a secret before you can create or update secrets.

\n

The authenticated user must have collaborator access to a repository to create, update, or read secrets.

\n

OAuth tokens and personal access tokens (classic) need theadmin:org scope to use this endpoint. If the repository is private, OAuth tokens and personal access tokens (classic) need the repo scope to use this endpoint.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets your public key, which you need to encrypt secrets. You need to\nencrypt a secret before you can create or update secrets.

\n

The authenticated user must have collaborator access to a repository to create, update, or read secrets.

\n

OAuth tokens and personal access tokens (classic) need theadmin:org scope to use this endpoint. If the repository is private, OAuth tokens and personal access tokens (classic) need the repo scope to use this endpoint.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -6499,13 +6499,13 @@ } ], "previews": [], - "descriptionHTML": "

Deletes a secret in an organization using the secret name.

\n

Authenticated users must have collaborator access to a repository to create, update, or read secrets.

\n

OAuth tokens and personal access tokens (classic) need theadmin:org scope to use this endpoint. If the repository is private, OAuth tokens and personal access tokens (classic) need the repo scope to use this endpoint.

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Deletes a secret in an organization using the secret name.

\n

Authenticated users must have collaborator access to a repository to create, update, or read secrets.

\n

OAuth tokens and personal access tokens (classic) need theadmin:org scope to use this endpoint. If the repository is private, OAuth tokens and personal access tokens (classic) need the repo scope to use this endpoint.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -10070,13 +10070,13 @@ } ], "previews": [], - "descriptionHTML": "

Replaces the list of organizations that have access to a self-hosted runner configured in an enterprise.

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Replaces the list of organizations that have access to a self-hosted runner configured in an enterprise.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -10140,13 +10140,13 @@ } ], "previews": [], - "descriptionHTML": "

Adds an organization to the list of selected organizations that can access a self-hosted runner group. The runner group must have visibility set to selected. For more information, see \"Create a self-hosted runner group for an enterprise.\"

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Adds an organization to the list of selected organizations that can access a self-hosted runner group. The runner group must have visibility set to selected. For more information, see \"Create a self-hosted runner group for an enterprise.\"

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -10664,13 +10664,13 @@ } ], "previews": [], - "descriptionHTML": "

Removes a self-hosted runner from a group configured in an enterprise. The runner is then returned to the default group.

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Removes a self-hosted runner from a group configured in an enterprise. The runner is then returned to the default group.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -11462,13 +11462,13 @@ } ], "previews": [], - "descriptionHTML": "

Deletes a self-hosted runner group for an organization.

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Deletes a self-hosted runner group for an organization.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -14974,13 +14974,13 @@ } ], "previews": [], - "descriptionHTML": "

Returns a token that you can pass to the config script. The token expires after one hour.

\n

Example using registration token:

\n

Configure your self-hosted runner, replacing TOKEN with the registration token provided by this endpoint.

\n
./config.sh --url https://github.com/enterprises/octo-enterprise --token TOKEN\n
\n

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

", "statusCodes": [ { "httpStatusCode": "201", "description": "

Created

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

Returns a token that you can pass to the config script. The token expires after one hour.

\n

Example using registration token:

\n

Configure your self-hosted runner, replacing TOKEN with the registration token provided by this endpoint.

\n
./config.sh --url https://github.com/enterprises/octo-enterprise --token TOKEN\n
\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -20402,7 +20402,6 @@ } ], "previews": [], - "descriptionHTML": "

Remove all previous custom labels and set the new custom labels for a specific\nself-hosted runner configured in an organization.

\n

Authenticated users must have admin access to the organization to use this endpoint.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

", "statusCodes": [ { "httpStatusCode": "200", @@ -20416,7 +20415,8 @@ "httpStatusCode": "422", "description": "

Validation failed, or the endpoint has been spammed.

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

Remove all previous custom labels and set the new custom labels for a specific\nself-hosted runner configured in an organization.

\n

Authenticated users must have admin access to the organization to use this endpoint.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -24695,13 +24695,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists all organization variables.

\n

Authenticated users must have collaborator access to a repository to create, update, or read variables.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists all organization variables.

\n

Authenticated users must have collaborator access to a repository to create, update, or read variables.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -24934,13 +24934,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets a specific variable in an organization.

\n

The authenticated user must have collaborator access to a repository to create, update, or read variables.

\n

OAuth tokens and personal access tokens (classic) need theadmin:org scope to use this endpoint. If the repository is private, OAuth tokens and personal access tokens (classic) need the repo scope to use this endpoint.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets a specific variable in an organization.

\n

The authenticated user must have collaborator access to a repository to create, update, or read variables.

\n

OAuth tokens and personal access tokens (classic) need theadmin:org scope to use this endpoint. If the repository is private, OAuth tokens and personal access tokens (classic) need the repo scope to use this endpoint.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -26168,7 +26168,6 @@ } ], "previews": [], - "descriptionHTML": "

Replaces all repositories for an organization variable that is available\nto selected repositories. Organization variables that are available to selected\nrepositories have their visibility field set to selected.

\n

Authenticated users must have collaborator access to a repository to create, update, or read variables.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

", "statusCodes": [ { "httpStatusCode": "204", @@ -26178,7 +26177,8 @@ "httpStatusCode": "409", "description": "

Response when the visibility of the variable is not set to selected

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

Replaces all repositories for an organization variable that is available\nto selected repositories. Organization variables that are available to selected\nrepositories have their visibility field set to selected.

\n

Authenticated users must have collaborator access to a repository to create, update, or read variables.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -26326,7 +26326,6 @@ } ], "previews": [], - "descriptionHTML": "

Removes a repository from an organization variable that is\navailable to selected repositories. Organization variables that are available to\nselected repositories have their visibility field set to selected.

\n

Authenticated users must have collaborator access to a repository to create, update, or read variables.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

", "statusCodes": [ { "httpStatusCode": "204", @@ -26336,7 +26335,8 @@ "httpStatusCode": "409", "description": "

Response when the visibility of the variable is not set to selected

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

Removes a repository from an organization variable that is\navailable to selected repositories. Organization variables that are available to\nselected repositories have their visibility field set to selected.

\n

Authenticated users must have collaborator access to a repository to create, update, or read variables.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -55267,13 +55267,13 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nThis API is not built to serve real-time use cases. Depending on the time of day, event latency can be anywhere from 30s to 6h.

\n
", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Note

\n

\nThis API is not built to serve real-time use cases. Depending on the time of day, event latency can be anywhere from 30s to 6h.

\n
" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -82132,13 +82132,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists all notifications for the current user in the specified repository.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists all notifications for the current user in the specified repository.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -101996,13 +101996,13 @@ } ], "previews": [], - "descriptionHTML": "

Enables an authenticated GitHub App to find the user’s installation information.

\n

You must use a JWT to access this endpoint.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Enables an authenticated GitHub App to find the user’s installation information.

\n

You must use a JWT to access this endpoint.

" } ], "installations": [ @@ -118401,7 +118401,6 @@ } ], "previews": [], - "descriptionHTML": "", "statusCodes": [ { "httpStatusCode": "201", @@ -118427,7 +118426,8 @@ "httpStatusCode": "422", "description": "

Validation failed, or the endpoint has been spammed.

" } - ] + ], + "descriptionHTML": "" } ], "branch-protection": [ @@ -156852,12 +156852,6 @@ "name": "dismissed_comment", "in": "body", "description": "

The dismissal comment associated with the dismissal of the alert.

" - }, - { - "type": "boolean", - "name": "create_request", - "in": "body", - "description": "

If true, attempt to create an alert dismissal request.

" } ], "progAccess": { @@ -156880,8 +156874,7 @@ "bodyParameters": { "state": "dismissed", "dismissed_reason": "false positive", - "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library.", - "create_request": true + "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library." }, "parameters": { "owner": "OWNER", @@ -185572,13 +185565,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets your public key, which you need to encrypt secrets. You need to\nencrypt a secret before you can create or update secrets.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets your public key, which you need to encrypt secrets. You need to\nencrypt a secret before you can create or update secrets.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -187656,13 +187649,13 @@ } ], "previews": [], - "descriptionHTML": "

Deletes a secret in a repository using the secret name.

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Deletes a secret in a repository using the secret name.

\n

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

" } ] }, @@ -201044,13 +201037,13 @@ } ], "previews": [], - "descriptionHTML": "", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

" } - ] + ], + "descriptionHTML": "" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -201243,13 +201236,13 @@ } ], "previews": [], - "descriptionHTML": "", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

" } - ] + ], + "descriptionHTML": "" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -201754,7 +201747,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -202132,7 +202125,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -202276,13 +202269,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets the GitHub Advanced Security active committers for an enterprise per repository.

\n

Each distinct user login across all repositories is counted as a single Advanced Security seat, so the total_advanced_security_committers is not the sum of active_users for each repository.

\n

The total number of repositories with committer information is tracked by the total_count field.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

Success

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

Gets the GitHub Advanced Security active committers for an enterprise per repository.

\n

Each distinct user login across all repositories is counted as a single Advanced Security seat, so the total_advanced_security_committers is not the sum of active_users for each repository.

\n

The total number of repositories with committer information is tracked by the total_count field.

" } ], "code-security-and-analysis": [ @@ -208712,13 +208705,13 @@ } ], "previews": [], - "descriptionHTML": "", "statusCodes": [ { "httpStatusCode": "202", "description": "

Accepted

" } - ] + ], + "descriptionHTML": "" } ], "pre-receive-environments": [ @@ -209709,13 +209702,13 @@ } ], "previews": [], - "descriptionHTML": "", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

" } - ] + ], + "descriptionHTML": "" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -210899,7 +210892,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -211259,7 +211252,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -211552,7 +211545,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -211869,7 +211862,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -212409,7 +212402,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -212922,7 +212915,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -213046,7 +213039,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -213587,7 +213580,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -214304,7 +214297,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -214805,7 +214798,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -215243,7 +215236,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -216251,7 +216244,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -293372,13 +293365,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists labels for issues in a milestone.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists labels for issues in a milestone.

" } ], "milestones": [ @@ -293860,7 +293853,6 @@ } ], "previews": [], - "descriptionHTML": "

Lists milestones for a repository.

", "statusCodes": [ { "httpStatusCode": "200", @@ -293870,7 +293862,8 @@ "httpStatusCode": "404", "description": "

Resource not found

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

Lists milestones for a repository.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -313606,13 +313599,13 @@ } ], "previews": [], - "descriptionHTML": "

Get the octocat as ASCII art

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Get the octocat as ASCII art

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -324565,7 +324558,6 @@ } ], "previews": [], - "descriptionHTML": "

Warning

\n

\nClosing down notice: GitHub Enterprise Server will discontinue the OAuth Authorizations API, which is used by integrations to create personal access tokens and OAuth tokens, and you must now create these tokens using our web application flow. The OAuth Authorizations API will be removed on November 13, 2020. For more information, including scheduled brownouts, see the blog post.

\n
\n

You can use this API to list the set of OAuth applications that have been granted access to your account. Unlike the list your authorizations API, this API does not manage individual tokens. This API will return one entry for each OAuth application that has been granted access to your account, regardless of the number of tokens an application has generated for your user. The list of OAuth applications returned matches what is shown on the application authorizations settings screen within GitHub. The scopes returned are the union of scopes authorized for the application. For example, if an application has one token with repo scope and another token with user scope, the grant will return [\"repo\", \"user\"].

", "statusCodes": [ { "httpStatusCode": "200", @@ -324587,7 +324579,8 @@ "httpStatusCode": "404", "description": "

Resource not found

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

Warning

\n

\nClosing down notice: GitHub Enterprise Server will discontinue the OAuth Authorizations API, which is used by integrations to create personal access tokens and OAuth tokens, and you must now create these tokens using our web application flow. The OAuth Authorizations API will be removed on November 13, 2020. For more information, including scheduled brownouts, see the blog post.

\n
\n

You can use this API to list the set of OAuth applications that have been granted access to your account. Unlike the list your authorizations API, this API does not manage individual tokens. This API will return one entry for each OAuth application that has been granted access to your account, regardless of the number of tokens an application has generated for your user. The list of OAuth applications returned matches what is shown on the application authorizations settings screen within GitHub. The scopes returned are the union of scopes authorized for the application. For example, if an application has one token with repo scope and another token with user scope, the grant will return [\"repo\", \"user\"].

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -338450,13 +338443,13 @@ } ], "previews": [], - "descriptionHTML": "

Warning

\n

\nClosing down notice: This operation is closing down and will be removed in the future. Use the \"List custom repository roles\" endpoint instead.

\n
\n

List the custom repository roles available in this organization. For more information on custom repository roles, see \"About custom repository roles.\"

\n

The authenticated user must be administrator of the organization or of a repository of the organization to use this endpoint.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

Response - list of custom role names

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

Warning

\n

\nClosing down notice: This operation is closing down and will be removed in the future. Use the \"List custom repository roles\" endpoint instead.

\n
\n

List the custom repository roles available in this organization. For more information on custom repository roles, see \"About custom repository roles.\"

\n

The authenticated user must be administrator of the organization or of a repository of the organization to use this endpoint.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -341713,13 +341706,13 @@ } ], "previews": [], - "descriptionHTML": "

Members of an organization can choose to have their membership publicized or not.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Members of an organization can choose to have their membership publicized or not.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -341778,7 +341771,6 @@ } ], "previews": [], - "descriptionHTML": "

Check if the provided user is a public member of the organization.

", "statusCodes": [ { "httpStatusCode": "204", @@ -341788,7 +341780,8 @@ "httpStatusCode": "404", "description": "

Not Found if user is not a public member

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

Check if the provided user is a public member of the organization.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -343781,7 +343774,6 @@ } ], "previews": [], - "descriptionHTML": "

Removing a user from this list will remove them from all the organization's repositories.

", "statusCodes": [ { "httpStatusCode": "204", @@ -343791,7 +343783,8 @@ "httpStatusCode": "422", "description": "

Unprocessable Entity if user is a member of the organization

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

Removing a user from this list will remove them from all the organization's repositories.

" } ], "personal-access-tokens": [ @@ -355478,13 +355471,13 @@ } ], "previews": [], - "descriptionHTML": "

Returns the webhook configuration for an organization. To get more information about the webhook, including the active state and events, use \"Get an organization webhook .\"

\n

You must be an organization owner to use this endpoint.

\n

OAuth app tokens and personal access tokens (classic) need admin:org_hook scope. OAuth apps cannot list, view, or edit\nwebhooks that they did not create and users cannot list, view, or edit webhooks that were created by OAuth apps.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Returns the webhook configuration for an organization. To get more information about the webhook, including the active state and events, use \"Get an organization webhook .\"

\n

You must be an organization owner to use this endpoint.

\n

OAuth app tokens and personal access tokens (classic) need admin:org_hook scope. OAuth apps cannot list, view, or edit\nwebhooks that they did not create and users cannot list, view, or edit webhooks that were created by OAuth apps.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -372738,7 +372731,6 @@ } ], "previews": [], - "descriptionHTML": "

Lists the projects in an organization. Returns a 404 Not Found status if projects are disabled in the organization. If you do not have sufficient privileges to perform this action, a 401 Unauthorized or 410 Gone status is returned.

", "statusCodes": [ { "httpStatusCode": "200", @@ -372748,7 +372740,8 @@ "httpStatusCode": "422", "description": "

Validation failed, or the endpoint has been spammed.

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

Lists the projects in an organization. Returns a 404 Not Found status if projects are disabled in the organization. If you do not have sufficient privileges to perform this action, a 401 Unauthorized or 410 Gone status is returned.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -400895,13 +400888,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists review comments for all pull requests in a repository. By default,\nreview comments are in ascending order by ID.

\n

This endpoint supports the following custom media types. For more information, see \"Media types.\"

\n
    \n
  • application/vnd.github-commitcomment.raw+json: Returns the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
  • \n
  • application/vnd.github-commitcomment.text+json: Returns a text only representation of the markdown body. Response will include body_text.
  • \n
  • application/vnd.github-commitcomment.html+json: Returns HTML rendered from the body's markdown. Response will include body_html.
  • \n
  • application/vnd.github-commitcomment.full+json: Returns raw, text, and HTML representations. Response will include body, body_text, and body_html.
  • \n
", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists review comments for all pull requests in a repository. By default,\nreview comments are in ascending order by ID.

\n

This endpoint supports the following custom media types. For more information, see \"Media types.\"

\n
    \n
  • application/vnd.github-commitcomment.raw+json: Returns the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
  • \n
  • application/vnd.github-commitcomment.text+json: Returns a text only representation of the markdown body. Response will include body_text.
  • \n
  • application/vnd.github-commitcomment.html+json: Returns HTML rendered from the body's markdown. Response will include body_html.
  • \n
  • application/vnd.github-commitcomment.full+json: Returns raw, text, and HTML representations. Response will include body, body_text, and body_html.
  • \n
" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -402977,13 +402970,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists all review comments for a specified pull request. By default, review comments\nare in ascending order by ID.

\n

This endpoint supports the following custom media types. For more information, see \"Media types.\"

\n
    \n
  • application/vnd.github-commitcomment.raw+json: Returns the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
  • \n
  • application/vnd.github-commitcomment.text+json: Returns a text only representation of the markdown body. Response will include body_text.
  • \n
  • application/vnd.github-commitcomment.html+json: Returns HTML rendered from the body's markdown. Response will include body_html.
  • \n
  • application/vnd.github-commitcomment.full+json: Returns raw, text, and HTML representations. Response will include body, body_text, and body_html.
  • \n
", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists all review comments for a specified pull request. By default, review comments\nare in ascending order by ID.

\n

This endpoint supports the following custom media types. For more information, see \"Media types.\"

\n
    \n
  • application/vnd.github-commitcomment.raw+json: Returns the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
  • \n
  • application/vnd.github-commitcomment.text+json: Returns a text only representation of the markdown body. Response will include body_text.
  • \n
  • application/vnd.github-commitcomment.html+json: Returns HTML rendered from the body's markdown. Response will include body_html.
  • \n
  • application/vnd.github-commitcomment.full+json: Returns raw, text, and HTML representations. Response will include body, body_text, and body_html.
  • \n
" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -415360,7 +415353,6 @@ } ], "previews": [], - "descriptionHTML": "

Creates a review on a specified pull request.

\n

This endpoint triggers notifications. Creating content too quickly using this endpoint may result in secondary rate limiting. For more information, see \"Rate limits for the API\" and \"Best practices for using the REST API.\"

\n

Pull request reviews created in the PENDING state are not submitted and therefore do not include the submitted_at property in the response. To create a pending review for a pull request, leave the event parameter blank. For more information about submitting a PENDING review, see \"Submit a review for a pull request.\"

\n

Note

\n

\nTo comment on a specific line in a file, you need to first determine the position of that line in the diff. To see a pull request diff, add the application/vnd.github.v3.diff media type to the Accept header of a call to the Get a pull request endpoint.

\n
\n

The position value equals the number of lines down from the first \"@@\" hunk header in the file you want to add a comment. The line just below the \"@@\" line is position 1, the next line is position 2, and so on. The position in the diff continues to increase through lines of whitespace and additional hunks until the beginning of a new file.

\n

This endpoint supports the following custom media types. For more information, see \"Media types.\"

\n
    \n
  • application/vnd.github-commitcomment.raw+json: Returns the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
  • \n
  • application/vnd.github-commitcomment.text+json: Returns a text only representation of the markdown body. Response will include body_text.
  • \n
  • application/vnd.github-commitcomment.html+json: Returns HTML rendered from the body's markdown. Response will include body_html.
  • \n
  • application/vnd.github-commitcomment.full+json: Returns raw, text, and HTML representations. Response will include body, body_text, and body_html.
  • \n
", "statusCodes": [ { "httpStatusCode": "200", @@ -415374,7 +415366,8 @@ "httpStatusCode": "422", "description": "

Validation failed, or the endpoint has been spammed.

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

Creates a review on a specified pull request.

\n

This endpoint triggers notifications. Creating content too quickly using this endpoint may result in secondary rate limiting. For more information, see \"Rate limits for the API\" and \"Best practices for using the REST API.\"

\n

Pull request reviews created in the PENDING state are not submitted and therefore do not include the submitted_at property in the response. To create a pending review for a pull request, leave the event parameter blank. For more information about submitting a PENDING review, see \"Submit a review for a pull request.\"

\n

Note

\n

\nTo comment on a specific line in a file, you need to first determine the position of that line in the diff. To see a pull request diff, add the application/vnd.github.v3.diff media type to the Accept header of a call to the Get a pull request endpoint.

\n
\n

The position value equals the number of lines down from the first \"@@\" hunk header in the file you want to add a comment. The line just below the \"@@\" line is position 1, the next line is position 2, and so on. The position in the diff continues to increase through lines of whitespace and additional hunks until the beginning of a new file.

\n

This endpoint supports the following custom media types. For more information, see \"Media types.\"

\n
    \n
  • application/vnd.github-commitcomment.raw+json: Returns the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
  • \n
  • application/vnd.github-commitcomment.text+json: Returns a text only representation of the markdown body. Response will include body_text.
  • \n
  • application/vnd.github-commitcomment.html+json: Returns HTML rendered from the body's markdown. Response will include body_html.
  • \n
  • application/vnd.github-commitcomment.full+json: Returns raw, text, and HTML representations. Response will include body, body_text, and body_html.
  • \n
" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -416673,7 +416666,6 @@ } ], "previews": [], - "descriptionHTML": "

Deletes a pull request review that has not been submitted. Submitted reviews cannot be deleted.

\n

This endpoint supports the following custom media types. For more information, see \"Media types.\"

\n
    \n
  • application/vnd.github-commitcomment.raw+json: Returns the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
  • \n
  • application/vnd.github-commitcomment.text+json: Returns a text only representation of the markdown body. Response will include body_text.
  • \n
  • application/vnd.github-commitcomment.html+json: Returns HTML rendered from the body's markdown. Response will include body_html.
  • \n
  • application/vnd.github-commitcomment.full+json: Returns raw, text, and HTML representations. Response will include body, body_text, and body_html.
  • \n
", "statusCodes": [ { "httpStatusCode": "200", @@ -416687,7 +416679,8 @@ "httpStatusCode": "422", "description": "

Validation failed, or the endpoint has been spammed.

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

Deletes a pull request review that has not been submitted. Submitted reviews cannot be deleted.

\n

This endpoint supports the following custom media types. For more information, see \"Media types.\"

\n
    \n
  • application/vnd.github-commitcomment.raw+json: Returns the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
  • \n
  • application/vnd.github-commitcomment.text+json: Returns a text only representation of the markdown body. Response will include body_text.
  • \n
  • application/vnd.github-commitcomment.html+json: Returns HTML rendered from the body's markdown. Response will include body_html.
  • \n
  • application/vnd.github-commitcomment.full+json: Returns raw, text, and HTML representations. Response will include body, body_text, and body_html.
  • \n
" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -423022,13 +423015,13 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nYou can also specify a repository by repository_id using the route DELETE delete /repositories/:repository_id/issues/comments/:comment_id/reactions/:reaction_id.

\n
\n

Delete a reaction to an issue comment.

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Note

\n

\nYou can also specify a repository by repository_id using the route DELETE delete /repositories/:repository_id/issues/comments/:comment_id/reactions/:reaction_id.

\n
\n

Delete a reaction to an issue comment.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -424481,7 +424474,6 @@ } ], "previews": [], - "descriptionHTML": "

List the reactions to a pull request review comment.

", "statusCodes": [ { "httpStatusCode": "200", @@ -424491,7 +424483,8 @@ "httpStatusCode": "404", "description": "

Resource not found

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

List the reactions to a pull request review comment.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -426181,7 +426174,6 @@ } ], "previews": [], - "descriptionHTML": "

Create a reaction to a release. A response with a Status: 200 OK means that you already added the reaction type to this release.

", "statusCodes": [ { "httpStatusCode": "200", @@ -426195,7 +426187,8 @@ "httpStatusCode": "422", "description": "

Validation failed, or the endpoint has been spammed.

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

Create a reaction to a release. A response with a Status: 200 OK means that you already added the reaction type to this release.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -432406,13 +432399,13 @@ } ], "previews": [], - "descriptionHTML": "

Users with push access to the repository can edit a release.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Users with push access to the repository can edit a release.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -432480,13 +432473,13 @@ } ], "previews": [], - "descriptionHTML": "

Users with push access to the repository can delete a release.

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Users with push access to the repository can delete a release.

" } ], "assets": [ @@ -465789,13 +465782,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets all autolinks that are configured for a repository.

\n

Information about autolinks are only available to repository administrators.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets all autolinks that are configured for a repository.

\n

Information about autolinks are only available to repository administrators.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -488986,7 +488979,6 @@ } ], "previews": [], - "descriptionHTML": "

Find commits via various criteria on the default branch (usually main). This method returns up to 100 results per page.

\n

When searching for commits, you can get text match metadata for the message field when you provide the text-match media type. For more details about how to receive highlighted search results, see Text match\nmetadata.

\n

For example, if you want to find commits related to CSS in the octocat/Spoon-Knife repository. Your query would look something like this:

\n

q=repo:octocat/Spoon-Knife+css

", "statusCodes": [ { "httpStatusCode": "200", @@ -488996,7 +488988,8 @@ "httpStatusCode": "304", "description": "

Not modified

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

Find commits via various criteria on the default branch (usually main). This method returns up to 100 results per page.

\n

When searching for commits, you can get text match metadata for the message field when you provide the text-match media type. For more details about how to receive highlighted search results, see Text match\nmetadata.

\n

For example, if you want to find commits related to CSS in the octocat/Spoon-Knife repository. Your query would look something like this:

\n

q=repo:octocat/Spoon-Knife+css

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", diff --git a/src/rest/data/ghes-3.14-2022-11-28/schema.json b/src/rest/data/ghes-3.14-2022-11-28/schema.json index 2884df768d10..238716b15cbd 100644 --- a/src/rest/data/ghes-3.14-2022-11-28/schema.json +++ b/src/rest/data/ghes-3.14-2022-11-28/schema.json @@ -957,7 +957,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1033,7 +1033,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1126,7 +1126,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -156852,12 +156852,6 @@ "name": "dismissed_comment", "in": "body", "description": "

The dismissal comment associated with the dismissal of the alert.

" - }, - { - "type": "boolean", - "name": "create_request", - "in": "body", - "description": "

If true, attempt to create an alert dismissal request.

" } ], "progAccess": { @@ -156880,8 +156874,7 @@ "bodyParameters": { "state": "dismissed", "dismissed_reason": "false positive", - "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library.", - "create_request": true + "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library." }, "parameters": { "owner": "OWNER", @@ -201754,7 +201747,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -202132,7 +202125,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -210899,7 +210892,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -211259,7 +211252,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -211552,7 +211545,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -211869,7 +211862,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -212409,7 +212402,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -212922,7 +212915,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -213046,7 +213039,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -213587,7 +213580,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -214304,7 +214297,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -214805,7 +214798,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -215243,7 +215236,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -216251,7 +216244,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, diff --git a/src/rest/data/ghes-3.15-2022-11-28/schema.json b/src/rest/data/ghes-3.15-2022-11-28/schema.json index d33e62485901..8e6b2d61fc6a 100644 --- a/src/rest/data/ghes-3.15-2022-11-28/schema.json +++ b/src/rest/data/ghes-3.15-2022-11-28/schema.json @@ -957,7 +957,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1033,7 +1033,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1126,7 +1126,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -157544,12 +157544,6 @@ "name": "dismissed_comment", "in": "body", "description": "

The dismissal comment associated with the dismissal of the alert.

" - }, - { - "type": "boolean", - "name": "create_request", - "in": "body", - "description": "

If true, attempt to create an alert dismissal request.

" } ], "progAccess": { @@ -157572,8 +157566,7 @@ "bodyParameters": { "state": "dismissed", "dismissed_reason": "false positive", - "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library.", - "create_request": true + "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library." }, "parameters": { "owner": "OWNER", @@ -205977,7 +205970,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -206355,7 +206348,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -213796,7 +213789,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -214156,7 +214149,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -214449,7 +214442,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -214766,7 +214759,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -215306,7 +215299,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -215819,7 +215812,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -215943,7 +215936,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -216484,7 +216477,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -217201,7 +217194,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -217702,7 +217695,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -218140,7 +218133,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -219148,7 +219141,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, diff --git a/src/rest/data/ghes-3.16-2022-11-28/schema.json b/src/rest/data/ghes-3.16-2022-11-28/schema.json index 73eff2e6a7e9..ae30d837807f 100644 --- a/src/rest/data/ghes-3.16-2022-11-28/schema.json +++ b/src/rest/data/ghes-3.16-2022-11-28/schema.json @@ -957,7 +957,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1033,7 +1033,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1126,7 +1126,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1228,13 +1228,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets the total GitHub Actions cache usage for an organization.\nThe data fetched using this API is refreshed approximately every 5 minutes, so values returned from this endpoint may take at least 5 minutes to get updated.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets the total GitHub Actions cache usage for an organization.\nThe data fetched using this API is refreshed approximately every 5 minutes, so values returned from this endpoint may take at least 5 minutes to get updated.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -1554,13 +1554,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets GitHub Actions cache usage policy for a repository.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets GitHub Actions cache usage policy for a repository.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -13114,13 +13114,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists self-hosted runners that are in a specific organization group.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists self-hosted runners that are in a specific organization group.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -16058,13 +16058,13 @@ } ], "previews": [], - "descriptionHTML": "

Returns a token that you can pass to the config script to remove a self-hosted runner from an enterprise. The token expires after one hour.

\n

Example using remove token:

\n

To remove your self-hosted runner from an enterprise, replace TOKEN with the remove token provided by this\nendpoint.

\n
./config.sh remove --token TOKEN\n
\n

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

", "statusCodes": [ { "httpStatusCode": "201", "description": "

Created

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

Returns a token that you can pass to the config script to remove a self-hosted runner from an enterprise. The token expires after one hour.

\n

Example using remove token:

\n

To remove your self-hosted runner from an enterprise, replace TOKEN with the remove token provided by this\nendpoint.

\n
./config.sh remove --token TOKEN\n
\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -19923,13 +19923,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets a specific self-hosted runner configured in an organization.

\n

Authenticated users must have admin access to the organization to use this endpoint.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets a specific self-hosted runner configured in an organization.

\n

Authenticated users must have admin access to the organization to use this endpoint.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -22428,13 +22428,13 @@ } ], "previews": [], - "descriptionHTML": "

Returns a token that you can pass to the config script. The token expires after one hour.

\n

For example, you can replace TOKEN in the following example with the registration token provided by this endpoint to configure your self-hosted runner:

\n
./config.sh --url https://github.com/octo-org --token TOKEN\n
\n

Authenticated users must have admin access to the repository to use this endpoint.

\n

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

", "statusCodes": [ { "httpStatusCode": "201", "description": "

Created

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

Returns a token that you can pass to the config script. The token expires after one hour.

\n

For example, you can replace TOKEN in the following example with the registration token provided by this endpoint to configure your self-hosted runner:

\n
./config.sh --url https://github.com/octo-org --token TOKEN\n
\n

Authenticated users must have admin access to the repository to use this endpoint.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -24719,13 +24719,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists all organization variables.

\n

Authenticated users must have collaborator access to a repository to create, update, or read variables.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists all organization variables.

\n

Authenticated users must have collaborator access to a repository to create, update, or read variables.

\n

OAuth app tokens and personal access tokens (classic) need the admin:org scope to use this endpoint. If the repository is private, the repo scope is also required.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -80978,13 +80978,13 @@ } ], "previews": [], - "descriptionHTML": "

Marks a thread as \"done.\" Marking a thread as \"done\" is equivalent to marking a notification in your notification inbox on GitHub Enterprise Server as done: https://github.com/notifications.

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No content

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

Marks a thread as \"done.\" Marking a thread as \"done\" is equivalent to marking a notification in your notification inbox on GitHub Enterprise Server as done: https://github.com/notifications.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -126176,13 +126176,13 @@ } ], "previews": [], - "descriptionHTML": "

Protected branches are available in public repositories with GitHub Free and GitHub Free for organizations, and in public and private repositories with GitHub Pro, GitHub Team, GitHub Enterprise Cloud, and GitHub Enterprise Server. For more information, see GitHub's products in the GitHub Help documentation.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Protected branches are available in public repositories with GitHub Free and GitHub Free for organizations, and in public and private repositories with GitHub Pro, GitHub Team, GitHub Enterprise Cloud, and GitHub Enterprise Server. For more information, see GitHub's products in the GitHub Help documentation.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -157723,12 +157723,6 @@ "name": "dismissed_comment", "in": "body", "description": "

The dismissal comment associated with the dismissal of the alert.

" - }, - { - "type": "boolean", - "name": "create_request", - "in": "body", - "description": "

If true, attempt to create an alert dismissal request.

" } ], "progAccess": { @@ -157751,8 +157745,7 @@ "bodyParameters": { "state": "dismissed", "dismissed_reason": "false positive", - "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library.", - "create_request": true + "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library." }, "parameters": { "owner": "OWNER", @@ -196291,13 +196284,13 @@ } ], "previews": [], - "descriptionHTML": "

Create a new snapshot of a repository's dependencies.

\n

The authenticated user must have access to the repository.

\n

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

", "statusCodes": [ { "httpStatusCode": "201", "description": "

Created

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

Create a new snapshot of a repository's dependencies.

\n

The authenticated user must have access to the repository.

\n

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

" } ], "sboms": [ @@ -196793,13 +196786,13 @@ } ], "previews": [], - "descriptionHTML": "", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

" } - ] + ], + "descriptionHTML": "" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -198065,13 +198058,13 @@ } ], "previews": [], - "descriptionHTML": "

Simple filtering of deployments is available via query parameters:

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Simple filtering of deployments is available via query parameters:

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -209855,7 +209848,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -211526,7 +211519,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -212433,13 +212426,13 @@ } ], "previews": [], - "descriptionHTML": "", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

" } - ] + ], + "descriptionHTML": "" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -212898,13 +212891,13 @@ } ], "previews": [], - "descriptionHTML": "

Note that this API call does not automatically initiate an LDAP sync. Rather, if a 201 is returned, the sync job is queued successfully, and is performed when the instance is ready.

", "statusCodes": [ { "httpStatusCode": "201", "description": "

Created

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

Note that this API call does not automatically initiate an LDAP sync. Rather, if a 201 is returned, the sync job is queued successfully, and is performed when the instance is ready.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -218980,7 +218973,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -219340,7 +219333,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -219633,7 +219626,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -219950,7 +219943,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -220490,7 +220483,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -221003,7 +220996,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -221127,7 +221120,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -221668,7 +221661,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -222385,7 +222378,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -222886,7 +222879,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -223324,7 +223317,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -224332,7 +224325,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -418027,13 +418020,13 @@ } ], "previews": [], - "descriptionHTML": "

Gets the users or teams whose review is requested for a pull request. Once a requested reviewer submits a review, they are no longer considered a requested reviewer. Their review will instead be returned by the List reviews for a pull request operation.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Gets the users or teams whose review is requested for a pull request. Once a requested reviewer submits a review, they are no longer considered a requested reviewer. Their review will instead be returned by the List reviews for a pull request operation.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -433978,13 +433971,13 @@ } ], "previews": [], - "descriptionHTML": "

Note

\n

\nYou can also specify a team or organization with team_id and org_id using the route DELETE /organizations/:org_id/team/:team_id/discussions/:discussion_number/reactions/:reaction_id.

\n
\n

Delete a reaction to a team discussion.

\n

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

", "statusCodes": [ { "httpStatusCode": "204", "description": "

No Content

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

Note

\n

\nYou can also specify a team or organization with team_id and org_id using the route DELETE /organizations/:org_id/team/:team_id/discussions/:discussion_number/reactions/:reaction_id.

\n
\n

Delete a reaction to a team discussion.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -440446,13 +440439,13 @@ } ], "previews": [], - "descriptionHTML": "

Warning

\n

\nEndpoint closing down notice: This endpoint route is closing down and will be removed from the Teams API. We recommend migrating your existing code to use the new List reactions for a team discussion endpoint.

\n
\n

List the reactions to a team discussion.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Warning

\n

\nEndpoint closing down notice: This endpoint route is closing down and will be removed from the Teams API. We recommend migrating your existing code to use the new List reactions for a team discussion endpoint.

\n
\n

List the reactions to a team discussion.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -443225,13 +443218,13 @@ } ], "previews": [], - "descriptionHTML": "

View the latest published full release for the repository.

\n

The latest release is the most recent non-prerelease, non-draft release, sorted by the created_at attribute. The created_at attribute is the date of the commit used for the release, and not the date when the release was drafted or published.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

View the latest published full release for the repository.

\n

The latest release is the most recent non-prerelease, non-draft release, sorted by the created_at attribute. The created_at attribute is the date of the commit used for the release, and not the date when the release was drafted or published.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -463922,13 +463915,13 @@ } ], "previews": [], - "descriptionHTML": "

Lists languages for the specified repository. The value shown for each language is the number of bytes of code written in that language.

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Lists languages for the specified repository. The value shown for each language is the number of bytes of code written in that language.

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -531661,13 +531654,13 @@ } ], "previews": [], - "descriptionHTML": "

Get a specific comment on a team discussion.

\n

Note

\n

\nYou can also specify a team by org_id and team_id using the route GET /organizations/{org_id}/team/{team_id}/discussions/{discussion_number}/comments/{comment_number}.

\n
\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Get a specific comment on a team discussion.

\n

Note

\n

\nYou can also specify a team by org_id and team_id using the route GET /organizations/{org_id}/team/{team_id}/discussions/{discussion_number}/comments/{comment_number}.

\n
\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", @@ -537961,13 +537954,13 @@ } ], "previews": [], - "descriptionHTML": "

Warning

\n

\nEndpoint closing down notice: This endpoint route is closing down and will be removed from the Teams API. We recommend migrating your existing code to use the new Update a discussion endpoint.

\n
\n

Edits the title and body text of a discussion post. Only the parameters you provide are updated.

\n

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

", "statusCodes": [ { "httpStatusCode": "200", "description": "

OK

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

Warning

\n

\nEndpoint closing down notice: This endpoint route is closing down and will be removed from the Teams API. We recommend migrating your existing code to use the new Update a discussion endpoint.

\n
\n

Edits the title and body text of a discussion post. Only the parameters you provide are updated.

\n

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

" }, { "serverUrl": "http(s)://HOSTNAME/api/v3", diff --git a/src/rest/data/ghes-3.17-2022-11-28/schema.json b/src/rest/data/ghes-3.17-2022-11-28/schema.json index 7f10423c6533..2ebaf3a875ca 100644 --- a/src/rest/data/ghes-3.17-2022-11-28/schema.json +++ b/src/rest/data/ghes-3.17-2022-11-28/schema.json @@ -957,7 +957,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1033,7 +1033,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -1126,7 +1126,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -158018,12 +158018,6 @@ "name": "dismissed_comment", "in": "body", "description": "

The dismissal comment associated with the dismissal of the alert.

" - }, - { - "type": "boolean", - "name": "create_request", - "in": "body", - "description": "

If true, attempt to create an alert dismissal request.

" } ], "progAccess": { @@ -158046,8 +158040,7 @@ "bodyParameters": { "state": "dismissed", "dismissed_reason": "false positive", - "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library.", - "create_request": true + "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library." }, "parameters": { "owner": "OWNER", @@ -210644,7 +210637,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "read" + "\"Enterprise administration\" enterprise permissions": "read" } ] }, @@ -212328,7 +212321,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise administration\" business permissions": "write" + "\"Enterprise administration\" enterprise permissions": "write" } ] }, @@ -219782,7 +219775,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -220142,7 +220135,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -220435,7 +220428,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -220752,7 +220745,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -221292,7 +221285,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -221805,7 +221798,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -221929,7 +221922,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -222470,7 +222463,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -223187,7 +223180,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "read" + "\"Enterprise SCIM\" enterprise permissions": "read" } ] }, @@ -223688,7 +223681,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -224126,7 +224119,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, @@ -225134,7 +225127,7 @@ "fineGrainedPat": true, "permissions": [ { - "\"Enterprise SCIM\" business permissions": "write" + "\"Enterprise SCIM\" enterprise permissions": "write" } ] }, diff --git a/src/rest/lib/config.json b/src/rest/lib/config.json index 994bbd9b8044..6cade8b556c3 100644 --- a/src/rest/lib/config.json +++ b/src/rest/lib/config.json @@ -47,5 +47,5 @@ ] } }, - "sha": "3ae8ad33b4276583395c1b28852650f329018927" + "sha": "c52348cd88be16e613e49c26b39d2653e20b817d" } \ No newline at end of file diff --git a/src/search/components/input/SearchOverlay.tsx b/src/search/components/input/SearchOverlay.tsx index c2e4d2e6d202..177a6f7a8205 100644 --- a/src/search/components/input/SearchOverlay.tsx +++ b/src/search/components/input/SearchOverlay.tsx @@ -805,7 +805,7 @@ export function SearchOverlay({ window.open('https://github.com/github/docs-team/discussions/5172', '_blank') } else { // public discussion for feedback - window.open('https://github.com/orgs/community/discussions/158488', '_blank') + window.open('https://github.com/orgs/community/discussions/164214', '_blank') } }} as="button" diff --git a/src/webhooks/lib/config.json b/src/webhooks/lib/config.json index ee79d0900ceb..d6a740c0786c 100644 --- a/src/webhooks/lib/config.json +++ b/src/webhooks/lib/config.json @@ -1,3 +1,3 @@ { - "sha": "3ae8ad33b4276583395c1b28852650f329018927" + "sha": "c52348cd88be16e613e49c26b39d2653e20b817d" } \ No newline at end of file