diff --git a/.github/workflows/sync-graphql.yml b/.github/workflows/sync-graphql.yml index 3b6fe3782acf..f8e00a3c3aeb 100644 --- a/.github/workflows/sync-graphql.yml +++ b/.github/workflows/sync-graphql.yml @@ -17,11 +17,16 @@ jobs: update_graphql_files: if: github.repository == 'github/docs-internal' runs-on: ubuntu-latest + outputs: + ignored-changes: ${{ steps.sync.outputs.ignored-changes }} + ignored-count: ${{ steps.sync.outputs.ignored-count }} + ignored-types: ${{ steps.sync.outputs.ignored-types }} steps: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: ./.github/actions/node-npm-setup - name: Run updater scripts + id: sync env: # need to use a token from a user with access to github/github for this step GITHUB_TOKEN: ${{ secrets.DOCS_BOT_PAT_BASE }} @@ -70,3 +75,22 @@ jobs: with: slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} + + notify_ignored_changes: + if: github.repository == 'github/docs-internal' && needs.update_graphql_files.outputs.ignored-count > 0 && github.event_name != 'workflow_dispatch' + needs: update_graphql_files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: ./.github/actions/slack-alert + with: + slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }} + slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }} + color: warning + message: | + ⚠️ GraphQL Sync found ${{ needs.update_graphql_files.outputs.ignored-count }} ignored change types: ${{ needs.update_graphql_files.outputs.ignored-types }} + + These change types are not in CHANGES_TO_REPORT and were silently ignored. Consider reviewing if they should be added to the changelog. + + See workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/content/actions/concepts/billing-and-usage.md b/content/actions/concepts/billing-and-usage.md new file mode 100644 index 000000000000..2b49ecfd86a2 --- /dev/null +++ b/content/actions/concepts/billing-and-usage.md @@ -0,0 +1,62 @@ +--- +title: 'Billing and usage' +intro: 'There are usage limits for {% data variables.product.prodname_actions %} workflows. Usage charges apply to repositories that go beyond the amount of free minutes and storage for a repository.' +redirect_from: + - /actions/getting-started-with-github-actions/usage-and-billing-information-for-github-actions + - /actions/reference/usage-limits-billing-and-administration + - /actions/learn-github-actions/usage-limits-billing-and-administration + - /actions/administering-github-actions/usage-limits-billing-and-administration + - /actions/concepts/overview/usage-limits-billing-and-administration +versions: + fpt: '*' + ghes: '*' + ghec: '*' +topics: + - Billing +--- + +## About billing for {% data variables.product.prodname_actions %} + +{% ifversion fpt or ghec %} +{% data reusables.actions.actions-billing %} For more information, see [AUTOTITLE](/billing/managing-billing-for-github-actions/about-billing-for-github-actions). +{% else %} +{% data variables.product.prodname_actions %} usage is free for {% data variables.product.prodname_ghe_server %} instances that use self-hosted runners. For more information, see [AUTOTITLE](/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners). +{% endif %} + +{% ifversion fpt or ghec %} + +## Availability + +{% data variables.product.prodname_actions %} is available on all {% data variables.product.prodname_dotcom %} products, but {% data variables.product.prodname_actions %} is not available for private repositories owned by accounts using legacy per-repository plans. {% data reusables.gated-features.more-info %} + +{% endif %} + +## Usage limits and policy + +There are several limits on {% data variables.product.prodname_actions %} usage when using {% data variables.product.prodname_dotcom %}-hosted runners. See [AUTOTITLE](/actions/reference/actions-limits). + +In addition to the usage limits, you must ensure that you use {% data variables.product.prodname_actions %} within the [GitHub Terms of Service](/free-pro-team@latest/site-policy/github-terms/github-terms-of-service). For more information on {% data variables.product.prodname_actions %}-specific terms, see the [GitHub Additional Product Terms](/free-pro-team@latest/site-policy/github-terms/github-terms-for-additional-products-and-features#a-actions-usage). + +{% ifversion fpt or ghec %} + +## {% data variables.product.prodname_actions %} usage metrics + +Organization owners and users with the "View organization Actions metrics" permission can view {% data variables.product.prodname_actions %} usage metrics for their organization. These metrics can help you understand how and where your Actions minutes are being used. For more information, see [AUTOTITLE](/enterprise-cloud@latest/organizations/collaborating-with-groups-in-organizations/viewing-usage-metrics-for-github-actions). + +When you view usage metrics, it is important to remember that {% data reusables.actions.actions-usage-metrics-not-billing-metrics %} + +{% endif %} + +## Billing for reusable workflows + +If you reuse a workflow, billing is always associated with the caller workflow. Assignment of {% data variables.product.prodname_dotcom %}-hosted runners is always evaluated using only the caller's context. The caller cannot use {% data variables.product.prodname_dotcom %}-hosted runners from the called repository. + +For more information see, [AUTOTITLE](/actions/using-workflows/reusing-workflows). + +## Next steps + +You can manage your {% data variables.product.prodname_actions %} usage and retention policies for your repository, organization, or enterprise account. For more information, see: +* [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository) +* [AUTOTITLE](/organizations/managing-organization-settings/configuring-the-retention-period-for-github-actions-artifacts-and-logs-in-your-organization) +* [AUTOTITLE](/organizations/managing-organization-settings/disabling-or-limiting-github-actions-for-your-organization) +* [AUTOTITLE](/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise) diff --git a/content/actions/concepts/index.md b/content/actions/concepts/index.md index d6c23add4953..2fe67a494c3a 100644 --- a/content/actions/concepts/index.md +++ b/content/actions/concepts/index.md @@ -12,6 +12,7 @@ children: - /runners - /security - /about-github-actions-metrics + - /billing-and-usage redirect_from: - /actions/concepts/use-cases --- diff --git a/content/actions/concepts/overview/index.md b/content/actions/concepts/overview/index.md index f7199394e24f..8a77af07f443 100644 --- a/content/actions/concepts/overview/index.md +++ b/content/actions/concepts/overview/index.md @@ -9,5 +9,4 @@ versions: children: - /about-continuous-deployment-with-github-actions - /continuous-integration - - /usage-limits-billing-and-administration --- diff --git a/content/actions/concepts/overview/usage-limits-billing-and-administration.md b/content/actions/concepts/overview/usage-limits-billing-and-administration.md deleted file mode 100644 index 09ec0defe5c6..000000000000 --- a/content/actions/concepts/overview/usage-limits-billing-and-administration.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: 'Usage limits, billing, and administration' -intro: 'There are usage limits for {% data variables.product.prodname_actions %} workflows. Usage charges apply to repositories that go beyond the amount of free minutes and storage for a repository.' -redirect_from: - - /actions/getting-started-with-github-actions/usage-and-billing-information-for-github-actions - - /actions/reference/usage-limits-billing-and-administration - - /actions/learn-github-actions/usage-limits-billing-and-administration - - /actions/administering-github-actions/usage-limits-billing-and-administration -versions: - fpt: '*' - ghes: '*' - ghec: '*' -topics: - - Billing -shortTitle: Workflow billing & limits ---- - -{% data reusables.actions.enterprise-github-hosted-runners %} - -## About billing for {% data variables.product.prodname_actions %} - -{% data reusables.repositories.about-github-actions %} For more information, see [AUTOTITLE](/actions/learn-github-actions/understanding-github-actions){% ifversion fpt %}.{% elsif ghes or ghec %} and [AUTOTITLE](/admin/github-actions/getting-started-with-github-actions-for-your-enterprise/about-github-actions-for-enterprises).{% endif %} - -{% ifversion fpt or ghec %} -{% data reusables.actions.actions-billing %} For more information, see [AUTOTITLE](/billing/managing-billing-for-github-actions/about-billing-for-github-actions). -{% else %} -GitHub Actions usage is free for {% data variables.product.prodname_ghe_server %} instances that use self-hosted runners. For more information, see [AUTOTITLE](/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners). -{% endif %} - -{% ifversion fpt or ghec %} - -## Availability - -{% data variables.product.prodname_actions %} is available on all {% data variables.product.prodname_dotcom %} products, but {% data variables.product.prodname_actions %} is not available for private repositories owned by accounts using legacy per-repository plans. {% data reusables.gated-features.more-info %} - -{% endif %} - -## Usage limits - -{% ifversion fpt or ghec %} -There are some limits on {% data variables.product.prodname_actions %} usage when using {% data variables.product.prodname_dotcom %}-hosted runners. These limits are subject to change. - -> [!NOTE] -> For self-hosted runners, different usage limits apply. For more information, see [AUTOTITLE](/actions/hosting-your-own-runners/managing-self-hosted-runners/usage-limits-for-self-hosted-runners). - -For more information about service rate limits, see [AUTOTITLE](/actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/actions-limits). - - **Standard {% data variables.product.prodname_dotcom %}-hosted runners** - - | GitHub plan | Total concurrent jobs | Maximum concurrent macOS jobs | - |---|---|---| - | Free | 20 | 5 | - | Pro | 40 | 5 | - | Team | 60 | 5 | - | Enterprise | 500 | 50 | - - **{% data variables.product.prodname_dotcom %}-hosted {% data variables.actions.hosted_runner %}s** - - | GitHub plan | Total concurrent jobs | Maximum concurrent macOS jobs | Maximum concurrent GPU jobs | - |---|---|---|---| - | Team | 1000 | 5 | 100 | - | Enterprise | 1000 | 50 | 100 | - - > [!NOTE] - > * If required, customers on enterprise plans can request a higher limit for concurrent jobs. For more information, contact us through the {% data variables.contact.contact_support_portal %}, or contact your sales representative. - > * The maximum concurrent macOS jobs is shared across standard {% data variables.product.prodname_dotcom %}-hosted runner and {% data variables.product.prodname_dotcom %}-hosted {% data variables.actions.hosted_runner %}s. - -* **Job matrix** - {% data reusables.actions.usage-matrix-limits %} -{% data reusables.actions.usage-workflow-queue-limits %} - -{% else %} -Usage limits apply to self-hosted runners. For more information, see [AUTOTITLE](/actions/hosting-your-own-runners/managing-self-hosted-runners/usage-limits-for-self-hosted-runners). -{% endif %} - -{% ifversion fpt or ghec %} - -## Usage policy - -In addition to the usage limits, you must ensure that you use {% data variables.product.prodname_actions %} within the [GitHub Terms of Service](/free-pro-team@latest/site-policy/github-terms/github-terms-of-service). For more information on {% data variables.product.prodname_actions %}-specific terms, see the [GitHub Additional Product Terms](/free-pro-team@latest/site-policy/github-terms/github-terms-for-additional-products-and-features#a-actions-usage). -{% endif %} - -{% ifversion fpt or ghec %} - -## {% data variables.product.prodname_actions %} usage metrics - -Organization owners and users with the "View organization Actions metrics" permission can view {% data variables.product.prodname_actions %} usage metrics for their organization. These metrics can help you understand how and where your Actions minutes are being used. For more information, see [AUTOTITLE](/enterprise-cloud@latest/organizations/collaborating-with-groups-in-organizations/viewing-usage-metrics-for-github-actions). - -When you view usage metrics, it is important to remember that {% data reusables.actions.actions-usage-metrics-not-billing-metrics %} - -{% endif %} - -## Billing for reusable workflows - -If you reuse a workflow, billing is always associated with the caller workflow. Assignment of {% data variables.product.prodname_dotcom %}-hosted runners is always evaluated using only the caller's context. The caller cannot use {% data variables.product.prodname_dotcom %}-hosted runners from the called repository. - -For more information see, [AUTOTITLE](/actions/using-workflows/reusing-workflows). - -## Artifact and log retention policy - -You can configure the artifact and log retention period for your repository, organization, or enterprise account. - -{% data reusables.actions.about-artifact-log-retention %} - -For more information, see: - -* [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#configuring-the-retention-period-for-github-actions-artifacts-and-logs-in-your-repository) -* [AUTOTITLE](/organizations/managing-organization-settings/configuring-the-retention-period-for-github-actions-artifacts-and-logs-in-your-organization) -* [AUTOTITLE](/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise#enforcing-a-policy-for-artifact-and-log-retention-in-your-enterprise) - -## Workflow run history retention policy - -The workflow runs in a repository's workflow run history are retained for 400 days. After 400 days, workflow runs are archived. 10 days after archival, they are permanently deleted. The retention period for workflow runs cannot be modified. For more information, see [AUTOTITLE](/actions/monitoring-and-troubleshooting-workflows/monitoring-workflows/viewing-workflow-run-history). - -## Disabling or limiting {% data variables.product.prodname_actions %} for your repository or organization - -{% data reusables.actions.disabling-github-actions %} - -{% ifversion ghes %}You can also manage {% data variables.product.prodname_actions %} settings for your enterprise, such as workflow permissions and cache storage.{% endif %} - -For more information, see: -* [AUTOTITLE](/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository) -* [AUTOTITLE](/organizations/managing-organization-settings/disabling-or-limiting-github-actions-for-your-organization) -* [AUTOTITLE](/admin/policies/enforcing-policies-for-your-enterprise/enforcing-policies-for-github-actions-in-your-enterprise) - -## Disabling and enabling workflows - -You can enable and disable individual workflows in your repository on {% data variables.product.prodname_dotcom %}. - -{% data reusables.actions.scheduled-workflows-disabled %} - -For more information, see [AUTOTITLE](/actions/managing-workflow-runs/disabling-and-enabling-a-workflow). diff --git a/content/actions/concepts/workflows-and-actions/concurrency.md b/content/actions/concepts/workflows-and-actions/concurrency.md new file mode 100644 index 000000000000..4f70fe8f46e6 --- /dev/null +++ b/content/actions/concepts/workflows-and-actions/concurrency.md @@ -0,0 +1,18 @@ +--- +title: Concurrency +intro: 'Learn about running workflows and jobs simultaneously.' +versions: + fpt: '*' + ghes: '*' + ghec: '*' +type: overview +topics: + - Actions + - Workflows +--- + +By default, {% data variables.product.prodname_actions %} allows multiple jobs within the same workflow, multiple workflow runs within the same repository, and multiple workflow runs across a repository owner's account to run concurrently. This means that multiple instances of the same workflow or job can run at the same time, performing the same steps. + +{% data variables.product.prodname_actions %} also allows you to disable concurrent execution. This can be useful for controlling your account’s or organization’s resources in situations where running multiple workflows or jobs at the same time could cause conflicts or consume more Actions minutes and storage than expected. For example, you might want to prevent multiple deployments from running at the same time, or cancel linters checking outdated commits. + +To start controlling concurrency in your own workflows with the `concurrency` keyword, see [AUTOTITLE](/actions/how-tos/writing-workflows/choosing-when-your-workflow-runs/control-the-concurrency-of-workflows-and-jobs). diff --git a/content/actions/concepts/workflows-and-actions/index.md b/content/actions/concepts/workflows-and-actions/index.md index 857fb8c6320b..30bf84a78973 100644 --- a/content/actions/concepts/workflows-and-actions/index.md +++ b/content/actions/concepts/workflows-and-actions/index.md @@ -14,6 +14,7 @@ children: - /contexts - /expressions - /deployment-environments + - /concurrency - /workflow-artifacts - /dependency-caching - /about-monitoring-workflows diff --git a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs.md b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs.md deleted file mode 100644 index 82e87b16f50e..000000000000 --- a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Control the concurrency of workflows and jobs -shortTitle: Concurrency -intro: Run a single job at a time. -versions: - fpt: '*' - ghes: '*' - ghec: '*' -redirect_from: - - /actions/using-jobs/using-concurrency - - /actions/writing-workflows/choosing-what-your-workflow-does/using-concurrency - - /early-access/actions/running-additional-jobs-in-github-actions - - /actions/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs ---- - -{% data reusables.actions.enterprise-github-hosted-runners %} - -## Overview - -By default, {% data variables.product.prodname_actions %} allows multiple jobs within the same workflow, multiple workflow runs within the same repository, and multiple workflow runs across a repository owner's account to run concurrently. This means that multiple instances of the same workflow or job can run at the same time, performing the same steps. - -{% data variables.product.prodname_actions %} also allows you to disable concurrent execution. This can be useful for controlling your account’s or organization’s resources in situations where running multiple workflows or jobs at the same time could cause conflicts or consume more Actions minutes and storage than expected. - -For example, the ability to run workflows concurrently means that if multiple commits are pushed to a repository in quick succession, each push could trigger a separate workflow run, and these runs will execute concurrently. - -## Using concurrency in different scenarios - -{% data reusables.actions.jobs.section-using-concurrency-jobs %} - -{% ifversion github-runner-dashboard %} - -## Monitoring your current jobs in your organization or enterprise - -{% data reusables.actions.github-hosted-runners-check-concurrency %} -{% endif %} diff --git a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/index.md b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/index.md index 451c347fe726..709b00097584 100644 --- a/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/index.md +++ b/content/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/index.md @@ -19,7 +19,5 @@ children: - /passing-information-between-jobs - /setting-a-default-shell-and-working-directory - /deploying-to-a-specific-environment - - /control-the-concurrency-of-workflows-and-jobs - /running-variations-of-jobs-in-a-workflow --- - diff --git a/content/actions/how-tos/writing-workflows/choosing-when-your-workflow-runs/control-the-concurrency-of-workflows-and-jobs.md b/content/actions/how-tos/writing-workflows/choosing-when-your-workflow-runs/control-the-concurrency-of-workflows-and-jobs.md new file mode 100644 index 000000000000..b65c095d08a2 --- /dev/null +++ b/content/actions/how-tos/writing-workflows/choosing-when-your-workflow-runs/control-the-concurrency-of-workflows-and-jobs.md @@ -0,0 +1,26 @@ +--- +title: Control the concurrency of workflows and jobs +shortTitle: Control workflow concurrency +intro: Manage which workflows and jobs can run simultaneously. +versions: + fpt: '*' + ghes: '*' + ghec: '*' +redirect_from: + - /actions/using-jobs/using-concurrency + - /actions/writing-workflows/choosing-what-your-workflow-does/using-concurrency + - /early-access/actions/running-additional-jobs-in-github-actions + - /actions/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs + - /actions/how-tos/writing-workflows/choosing-what-your-workflow-does/control-the-concurrency-of-workflows-and-jobs +--- + +## Using concurrency in different scenarios + +{% data reusables.actions.jobs.section-using-concurrency-jobs %} + +{% ifversion github-runner-dashboard %} + +## Monitoring your current jobs in your organization or enterprise + +{% data reusables.actions.github-hosted-runners-check-concurrency %} +{% endif %} diff --git a/content/actions/how-tos/writing-workflows/choosing-when-your-workflow-runs/index.md b/content/actions/how-tos/writing-workflows/choosing-when-your-workflow-runs/index.md index 9bd65d058e46..ac2ce3ceb713 100644 --- a/content/actions/how-tos/writing-workflows/choosing-when-your-workflow-runs/index.md +++ b/content/actions/how-tos/writing-workflows/choosing-when-your-workflow-runs/index.md @@ -9,7 +9,7 @@ versions: children: - /triggering-a-workflow - /using-conditions-to-control-job-execution + - /control-the-concurrency-of-workflows-and-jobs redirect_from: - /actions/writing-workflows/choosing-when-your-workflow-runs --- - diff --git a/content/actions/reference/actions-limits.md b/content/actions/reference/actions-limits.md index 92e37dfbfd86..41c6ed618861 100644 --- a/content/actions/reference/actions-limits.md +++ b/content/actions/reference/actions-limits.md @@ -3,6 +3,8 @@ title: Actions limits intro: 'There are limits in {% data variables.product.prodname_actions %} which you may hit as you scale up, some may be increased by contacting support.' redirect_from: - /actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/actions-limits + - /actions/hosting-your-own-runners/managing-self-hosted-runners/usage-limits-for-self-hosted-runners + - /actions/reference/usage-limits-for-self-hosted-runners versions: fpt: '*' ghes: '*' @@ -10,8 +12,6 @@ versions: shortTitle: Actions limits --- -## Limits in {% data variables.product.prodname_actions %} - You may be rate limited by {% data variables.product.prodname_actions %} when you scale your usage. Some limits can be increased by contacting {% data variables.contact.contact_support %}. Unless otherwise stated, the expected behaviour when a limit is reached is that the workflow/job will get cancelled. @@ -29,16 +29,50 @@ These limits are subject to change. | Workflow execution | Job Matrix | 256 jobs / workflow run | A job matrix can generate a maximum of jobs per workflow run. This limit applies to both {% data variables.product.github %}-hosted and self-hosted runners. | {% octicon "x" aria-label="No" %} | | Self-hosted | Runner registrations | 1500 runners / 5 minutes / repository/org/enterprise | Runners can be registered per repository/organization/enterprise. | {% octicon "check" aria-label="Yes" %} Support ticket | | Self-hosted | Runners per runner group | 10,000 runners | Runners registered at the same time per runner group. | {% octicon "x" aria-label="No" %} | -| Hosted-runners | Job Concurrency | Varies | For more information about concurrency limits for standard and larger runners, see [AUTOTITLE](/actions/administering-github-actions/usage-limits-billing-and-administration#usage-limits). | {% octicon "check" aria-label="Yes" %} Support ticket | -| Hosted-runners | Job execution time | 6 hours | Each job in a workflow can run for up to 6 hours of execution time. If a job reaches this limit, the job is terminated and fails. | {% octicon "x" aria-label="No" %} | +| Self-hosted | Job execution time | 5 days | Each job in a workflow can run for up to 5 days of execution time. If a job reaches this limit, the job is terminated and fails. | {% octicon "x" aria-label="No" %} | +| Self-hosted | Job queue time | 24 hours | A job can be in the queue for 24 hours before it is automatically cancelled. | {% octicon "x" aria-label="No" %} | +| All {% data variables.product.github %}-hosted runners | Job Concurrency | Varies | See [Job concurrency limits for {% data variables.product.github %}-hosted runners](#job-concurrency-limits-for-github-hosted-runners). | {% octicon "check" aria-label="Yes" %} Support ticket | +| All {% data variables.product.github %}-hosted runners | Job execution time | 6 hours | Each job in a workflow can run for up to 6 hours of execution time. If a job reaches this limit, the job is terminated and fails. | {% octicon "x" aria-label="No" %} | | {% ifversion fpt or ghec %} | -| Hosted-runners | Storage limits | Varies | For more information, see [AUTOTITLE](/billing/managing-billing-for-your-products/managing-billing-for-github-actions/about-billing-for-github-actions#included-storage-and-minutes). | {% octicon "x" aria-label="No" %} | +| All {% data variables.product.github %}-hosted runners | Storage limits | Varies | For more information, see [Storage limits for all {% data variables.product.github %}-hosted runners](#storage-limits-for-all-github-hosted-runners). | {% octicon "x" aria-label="No" %} | | {% endif %} | -| Larger runners | Per runner concurrency limit | Varies by runner type | You establish when setting up a runner, normally 1,000 max for Linux CPU runners but varies by type. For more information, see [AUTOTITLE](/actions/administering-github-actions/usage-limits-billing-and-administration#usage-limits). | {% octicon "check" aria-label="Yes" %} Support ticket | +| Larger runners | Per runner concurrency limit | Varies by runner type | Established when setting up a runner. Normally 1,000 max for Linux CPU runners, but varies by type. See [Job concurrency limits for {% data variables.product.github %}-hosted runners](#job-concurrency-limits-for-github-hosted-runners). | {% octicon "check" aria-label="Yes" %} Support ticket | | Larger runners | Static IP limits | 10-50 IPs | 10 IPs for team plans, 50 IPs for enterprise, and the limit is configurable. | {% octicon "check" aria-label="Yes" %} Support ticket | -| Larger runners | Private IP scaling for vnet injection | 30% buffer | You need to determine the appropriate subnet IP address range, for which we recommend adding a buffer to the maximum job concurrency you anticipate. For instance, if the network configuration's runners are set to a maximum job concurrency of 300, utilize a subnet IP address range that can accommodate at least 390 runners. Note that Azure reserves 5 IPs in every subnet (first 4 and last 1), which sets a minimum practical subnet size depending on runner requirements. Very small subnets (like /29 or smaller) may not provide enough usable addresses for your needs. | {% octicon "check" aria-label="Yes" %} \- Configurable Azure virtual network | +| Larger runners | Private IP scaling for vnet injection | 30% buffer | You need a buffer to accommodate the maximum job concurrency you anticipate. See [Private IP scaling for vnet injection on larger runners](#private-ip-scaling-for-vnet-injection-on-larger-runners). | {% octicon "check" aria-label="Yes" %} Configurable Azure virtual network | + +### Job concurrency limits for {% data variables.product.github %}-hosted runners + +{% data variables.product.github %} Support **can** increase job concurrency limits for {% data variables.product.prodname_actions %}. To request an increase, submit a support ticket. + +| Runner type | {% data variables.product.github %} plan | Total concurrent jobs | Maximum concurrent macOS jobs | Maximum concurrent GPU jobs | +|---|---|---|---|---| +| Standard {% data variables.product.github %}-hosted runner | Free | 20 | 5 | Not applicable | +| Standard {% data variables.product.github %}-hosted runner | Pro | 40 | 5 | Not applicable | +| Standard {% data variables.product.github %}-hosted runner | Team | 60 | 5 | Not applicable | +| Standard {% data variables.product.github %}-hosted runner | Enterprise | 500 | 50 | Not applicable | +| Larger runner | Team | 1000 | 5 | 100 | +| Larger runner | Enterprise | 1000 | 50 | 100 | + +> [!NOTE] +> The maximum concurrent macOS jobs is shared across standard {% data variables.product.github %}-hosted runners and {% data variables.product.github %}-hosted larger runners. + +### Storage limits for all {% data variables.product.github %}-hosted runners + +{% data variables.product.github %} Support **cannot** increase storage limits for {% data variables.product.prodname_actions %}. + +| {% data variables.product.github %} plan | Storage | Minutes (per month)| +|------- | ------- | ---------| +| {% data variables.product.prodname_free_user %} | 500 MB | 2,000 | +| {% data variables.product.prodname_pro %} | 1 GB | 3,000 | +| {% data variables.product.prodname_free_team %} for organizations | 500 MB | 2,000 | +| {% data variables.product.prodname_team %} | 2 GB | 3,000 | +| {% data variables.product.prodname_ghe_cloud %} | 50 GB | 50,000 | + +### Private IP scaling for vnet injection on larger runners + +When using larger runners with vnet injection, you need to determine the appropriate subnet IP address range, for which we recommend adding a buffer to the maximum job concurrency you anticipate. For instance, if the network configuration's runners are set to a maximum job concurrency of 300, utilize a subnet IP address range that can accommodate at least 390 runners. Note that Azure reserves 5 IPs in every subnet (first 4 and last 1), which sets a minimum practical subnet size depending on runner requirements. Very small subnets (like /29 or smaller) may not provide enough usable addresses for your needs. -### Commonly hit dependent service limits +## Commonly hit dependent service limits {% data variables.product.github %}'s [REST API rate limits](/rest/using-the-rest-api/rate-limits-for-the-rest-api) apply to {% data variables.product.prodname_actions %} users, those that are commonly hit are: diff --git a/content/actions/reference/index.md b/content/actions/reference/index.md index 2f4f3b5e92da..1a70bb2fc4e1 100644 --- a/content/actions/reference/index.md +++ b/content/actions/reference/index.md @@ -24,8 +24,6 @@ children: - /dockerfile-support-for-github-actions - /github-hosted-runners-reference - /self-hosted-runners-reference - - /usage-limits-for-self-hosted-runners - /supplemental-arguments-and-settings - /extending-github-actions-importer-with-custom-transformers --- - diff --git a/content/actions/reference/usage-limits-for-self-hosted-runners.md b/content/actions/reference/usage-limits-for-self-hosted-runners.md deleted file mode 100644 index 821ddaea1373..000000000000 --- a/content/actions/reference/usage-limits-for-self-hosted-runners.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Usage limits for self-hosted runners -shortTitle: Usage limits -intro: 'There are some limits on {% data variables.product.prodname_actions %} usage when using self-hosted runners. These limits are subject to change.' -redirect_from: - - /actions/hosting-your-own-runners/managing-self-hosted-runners/usage-limits-for-self-hosted-runners -versions: - fpt: '*' - ghes: '*' - ghec: '*' -type: overview ---- - -* **Job execution time** - Each job in a workflow can run for up to 5 days of execution time. If a job reaches this limit, the job is terminated and fails to complete. -{% data reusables.actions.usage-workflow-run-time %} -* **Job queue time** - Each job for self-hosted runners that has been queued for at least 24 hours will be canceled. The actual time in queue can reach up to 48 hours before cancellation occurs. If a self-hosted runner does not start executing the job within this limit, the job is terminated and fails to complete. -{% data reusables.actions.usage-api-requests %} -* **Job matrix** - {% data reusables.actions.usage-matrix-limits %} -{% data reusables.actions.usage-workflow-queue-limits %} -* **Registering self-hosted runners** - {% data reusables.actions.self-hosted-runner-group-limit %} diff --git a/content/code-security/securing-your-organization/understanding-your-organizations-exposure-to-vulnerabilities/prioritizing-dependabot-alerts-using-metrics.md b/content/code-security/securing-your-organization/understanding-your-organizations-exposure-to-vulnerabilities/prioritizing-dependabot-alerts-using-metrics.md index 45cb70e8c4b1..5a7b24c3ccdb 100644 --- a/content/code-security/securing-your-organization/understanding-your-organizations-exposure-to-vulnerabilities/prioritizing-dependabot-alerts-using-metrics.md +++ b/content/code-security/securing-your-organization/understanding-your-organizations-exposure-to-vulnerabilities/prioritizing-dependabot-alerts-using-metrics.md @@ -3,6 +3,7 @@ title: Prioritizing Dependabot alerts using metrics shortTitle: Prioritize Dependabot alerts using metrics intro: 'You can prioritize {% data variables.product.prodname_dependabot_alerts %} in your organization by analyzing the provided metrics. Using this approach, you can tell your developers to focus on the most important vulnerabilities first.' allowTitleToDifferFromFilename: true +product: '{% data reusables.gated-features.security-overview-fpt-cs-only %}' permissions: '{% data reusables.permissions.security-org-enable %}' versions: feature: dependabot-metrics @@ -30,6 +31,8 @@ Application Security (AppSec) managers often face a flood of {% data variables.p * **Alerts closed in the last 30 days, including the number of alerts fixed by {% data variables.product.prodname_dependabot %}, manually dismissed, and auto dismissed**: Tracks alert resolution progress. Illustrates how {% data variables.product.prodname_GH_code_security %} can help you detect vulnerabilities early. * **Table showing the total number of open alerts for each repository, as well as severity and expoitability data**: Allows you to dig deeper at the repository level. +For more information about these metrics, see [AUTOTITLE](/code-security/security-overview/viewing-metrics-for-dependabot-alerts). + Additionally, you can specify complex filters, which are combinations of the individual filters that are available. For more information about filters, see [{% data variables.product.prodname_dependabot %} dashboard view filters](/code-security/security-overview/filtering-alerts-in-security-overview#dependabot-dashboard-view-filters). ## Steps to prioritize alerts diff --git a/content/code-security/security-overview/filtering-alerts-in-security-overview.md b/content/code-security/security-overview/filtering-alerts-in-security-overview.md index ea58718225d4..6d4f7a9a495d 100644 --- a/content/code-security/security-overview/filtering-alerts-in-security-overview.md +++ b/content/code-security/security-overview/filtering-alerts-in-security-overview.md @@ -158,7 +158,7 @@ You can also filter the "Overview" view by properties of alerts. | `severity` | Display data only for alerts of a specific severity (`critical`, `high`, `medium`, or `low`). | `third-party.rule`| Display data only for {% data variables.product.prodname_code_scanning %} identified by a specific rule for a tool developed by a third party. For example, `third-party.rule:CVE-2021-26291-maven-artifact` shows only results for the `CVE-2021-26291-maven-artifact` rule of a third-party {% data variables.product.prodname_code_scanning %} tool. -### {% data variables.product.prodname_dependabot %} alert view filters +## {% data variables.product.prodname_dependabot %} alert view filters You can filter the view to show {% data variables.product.prodname_dependabot_alerts %} that are ready to fix or where additional information about exposure is available. You can click any result to see full details of the alert. @@ -174,7 +174,7 @@ You can filter the view to show {% data variables.product.prodname_dependabot_al {% ifversion dependabot-metrics %} -### {% data variables.product.prodname_dependabot %} dashboard filters +## {% data variables.product.prodname_dependabot %} dashboard filters You can filter the "{% data variables.product.prodname_dependabot %} dashboard" view using these filters. @@ -184,7 +184,7 @@ Alternatively, you can use complex filters by clicking **{% octicon "filter" ari {% endif %} -### {% data variables.product.prodname_code_scanning_caps %} alert view filters +## {% data variables.product.prodname_code_scanning_caps %} alert view filters All {% data variables.product.prodname_code_scanning %} alerts have one of the categories shown below. You can click any result to see full details of the relevant query and the line of code that triggered the alert. diff --git a/content/copilot/tutorials/choosing-the-right-ai-tool-for-your-task.md b/content/copilot/concepts/choosing-the-right-ai-tool-for-your-task.md similarity index 99% rename from content/copilot/tutorials/choosing-the-right-ai-tool-for-your-task.md rename to content/copilot/concepts/choosing-the-right-ai-tool-for-your-task.md index 0d2f6b3067c1..316b321bc76e 100644 --- a/content/copilot/tutorials/choosing-the-right-ai-tool-for-your-task.md +++ b/content/copilot/concepts/choosing-the-right-ai-tool-for-your-task.md @@ -8,6 +8,7 @@ topics: - Copilot redirect_from: - /copilot/using-github-copilot/guides-on-using-github-copilot/choosing-the-right-ai-tool-for-your-task + - /copilot/tutorials/choosing-the-right-ai-tool-for-your-task --- ## Overview diff --git a/content/copilot/concepts/index.md b/content/copilot/concepts/index.md index 66a232a164ec..b0f8b1f932b7 100644 --- a/content/copilot/concepts/index.md +++ b/content/copilot/concepts/index.md @@ -1,5 +1,5 @@ --- -title: 'Concepts for GitHub Copilot' +title: Concepts for GitHub Copilot shortTitle: Concepts intro: 'Learn the core concepts that you''ll need to understand {% data variables.product.prodname_copilot %}.' versions: @@ -8,6 +8,7 @@ topics: - Copilot children: - /copilot-billing + - /choosing-the-right-ai-tool-for-your-task - /completions - /prompt-engineering-for-copilot-chat - /about-customizing-github-copilot-chat-responses @@ -19,3 +20,4 @@ children: - /copilot-knowledge-bases - /build-copilot-extensions --- + diff --git a/content/copilot/how-tos/index.md b/content/copilot/how-tos/index.md index adb920bc5467..9163eaba43a2 100644 --- a/content/copilot/how-tos/index.md +++ b/content/copilot/how-tos/index.md @@ -16,7 +16,7 @@ children: - /custom-instructions - /content-exclusion - /github-flow - - /premium-requests + - /spending - /personal-settings - /manage-your-account - /administer diff --git a/content/copilot/how-tos/premium-requests/index.md b/content/copilot/how-tos/premium-requests/index.md deleted file mode 100644 index 2e75eded2f51..000000000000 --- a/content/copilot/how-tos/premium-requests/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Premium requests for Copilot -shortTitle: Premium requests -intro: 'Manage and track premium requests for yourself or for your users.' -versions: - feature: copilot -topics: - - Copilot -children: - - /monitoring-your-copilot-usage-and-entitlements - - /manage-for-enterprise ---- - diff --git a/content/copilot/how-tos/spending/index.md b/content/copilot/how-tos/spending/index.md new file mode 100644 index 000000000000..00da3e2df6a3 --- /dev/null +++ b/content/copilot/how-tos/spending/index.md @@ -0,0 +1,16 @@ +--- +title: Manage and monitor spending for Copilot +shortTitle: Spending +intro: 'Manage and track spending on Copilot for your company.' +versions: + feature: copilot +topics: + - Copilot +children: + - /monitoring-your-copilot-usage-and-entitlements + - /manage-for-enterprise + - /managing-your-companys-spending-on-github-copilot +redirect_from: + - /copilot/how-tos/premium-requests +--- + diff --git a/content/copilot/how-tos/premium-requests/manage-for-enterprise.md b/content/copilot/how-tos/spending/manage-for-enterprise.md similarity index 98% rename from content/copilot/how-tos/premium-requests/manage-for-enterprise.md rename to content/copilot/how-tos/spending/manage-for-enterprise.md index 65e937800622..22f5b8fb49e7 100644 --- a/content/copilot/how-tos/premium-requests/manage-for-enterprise.md +++ b/content/copilot/how-tos/spending/manage-for-enterprise.md @@ -1,6 +1,6 @@ --- title: Managing the premium request allowance for users in your enterprise -shortTitle: Manage allowance for members +shortTitle: Enterprise premium requests intro: 'Change the default spending limit or upgrade users to {% data variables.copilot.copilot_enterprise_short %}.' permissions: 'Enterprise owners' versions: @@ -9,6 +9,8 @@ topics: - Copilot allowTitleToDifferFromFilename: true product: '{% data variables.copilot.copilot_for_business %} or {% data variables.copilot.copilot_enterprise %}' +redirect_from: + - /copilot/how-tos/premium-requests/manage-for-enterprise --- Each {% data variables.product.prodname_copilot_short %} plan includes a per-user allowance for premium requests. To learn more about premium requests, see [AUTOTITLE](/copilot/concepts/copilot-billing/understanding-and-managing-requests-in-copilot). For allowances per plan, see [AUTOTITLE](/copilot/get-started/plans-for-github-copilot#comparing-copilot-plans). diff --git a/content/copilot/tutorials/rolling-out-github-copilot-at-scale/assigning-licenses/managing-your-companys-spending-on-github-copilot.md b/content/copilot/how-tos/spending/managing-your-companys-spending-on-github-copilot.md similarity index 89% rename from content/copilot/tutorials/rolling-out-github-copilot-at-scale/assigning-licenses/managing-your-companys-spending-on-github-copilot.md rename to content/copilot/how-tos/spending/managing-your-companys-spending-on-github-copilot.md index eb9c03f2e951..534664c3e8ae 100644 --- a/content/copilot/tutorials/rolling-out-github-copilot-at-scale/assigning-licenses/managing-your-companys-spending-on-github-copilot.md +++ b/content/copilot/how-tos/spending/managing-your-companys-spending-on-github-copilot.md @@ -1,6 +1,6 @@ --- title: Managing your company's spending on GitHub Copilot -shortTitle: Manage spending +shortTitle: Manage company spending intro: 'Learn how to track spending, view usage, and optimize license distribution.' versions: feature: copilot @@ -11,6 +11,7 @@ product: '{% data variables.copilot.copilot_for_business %} or {% data variables redirect_from: - /copilot/rolling-out-github-copilot-at-scale/managing-your-companys-spending-on-github-copilot - /copilot/rolling-out-github-copilot-at-scale/assigning-licenses/managing-your-companys-spending-on-github-copilot + - /copilot/tutorials/rolling-out-github-copilot-at-scale/assigning-licenses/managing-your-companys-spending-on-github-copilot --- When you're adopting {% data variables.product.prodname_copilot %} in an enterprise, you will want to set budgets and track spending to ensure your rollout is sustainable. {% data variables.product.github %} offers billing tools to help you visualize your spending patterns, receive alerts when you reach budget thresholds, and optimize your license usage. @@ -21,6 +22,8 @@ To control spending, it's important to understand who can affect your bill by gr We recommend that you identify the people with this role and communicate with them about your company's strategy for distributing licenses. For example, you may have a budget or limited pilot program, or you may distribute licenses through an internal website. +For more information, see [AUTOTITLE](/admin/managing-accounts-and-repositories/managing-users-in-your-enterprise/viewing-people-in-your-enterprise#viewing-members). + ## Managing premium requests Each {% data variables.product.prodname_copilot_short %} plan includes a per-user allowance for premium requests. To learn more about premium requests, see [AUTOTITLE](/copilot/concepts/copilot-billing/understanding-and-managing-requests-in-copilot). For allowances per plan, see [AUTOTITLE](/copilot/get-started/plans-for-github-copilot#comparing-copilot-plans). @@ -77,9 +80,9 @@ For more detailed insights, you can filter the results by cost center and group ![Screenshot of the "Usage" page. A line chart tracks Copilot spending over the current month, grouped by SKU.](/assets/images/help/copilot/track-spending.png) -## Optimize license usage +## Next steps -When you begin rolling out {% data variables.product.prodname_copilot_short %} in a company, you may see low rates of adoption at first. An effective enablement process is essential to drive adoption of {% data variables.product.prodname_copilot_short %} in your company. Tailor this process to your company's needs and goals, and design it to help your teams understand how to use {% data variables.product.prodname_copilot_short %} effectively. +As well as managing spending on licenses, it is important to ensure licenses are being used effectively. When you begin rolling out {% data variables.product.prodname_copilot_short %} in a company, you may see low rates of adoption at first. An effective enablement process is essential to drive adoption of {% data variables.product.prodname_copilot_short %} in your company. Tailor this process to your company's needs and goals, and design it to help your teams understand how to use {% data variables.product.prodname_copilot_short %} effectively. To ensure your licenses are being used effectively, you can use the API to identify inactive users. We recommend sending these users a message with advice and resources for getting started. If a user remains inactive, you can revoke their license and assign it to another user. diff --git a/content/copilot/how-tos/premium-requests/monitoring-your-copilot-usage-and-entitlements.md b/content/copilot/how-tos/spending/monitoring-your-copilot-usage-and-entitlements.md similarity index 98% rename from content/copilot/how-tos/premium-requests/monitoring-your-copilot-usage-and-entitlements.md rename to content/copilot/how-tos/spending/monitoring-your-copilot-usage-and-entitlements.md index 1495c5bf2400..2be29b0acc22 100644 --- a/content/copilot/how-tos/premium-requests/monitoring-your-copilot-usage-and-entitlements.md +++ b/content/copilot/how-tos/spending/monitoring-your-copilot-usage-and-entitlements.md @@ -1,6 +1,6 @@ --- title: Monitoring your Copilot usage and entitlements -shortTitle: Monitor usage and entitlements +shortTitle: Monitor premium requests intro: 'Learn how you can monitor your monthly usage of {% data variables.product.prodname_copilot_short %} and get the most value out of your {% data variables.product.prodname_copilot_short %} plan.' permissions: 'Individual users on a paid {% data variables.product.prodname_copilot_short %} plan can view their own usage and entitlements. For {% data variables.copilot.copilot_business_short %} or {% data variables.copilot.copilot_enterprise_short %} plans, organization admins and billing managers can view usage reports for members.' versions: @@ -12,6 +12,7 @@ redirect_from: - /copilot/managing-copilot/monitoring-usage-and-entitlements/monitoring-your-copilot-usage-and-entitlements - /copilot/managing-copilot/understanding-and-managing-copilot-usage/monitoring-your-copilot-usage-and-entitlements - /copilot/how-tos/monitoring-your-copilot-usage-and-entitlements + - /copilot/how-tos/premium-requests/monitoring-your-copilot-usage-and-entitlements --- You can track your monthly usage of premium requests to help you get the most value from your {% data variables.product.prodname_copilot_short %} plan. diff --git a/content/copilot/tutorials/index.md b/content/copilot/tutorials/index.md index 5ca99897b3f7..f5bc7a81ef23 100644 --- a/content/copilot/tutorials/index.md +++ b/content/copilot/tutorials/index.md @@ -8,7 +8,6 @@ topics: - Copilot children: - /copilot-chat-cookbook - - /choosing-the-right-ai-tool-for-your-task - /comparing-ai-models-using-different-tasks - /enhancing-copilot-agent-mode-with-mcp - /quickstart-for-github-copilot-extensions-using-agents diff --git a/content/copilot/tutorials/rolling-out-github-copilot-at-scale/assigning-licenses/index.md b/content/copilot/tutorials/rolling-out-github-copilot-at-scale/assigning-licenses/index.md index 4cef1dcc6478..204fe5e69fc6 100644 --- a/content/copilot/tutorials/rolling-out-github-copilot-at-scale/assigning-licenses/index.md +++ b/content/copilot/tutorials/rolling-out-github-copilot-at-scale/assigning-licenses/index.md @@ -9,7 +9,6 @@ topics: children: - /setting-up-a-self-serve-process-for-github-copilot-licenses - /reminding-inactive-users - - /managing-your-companys-spending-on-github-copilot redirect_from: - /copilot/rolling-out-github-copilot-at-scale/assigning-licenses --- diff --git a/data/reusables/contributing/content-linter-rules.md b/data/reusables/contributing/content-linter-rules.md index 5f861a8dc84d..126d0d424ade 100644 --- a/data/reusables/contributing/content-linter-rules.md +++ b/data/reusables/contributing/content-linter-rules.md @@ -73,4 +73,5 @@ | GHD048 | british-english-quotes | Periods and commas should be placed inside quotation marks (American English style) | warning | punctuation, quotes, style, consistency | | GHD050 | multiple-emphasis-patterns | Do not use more than one emphasis/strong, italics, or uppercase for a string | warning | formatting, emphasis, style | | GHD049 | note-warning-formatting | Note and warning tags should be formatted according to style guide | warning | formatting, callouts, notes, warnings, style | -| GHD051 | frontmatter-versions-whitespace | Versions frontmatter should not contain unnecessary whitespace | warning | frontmatter, versions | \ No newline at end of file +| GHD051 | frontmatter-versions-whitespace | Versions frontmatter should not contain unnecessary whitespace | warning | frontmatter, versions | +| GHD054 | third-party-actions-reusable | Code examples with third-party actions must include disclaimer reusable | warning | actions, reusable, third-party | \ No newline at end of file diff --git a/data/reusables/gated-features/security-overview-fpt-cs-only.md b/data/reusables/gated-features/security-overview-fpt-cs-only.md index 79c75b903210..ebd4d288bc3c 100644 --- a/data/reusables/gated-features/security-overview-fpt-cs-only.md +++ b/data/reusables/gated-features/security-overview-fpt-cs-only.md @@ -1,3 +1 @@ -{% ifversion fpt %} -Organizations owned by a {% data variables.product.prodname_team %} account with {% data variables.product.prodname_GH_code_security %}, or owned by a {% data variables.product.prodname_enterprise %} account -{% endif %} +Organizations owned by a {% data variables.product.prodname_team %} account with {% data variables.product.prodname_GH_code_security %}, or owned by a {% data variables.product.prodname_enterprise %} account with {% data variables.product.prodname_GH_code_security %} diff --git a/src/content-linter/lib/linting-rules/index.js b/src/content-linter/lib/linting-rules/index.js index 918e76924d06..8afe18b8e7b6 100644 --- a/src/content-linter/lib/linting-rules/index.js +++ b/src/content-linter/lib/linting-rules/index.js @@ -51,6 +51,7 @@ import { britishEnglishQuotes } from '@/content-linter/lib/linting-rules/british import { multipleEmphasisPatterns } from '@/content-linter/lib/linting-rules/multiple-emphasis-patterns' import { noteWarningFormatting } from '@/content-linter/lib/linting-rules/note-warning-formatting' import { frontmatterVersionsWhitespace } from '@/content-linter/lib/linting-rules/frontmatter-versions-whitespace' +import { thirdPartyActionsReusable } from '@/content-linter/lib/linting-rules/third-party-actions-reusable' const noDefaultAltText = markdownlintGitHub.find((elem) => elem.names.includes('no-default-alt-text'), @@ -107,5 +108,6 @@ export const gitHubDocsMarkdownlint = { multipleEmphasisPatterns, noteWarningFormatting, frontmatterVersionsWhitespace, + thirdPartyActionsReusable, ], } diff --git a/src/content-linter/lib/linting-rules/third-party-actions-reusable.js b/src/content-linter/lib/linting-rules/third-party-actions-reusable.js new file mode 100644 index 000000000000..2c0000dc6879 --- /dev/null +++ b/src/content-linter/lib/linting-rules/third-party-actions-reusable.js @@ -0,0 +1,97 @@ +import { addError, filterTokens } from 'markdownlint-rule-helpers' + +export const thirdPartyActionsReusable = { + names: ['GHD054', 'third-party-actions-reusable'], + description: 'Code examples with third-party actions must include disclaimer reusable', + tags: ['actions', 'reusable', 'third-party'], + function: (params, onError) => { + // Find all code fence blocks + filterTokens(params, 'fence', (token) => { + // Only check YAML code blocks (GitHub Actions workflows) + if (token.info !== 'yaml' && token.info !== 'yaml copy') return + + const codeContent = token.content + const lineNumber = token.lineNumber + + // Find third-party actions in the code block + const thirdPartyActions = findThirdPartyActions(codeContent) + + if (thirdPartyActions.length === 0) return + + // Check if the required disclaimer reusable is present before this code block or inside it + const hasDisclaimer = checkForDisclaimer(params.lines, lineNumber, codeContent) + + if (!hasDisclaimer) { + const actionList = thirdPartyActions.map((action) => `'${action}'`).join(', ') + addError( + onError, + lineNumber, + `Code examples with third-party actions must include the disclaimer reusable. Found third-party actions: ${actionList}. Add '{% data reusables.actions.actions-not-certified-by-github-comment %}' before or inside this code block.`, + token.line, + null, // No specific range within the line + null, // No fix possible - requires manual addition of reusable + ) + } + }) + }, +} + +/** + * Find third-party actions in YAML content + * Third-party actions are identified by the pattern: owner/action@version + * where owner is not 'actions' or 'github' + */ +function findThirdPartyActions(yamlContent) { + const thirdPartyActions = [] + + // Pattern to match 'uses: owner/action@version' where owner is not actions or github + const actionPattern = /uses:\s+([^{\s]+\/[^@\s]+@[^\s]+)/g + + let match + while ((match = actionPattern.exec(yamlContent)) !== null) { + const actionRef = match[1] + + // Extract owner from action reference + const parts = actionRef.split('/') + if (parts.length >= 2) { + const owner = parts[0] + + // Skip GitHub-owned actions (actions/* and github/*) + if (owner !== 'actions' && owner !== 'github') { + thirdPartyActions.push(actionRef) + } + } + } + + return thirdPartyActions +} + +/** + * Check if the disclaimer reusable is present before the given line number or inside the code block + * Looks backward from the code block and also inside the code block content + */ +function checkForDisclaimer(lines, codeBlockLineNumber, codeContent) { + const disclaimerPattern = /{% data reusables\.actions\.actions-not-certified-by-github-comment %}/ + + // First, check inside the code block content + if (disclaimerPattern.test(codeContent)) { + return true + } + + // Convert from 1-based line number to 0-based array index + const codeBlockIndex = codeBlockLineNumber - 1 + + // Search backwards from the code block (up to 10 lines before) + // This is reasonable since disclaimers are typically right before code blocks + const searchStart = Math.max(0, codeBlockIndex - 10) + + for (let i = codeBlockIndex - 1; i >= searchStart; i--) { + const line = lines[i] + + if (disclaimerPattern.test(line)) { + return true + } + } + + return false +} diff --git a/src/content-linter/style/github-docs.js b/src/content-linter/style/github-docs.js index 19b3d3e4c650..8f01be70d952 100644 --- a/src/content-linter/style/github-docs.js +++ b/src/content-linter/style/github-docs.js @@ -237,6 +237,12 @@ const githubDocsConfig = { 'partial-markdown-files': true, 'yml-files': true, }, + 'third-party-actions-reusable': { + // GHD054 + severity: 'warning', + 'partial-markdown-files': true, + 'yml-files': true, + }, } export const githubDocsFrontmatterConfig = { diff --git a/src/content-linter/tests/unit/third-party-actions-reusable.js b/src/content-linter/tests/unit/third-party-actions-reusable.js new file mode 100644 index 000000000000..6227dff9a08f --- /dev/null +++ b/src/content-linter/tests/unit/third-party-actions-reusable.js @@ -0,0 +1,404 @@ +import { describe, expect, test } from 'vitest' + +import { runRule } from '../../lib/init-test' +import { thirdPartyActionsReusable } from '../../lib/linting-rules/third-party-actions-reusable' + +// Configure the test figure to not split frontmatter and content +const fmOptions = { markdownlintOptions: { frontMatter: null } } + +describe(thirdPartyActionsReusable.names.join(' - '), () => { + describe('valid cases', () => { + test('should pass when third-party actions have disclaimer', async () => { + const content = `--- +title: Test +--- + +# Test + +This example shows proper usage: + +{% data reusables.actions.actions-not-certified-by-github-comment %} + +\`\`\`yaml copy +name: Test +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 6.10.0 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + + test('should pass when no third-party actions are used', async () => { + const content = `--- +title: Test +--- + +# Test + +This example uses only GitHub actions: + +\`\`\`yaml copy +name: Test +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + - uses: github/super-action@v1 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + + test('should pass when using reusables instead of direct action references', async () => { + const content = `--- +title: Test +--- + +# Test + +This example uses reusables: + +\`\`\`yaml copy +name: Test +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: {% data reusables.actions.action-checkout %} + - uses: {% data reusables.actions.action-setup-node %} +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + + test('should pass when disclaimer is within search range', async () => { + const content = `--- +title: Test +--- + +# Test + +Some explanatory text here. + +More text. + +{% data reusables.actions.actions-not-certified-by-github-comment %} + +Some additional notes. + +\`\`\`yaml copy +name: Test +jobs: + test: + steps: + - uses: azure/login@v1 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + + test('should pass when disclaimer is inside code block', async () => { + const content = `--- +title: Test +--- + +# Test + +This example has disclaimer inside the code block: + +\`\`\`yaml copy + +{% data reusables.actions.actions-not-certified-by-github-comment %} + +name: Test +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: swift-actions/setup-swift@v2 + with: + swift-version: 5.3 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + + test('should pass for non-YAML code blocks', async () => { + const content = `--- +title: Test +--- + +# Test + +\`\`\`javascript +const actions = 'pnpm/action-setup@v2'; +console.log(actions); +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + }) + + describe('invalid cases', () => { + test('should fail when third-party action lacks disclaimer', async () => { + const content = `--- +title: Test +--- + +# Test + +This example is missing the disclaimer: + +\`\`\`yaml copy +name: Test +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 6.10.0 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(1) + expect(result.content[0].errorDetail).toContain('pnpm/action-setup@v2') + expect(result.content[0].errorDetail).toContain('actions-not-certified-by-github-comment') + }) + + test('should fail when multiple third-party actions lack disclaimer', async () => { + const content = `--- +title: Test +--- + +# Test + +\`\`\`yaml copy +name: Test +jobs: + test: + steps: + - uses: azure/login@v1 + - uses: pnpm/action-setup@v2 + - uses: docker/build-push-action@v3 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(1) + expect(result.content[0].errorDetail).toContain('azure/login@v1') + expect(result.content[0].errorDetail).toContain('pnpm/action-setup@v2') + expect(result.content[0].errorDetail).toContain('docker/build-push-action@v3') + }) + + test('should pass when disclaimer is close but not immediate', async () => { + const content = `--- +title: Test +--- + +# Test + +{% data reusables.actions.actions-not-certified-by-github-comment %} + +Some explanation text here. +More details about the example. + +\`\`\`yaml copy +name: Test +jobs: + test: + steps: + - uses: pnpm/action-setup@v2 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + + test('should fail when disclaimer is outside search range', async () => { + const content = `--- +title: Test +--- + +# Test + +{% data reusables.actions.actions-not-certified-by-github-comment %} + +Some text here. +More text. +Line 1 +Line 2 +Line 3 +Line 4 +Line 5 +Line 6 +Line 7 +Line 8 +Line 9 +Line 10 +Line 11 + +\`\`\`yaml copy +name: Test +jobs: + test: + steps: + - uses: pnpm/action-setup@v2 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(1) + }) + }) + + describe('edge cases', () => { + test('should handle mixed GitHub and third-party actions correctly', async () => { + const content = `--- +title: Test +--- + +# Test + +{% data reusables.actions.actions-not-certified-by-github-comment %} + +\`\`\`yaml copy +name: Test +jobs: + test: + steps: + - uses: actions/checkout@v3 # GitHub action - OK + - uses: github/super-action@v1 # GitHub action - OK + - uses: pnpm/action-setup@v2 # Third-party - needs disclaimer +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + + test('should handle actions with complex version specifiers', async () => { + const content = `--- +title: Test +--- + +# Test + +{% data reusables.actions.actions-not-certified-by-github-comment %} + +\`\`\`yaml copy +name: Test +jobs: + test: + steps: + - uses: some-org/action@1.2.3 + - uses: another-org/tool@v1.0.0-beta.1 + - uses: company/action@main + - uses: user/action@sha1234567890abcdef +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + + test('should handle yaml copy blocks', async () => { + const content = `--- +title: Test +--- + +# Test + +\`\`\`yaml copy +name: Test +jobs: + test: + steps: + - uses: pnpm/action-setup@v2 +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(1) + }) + + test('should not match incomplete action references', async () => { + const content = `--- +title: Test +--- + +# Test + +\`\`\`yaml copy +name: Test +jobs: + test: + steps: + - uses: incomplete-action + - uses: also/incomplete + - name: Not an action reference + run: echo "hello" +\`\`\` +` + const result = await runRule(thirdPartyActionsReusable, { + strings: { content }, + ...fmOptions, + }) + expect(result.content.length).toBe(0) + }) + }) +}) diff --git a/src/graphql/scripts/build-changelog.js b/src/graphql/scripts/build-changelog.js index 3d2345a43dc0..324b7b5a83f9 100644 --- a/src/graphql/scripts/build-changelog.js +++ b/src/graphql/scripts/build-changelog.js @@ -50,21 +50,34 @@ export async function createChangelogEntry( // Generate changes between the two schemas const changes = await diff(oldSchema, newSchema) const changesToReport = [] + const ignoredChanges = [] changes.forEach((change) => { if (CHANGES_TO_REPORT.includes(change.type)) { changesToReport.push(change) - } else if (CHANGES_TO_IGNORE.includes(change.type)) { - // Do nothing } else { - console.error('Change object causing error:') - console.error(change) - throw new Error( - 'This change type should be added to CHANGES_TO_REPORT or CHANGES_TO_IGNORE: ' + - change.type, - ) + // Track ignored changes for visibility + ignoredChanges.push(change) } }) + // Log warnings for ignored change types to provide visibility + if (ignoredChanges.length > 0) { + const ignoredTypes = [...new Set(ignoredChanges.map((change) => change.type))] + console.warn( + `⚠️ GraphQL changelog: Ignoring ${ignoredChanges.length} changes of ${ignoredTypes.length} type(s):`, + ) + ignoredTypes.forEach((type) => { + const count = ignoredChanges.filter((change) => change.type === type).length + console.warn(` - ${type} (${count} change${count > 1 ? 's' : ''})`) + }) + console.warn( + ' These change types are not in CHANGES_TO_REPORT and will not appear in the changelog.', + ) + } + + // Store ignored changes for potential workflow outputs + createChangelogEntry.lastIgnoredChanges = ignoredChanges + const { schemaChangesToReport, previewChangesToReport } = segmentPreviewChanges( changesToReport, previews, @@ -276,40 +289,36 @@ const CHANGES_TO_REPORT = [ ChangeType.DirectiveUsageFieldDefinitionRemoved, ] -const CHANGES_TO_IGNORE = [ - ChangeType.FieldArgumentDescriptionChanged, - ChangeType.DirectiveRemoved, - ChangeType.DirectiveAdded, - ChangeType.DirectiveDescriptionChanged, - ChangeType.DirectiveLocationAdded, - ChangeType.DirectiveLocationRemoved, - ChangeType.DirectiveArgumentAdded, - ChangeType.DirectiveArgumentRemoved, - ChangeType.DirectiveArgumentDescriptionChanged, - ChangeType.DirectiveArgumentDefaultValueChanged, - ChangeType.DirectiveArgumentTypeChanged, - ChangeType.DirectiveUsageArgumentDefinitionRemoved, - ChangeType.EnumValueDescriptionChanged, - ChangeType.EnumValueDeprecationReasonChanged, - ChangeType.EnumValueDeprecationReasonAdded, - ChangeType.EnumValueDeprecationReasonRemoved, - ChangeType.FieldDescriptionChanged, - ChangeType.FieldDescriptionAdded, - ChangeType.FieldDescriptionRemoved, - ChangeType.FieldDeprecationAdded, - ChangeType.FieldDeprecationRemoved, - ChangeType.FieldDeprecationReasonChanged, - ChangeType.FieldDeprecationReasonAdded, - ChangeType.FieldDeprecationReasonRemoved, - ChangeType.InputFieldDescriptionAdded, - ChangeType.InputFieldDescriptionRemoved, - ChangeType.InputFieldDescriptionChanged, - ChangeType.TypeDescriptionChanged, - ChangeType.TypeDescriptionRemoved, - ChangeType.TypeDescriptionAdded, - ChangeType.DirectiveUsageFieldDefinitionAdded, - ChangeType.DirectiveUsageArgumentDefinitionAdded, - ChangeType.DirectiveUsageEnumValueAdded, -] +// CHANGES_TO_IGNORE list removed - now we only process changes explicitly listed +// in CHANGES_TO_REPORT and silently ignore all others for future compatibility + +/** + * Get the ignored change types from the last changelog entry creation + * @returns {Array} Array of ignored change objects + */ +export function getLastIgnoredChanges() { + return createChangelogEntry.lastIgnoredChanges || [] +} + +/** + * Get summary of ignored change types for workflow outputs + * @returns {Object} Summary with counts and types + */ +export function getIgnoredChangesSummary() { + const ignored = getLastIgnoredChanges() + if (ignored.length === 0) return null + + const types = [...new Set(ignored.map((change) => change.type))] + const summary = { + totalCount: ignored.length, + typeCount: types.length, + types: types.map((type) => ({ + type, + count: ignored.filter((change) => change.type === type).length, + })), + } + + return summary +} export default { createChangelogEntry, cleanPreviewTitle, previewAnchor, prependDatedEntry } diff --git a/src/graphql/scripts/sync.js b/src/graphql/scripts/sync.js index d646a5bef102..6b37b28fd921 100755 --- a/src/graphql/scripts/sync.js +++ b/src/graphql/scripts/sync.js @@ -1,4 +1,5 @@ import fs from 'fs/promises' +import { appendFileSync } from 'fs' import path from 'path' import { mkdirp } from 'mkdirp' import yaml from 'js-yaml' @@ -8,7 +9,11 @@ import { allVersions } from '@/versions/lib/all-versions' import processPreviews from './utils/process-previews' import processUpcomingChanges from './utils/process-upcoming-changes' import processSchemas from './utils/process-schemas' -import { prependDatedEntry, createChangelogEntry } from './build-changelog' +import { + prependDatedEntry, + createChangelogEntry, + getIgnoredChangesSummary, +} from './build-changelog' const graphqlStaticDir = 'src/graphql/data' const dataFilenames = JSON.parse(await fs.readFile('src/graphql/scripts/utils/data-filenames.json')) @@ -22,6 +27,8 @@ const versionsToBuild = Object.keys(allVersions) main() +let allIgnoredChanges = [] + async function main() { for (const version of versionsToBuild) { // Get the relevant GraphQL name for the current version @@ -77,11 +84,42 @@ async function main() { path.join(graphqlStaticDir, graphqlVersion, 'changelog.json'), ) } + + // Capture ignored changes for potential workflow notifications + const ignoredSummary = getIgnoredChangesSummary() + if (ignoredSummary) { + allIgnoredChanges.push({ + version: graphqlVersion, + ...ignoredSummary, + }) + } } } // Ensure the YAML linter runs before checkinging in files execSync('npx prettier -w "**/*.{yml,yaml}"') + + // Output ignored changes for GitHub Actions + if (allIgnoredChanges.length > 0) { + const totalIgnored = allIgnoredChanges.reduce((sum, item) => sum + item.totalCount, 0) + const uniqueTypes = [ + ...new Set(allIgnoredChanges.flatMap((item) => item.types.map((t) => t.type))), + ] + + console.log( + '::notice title=GraphQL Ignored Changes::Found ignored change types that may need review', + ) + + // Write outputs to GitHub Actions output file + if (process.env.GITHUB_OUTPUT) { + appendFileSync( + process.env.GITHUB_OUTPUT, + `ignored-changes=${JSON.stringify(allIgnoredChanges)}\n`, + ) + appendFileSync(process.env.GITHUB_OUTPUT, `ignored-count=${totalIgnored}\n`) + appendFileSync(process.env.GITHUB_OUTPUT, `ignored-types=${uniqueTypes.join(', ')}\n`) + } + } } // get latest from github/github diff --git a/src/graphql/tests/build-changelog.js b/src/graphql/tests/build-changelog.js index 2fe32ea5239b..2dd5c98609de 100644 --- a/src/graphql/tests/build-changelog.js +++ b/src/graphql/tests/build-changelog.js @@ -9,6 +9,8 @@ import { cleanPreviewTitle, previewAnchor, prependDatedEntry, + getLastIgnoredChanges, + getIgnoredChangesSummary, } from '../scripts/build-changelog' import readJsonFile from '@/frame/lib/read-json-file' @@ -22,6 +24,60 @@ describe('creating a changelog from old schema and new schema', () => { MockDate.reset() }) + test('ignores unknown change types without throwing errors', async () => { + // Create a minimal test that would generate an unknown change type + // This test ensures the system gracefully handles new change types + const oldSchemaString = ` + type Query { + field: String + } + ` + + const newSchemaString = ` + """ + Updated description for Query type + """ + type Query { + field: String + } + ` + + // This should generate TypeDescriptionAdded change type + // which should be silently ignored if not in CHANGES_TO_REPORT + const entry = await createChangelogEntry(oldSchemaString, newSchemaString, [], [], []) + + // Should return null since TypeDescriptionAdded is not in CHANGES_TO_REPORT + // and will be silently ignored without throwing an error + expect(entry).toBeNull() + }) + + test('handles new directive usage change types gracefully', async () => { + // Test that verifies the system can handle new directive-related change types + // that were previously causing errors in the pipeline + const oldSchemaString = ` + directive @example on FIELD_DEFINITION + + type Query { + field: String + } + ` + + const newSchemaString = ` + directive @example on FIELD_DEFINITION + + type Query { + field: String @example + } + ` + + // This should generate DirectiveUsage* change types that are not in CHANGES_TO_REPORT + // The system should silently ignore these and not throw errors + const entry = await createChangelogEntry(oldSchemaString, newSchemaString, [], [], []) + + // Should return null since directive usage changes are typically ignored + expect(entry).toBeNull() + }) + test('finds a diff of schema changes, upcoming changes, and preview changes', async () => { const oldSchemaString = ` type PreviewType { @@ -146,3 +202,71 @@ describe('updating the changelog file', () => { expect(JSON.parse(newContents)).toEqual(expectedUpdatedChangelogFile) }) }) + +describe('ignored changes tracking', () => { + test('tracks ignored change types', async () => { + const oldSchemaString = ` + type Query { + field: String + } + ` + + const newSchemaString = ` + """ + Updated description for Query type + """ + type Query { + field: String + } + ` + + // This should generate a TypeDescriptionAdded change type that gets ignored + await createChangelogEntry(oldSchemaString, newSchemaString, [], [], []) + + const ignoredChanges = getLastIgnoredChanges() + expect(ignoredChanges.length).toBe(1) + expect(ignoredChanges[0].type).toBe('TYPE_DESCRIPTION_ADDED') + }) + + test('provides ignored changes summary', async () => { + const oldSchemaString = ` + directive @example on FIELD_DEFINITION + type Query { + field1: String + field2: Int + } + ` + + const newSchemaString = ` + directive @example on FIELD_DEFINITION + type Query { + field1: String @example + field2: Int @example + } + ` + + // This should generate multiple DirectiveUsage changes that get ignored + await createChangelogEntry(oldSchemaString, newSchemaString, [], [], []) + + const summary = getIgnoredChangesSummary() + expect(summary).toBeTruthy() + expect(summary.totalCount).toBe(2) + expect(summary.typeCount).toBe(1) + expect(summary.types[0].type).toBe('DIRECTIVE_USAGE_FIELD_DEFINITION_ADDED') + expect(summary.types[0].count).toBe(2) + }) + + test('returns null summary when no changes ignored', async () => { + const schemaString = ` + type Query { + field: String + } + ` + + // No changes should be generated + await createChangelogEntry(schemaString, schemaString, [], [], []) + + const summary = getIgnoredChangesSummary() + expect(summary).toBeNull() + }) +}) diff --git a/src/secret-scanning/data/public-docs.yml b/src/secret-scanning/data/public-docs.yml index b1c420ab8be2..5bbe665e7a28 100644 --- a/src/secret-scanning/data/public-docs.yml +++ b/src/secret-scanning/data/public-docs.yml @@ -3072,7 +3072,7 @@ isPrivateWithGhas: true hasPushProtection: true hasValidityCheck: '{% ifversion fpt or ghes %}false{% else %}true{% endif %}' - isduplicate: false + isduplicate: true - provider: Octopus Deploy supportedSecret: Octopus Deploy API Key secretType: octopus_deploy_api_key diff --git a/src/secret-scanning/lib/config.json b/src/secret-scanning/lib/config.json index 41ddff7381ba..86b03bf2a634 100644 --- a/src/secret-scanning/lib/config.json +++ b/src/secret-scanning/lib/config.json @@ -1,5 +1,5 @@ { - "sha": "8b3254a87c5c709c467646b6c2773020b00b8be2", - "blob-sha": "1c2582c53c06065252060d41509997eeb763f4a5", + "sha": "656c184564b10879e349c25088fdbcd77191830b", + "blob-sha": "441e546f626e8c18568b923c62102e053fc01366", "targetFilename": "code-security/secret-scanning/introduction/supported-secret-scanning-patterns" } \ No newline at end of file pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy