Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/check-for-spammy-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ jobs:
});

const onlyDeletes = files.length > 0 && files.every(f => f.status === 'removed')
const emptyCommit = !files.length
const isEmptyCommit = !files.length
const touchesTooMany = files.length > 10
const totalChanges = files.reduce((sum, f) => sum + f.additions + f.deletions, 0)
const isOneLineAddition = files.every(f => f.status === 'added') && totalChanges <= 1

// Close the PR and add the invalid label
if (onlyDeletes || emptyCommit || touchesTooMany) {
if (onlyDeletes || isEmptyCommit || touchesTooMany || isOneLineAddition) {
await github.rest.issues.update({
owner: owner,
repo: repo,
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/sync-openapi.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Sync OpenAPI schema

# **What it does**: Once a day, this workflow syncs the REST, Webhooks, and GitHub Apps automated pipelines with the github/rest-api-description repository, and creates a pull request if there are updates to any of the data files we generate from the OpenAPI.
# **What it does**: Syncs the REST, Webhooks, and GitHub Apps automated pipelines with the github/rest-api-description repository, and creates a pull request if there are updates to any of the data files we generate from the OpenAPI. Runs on a weekday schedule or a `sync-openapi` repository dispatch.
# **Why we have it**: So we can automate updates to REST, Webhooks, and GitHub Apps documentation
# **Who does it impact**: Anyone making OpenAPI changes in `github/github`, and wanting to get them published on the docs site.

Expand All @@ -12,6 +12,8 @@ on:
type: string
required: true
default: 'main'
repository_dispatch:
types: [sync-openapi]
schedule:
- cron: '20 16 * * 1-5' # Run Mon-Fri at 16:20 UTC / 8:20 PST

Expand Down Expand Up @@ -40,7 +42,7 @@ jobs:
# will be checked out
repository: github/rest-api-description
path: rest-api-description
ref: ${{ inputs.SOURCE_BRANCH }}
ref: ${{ inputs.SOURCE_BRANCH || github.event.client_payload.ref || 'main' }}

- uses: ./.github/actions/node-npm-setup

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ By default, repository administrators can rename branches that are targeted by e

To keep your repository size manageable and prevent performance issues, you can configure a file size limit for repositories in your enterprise.

By default, when you enforce repository upload limits, people cannot add or update files larger than 100 MB.
By default, people cannot add or update files larger than 100 MB, but you can raise or remove this limit. If you enforce your chosen limit for all repositories on the instance, individual repositories cannot use a different limit.

{% data reusables.enterprise-accounts.access-enterprise %}
{% data reusables.enterprise-accounts.policies-tab %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ The installation token you just received gives you permission to create a reposi

1. To check the repository was created successfully, go to `https://github.com/orgs/ORG/repositories`, replacing ORG with the name of your organization.

{% note %}
<div class="border rounded-2 p-3">

Was the repository created successfully?

<a href="https://docs.github.io/success-test/yes.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>Yes</span></a> <a href="https://docs.github.io/success-test/no.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>No</span></a>

{% endnote %}
</div>

## 7. Uninstall the apps

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,58 @@ Logs are stored locally on the stateless nodes. They can be exported from these

You can use the `ghe-cluster-support-bundle` and `ghe-support-bundle` commands to generate and upload cluster or single-node bundles.

## Mitigating single-core softirq saturation



Adding a stateless node to a {% data variables.product.prodname_ghe_server %} high-availability deployment sends all traffic between two nodes over a single WireGuard tunnel. Because every packet for that node pair shares one UDP port, the network card steers it to one receive queue, and one CPU core processes all inbound packets. Under heavy traffic that core reaches 100 percent while the others stay idle, and the node drops packets. {% data variables.product.prodname_ghe_server %} includes the built-in mitigations described below.

### 1. Scale out with more stateless nodes

Each stateless node reaches the primary over its own WireGuard tunnel, so the primary processes each node's traffic on a separate receive queue and CPU core. Spreading workloads across more, smaller stateless nodes lets the load balancer share cross-tunnel load across more of the primary's cores, and this does not rely on tunnel-level hashing. Two nodes roughly halve the per-core receive load, and three cut it to about a third.

{% data variables.product.prodname_ghe_server %} sizes each node's web workers from its memory and caps its own value at 30. Keep `app.github.github-workers` near 30 per node; higher counts cost memory and, during a tunnel stall, add queue depth rather than throughput, because the extra workers block on the primary. For more capacity, add more stateless nodes.

### 2. Multi-tunnel WireGuard (opt-in)

{% data variables.product.prodname_ghe_server %} can spread inter-node traffic across several WireGuard tunnels. Each tunnel uses its own UDP port, so different connections land on different receive queues and different CPU cores share the work. Set the tunnel count to the lowest number of receive queues across your cluster nodes, the "Combined" value of `ethtool -l eth0`.

```shell copy
ghe-config wireguard.num-tunnels 8
ghe-config-apply
```

The default is 1. The maximum is 16; higher values are capped. More tunnels than the interface has receive queues adds no benefit. To revert, remove the setting and apply.

```shell copy
ghe-config --unset wireguard.num-tunnels
ghe-config-apply
```

**Before you enable (one-time):**

* In your external firewall or cloud security group, open the extra tunnel UDP ports between all nodes, including all replicas. Ports count up from 1194, so 8 tunnels use UDP 1194 to 1201. The full range requires UDP 1194 to 1209.
* Enabling multi-tunnel updates the host firewall. Apply it once by rebooting all nodes, or by reloading the firewall with `sudo ufw reload` on each node. Confirm your network security group already restricts inbound access first, as the ufw reload briefly drops and recreates the rules. Later `num-tunnels` changes do not need this step.

### 3. Local git-proxy routing on the primary (automatic)

Git requests that a stateless node would otherwise send back across the tunnel now stay on the primary, where the Git data already lives. This removes a large share of cross-tunnel packets, and needs no action. The primary uses its local Git proxy first and falls back to a remote node only if the local one is unavailable.

### 4. Capacity-based web request weighting (opt-in)

When nodes run different numbers of web workers, {% data variables.product.prodname_ghe_server %} can distribute requests in proportion to each node's worker count instead of evenly. Enable it when worker counts are uneven, for example a primary with 100 workers and a stateless node with 30.

```shell copy
ghe-config app.github.unicorn-weight-by-capacity true
ghe-config-apply
```

The default is off.

### Choosing what to enable

Start by scaling out to more stateless nodes. It is the most complete option, spreads load across more of the primary's cores through the load balancer, and needs no feature flag. If a single core still saturates, enable multi-tunnel WireGuard. Enable capacity-based weighting only when worker counts differ across nodes.

## Known limitations

This feature is not designed for monorepos, but the addition of new stateless nodes may indirectly improve monorepo operations by reducing web and job workloads on the primary node. There are no autoscaling and scaledown features.
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,13 @@ Before you enable CCR, confirm the following.
* Your instance is configured for high availability with at least two appliances (a primary and one or more replicas).
* You have an updated {% data variables.product.prodname_ghe_server %} license that includes the Elasticsearch entitlement required for CCR. Contact {% data variables.contact.contact_enterprise_sales %} or {% data variables.contact.github_support %} to have your enterprise enabled for the new license, then download the updated license file.

{% warning %}

**Warning:** When CCR is enabled, the upgrade preflight check requires a valid CCR-enabled license. If the flag is enabled and the license check fails, the upgrade will not proceed. Make sure your updated license is installed before you enable the feature or upgrade. If you are unsure whether your license includes the Elasticsearch entitlement, contact {% data variables.contact.github_support %}.

{% endwarning %}
> [!WARNING]
> When CCR is enabled, the upgrade preflight check requires a valid CCR-enabled license. If the flag is enabled and the license check fails, the upgrade will not proceed. Make sure your updated license is installed before you enable the feature or upgrade. If you are unsure whether your license includes the Elasticsearch entitlement, contact {% data variables.contact.github_support %}.

## Enabling Elasticsearch Cross-Cluster Replication

{% note %}

**Note:** The migration may take a significant amount of time depending on the size of your instance, because search data is consolidated onto the primary before replication restarts. Plan to enable CCR during a maintenance window, and test the process in a non-production environment first. For more information, see [AUTOTITLE](/admin/upgrading-your-instance).

{% endnote %}
> [!NOTE]
> The migration may take a significant amount of time depending on the size of your instance, because search data is consolidated onto the primary before replication restarts. Plan to enable CCR during a maintenance window, and test the process in a non-production environment first. For more information, see [AUTOTITLE](/admin/upgrading-your-instance).

1. Contact {% data variables.contact.github_support %} and request access to the new HA search architecture. {% data variables.product.company_short %} will enable your enterprise so that you can download the required CCR-enabled license.
1. Download your updated license and upload it to your instance. For more information, see [AUTOTITLE](/billing/how-tos/manage-server-licenses/download-your-license).
Expand Down Expand Up @@ -81,11 +75,8 @@ After a failover with CCR enabled, the promoted appliance becomes the new leader

### Disabling Elasticsearch Cross-Cluster Replication

{% warning %}

**Warning:** Do not disable CCR on a production instance without guidance from {% data variables.contact.github_support %}. Disabling CCR is not a routine self-service operation. Turning the feature off can trigger removal of replica Elasticsearch data as part of returning to the previous mode.

{% endwarning %}
> [!WARNING]
> Do not disable CCR on a production instance without guidance from {% data variables.contact.github_support %}. Disabling CCR is not a routine self-service operation. Turning the feature off can trigger removal of replica Elasticsearch data as part of returning to the previous mode.

If you need to return to the previous search architecture, contact {% data variables.contact.github_support %} before making any changes. {% data variables.product.company_short %} will help you confirm that your license, replication state, and upgrade path are handled safely.

Expand Down
16 changes: 11 additions & 5 deletions content/billing/reference/product-and-sku-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,22 @@ For **SkuPricing** budgets or to query usage by SKU, use one of the following va

### {% data variables.product.prodname_copilot %} SKUs

* `copilot_ai_credits` - Copilot {% data variables.product.prodname_ai_credits_short %}
* `coding_agent_ai_credit` - Copilot Cloud Agent
* `copilot_ai_credit` - {% data variables.product.prodname_copilot_short %} {% data variables.product.prodname_ai_credits_short %}
* `copilot_enterprise` - Copilot Enterprise
* `copilot_for_business` - Copilot for Business
* `copilot_standalone` - Copilot standalone

### {% data variables.product.prodname_GH_advanced_security %} SKUs

* `ghas_code_security_licenses` - GHAS code security licenses
* `ghas_licenses` - GHAS licenses
* `ghas_secret_protection_licenses` - GHAS secret protection licenses
* `ghas_code_security_licenses` - Code Security
* `ghas_licenses` - Advanced Security
* `ghas_secret_protection_licenses` - Secret Protection

### {% data variables.product.prodname_code_quality %} SKUs

* `code_quality_licenses` - Code Quality Licenses
* `code_quality_ai_credit` - Code Quality {% data variables.product.prodname_ai_credits_short %}

### Cloud and local sandboxes for {% data variables.product.prodname_copilot %} SKUs

Expand All @@ -110,7 +116,7 @@ For **SkuPricing** budgets or to query usage by SKU, use one of the following va
* `git_lfs_bandwidth` - Git LFS bandwidth
* `git_lfs_storage` - Git LFS storage
* `models_inference` - Models inference
* `packages_bandwidth` - Packages bandwidth
* `packages_bandwidth` - Packages data transfer
* `packages_storage` - Packages storage
* `spark_ai_credits` - Spark {% data variables.product.prodname_ai_credits_short %}

Expand Down
4 changes: 2 additions & 2 deletions content/billing/tutorials/control-costs-at-scale.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ gh api \
-H "X-GitHub-Api-Version: {{ defaultRestApiVersion }}" \
/enterprises/ENTERPRISE/settings/billing/budgets \
-f budget_type='SkuPricing' \
-f budget_product_sku='copilot_ai_credits' \
-f budget_product_sku='copilot_ai_credit' \
-f budget_scope='cost_center' \
-f budget_entity_name='COST_CENTER_ID' \
-F budget_amount=1000.0 \
Expand All @@ -276,7 +276,7 @@ The response confirms the budget was created and returns its configuration. Noti
{
"id": "budget-uuid-here",
"budget_type": "SkuPricing",
"budget_product_sku": "copilot_ai_credits",
"budget_product_sku": "copilot_ai_credit",
"budget_scope": "cost_center",
"budget_entity_name": "3312fdf2-5950-4f64-913d-e734124059c9",
"budget_amount": 1000.0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ You choose the alerts that you want to include in the campaign by using either:

The security campaign is created and the campaign overview page is displayed.

{% note %}
<div class="border rounded-2 p-3">

Did you successfully create a security campaign for your organization?

<a href="https://docs.github.io/success-test/yes.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>Yes</span></a> <a href="https://docs.github.io/success-test/no.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>No</span></a>

{% endnote %}
</div>

### Examples of useful filters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ You need to have generated a secret risk assessment for your organization. See [
* The **per-committer rate** (for example, $19 per active committer).
1. To proceed with enabling {% data variables.product.prodname_secret_protection %}, click **Review and enable**.

{% note %}
<div class="border rounded-2 p-3">

Did you successfully use the {% data variables.secret-scanning.pricing-calculator %} to estimate the cost of using {% data variables.product.prodname_secret_protection %} features on your organization?

<a href="https://docs.github.io/success-test/yes.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>Yes</span></a> <a href="https://docs.github.io/success-test/no.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>No</span></a>

{% endnote %}
</div>

## Understanding your results

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ Push protection is a paid feature which is available with {% data variables.prod
* **Time saved**: Total hours saved by preventing these secrets, based on your input.
* **Potential savings with push protection**: The total estimated labor cost avoided.

{% note %}
<div class="border rounded-2 p-3">

Did you successfully use the {% data variables.secret-scanning.roi-calculator %} to estimate the cost savings of using push protection on your organization?

<a href="https://docs.github.io/success-test/yes.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>Yes</span></a> <a href="https://docs.github.io/success-test/no.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>No</span></a>

{% endnote %}
</div>

## Understanding your results

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ category:

You can block non-members from within your organization's settings or from content in the organization's repositories.

When you block a user from a comment, you can choose to send the user a notification explaining that they were blocked and why. Otherwise, the user is not directly notified that you've blocked them. Blocked users can still delete their existing content.
You can also close any open issues, pull requests, and discussions the user has opened in repositories owned by the organization. Organization moderators can close content only in repositories where they have write access. When you block a user from a comment, you can choose to send the user a notification explaining that they were blocked and why. Otherwise, the user is not directly notified that you've blocked them. Blocked users can still delete their existing content.

{% data reusables.organizations.blocking-a-user %}

Expand Down Expand Up @@ -53,6 +53,7 @@ You must be an organization owner or moderator to block a user from a repository
![Screenshot of a pull request comment by octo-user. Below an icon of three dots, a dropdown menu is expanded, and "Block user" is outlined in orange.](/assets/images/help/repository/comment-menu-block-user.png)

1. If you'd like to set a time limit for the block, select the **Block user** dropdown menu, and click the amount of time you'd like to block the user.
{% data reusables.organizations.close-all-content-when-blocking-user %}
1. If you'd like to hide all of the comments the user has made in the organization, select **Hide this user's comments** and choose a reason.
1. If you'd like to notify the user why they're being blocked, select **Send a notification to this user**.
1. To block the user, click **Block user from organization** or **Block user from organization and send message**.
Expand All @@ -75,6 +76,7 @@ You must be an organization owner or moderator to block a user from a repository
{% data reusables.organizations.block_users %}
1. Under "Block a user", in the text field, type the username of the user you'd like to block.
1. If you'd like to set a time limit for the block, next to the text field, select the **Block options** dropdown menu, and click the amount of time you'd like to block the user.
{% data reusables.organizations.close-all-content-when-blocking-user %}
1. Click **Block user**.
1. Optionally, to add a note to describe why a user was blocked, click **Add Note**. The note will be visible to the owners and moderators of the organization.

Expand All @@ -86,9 +88,8 @@ You must be an organization owner or moderator to block a user from a repository
![Screenshot of a pull request comment by octo-user. Below an icon of three dots, a dropdown menu is expanded, and "Block user" is outlined in orange.](/assets/images/help/repository/comment-menu-block-user.png)

1. If you'd like to set a time limit for the block, select the **Block user** dropdown menu, and click the amount of time you'd like to block the user.
{% data reusables.organizations.close-all-content-when-blocking-user %}
1. If you'd like to hide all of the comments the user has made in the organization, select **Hide this user's comments** and choose a reason.
1. If you'd like to delete just the discussion you're viewing, select **Delete this discussion**.
1. If you'd like to delete all of the discussions the user has made in the organization, select **Delete all of USER's discussions in ORGANIZATION**.
1. Click **Block user from organization**.

## Further reading
Expand Down
Loading
Loading