diff --git a/.github/workflows/check-for-spammy-issues.yml b/.github/workflows/check-for-spammy-issues.yml index 9ef657e21967..578706526565 100644 --- a/.github/workflows/check-for-spammy-issues.yml +++ b/.github/workflows/check-for-spammy-issues.yml @@ -1,6 +1,6 @@ name: Check for Spammy Issues -# **What it does**: This action closes low value pull requests in the open-source repository. +# **What it does**: This action closes low value issues in the open-source repository. # **Why we have it**: We get lots of spam in the open-source repository. # **Who does it impact**: Open-source contributors. diff --git a/.github/workflows/check-for-spammy-pr.yml b/.github/workflows/check-for-spammy-pr.yml new file mode 100644 index 000000000000..0334d594750d --- /dev/null +++ b/.github/workflows/check-for-spammy-pr.yml @@ -0,0 +1,54 @@ +name: Check for Spammy PRs + +# **What it does**: This action closes low value pull requests in the open-source repository. +# **Why we have it**: We get lots of spam in the open-source repository. +# **Who does it impact**: Open-source contributors. + +on: + pull_request_target: + types: [opened] + +permissions: + contents: read + pull-requests: write + +jobs: + spammy-pr-check: + name: Label PRs that only delete files or touch a large number of files + if: github.repository == 'github/docs' && github.event_name == 'pull_request_target' + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 + with: + github-token: ${{ secrets.DOCS_BOT_PAT_BASE }} + script: | + const owner = 'github' + const repo = 'docs' + const pull_number = context.payload.pull_request.number + + const { data: files } = await github.rest.pulls.listFiles({ + owner: owner, + repo: repo, + pull_number: pull_number, + }); + + const onlyDeletes = files.length > 0 && files.every(f => f.status === 'removed') + const touchesTooMany = files.length > 10 + + // Close the PR and add the invalid label + if (onlyDeletes || touchesTooMany) { + await github.rest.issues.update({ + owner: owner, + repo: repo, + issue_number: pull_number, + labels: ['invalid'], + }); + + // Comment on the PR + await github.rest.issues.createComment({ + owner: owner, + repo: repo, + issue_number: pull_number, + body: `This pull request may have been opened accidentally. I'm going to close it now, but feel free to check out our [contribution guidelines](https://docs.github.com/en/contributing), or raise a new issue.` + }); + } diff --git a/.github/workflows/link-check-internal.yml b/.github/workflows/link-check-internal.yml index 6a6b1ffa800a..482948c6ab28 100644 --- a/.github/workflows/link-check-internal.yml +++ b/.github/workflows/link-check-internal.yml @@ -47,9 +47,12 @@ jobs: # Manual run: use the provided version and language echo "matrix={\"include\":[{\"version\":\"${INPUT_VERSION}\",\"language\":\"${INPUT_LANGUAGE}\"}]}" >> $GITHUB_OUTPUT else - # Scheduled run: English free-pro-team + English latest enterprise-server - LATEST_GHES=$(npx tsx -e "import { latest } from './src/versions/lib/enterprise-server-releases'; console.log(latest)") - echo "matrix={\"include\":[{\"version\":\"free-pro-team@latest\",\"language\":\"en\"},{\"version\":\"enterprise-server@${LATEST_GHES}\",\"language\":\"en\"}]}" >> $GITHUB_OUTPUT + # Scheduled run: every published version, in English. A link can be broken in + # one version and fine in another, so checking two of eight left most of the + # site unchecked. The report job merges the results, so this does not multiply + # the size of the issue. + MATRIX=$(npx tsx -e "import { allVersions } from './src/versions/lib/all-versions'; console.log(JSON.stringify({ include: Object.keys(allVersions).map((version) => ({ version, language: 'en' })) }))") + echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT fi env: EVENT_NAME: ${{ github.event_name }} @@ -245,6 +248,17 @@ jobs: echo "No broken link reports generated - all links valid!" fi + - name: Upload the combined report + if: steps.combine.outputs.has_reports == 'true' + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + # The issue body caps every long section, and the notes there point at + # "the report attached to the workflow run". Upload it so that is true. + name: combined-link-report + path: combined-report.md + retention-days: 5 + if-no-files-found: error + - name: Create or update the rolling report issue if: | steps.combine.outputs.has_reports == 'true' @@ -268,7 +282,15 @@ jobs: let body = fs.readFileSync('combined-report.md', 'utf8') if (body.length > MAX_BODY_SIZE) { const notice = `\n\n---\n\n*Report truncated. Download the full report from the [workflow run artifacts](${runUrl}).*` - body = body.slice(0, MAX_BODY_SIZE - notice.length) + notice + let cut = body.slice(0, MAX_BODY_SIZE - notice.length) + // Cut at a line boundary so the last thing a reader sees is not half + // a table row, and close any `
` the cut left open, since an + // unclosed one swallows everything after it. + cut = cut.slice(0, cut.lastIndexOf('\n')) + const opened = (cut.match(/
/g) || []).length + const closed = (cut.match(/<\/details>/g) || []).length + cut += '\n
'.repeat(Math.max(0, opened - closed)) + body = cut + notice core.warning(`Report exceeded ${MAX_BODY_SIZE} characters, so it was truncated.`) } diff --git a/assets/images/help/billing/request-budget-flow.png b/assets/images/help/billing/request-budget-flow.png new file mode 100644 index 000000000000..42df6a7e4b39 Binary files /dev/null and b/assets/images/help/billing/request-budget-flow.png differ diff --git a/content/code-security/concepts/code-quality/code-quality.md b/content/code-security/concepts/code-quality/code-quality.md index cef2818f5a2d..91261023bc9b 100644 --- a/content/code-security/concepts/code-quality/code-quality.md +++ b/content/code-security/concepts/code-quality/code-quality.md @@ -20,7 +20,7 @@ category: {% data variables.product.prodname_code_quality %} analyzes your code for quality and coverage issues and delivers {% data variables.product.prodname_copilot_short %}-powered fixes you can apply in one click. It runs in two places: -* **On pull requests**, {% data variables.product.prodname_code_quality_short %} uses deterministic {% data variables.product.prodname_codeql %} rules to detect known anti-patterns and posts findings as inline comments before code is merged. If you upload a Cobertura XML coverage report, coverage metrics show whether a change maintains or reduces coverage. You can enforce quality and coverage thresholds with rulesets to block pull requests that don't meet your criteria, so new quality debt doesn't accumulate. +* **On pull requests**, {% data variables.product.prodname_code_quality_short %} uses deterministic {% data variables.product.prodname_codeql %} rules to detect known anti-patterns and posts findings as inline comments before code is merged. If you upload a Cobertura XML coverage report, line coverage metrics show whether a change maintains or reduces coverage. You can enforce quality and coverage thresholds with rulesets to block pull requests that don't meet your criteria, so new quality debt doesn't accumulate. * **On the default branch**, rules-based scans identify existing quality debt across your codebase, with autofixes you can apply directly or assign to {% data variables.copilot.copilot_cloud_agent %} to resolve on your behalf. AI-powered analysis also runs on recently changed files, flagging issues that fall outside existing rule sets, including languages not yet covered by {% data variables.product.prodname_codeql %} queries. > [!NOTE] @@ -32,14 +32,14 @@ Here's what {% data variables.product.prodname_code_quality %} looks like in pra For developers and teams: -* **A developer opens a pull request** that introduces a reliability or maintainability issue. {% data variables.product.prodname_code_quality_short %} posts a comment explaining the issue and offers a one-click fix before the code is merged. The developer also sees a report of coverage metrics, and can tell at a glance whether the pull request improves or reduces coverage compared to the default branch. +* **A developer opens a pull request** that introduces a reliability or maintainability issue. {% data variables.product.prodname_code_quality_short %} posts a comment explaining the issue and offers a one-click fix before the code is merged. The developer also sees a report of line coverage metrics, and can tell at a glance whether the pull request improves or reduces coverage compared to the default branch. * **A team inherits a large codebase** with years of accumulated quality debt. {% data variables.product.prodname_code_quality_short %} scans the default branch, surfaces findings with autofixes on a dashboard, and the team assigns remediation work to {% data variables.copilot.copilot_cloud_agent %} to open fix pull requests automatically. * **A team adopts AI coding assistants** and needs assurance that generated code meets the same bar as hand-written code. AI-powered analysis catches issues in recently changed files that rule-based queries weren't written for, while {% data variables.product.prodname_codeql %} rules cover well-defined anti-patterns. For administrators and leads: * **An engineering lead sets coverage and quality thresholds** using rulesets. Pull requests that don't meet the criteria are blocked from merging, so no new quality or coverage debt accumulates. -* **An administrator needs visibility across repositories** for audits or compliance reporting. {% data variables.product.prodname_code_quality_short %} reports through the security overview alongside security tools, so they can see quality posture across the organization at a glance, identify which repositories need attention, and track improvement metrics using standard {% data variables.product.github %} audit controls and policies. +* **An administrator needs visibility across repositories** for audits or compliance reporting. {% data variables.product.prodname_code_quality_short %} reports through the security overview alongside security tools, so they can see current quality posture across the organization, review how open findings have changed over time, and identify which repositories need attention. See [AUTOTITLE](/code-security/how-tos/maintain-quality-code/explore-code-quality). ## Availability and billing diff --git a/content/code-security/how-tos/maintain-quality-code/explore-code-quality.md b/content/code-security/how-tos/maintain-quality-code/explore-code-quality.md index 00067b3d9685..72ad5e5af369 100644 --- a/content/code-security/how-tos/maintain-quality-code/explore-code-quality.md +++ b/content/code-security/how-tos/maintain-quality-code/explore-code-quality.md @@ -22,33 +22,106 @@ redirect_from: ## Viewing code quality insights for your organization +The organization-level dashboard has two tabs: + +* The **Health** tab shows a snapshot of your organization's current code health. +* The **Trends** tab shows how open findings have changed over a selected period of time, so you can track progress and identify repositories that need attention. + 1. On {% data variables.product.prodname_dotcom %}, navigate to the main page of your organization. For example, from [https://github.com/settings/organizations](https://github.com/settings/organizations?ref_product=github&ref_type=engagement&ref_style=text&utm_campaign=code-quality-ga-july-2026&utm_medium=docs&utm_source=docs-explore-cq-org-settings). {% data reusables.organizations.security-overview %} -1. In the "Insights" section of the sidebar, click {% octicon "code-square" aria-hidden="true" aria-label="code-square" %} **Code quality**. +1. In the "Insights" section of the sidebar, click **{% data variables.code-quality.code_quality_ui_settings %}**. > [!NOTE] > What you see on the dashboard depends on your access: +> > * Organization owners see data for **every** repository that has {% data variables.product.prodname_code_quality_short %} enabled. > * All other organization members see data only for repositories where they can view {% data variables.product.prodname_code_quality_short %} findings (the repository-level pages), up to a maximum of 3,000 repositories. -## Interpreting the score distribution chart +## Filtering dashboard data + +A filter bar at the top of the dashboard applies to both the **Health** and **Trends** tabs. You can filter by: + +* Reliability score +* Maintainability score +* {% data variables.code-quality.all_findings %} +* {% data variables.code-quality.recent_suggestions %} +* Topic +* Team +* Visibility +* Any custom properties defined for your organization + +You can also sort the dashboard data using the **Sort** control in the same filter bar. + +## Viewing current code health + +The **Health** tab shows a snapshot of your organization's code health right now. + +### Interpreting the score distribution chart The score distribution chart provides a visual overview of the code health of your organization. Each bubble represents a collection of repositories with the same maintainability and reliability scores. + * The **position** of each bubble demonstrates the overall health of those repositories. Higher bubbles represent higher maintainability scores, while bubbles further to the right represent higher reliability scores. * The **color and border pattern** of a bubble indicate the severity of the lower score for those repositories. For example, a bubble with a "Poor" score in either category will always be red with a dashed border. * The **size** of each bubble represents the number of repositories with that particular score combination. To view the maintainability score, reliability score, and number of repositories represented by a particular bubble, hover over the bubble. -## Exploring the repository table +### Exploring the repository table Below the bubble chart, there is a table that lists all repositories in your organization. Here, you can view code quality findings, along with more detailed information about those findings. You can sort the repository table in ascending or descending order for any column by clicking the column header. -## Investigating low-scoring repositories +### Investigating low-scoring repositories 1. To filter the dashboard data for the lowest-performing repositories, on the score distribution chart, click the bubble with the lowest combined scores. 1. Scroll down to the repository table. By default, the table is sorted from most to least recent repository scan, helping you prioritize current quality issues. -1. Optionally, to prioritize repositories with the highest number of {% data variables.product.prodname_codeql %} findings, click **Standard Findings** twice. +1. Optionally, to prioritize repositories with the highest number of {% data variables.product.prodname_codeql %} findings, click **{% data variables.code-quality.all_findings %}** twice. 1. To view the repository-level dashboard for a specific repository, click the repository's name. + +## Tracking quality trends over time + +The **Trends** tab shows how open findings across repositories that you have access to and that match the current filters have changed over time, so you can tell whether your code quality work is having an effect and where to focus attention next. + +1. On the organization-level dashboard, click the **Trends** tab. +1. Use the **Period** dropdown to select a time range: the last 7, 14, or 30 days. +1. Review the "Open findings over time" graph, which shows the total number of open findings across applicable repositories for the selected period. +1. Optionally, use the buttons above the graph to group the data by **Health score** or **Severity**. +1. Hover over a point on the graph to see the open finding count for that day. + +### Understanding the trends data + +Keep the following in mind when you interpret the graph: + +* The graph is based on daily snapshots of open findings. If no analysis ran on a given day, there may be no data point for that day. +* Historical data is only available from when {% data variables.product.prodname_code_quality_short %} started taking snapshots, so the available time range may initially be limited. +* The graph tracks the total count of open findings, not individual findings being opened or fixed. A change in the count doesn't necessarily mean developers fixed or introduced problems. +* Enabling {% data variables.product.prodname_code_quality_short %} on additional repositories can increase the finding count shown in the graph. An increase after enabling new repositories doesn't necessarily mean code quality is declining. +* The graph tracks the total count of open findings for the repositories you are currently filtering on. The total count includes: + + * New findings that are introduced by code changes or when code quality analysis is enabled on new repositories + * Findings that are fixed in the code or dismissed by users + +## Identifying repositories that need attention + +Below the trends graph, two tables help you identify which repositories need attention over the selected time period: + +* **Most improved repositories** lists repositories with the largest decrease in open findings over the selected time period. +* **Repositories needing improvement** lists repositories with the largest increase in open findings over the selected time period. + +Both tables include the following columns: + +* **Repository**: The name of the repository. +* **Total open**: The number of open findings for the repository at the end of the selected time period. +* **Net change**: How the open finding count for the repository has changed over the selected time period. +* **Dismissed**: How many findings were dismissed for the repository over the selected time period. + +The number of findings for a repository is affected by findings being fixed and dismissed. You can use the repository-level dashboard to confirm what changed. + +To investigate a repository, click its name to open its repository-level {% data variables.product.prodname_code_quality_short %} dashboard, where you can review individual findings and take remediation action. + +## Next steps + +To understand the code health information available on the repository-level dashboard, see [AUTOTITLE](/code-security/how-tos/maintain-quality-code/interpret-results). + +If you're planning to enable {% data variables.product.prodname_code_quality_short %} across many repositories, see [AUTOTITLE](/code-security/how-tos/maintain-quality-code/roll-out-at-scale). diff --git a/content/code-security/how-tos/maintain-quality-code/restrict-code-coverage.md b/content/code-security/how-tos/maintain-quality-code/restrict-code-coverage.md index 32ccb7b3ab22..f9362006137f 100644 --- a/content/code-security/how-tos/maintain-quality-code/restrict-code-coverage.md +++ b/content/code-security/how-tos/maintain-quality-code/restrict-code-coverage.md @@ -19,6 +19,9 @@ category: * {% data variables.product.prodname_code_quality %} is enabled on the repository. * Code coverage data is uploaded to {% data variables.product.github %} for the pull request branch. See [AUTOTITLE](/code-security/how-tos/maintain-quality-code/set-up-code-coverage). +> [!NOTE] +> Coverage thresholds are evaluated against **line coverage**. See [AUTOTITLE](/code-security/reference/code-quality/code-coverage). + ## Creating a coverage threshold rule {% data reusables.repositories.navigate-to-repo %} @@ -28,8 +31,8 @@ category: 1. Under "Branch rules", select **Restrict code coverage**. 1. Expand **Additional settings** to configure thresholds. A value of 0 means that the threshold is disabled. - * **Minimum coverage percentage**: enter a value to block pull requests where aggregated coverage falls below this percentage. - * **Maximum coverage drop**: enter a value to block pull requests where coverage drops by more than this many percentage points relative to the default branch. + * **Minimum line coverage percentage**: enter a value to block pull requests where aggregated line coverage falls below this percentage. + * **Maximum line coverage drop**: enter a value to block pull requests where line coverage drops by more than this many percentage points relative to the default branch. 1. Click **Create** or **Save changes**. diff --git a/content/code-security/how-tos/maintain-quality-code/set-pr-thresholds.md b/content/code-security/how-tos/maintain-quality-code/set-pr-thresholds.md index 36ae5e2ca9b1..16328cb1dd01 100644 --- a/content/code-security/how-tos/maintain-quality-code/set-pr-thresholds.md +++ b/content/code-security/how-tos/maintain-quality-code/set-pr-thresholds.md @@ -21,7 +21,7 @@ You can block pull requests that don't meet your code quality standards by addin You can set thresholds for: * **{% data variables.product.prodname_codeql %} findings**, by the lowest severity of results you require to be resolved. -* **Code coverage**, by the minimum percentage of code that must be covered by tests. +* **Code coverage**, by the minimum percentage of lines that must be covered by tests. You can enforce these thresholds at the **repository** level, or at the **organization** level to apply the same standard across many repositories at once. Choose the organization level when you want a consistent quality bar across teams, and the repository level when a single project needs its own standard. {% data variables.product.prodname_code_quality_short %} {% data variables.code-quality.recent_suggestions %} cannot be set as a threshold. diff --git a/content/code-security/how-tos/maintain-quality-code/set-up-code-coverage.md b/content/code-security/how-tos/maintain-quality-code/set-up-code-coverage.md index dd0e44658efb..488f2a84121f 100644 --- a/content/code-security/how-tos/maintain-quality-code/set-up-code-coverage.md +++ b/content/code-security/how-tos/maintain-quality-code/set-up-code-coverage.md @@ -161,5 +161,5 @@ jobs: 1. Open a pull request (or push to an existing one) that triggers the workflow you configured. 1. After the workflow completes, look for a comment from `{% data variables.code-quality.pr_commenter %}` on the pull request. The comment includes: - * The aggregate coverage percentage for the pull request branch compared to the default branch. + * The aggregate line coverage percentage for the pull request branch compared to the default branch. * A per-file breakdown showing which files gained or lost coverage. diff --git a/content/code-security/how-tos/maintain-quality-code/unblock-your-pr.md b/content/code-security/how-tos/maintain-quality-code/unblock-your-pr.md index 7b2352f53cf2..62a078e07d90 100644 --- a/content/code-security/how-tos/maintain-quality-code/unblock-your-pr.md +++ b/content/code-security/how-tos/maintain-quality-code/unblock-your-pr.md @@ -19,7 +19,7 @@ Repository administrators and organization owners can set quality gates using {% There are two types of blocks: * **Code quality findings**: your changes introduce issues that fall below the required quality threshold. -* **Coverage threshold**: your changes cause code coverage to fall below a required minimum, or cause coverage to drop by more than a permitted amount relative to the default branch. +* **Coverage threshold**: your changes cause code coverage to fall below a required minimum, or cause code coverage to drop by more than a permitted amount relative to the default branch. These checks help maintain a healthy, maintainable codebase and prevent technical debt from accumulating. @@ -41,13 +41,13 @@ To unblock your pull request, you need to fix or dismiss the findings that meet If your pull request is blocked by a coverage threshold rule, you'll see a merge block banner in the "Checks" section with a message describing which threshold was not met. For example: -* "Coverage 22.0% is below minimum 50.0%": your pull request branch coverage is below the minimum coverage percentage configured in the ruleset. -* "Coverage decreased by 2.5%, maximum allowed drop is 1.0%": your changes caused coverage to drop by more than the permitted amount relative to the default branch. +* "Line coverage 22.0% is below minimum 50.0%": the line coverage on your pull request branch is below the minimum line coverage percentage configured in the ruleset. +* "Line coverage decreased by 2.5%, maximum allowed drop is 1.0%": your changes caused line coverage to drop by more than the permitted amount relative to the default branch. -To unblock your pull request, you need to add or modify tests so that more of the codebase is executed: +To unblock your pull request, you need to add or modify tests so that more lines of the codebase are executed: 1. Review the coverage summary comment on your pull request to identify which files or areas lack coverage. -1. Add or update tests to increase execution coverage. {% data variables.product.prodname_copilot_short %} can help you write and update your tests. See [AUTOTITLE](/copilot/tutorials/copilot-cookbook/testing-code). +1. Add or update tests to increase line coverage. {% data variables.product.prodname_copilot_short %} can help you write and update your tests. See [AUTOTITLE](/copilot/tutorials/copilot-cookbook/testing-code). 1. Push your changes. The coverage check will re-run automatically. ## Next steps diff --git a/content/code-security/how-tos/maintain-quality-code/view-coverage-on-prs.md b/content/code-security/how-tos/maintain-quality-code/view-coverage-on-prs.md index f7e7c8894133..be75b69a2182 100644 --- a/content/code-security/how-tos/maintain-quality-code/view-coverage-on-prs.md +++ b/content/code-security/how-tos/maintain-quality-code/view-coverage-on-prs.md @@ -16,13 +16,16 @@ category: * Code coverage is configured for your repository. See [AUTOTITLE](/code-security/how-tos/maintain-quality-code/set-up-code-coverage). +> [!NOTE] +> The coverage summary comment reports **line coverage**. See [AUTOTITLE](/code-security/reference/code-quality/code-coverage). + ## Reading the coverage summary comment After code coverage is configured for your repository, the `{% data variables.code-quality.pr_commenter %}` posts a coverage summary comment on each pull request. The comment includes: -* **Branch-vs-default-branch comparison:** The aggregate coverage percentage for the pull request branch and the default branch (for example, "65% on pull request branch, 44% on default branch"). +* **Branch-vs-default-branch comparison:** The aggregate line coverage percentage for the pull request branch and the default branch (for example, "65% on pull request branch, 44% on default branch"). * **Most impacted files:** The 10 files with the largest coverage changes between the default branch and the pull request branch. This list may include files not directly modified in the pull request. New or modified files are ranked above deleted files. Within each group, files are sorted by the absolute change in line coverage weighted by the number of lines in the file, with coverage magnitude and then filename as tiebreakers. -* **Per-file breakdown:** An expandable section listing each file with its coverage percentage and delta value. A positive delta means the file gained coverage on this branch. A negative delta indicates coverage decreased, which may signal untested code paths introduced by the change. +* **Per-file breakdown:** An expandable section listing each file with its line coverage percentage and delta value. A positive delta means the file gained line coverage on this branch. A negative delta indicates line coverage decreased, which may signal untested code paths introduced by the change. Use the coverage summary to identify files with low or declining coverage and prioritize review attention on untested changes. diff --git a/content/code-security/reference/code-quality/code-coverage.md b/content/code-security/reference/code-quality/code-coverage.md index aef9e718ba10..8a15a685fb89 100644 --- a/content/code-security/reference/code-quality/code-coverage.md +++ b/content/code-security/reference/code-quality/code-coverage.md @@ -1,7 +1,7 @@ --- title: Code coverage reference shortTitle: Code coverage -intro: '{% data variables.product.prodname_code_quality_short %} shows how much of your code your tests actually exercise, so you can find untested code before you merge.' +intro: '{% data variables.product.prodname_code_quality_short %} shows what percentage of the lines of your code your tests actually exercise, so you can find untested code before you merge.' versions: feature: code-quality contentType: reference @@ -9,17 +9,20 @@ category: - Improve code quality --- -Code coverage measures what percentage of your source code is executed when your test suite runs. {% data variables.product.prodname_code_quality_short %} displays a coverage percentage on pull requests after you upload a Cobertura XML coverage report. +Code coverage measures what percentage of the lines in your source code are executed when your test suite runs. {% data variables.product.prodname_code_quality_short %} displays a line coverage percentage on pull requests after you upload a Cobertura XML coverage report. -## How coverage is calculated +> [!NOTE] +> {% data variables.product.prodname_code_quality_short %} reports **line coverage** only. Coverage tools often also report function, branch, or statement coverage. {% data variables.product.prodname_code_quality_short %} does not currently use these metrics, even if your Cobertura XML report includes them, and they are not shown on pull requests or evaluated by coverage threshold rules. -The coverage percentage represents the number of lines covered by tests divided by the total number of lines, expressed as a percentage. {% data variables.product.prodname_code_quality_short %} stores the latest upload for each branch (including the default branch) and compares the pull request branch coverage to the default branch coverage. +## How line coverage is calculated -For example, if your default branch has 44% coverage and your pull request branch has 65% coverage, the pull request gained 21 percentage points of coverage. +The line coverage percentage represents the number of lines covered by tests divided by the total number of lines, expressed as a percentage. {% data variables.product.prodname_code_quality_short %} stores the latest upload for each branch (including the default branch) and compares the pull request branch line coverage to the default branch line coverage. + +For example, if your default branch has 44% line coverage and your pull request branch has 65% line coverage, the pull request gained 21 percentage points of line coverage. ## Per-file delta -The per-file breakdown on pull requests shows how coverage changed for each modified file. A positive delta means the file gained coverage on the pull request branch compared to the default branch. +The per-file breakdown on pull requests shows how line coverage changed for each modified file. A positive delta means the file gained line coverage on the pull request branch compared to the default branch. To set up code coverage for your repository, see [AUTOTITLE](/code-security/how-tos/maintain-quality-code/set-up-code-coverage). diff --git a/content/contributing/collaborating-on-github-docs/about-contributing-to-github-docs.md b/content/contributing/collaborating-on-github-docs/about-contributing-to-github-docs.md index 47aa3ccb0746..91a71daefc30 100644 --- a/content/contributing/collaborating-on-github-docs/about-contributing-to-github-docs.md +++ b/content/contributing/collaborating-on-github-docs/about-contributing-to-github-docs.md @@ -21,7 +21,7 @@ The documentation repository is the place to discuss and collaborate on the docu If you've found something in the documentation content, or something about the docs.github.com website, that should be updated, search the open issues to see if someone else has reported the same thing. If it's something new, open an issue using a [template](https://github.com/github/docs/issues/new/choose). We'll use the issue to have a conversation about the problem you'd like to be fixed. > [!NOTE] -> {% data variables.product.prodname_dotcom %} employees should open issues in the private `docs-content` repository. +> For larger updates, we highly recommend that you open an issue first, to give us the opportunity to review your proposal before you go ahead and raise a pull request. ## Pull requests diff --git a/content/copilot/concepts/agents/cloud-agent/about-cloud-agent.md b/content/copilot/concepts/agents/cloud-agent/about-cloud-agent.md index e33e3bfa5dbf..28421701411e 100644 --- a/content/copilot/concepts/agents/cloud-agent/about-cloud-agent.md +++ b/content/copilot/concepts/agents/cloud-agent/about-cloud-agent.md @@ -48,7 +48,7 @@ When you delegate tasks to {% data variables.copilot.copilot_cloud_agent %}, you While working on a coding task, {% data variables.copilot.copilot_cloud_agent %} has access to its own ephemeral development environment, powered by {% data variables.product.prodname_actions %}, where it can explore your code, make changes, execute automated tests and linters and more. -> [!NOTE] Deep research, planning, and iterating on code changes before creating a pull request are only available with {% data variables.copilot.copilot_cloud_agent %} on {% data variables.product.prodname_dotcom_the_website %}. {% data variables.copilot.copilot_cloud_agent_short_cap_c %} integrations (such as Azure Boards, JIRA, Linear, Slack, or Teams) only support creating a pull request directly. +> [!NOTE] Deep research, planning, and iterating on code changes before creating a pull request are available with {% data variables.copilot.copilot_cloud_agent %} on {% data variables.product.prodname_dotcom_the_website %}, and in {% data variables.release-phases.public_preview %} for the Microsoft Teams integration. Other {% data variables.copilot.copilot_cloud_agent_short %} integrations (such as Azure Boards, JIRA, Linear, or Slack) only support creating a pull request directly. ### Benefits over traditional AI workflows @@ -94,7 +94,11 @@ These metrics can help you track adoption of {% data variables.copilot.copilot_c ## Integrating {% data variables.copilot.copilot_cloud_agent %} with third-party tools -You can also invoke {% data variables.copilot.copilot_cloud_agent %} from external tools, allowing you to assign tasks to {% data variables.product.prodname_copilot_short %}, provide context, and open pull requests without leaving your workflow. See [AUTOTITLE](/copilot/concepts/tools/about-copilot-integrations) +You can invoke {% data variables.copilot.copilot_cloud_agent %} from external tools, allowing you to assign tasks to {% data variables.product.prodname_copilot_short %}, provide context, and open pull requests without leaving your workflow. + +Use {% data variables.copilot.copilot_cloud_agent %} in Microsoft Teams to collaborate with your team on agent-assisted work. You can @mention {% data variables.product.github %} in channels, threads, and direct messages to work alongside teammates and {% data variables.product.prodname_copilot_short %} on research, planning, and coding tasks. Teammates can add context, steer {% data variables.product.prodname_copilot_short %} sessions, monitor progress, and then review the resulting artifacts. + +For more information, see [AUTOTITLE](/copilot/concepts/tools/about-copilot-integrations). ## Making {% data variables.copilot.copilot_cloud_agent %} available diff --git a/content/copilot/concepts/agents/cloud-agent/risks-and-mitigations.md b/content/copilot/concepts/agents/cloud-agent/risks-and-mitigations.md index 8eb2eed04d76..4265328acd53 100644 --- a/content/copilot/concepts/agents/cloud-agent/risks-and-mitigations.md +++ b/content/copilot/concepts/agents/cloud-agent/risks-and-mitigations.md @@ -38,6 +38,7 @@ To mitigate this risk, {% data variables.product.github %}: * **Requires human review before merging.** Draft pull requests created by {% data variables.copilot.copilot_cloud_agent %} must be reviewed and merged by a human. {% data variables.copilot.copilot_cloud_agent %} cannot mark its pull requests as "Ready for review" and cannot approve or merge a pull request. * **Restricts {% data variables.product.prodname_actions %} workflow runs.** By default, workflows are not triggered until {% data variables.copilot.copilot_cloud_agent %}'s code is reviewed and a user with write access to the repository clicks the **Approve and run workflows** button. Optionally, you can configure {% data variables.product.prodname_copilot_short %} to allow workflows to run automatically. See [AUTOTITLE](/copilot/how-tos/copilot-on-github/use-copilot-agents/review-copilot-output#manage-github-actions-workflow-runs). * **Prevents the user who asked {% data variables.copilot.copilot_cloud_agent %} to create a pull request from approving it.** This maintains the expected controls in the "Required approvals" rule and branch protection. See [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets). +* **Requires an additional approval when a pull request isn't attributed to a person.** When {% data variables.copilot.copilot_cloud_agent %} opens a pull request under its own app identity, one more approval is required before it can be merged, as long as the repository already requires at least one approval. This is enabled by default in rulesets, where administrators can turn it off, and always applies to branch protection rules. See [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#additional-approval-for-unattributed-copilot-pull-requests). ## {% data variables.copilot.copilot_cloud_agent %} has access to sensitive information diff --git a/content/copilot/concepts/agents/index.md b/content/copilot/concepts/agents/index.md index 53d902eb1e36..cd8858a5f1e6 100644 --- a/content/copilot/concepts/agents/index.md +++ b/content/copilot/concepts/agents/index.md @@ -22,6 +22,7 @@ children: - /anthropic-claude - /about-agent-skills - /enterprise-management + - /opentelemetry contentType: concepts --- diff --git a/content/copilot/concepts/agents/opentelemetry.md b/content/copilot/concepts/agents/opentelemetry.md new file mode 100644 index 000000000000..ac019fd8bbec --- /dev/null +++ b/content/copilot/concepts/agents/opentelemetry.md @@ -0,0 +1,46 @@ +--- +title: OpenTelemetry for agent monitoring +shortTitle: OpenTelemetry +intro: Understand how {% data variables.product.prodname_copilot_short %} agents perform and interact with models and tools. +versions: + feature: copilot +contentType: concepts +category: + - Manage Copilot for a team +--- + +OpenTelemetry (OTel) is an open source observability framework. It provides a standard way to collect telemetry events and metrics and export them to compatible observability tools. For more information, see [What is OpenTelemetry?](https://opentelemetry.io/docs/what-is-opentelemetry/) on the OTel website. + +When you enable OTel monitoring, you can send data from users' {% data variables.product.prodname_copilot_short %} clients to an OTel-compatible backend. This lets you analyze agent sessions and understand agent usage across your enterprise. + +## What data does {% data variables.product.prodname_copilot_short %} send? + +{% data variables.product.prodname_copilot_short %} sends three types of data: + +* **Traces** show the flow of an agent session and connect each step, including model calls and tool use. For example, a trace can show an agent calling a model, using the `readFile` tool, and calling the model again to produce a response. +* **Metrics** are numeric measurements that help you identify patterns over time. For example, token usage metrics track the number of input and output tokens used in model calls. +* **Events** record individual actions at a specific point in time. For example, an edit feedback event records whether a user accepted or rejected an agent edit. + +By default, the data does not include prompts, responses, or tool arguments. You can choose to capture this content, but it may contain sensitive information, such as code, file contents, and user prompts. + +## Enabling OpenTelemetry + +To collect OTel data from users' {% data variables.product.prodname_copilot_short %} clients: + +1. **Set up an observability backend.** Choose a secure backend that supports the OpenTelemetry Protocol (OTLP). Some backends can receive OTLP data directly. For other backends, deploy an [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) to receive, process, and forward the data. For examples, see [Use with observability backends](https://code.visualstudio.com/docs/agents/guides/monitoring-agents#_use-with-observability-backends) in the {% data variables.product.prodname_vscode_shortname %} documentation. +1. **Configure users' clients.** Set configuration values to enable OTel in each client and configure it to send data to your OTLP endpoint by configuring the endpoint, headers, and authentication token. +1. **Interpret data.** Use the collected data to analyze sessions and identify trends. For an example implementation, see [Monitor AI coding agents with Grafana](https://learn.microsoft.com/en-gb/azure/managed-grafana/grafana-opentelemetry-app-insights) in the Microsoft documentation. + +### Configuring users' clients + +Enterprises can enforce OTel configuration across supported clients with managed settings. These settings are enforced across users' clients and cannot be overridden. The `telemetry` property includes keys for enabling and configuring OpenTelemetry. + +For more information, see [AUTOTITLE](/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/configure-enterprise-managed-settings) and [AUTOTITLE](/copilot/reference/enterprise-administrators/enterprise-managed-settings). + +## Client documentation + +For more details of how OpenTelemetry is used across clients, see: + +* [Monitor agent usage with OpenTelemetry](https://code.visualstudio.com/docs/agents/guides/monitoring-agents) in the {% data variables.product.prodname_vscode_shortname %} documentation +* [AUTOTITLE](/copilot/how-tos/copilot-sdk/observability/opentelemetry) +* [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-command-reference#opentelemetry-monitoring) diff --git a/content/copilot/concepts/billing/budgets-for-usage-based-billing.md b/content/copilot/concepts/billing/budgets-for-usage-based-billing.md index 4f263f7841c3..010ebbb8fe20 100644 --- a/content/copilot/concepts/billing/budgets-for-usage-based-billing.md +++ b/content/copilot/concepts/billing/budgets-for-usage-based-billing.md @@ -106,6 +106,8 @@ When someone in your enterprise uses {% data variables.product.prodname_copilot_ > [!NOTE] > For additional (metered) usage to occur, the "{% data variables.product.prodname_ai_credit_singular %} paid usage" policy must be enabled in your enterprise or organization settings. If this policy is disabled, usage is blocked when the shared pool is exhausted, regardless of your budget configuration. +![Flowchart of AI credit budget checks: individual budget, then shared pool, then metered charge against the most specific budget.](/assets/images/help/billing/request-budget-flow.png) + Each request for an {% data variables.product.prodname_ai_credit_singular %}-consuming feature goes through these checks: 1. **User-level budget check.** The system first checks whether the user has exceeded their user-level budget. When a user has more than one type of user-level budget, the most specific one applies: an individual budget if set, otherwise the budget for the user's cost center, otherwise the universal budget. If the applicable budget is exceeded, the request is blocked immediately. ULBs are always a hard stop, and no other budget can override or supplement them. If no user-level budget is set, the request continues. diff --git a/content/copilot/concepts/billing/index.md b/content/copilot/concepts/billing/index.md index e5493b84935b..9fc7b824e06c 100644 --- a/content/copilot/concepts/billing/index.md +++ b/content/copilot/concepts/billing/index.md @@ -8,7 +8,6 @@ children: - /usage-based-billing-for-individuals - /usage-based-billing-for-organizations-and-enterprises - /budgets-for-usage-based-billing - - /individual-plans - /organizations-and-enterprises redirect_from: - /managing-copilot/managing-copilot-as-an-individual-subscriber/billing-and-payments diff --git a/content/copilot/concepts/billing/individual-plans.md b/content/copilot/concepts/billing/individual-plans.md deleted file mode 100644 index ea8fdc1a20e5..000000000000 --- a/content/copilot/concepts/billing/individual-plans.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: About individual GitHub Copilot plans and benefits -shortTitle: Individual plans -intro: '{% data variables.product.company_short %} offers several {% data variables.product.prodname_copilot_short %} plans for individual developers, each with different features, model access, and usage limits to support a wide range of coding needs.' -versions: - feature: copilot -redirect_from: - - /copilot/managing-copilot/managing-copilot-as-an-individual-subscriber/about-github-copilot-free - - /copilot/managing-copilot/managing-copilot-as-an-individual-subscriber/managing-copilot-free/about-github-copilot-free - - /copilot/managing-copilot/managing-copilot-as-an-individual-subscriber/getting-started-with-copilot-on-your-personal-account/about-github-copilot-free - - /copilot/managing-copilot/managing-copilot-as-an-individual-subscriber/getting-started-with-copilot-on-your-personal-account/about-individual-copilot-plans-and-benefits - - /copilot/concepts/copilot-billing/about-individual-copilot-plans-and-benefits - - /copilot/concepts/copilot-billing/individual-plans -contentType: concepts -category: - - Learn about Copilot ---- - -{% data variables.product.company_short %} offers multiple {% data variables.product.prodname_copilot_short %} plans for individual developers, as well as a dedicated student offering, each designed to meet different needs based on your coding habits, interest in AI models, and desired level of flexibility. - -You can choose from the following plans. - -## {% data variables.copilot.copilot_free %} - -For developers looking to get started with {% data variables.product.prodname_copilot_short %}. - -* Includes up to **2,000 code completions** and an allowance of {% data variables.product.prodname_ai_credits %} -* Limited chat and agent usage with models available through {% data variables.copilot.copilot_auto_model_selection_short %} only -* Designed to give you a limited taste of {% data variables.product.prodname_copilot_short %}'s capabilities -* No subscription or payment required -* Intended for **personal use only**, not for users managed by an organization or enterprise -* Great for developers who want to explore {% data variables.product.prodname_copilot_short %}'s capabilities before upgrading to a paid plan - -## {% data variables.copilot.copilot_student %} - -Verified students can access unlimited completions and additional models at no cost. - -* Includes **unlimited** code completions and an allowance of {% data variables.product.prodname_ai_credits %} -* Limited chat and agent usage with models available through {% data variables.copilot.copilot_auto_model_selection_short %} only -* Free for verified students - -## {% data variables.copilot.copilot_pro %} - -For developers who want more flexibility, including unlimited completions and access to additional models. - -* Includes **unlimited completions** in IDEs -* Access to {% data variables.copilot.copilot_chat_short %} and a selection of models -* A monthly allowance of {% data variables.product.prodname_ai_credits_short %}. See [{% data variables.product.prodname_ai_credits %} allowance by plan](/copilot/concepts/billing/usage-based-billing-for-individuals). -* Free for verified teachers and maintainers of popular open source projects - -## {% data variables.copilot.copilot_pro_plus %} - -For developers who need maximum flexibility, premium access to available models, and expanded limits. - -* Everything in {% data variables.copilot.copilot_pro_short %}, and: - - * Access to premium models - * A higher monthly allowance of {% data variables.product.prodname_ai_credits_short %}. See [{% data variables.product.prodname_ai_credits %} allowance by plan](/copilot/concepts/billing/usage-based-billing-for-individuals). - * Priority access to advanced AI capabilities - -* Ideal for AI power users and developers who want cutting-edge tools - -## {% data variables.copilot.copilot_max %} - -Designed for sustained, high-volume {% data variables.product.prodname_copilot_short %} users. - -* Everything in {% data variables.copilot.copilot_pro_plus_short %}, and: - - * Our highest available monthly allowance of {% data variables.product.prodname_ai_credits_short %}. See [{% data variables.product.prodname_ai_credits %} allowance by plan](/copilot/concepts/billing/usage-based-billing-for-individuals). - * **Priority access** to new models and features - -* Ideal for high-volume AI power users who want access to the most AI credits available to them - -## Comparing plans - -The following table highlights the key differences between individual {% data variables.product.prodname_copilot_short %} plans. - -{% rowheaders %} - -| Feature | {% data variables.copilot.copilot_free_short %} | {% data variables.copilot.copilot_student_short %} | {% data variables.copilot.copilot_pro_short %} | {% data variables.copilot.copilot_pro_plus_short %} | {% data variables.copilot.copilot_max_short %} | -|--------|----------------------------------------------------|----------------------------------------------|--------------------------------------------------|----------------------------------------------------------|----------------------------------------------------------| -| Price | Free | [Free](/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-students) | {% data variables.copilot.cfi_price_per_month %} per month
([free](/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-teachers-and-os-maintainers) for some users) | {% data variables.copilot.cpp_price_per_month %} per month | {% data variables.copilot.cm_price_per_month %} per month | -| Real-time code suggestions with included models | Up to 2,000 per month | Unlimited | Unlimited | Unlimited | Unlimited | -| {% data variables.product.prodname_copilot_short %} interactions[^1] | Limited ({% data variables.copilot.copilot_auto_model_selection_short %} only) | Limited ({% data variables.copilot.copilot_auto_model_selection_short %} only) | Subject to monthly {% data variables.product.prodname_ai_credits_short %} allowance | Subject to monthly {% data variables.product.prodname_ai_credits_short %} allowance | Subject to monthly {% data variables.product.prodname_ai_credits_short %} allowance | -| Access to premium models | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} Full access | {% octicon "check" aria-label="Included" %} Full access | - -{% endrowheaders %} - -[^1]: Response times may vary during periods of high usage. - -### {% data variables.product.prodname_ai_credits %} allowance by plan - -The following table shows what's included with each paid plan. - -{% data reusables.copilot.plans.ai-credits-by-plan %} - -For more information on how {% data variables.product.prodname_ai_credits %} work, see [AUTOTITLE](/copilot/concepts/billing/usage-based-billing-for-individuals) and [AUTOTITLE](/copilot/concepts/billing/usage-based-billing-for-organizations-and-enterprises). - -For a detailed comparison of features and benefits, see [AUTOTITLE](/copilot/get-started/plans). - -## Choosing the right plan - -Consider the following to decide which plan is right for you: - -* **Just getting started?** [Try {% data variables.copilot.copilot_free %}](https://github.com/copilot?ref_product=copilot&ref_type=engagement&ref_style=text&ref_plan=free) to explore basic functionality at no cost. -* **Studying?** Choose {% data variables.copilot.copilot_student_short %} to access premium features at no cost. -* **Coding regularly with AI?** [Subscribe to {% data variables.copilot.copilot_pro %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro) for more flexibility and access to premium features. -* **Want the best performance and premium model access?** [Go with {% data variables.copilot.copilot_pro_plus %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro-plus) to unlock everything {% data variables.product.prodname_copilot_short %} has to offer. -* **Doing sustained high-volume {% data variables.product.prodname_copilot_short %} development?** [Subscribe to {% data variables.copilot.copilot_max %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=max), which offers the highest monthly allowance of {% data variables.product.prodname_ai_credits_short %} for individual plans. - -To learn how to set up the plan that’s right for you, see [AUTOTITLE](/copilot/how-tos/manage-your-account/get-started-with-a-copilot-plan). - -### Limitations for enterprises - -{% data variables.copilot.copilot_free_short %} is not suitable for enterprises, as it does not include the following features: - -* Access management -* Audit logs -* Policy management -* File exclusion -* Usage data -* Indemnification coverage diff --git a/content/copilot/concepts/billing/usage-based-billing-for-individuals.md b/content/copilot/concepts/billing/usage-based-billing-for-individuals.md index 0e6c5258c327..2a1f6446f654 100644 --- a/content/copilot/concepts/billing/usage-based-billing-for-individuals.md +++ b/content/copilot/concepts/billing/usage-based-billing-for-individuals.md @@ -57,6 +57,8 @@ The following table shows what's included with each paid plan. {% data reusables.copilot.plans.ai-credits-by-plan %} + {% data variables.copilot.copilot_free_short %} and {% data variables.copilot.copilot_student_short %} both have an allowance of {% data variables.product.prodname_ai_credits_short %} and access to models through {% data variables.copilot.copilot_auto_model_selection_short %} only. {% data variables.copilot.copilot_free_short %} includes 2000 code completions per month and {% data variables.copilot.copilot_student_short %} includes unlimited code completions. + If you use everything included in your plan, you can purchase more and keep working. See [What happens if I exceed my included {% data variables.product.prodname_ai_credits_short %}](#what-happens-if-i-exceed-my-included--data-variablesproductprodname_ai_credits_short-). ## What is billed in {% data variables.product.prodname_ai_credits_short %}? diff --git a/content/copilot/concepts/tools/about-copilot-integrations.md b/content/copilot/concepts/tools/about-copilot-integrations.md index 60f4d945ab26..56d9a963294f 100644 --- a/content/copilot/concepts/tools/about-copilot-integrations.md +++ b/content/copilot/concepts/tools/about-copilot-integrations.md @@ -13,7 +13,7 @@ category: ## Overview -{% data variables.copilot.copilot_cloud_agent %} can be integrated with various tools and platforms to enhance its functionality and streamline your development workflow. With integrations, you can trigger {% data variables.copilot.copilot_cloud_agent %} from within your existing tools, providing the cloud agent with the context it needs to assist you effectively. +{% data variables.copilot.copilot_cloud_agent %} can be integrated with various tools and platforms to enhance its functionality and streamline your development workflow. With integrations, you can work with and trigger {% data variables.copilot.copilot_cloud_agent %} from within your existing tools, providing the cloud agent with the context it needs to assist you effectively. For more information about {% data variables.copilot.copilot_cloud_agent %}, see [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-cloud-agent). @@ -21,7 +21,7 @@ For more information about {% data variables.copilot.copilot_cloud_agent %}, see Currently, {% data variables.copilot.copilot_cloud_agent %} supports integrations with the following tools: -* **Microsoft Teams**: [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-teams) - Learn how to set up the Microsoft Teams integration to trigger {% data variables.copilot.copilot_cloud_agent %} directly from your Teams channels. +* **Microsoft Teams**: [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-teams) - Learn how to set up the Microsoft Teams integration to collaborate with {% data variables.copilot.copilot_cloud_agent %} directly in your Teams messages and channels. * **Slack**: [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-slack) - Learn how to set up the Slack integration to trigger {% data variables.copilot.copilot_cloud_agent %} directly from your Slack workspace. * **Linear**: [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-linear) - Learn how to set up the Linear integration to trigger {% data variables.copilot.copilot_cloud_agent %} directly from your Linear issues. * **Azure Boards**: [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-azure-boards) - Learn how to set up the Azure Boards integration to trigger {% data variables.copilot.copilot_cloud_agent %} directly from your Azure Boards work items. @@ -31,10 +31,10 @@ Currently, {% data variables.copilot.copilot_cloud_agent %} supports integration Integrating {% data variables.copilot.copilot_cloud_agent %} with your existing tools offers several benefits: -* **Seamless workflow**: Trigger {% data variables.copilot.copilot_cloud_agent %} directly from the tools you already use, reducing context switching and improving productivity. +* **Seamless workflow**: Work with {% data variables.copilot.copilot_cloud_agent %} directly in the tools you already use, reducing context switching and improving productivity. * **Context-aware assistance**: Provide {% data variables.copilot.copilot_cloud_agent %} with the necessary context from your tools, enabling it to generate more relevant and accurate code suggestions. -* **Collaboration**: Facilitate collaboration among team members by allowing them to trigger {% data variables.copilot.copilot_cloud_agent %} from shared platforms, ensuring everyone benefits from the agent's capabilities. +* **Collaboration**: Facilitate collaboration among team members by allowing them to work with {% data variables.copilot.copilot_cloud_agent %} from shared platforms, ensuring everyone benefits from the agent's capabilities. ## Data usage -When you trigger {% data variables.copilot.copilot_cloud_agent %} through an integration, the agent will capture the entire thread or issue to understand the context in order to assist you effectively. This context is stored in the pull request created by the agent. +When you use {% data variables.copilot.copilot_cloud_agent %} through an integration, the agent will capture the entire thread or issue to understand the context in order to assist you effectively. This context is stored in the artifacts created by the agent. diff --git a/content/copilot/get-started/plans.md b/content/copilot/get-started/plans.md index 16343f093af4..05d15f924def 100644 --- a/content/copilot/get-started/plans.md +++ b/content/copilot/get-started/plans.md @@ -1,6 +1,6 @@ --- title: Plans for GitHub Copilot -intro: 'Learn about the available plans for {% data variables.product.prodname_copilot_short %}.' +intro: 'Discover the plans available for {% data variables.product.prodname_copilot_short %}.' versions: feature: copilot shortTitle: Plans @@ -8,55 +8,270 @@ redirect_from: - /copilot/about-github-copilot/subscription-plans-for-github-copilot - /copilot/about-github-copilot/plans-for-github-copilot - /copilot/get-started/plans-for-github-copilot + - /copilot/concepts/billing/individual-plans contentType: get-started category: - Learn about Copilot --- -> [!IMPORTANT] {% data reusables.copilot.plans.organization-plans-paused %} +## {% data variables.product.prodname_copilot %} plans -{% data variables.product.company_short %} offers several plans for {% data variables.product.prodname_copilot %}, depending on your needs and whether you're using {% data variables.product.prodname_copilot_short %} as an individual or as part of an organization or enterprise. +{% data variables.product.company_short %} offers a variety of plans for {% data variables.product.prodname_copilot_short %}. Choose between them depending on your needs and whether you're using {% data variables.product.prodname_copilot_short %} as an individual or as part of an organization or enterprise. -* **{% data variables.copilot.copilot_free %}** is available to individual developers who don't have access to {% data variables.product.prodname_copilot_short %} through an organization or enterprise. This free plan includes limited access to a selection of {% data variables.product.prodname_copilot_short %} features and models available through {% data variables.copilot.copilot_auto_model_selection_short %} only, allowing you to try AI-powered coding assistance at no cost. +**{% data variables.copilot.copilot_free_short %}**: [Start using {% data variables.copilot.copilot_free_short %}](https://github.com/copilot?ref_product=copilot&ref_type=engagement&ref_style=text&ref_plan=free). -* **{% data variables.copilot.copilot_student %}** is available to verified students. The plan includes unlimited code completions and an allowance of {% data variables.product.prodname_ai_credits %}, plus limited chat and agent usage with models available through {% data variables.copilot.copilot_auto_model_selection_short %} only. +* This plan includes limited access to a selection of {% data variables.product.prodname_copilot_short %} features allowing you to try AI-powered coding assistance at no cost. -* **{% data variables.copilot.copilot_pro %}** is designed for individuals who want more flexibility. This paid plan includes unlimited completions, access to a selection of models, {% data variables.copilot.copilot_cloud_agent %}, and a monthly allowance of {% data variables.product.prodname_ai_credits_short %}. Verified teachers, and maintainers of popular open source projects may be eligible for free access. +**{% data variables.copilot.copilot_student_short %}**: [Get access to {% data variables.copilot.copilot_student_short %}](/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-students). -* **{% data variables.copilot.copilot_pro_plus %}** includes, in addition to everything in {% data variables.copilot.copilot_pro_short %}, a higher monthly allowance of {% data variables.product.prodname_ai_credits_short %}, and access to premium models. Ideal for AI power users who want access to the most advanced capabilities. +* Available to verified students. Get access to {% data variables.product.prodname_copilot_short %}'s features for free. -* **{% data variables.copilot.copilot_max %}** is designed for high-volume {% data variables.product.prodname_copilot_short %} users. This paid plan includes, in addition to everything in {% data variables.copilot.copilot_pro_plus_short %}, our highest individual monthly allowance of {% data variables.product.prodname_ai_credits_short %}, and priority access to new models and features. Ideal for sustained, high-volume AI power users who want access to the most AI credits available to them. +**{% data variables.copilot.copilot_pro %}**: [Subscribe to {% data variables.copilot.copilot_pro_short %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro). -* **{% data variables.copilot.copilot_for_business %}** is for organizations on {% data variables.product.prodname_free_team %} or {% data variables.product.prodname_team %} plan, or enterprises on {% data variables.product.prodname_ghe_cloud %}. This plan includes {% data variables.copilot.copilot_cloud_agent %}, access to a broad model catalog, a monthly pool of {% data variables.product.prodname_ai_credits_short %}, and enables centralized management and {% data variables.product.prodname_copilot_short %} policy control for organization members. +* Designed for individuals who want more flexibility with access to a selection of models and a monthly allowance of {% data variables.product.prodname_ai_credits_short %}. -* **{% data variables.copilot.copilot_enterprise %}** is for enterprises using {% data variables.product.prodname_ghe_cloud %}. It includes all the features of {% data variables.copilot.copilot_business_short %}, priority access to new models and features, a larger monthly pool of {% data variables.product.prodname_ai_credits_short %}, plus additional enterprise-grade capabilities. Enterprise owners can assign {% data variables.copilot.copilot_enterprise_short %} or {% data variables.copilot.copilot_business_short %} to individual organizations, or assign {% data variables.copilot.copilot_business_short %} directly to users and teams. +**{% data variables.copilot.copilot_pro_plus %}**: [Subscribe to {% data variables.copilot.copilot_pro_plus_short %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro-plus). -{% data variables.product.prodname_copilot_short %} is not currently available for {% data variables.product.prodname_ghe_server %}. +* Ideal for AI power users who want access to the most advanced capabilities. This paid plan includes everything in {% data variables.copilot.copilot_pro %} and a higher monthly allowance of {% data variables.product.prodname_ai_credits_short %}. -## Comparing {% data variables.product.prodname_copilot_short %} plans +**{% data variables.copilot.copilot_max %}**: [Upgrade to {% data variables.copilot.copilot_max_short %}](https://github.com/settings/billing/licensing?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=max). -The tables below show the features available in each {% data variables.product.prodname_copilot_short %} plan. +* Ideal for sustained, high-volume AI power users who want access to the most AI credits available to them. This paid plan includes everything in {% data variables.copilot.copilot_pro_plus_short %}, plus our highest individual monthly allowance of {% data variables.product.prodname_ai_credits_short %}. -{% data reusables.copilot.differences-cfi-cfb-table %} +> [!IMPORTANT] +> {% data reusables.copilot.plans.organization-plans-paused %} -For more information, see [AUTOTITLE](/copilot/get-started/features). +**{% data variables.copilot.copilot_for_business %}**: To get started, [contact sales](https://github.com/enterprise/contact?ref_product=copilot&ref_type=purchase&ref_style=text). -## Ready to choose a plan? +* Made for organizations an enterprises, this plan offers centralized management and {% data variables.product.prodname_copilot_short %} policy control for organization members. -Start using {% data variables.product.prodname_copilot_short %} by signing up for the plan that best fits your needs. +**{% data variables.copilot.copilot_enterprise %}**: [Contact sales](https://github.com/enterprise/contact?ref_product=copilot&ref_type=purchase&ref_style=text) to get started. -> [!IMPORTANT] {% data reusables.copilot.plans.organization-plans-paused %} +* Designed for enterprises using {% data variables.product.prodname_ghe_cloud %}. This plan includes all the features of {% data variables.copilot.copilot_business_short %}, offers a larger monthly pool of {% data variables.product.prodname_ai_credits_short %}, plus additional enterprise-grade capabilities. -* **{% data variables.copilot.copilot_free_short %}** — Try {% data variables.product.prodname_copilot_short %} with limited features and usage. [Start using {% data variables.copilot.copilot_free_short %}](https://github.com/copilot?ref_product=copilot&ref_type=engagement&ref_style=text&ref_plan=free). +> [!NOTE] +> {% data variables.product.prodname_copilot_short %} is not currently available for {% data variables.product.prodname_ghe_server %}. -* **{% data variables.copilot.copilot_student %}** — Get access to {% data variables.product.prodname_copilot_short %}'s features for free. [Access {% data variables.copilot.copilot_student %}](/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-students). +## {% data variables.product.prodname_copilot_short %} plans overview -* **{% data variables.copilot.copilot_pro_short %}** — Get unlimited completions and access to select models. [Subscribe to {% data variables.copilot.copilot_pro_short %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro). +The table below provides an overview of differences between plans. All plans include {% data variables.copilot.copilot_cli_short %} and {% data variables.copilot.github_copilot_app_short %}. -* **{% data variables.copilot.copilot_pro_plus_short %}** — Unlock premium AI models and extra capabilities. [Subscribe to {% data variables.copilot.copilot_pro_plus_short %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro-plus). +{% rowheaders %} -* **{% data variables.copilot.copilot_max_short %}** — Unlock priority access to new AI models and our highest individual monthly allowance of {% data variables.product.prodname_ai_credits_short %}. [Upgrade to {% data variables.copilot.copilot_max_short %}](https://github.com/settings/billing/licensing?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=max). +| Plan | Pricing | {% data variables.product.prodname_ai_credits %} | Agents | Models | +| ----------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------- | --------------------------------- | +| {% data variables.copilot.copilot_free_short %} | Free | An allowance of {% data variables.product.prodname_ai_credits %} | Limited | Auto model selection only | +| {% data variables.copilot.copilot_student_short %} | Free | An allowance of {% data variables.product.prodname_ai_credits %} | {% octicon "check" aria-label="Included" %}
Excludes third-party agents | Auto model selection only | +| {% data variables.copilot.copilot_pro_short %} | {% data variables.copilot.cfi_price_per_month %} per month
(free for some users) | Base: {% data variables.copilot.ai_credits_per_user_pro %} | {% octicon "check" aria-label="Included" %} | A selection of models | +| {% data variables.copilot.copilot_pro_plus_short %} | {% data variables.copilot.cpp_price_per_month %} per month. | Base: {% data variables.copilot.ai_credits_per_user_pro_plus %} | {% octicon "check" aria-label="Included" %} | Access to premium models | +| {% data variables.copilot.copilot_max_short %} | {% data variables.copilot.cm_price_per_month %} per month | Base: {% data variables.copilot.ai_credits_per_user_max %} | {% octicon "check" aria-label="Included" %} | Priority access to premium models | +| {% data variables.copilot.copilot_business_short %} | {% data variables.copilot.cfb_price_per_month %} per granted seat per month | Total per user per month: {% data variables.copilot.ai_credits_per_user_business %} | {% octicon "check" aria-label="Included" %} | Access to premium models | +| {% data variables.copilot.copilot_enterprise_short %} | {% data variables.copilot.ce_price_per_month %} per granted seat per month | Total per user per month: {% data variables.copilot.ai_credits_per_user_enterprise %} | {% octicon "check" aria-label="Included" %} | Priority access to premium models | -* **{% data variables.copilot.copilot_business_short %}** — For teams and organizations. [Contact Sales](https://github.com/enterprise/contact?ref_product=copilot&ref_type=purchase&ref_style=text). +{% endrowheaders %} -* **{% data variables.copilot.copilot_enterprise_short %}** — For enterprises that need advanced features and centralized management. [Contact Sales](https://github.com/enterprise/contact?ref_product=copilot&ref_type=purchase&ref_style=text). +Each plan comes with an allowance of {% data variables.product.prodname_ai_credits %}. For more information, including how {% data variables.product.prodname_ai_credits %} work, see [AUTOTITLE](/copilot/concepts/billing/usage-based-billing-for-individuals) and [AUTOTITLE](/copilot/concepts/billing/usage-based-billing-for-organizations-and-enterprises). + +For more detail on what's uniquely available in each plan, see the following sections: +* [Individual plans](#individual-plans) +* [Organization and enterprise plans](#organization-and-enterprise-plans) + +## Individual plans + +The individual plans available are: +* Free plans including {% data variables.copilot.copilot_free_short %} and {% data variables.copilot.copilot_student_short %}. +* Paid plans including {% data variables.copilot.copilot_pro_short %}, {% data variables.copilot.copilot_pro_plus_short %}, and {% data variables.copilot.copilot_max_short %}. + +With these plans you'll receive access to the following features and capabilities. + +> [!NOTE] +> * {% data variables.copilot.copilot_free_short %} plans are only available to individual developers who don't have access to {% data variables.product.prodname_copilot_short %} through an organization or enterprise. +> * Verified teachers, and maintainers of popular open source projects may be eligible for free access to {% data variables.copilot.copilot_pro_short %}. + +### {% data variables.product.prodname_ai_credits %} allowance by plan + +The following table shows what's included with each paid plan. + +{% data reusables.copilot.plans.ai-credits-by-plan %} + +{% data variables.copilot.copilot_free_short %} and {% data variables.copilot.copilot_student_short %} both have an allowance of {% data variables.product.prodname_ai_credits_short %}. + +For more information on how {% data variables.product.prodname_ai_credits %} work, see [AUTOTITLE](/copilot/concepts/billing/usage-based-billing-for-individuals) + +### Inline suggestions and {% data variables.copilot.copilot_chat_short %} + +Inline suggestions are real-time code suggestions with included models in IDEs and {% data variables.copilot.next_edit_suggestions_caps %}. +* Limited to 2000 completions per month on {% data variables.copilot.copilot_free_short %}. + +**{% data variables.copilot.copilot_chat_short %}** features available include: +* {% data variables.copilot.copilot_chat_short %} in IDEs +* Inline chat +* Slash commands +* {% data variables.copilot.copilot_mobile_short %} +* {% data variables.copilot.copilot_chat_dotcom_short %} +* {% data variables.copilot.copilot_chat_short %} in {% data variables.product.prodname_windows_terminal %} +* {% data variables.copilot.copilot_chat_short %} skills in IDEs.[^1] (Not available in {% data variables.copilot.copilot_free_short %}). + +### Models + +On {% data variables.copilot.copilot_free_short %} and {% data variables.copilot.copilot_student_short %} plans, access to models is available through {% data variables.copilot.copilot_auto_model_selection_short %} only. + +{% rowheaders %} + +| Available models | {% data variables.copilot.copilot_pro_short %} | {% data variables.copilot.copilot_pro_plus_short %} | {% data variables.copilot.copilot_max_short %} | +|---------------------------------------------------------|-------------------------------------------------|-----------------------------------------------------|------------------------------------------------| +| {% for model in tables.copilot.model-supported-plans %} | +| {{ model.name }}{% if model.name == 'GPT-5.4 nano' %}[^gpt54nano]{% endif %}{% if model.name == 'Claude Fable 5' %}[^claude-fable-5]{% endif %} | {% if model.pro == true %}{% octicon "check" aria-label="Included" %}{% else %}{% octicon "x" aria-label="Not included" %}{% endif %} | {% if model.pro_plus == true %}{% octicon "check" aria-label="Included" %}{% else %}{% octicon "x" aria-label="Not included" %}{% endif %} | {% if model.max == true %}{% octicon "check" aria-label="Included" %}{% else %}{% octicon "x" aria-label="Not included" %}{% endif %} | +| {% endfor %} | + +{% endrowheaders %} + +### Agents + +{% rowheaders %} + +| Agents | {% data variables.copilot.copilot_free_short %} | {% data variables.copilot.copilot_student_short %} | {% data variables.copilot.copilot_pro_short %} | {% data variables.copilot.copilot_pro_plus_short %} | {% data variables.copilot.copilot_max_short %} | +| ----------------------------------------------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------- | ---------------------------------------------- | --------------------------------------------------- | ---------------------------------------------- | +| {% data variables.copilot.copilot_cloud_agent %} | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Agent mode | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| {% data variables.product.prodname_copilot_short %} code review | Only "Review selection" in {% data variables.product.prodname_vscode_shortname %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Model Context Protocol (MCP) | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Third-party Agents ({% data variables.release-phases.public_preview %}) | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | + +{% endrowheaders %} + +### Customization + +{% rowheaders %} + +| Customization | {% data variables.copilot.copilot_free_short %} | {% data variables.copilot.copilot_student_short %} | {% data variables.copilot.copilot_pro_short %} | {% data variables.copilot.copilot_pro_plus_short %} | {% data variables.copilot.copilot_max_short %} | +| -------------------------------------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------- | ---------------------------------------------- | --------------------------------------------------- | ---------------------------------------------- | +| Repository and personal custom instructions | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Organization custom instructions | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | +| Prompt files | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Model Context Protocol (MCP) | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Block suggestions matching public code | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Exclude specified files from {% data variables.product.prodname_copilot_short %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | +| Organization-wide policy management | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | + +{% endrowheaders %} + +### Other features + +{% rowheaders %} + +| | {% data variables.copilot.copilot_free_short %} | {% data variables.copilot.copilot_student_short %} | {% data variables.copilot.copilot_pro_short %} | {% data variables.copilot.copilot_pro_plus_short %} | {% data variables.copilot.copilot_max_short %} | +| ------------------------------------------------------------------------------------------------ | ----------------------------------------------- | -------------------------------------------------- | ---------------------------------------------- | --------------------------------------------------- | ---------------------------------------------- | +| {% data variables.copilot.copilot_for_prs %} | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Audit logs | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Content exclusion | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | +| {% data variables.copilot.copilot_cli_short %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| {% data variables.copilot.github_copilot_app_short %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| {% data variables.product.prodname_spark %} ({% data variables.release-phases.public_preview %}) | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | {% octicon "x" aria-label="Not included" %} | + +{% endrowheaders %} + +## Organization and enterprise plans + +The {% data variables.product.prodname_copilot_short %} plans available for organizations and enterprises are: +* {% data variables.copilot.copilot_business_short %} +* {% data variables.copilot.copilot_enterprise_short %} + +With these plans you'll receive access to the following features and capabilities. + +> [!NOTE] With {% data variables.product.prodname_ghe_cloud %}, an enterprise owner chooses the plan for each organization in the enterprise. For guidance on choosing a plan, see [AUTOTITLE](/copilot/tutorials/roll-out-at-scale/assign-licenses/choose-enterprise-plan). + +### {% data variables.product.prodname_ai_credits %} allowance by plan + +| Plan | Price per granted seat per month | {% data variables.product.prodname_ai_credits %} per user per month | +| --- | --- | --- | +| {% data variables.copilot.copilot_business_short %} | {% data variables.copilot.cfb_price_per_month %} | {% data variables.copilot.ai_credits_per_user_business %} | +| {% data variables.copilot.copilot_enterprise_short %}| {% data variables.copilot.ce_price_per_month %} | {% data variables.copilot.ai_credits_per_user_enterprise %} | + +{% data variables.product.prodname_copilot_short %} usage is measured in {% data variables.product.prodname_ai_credits_short %} under usage-based billing. Each license contributes {% data variables.product.prodname_ai_credits_short %} to a shared enterprise pool, and usage beyond the pool is charged at {% data variables.product.prodname_ai_credits_value %} per {% data variables.product.prodname_ai_credit_singular %}. Code completions and {% data variables.copilot.next_edit_suggestions %} are not billed in {% data variables.product.prodname_ai_credits_short %} and remain unlimited for all paid plans. + +For a full explanation of how {% data variables.product.prodname_ai_credits_short %} work, including pooling, additional usage, and what happens when credits run out, see [AUTOTITLE](/copilot/concepts/billing/usage-based-billing-for-organizations-and-enterprises). + +### Inline suggestions and {% data variables.copilot.copilot_chat_short %} + +**Inline suggestions**: Inline suggestion features are available in all plans: + +* Real-time code suggestions with included models +* {% data variables.copilot.next_edit_suggestions_caps %} + +**{% data variables.copilot.copilot_chat_short %}** features are available in all plans: + +* {% data variables.copilot.copilot_chat_short %} in IDEs +* Inline chat +* Slash commands +* {% data variables.copilot.copilot_mobile_short %} +* {% data variables.copilot.copilot_chat_dotcom_short %} +* {% data variables.copilot.copilot_chat_short %} in {% data variables.product.prodname_windows_terminal %} +* {% data variables.copilot.copilot_chat_short %} skills in IDEs[^1] + +### Models + +{% rowheaders %} + +| Available models | {% data variables.copilot.copilot_business_short %} | {% data variables.copilot.copilot_enterprise_short %} | +|---------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------| +| {% for model in tables.copilot.model-supported-plans %} | +| {{ model.name }}{% if model.name == 'GPT-5.4 nano' %}[^gpt54nano]{% endif %}{% if model.name == 'Claude Fable 5' %}[^claude-fable-5]{% endif %} | {% if model.business == true %}{% octicon "check" aria-label="Included" %}{% else %}{% octicon "x" aria-label="Not included" %}{% endif %} | {% if model.enterprise == true %}{% octicon "check" aria-label="Included" %}{% else %}{% octicon "x" aria-label="Not included" %}{% endif %} | +| {% endfor %} | + +{% endrowheaders %} + +[^gpt54nano]: GPT-5.4 nano is currently only available in the Codex {% data variables.product.prodname_vscode %} extension ({% data variables.copilot.copilot_pro_plus_short %} only) and is not available in {% data variables.copilot.copilot_chat_short %}. + +### Agents + +{% rowheaders %} + +| Agents | {% data variables.copilot.copilot_business_short %} | {% data variables.copilot.copilot_enterprise_short %} | +| ----------------------------------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------- | +| {% data variables.copilot.copilot_cloud_agent %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Agent mode | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| {% data variables.product.prodname_copilot_short %} code review | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Model Context Protocol (MCP) | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Third-party Agents ({% data variables.release-phases.public_preview %}) | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | + +{% endrowheaders %} + +### Customization + +{% rowheaders %} + +| Customization | {% data variables.copilot.copilot_business_short %} | {% data variables.copilot.copilot_enterprise_short %} | +| -------------------------------------------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------- | +| Repository and personal custom instructions | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Organization custom instructions | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Prompt files | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Model Context Protocol (MCP) | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Block suggestions matching public code | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Exclude specified files from {% data variables.product.prodname_copilot_short %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Organization-wide policy management | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | + +{% endrowheaders %} + +### Other features + +{% rowheaders %} + +| | {% data variables.copilot.copilot_business_short %} | {% data variables.copilot.copilot_enterprise_short %} | +| ------------------------------------------------------------------------------------------------ | --------------------------------------------------- | ----------------------------------------------------- | +| {% data variables.copilot.copilot_for_prs %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Audit logs | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| Content exclusion | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| {% data variables.copilot.copilot_cli_short %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| {% data variables.copilot.github_copilot_app_short %} | {% octicon "check" aria-label="Included" %} | {% octicon "check" aria-label="Included" %} | +| {% data variables.product.prodname_spark %} ({% data variables.release-phases.public_preview %}) | {% octicon "x" aria-label="Not included" %} | {% octicon "check" aria-label="Included" %} | + +{% endrowheaders %} + +## Further reading + +* To compare feature support across IDEs, see [AUTOTITLE](/copilot/reference/copilot-feature-matrix). +* To compare models supported across plans, features, and IDEs, see [AUTOTITLE](/copilot/reference/ai-models/supported-models). + +[^1]: {% data variables.copilot.copilot_chat_short %} skills in IDEs is available in {% data variables.product.prodname_vscode %} and {% data variables.product.prodname_vs %}. +[^claude-fable-5]: When {% data variables.copilot.copilot_claude_fable_5 %} is used, Anthropic retains data, including prompts and outputs, to operate safety classifiers that detect harmful use. Other Claude models in {% data variables.product.prodname_copilot %} remain covered by {% data variables.product.github %}'s existing data retention agreements, as documented at [AUTOTITLE](/copilot/reference/ai-models/model-hosting#anthropic-models). Enterprise and business users need to enable the {% data variables.copilot.copilot_claude_fable_5 %} model to make it available for your organization. You can read more about Anthropic's data handling practices for this model under section F of their [Service Specific Terms](https://www.anthropic.com/legal/service-specific-terms). To enable {% data variables.copilot.copilot_claude_fable_5 %}, see [AUTOTITLE](/copilot/how-tos/copilot-on-github/set-up-copilot/configure-access-to-ai-models). diff --git a/content/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/monitor-agentic-activity.md b/content/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/monitor-agentic-activity.md index 47e304d35eb2..62c0ea639fd7 100644 --- a/content/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/monitor-agentic-activity.md +++ b/content/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/monitor-agentic-activity.md @@ -34,3 +34,11 @@ Track agentic activity on {% data variables.product.github %} or through streami To enable streaming for {% data variables.product.prodname_copilot_short %} agent session events and configure a streaming destination from your enterprise audit log settings, see [AUTOTITLE](/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise#enabling-audit-log-streaming-of-copilot-agent-session-events). In addition to streaming, you can also retrieve Copilot usage data through the REST API. See [AUTOTITLE](/rest/copilot/copilot-usage-metrics#get-copilot-usage-records-for-an-enterprise). + +## Enabling OpenTelemetry + +OpenTelemetry (OTel) is an open source observability framework. It provides a standard way to collect telemetry events and metrics and export them to compatible observability tools. + +When you enable OTel monitoring, you can send data from users' {% data variables.product.prodname_copilot_short %} clients to an OTel-compatible backend. This lets you analyze agent sessions and understand agent usage across your enterprise. + +For more information, see [AUTOTITLE](/copilot/concepts/agents/opentelemetry). diff --git a/content/copilot/how-tos/copilot-integrations/integrate-cloud-agent-with-teams.md b/content/copilot/how-tos/copilot-integrations/integrate-cloud-agent-with-teams.md index 79f98ef085bc..5b0c14d23f93 100644 --- a/content/copilot/how-tos/copilot-integrations/integrate-cloud-agent-with-teams.md +++ b/content/copilot/how-tos/copilot-integrations/integrate-cloud-agent-with-teams.md @@ -18,17 +18,45 @@ redirect_from: > * This feature is currently in {% data variables.release-phases.public_preview %} and subject to change. > * {% data variables.product.prodname_copilot %} uses AI. Check for mistakes. See [AUTOTITLE](/copilot/responsible-use/agents). -The {% data variables.product.github %} integration in Microsoft Teams allows you to interact with {% data variables.copilot.copilot_cloud_agent %} all from within your Teams channels. From within a Teams thread you can initiate {% data variables.copilot.copilot_cloud_agent_short %} sessions and open pull requests, using the context of your conversation. +The {% data variables.product.github %} integration in Microsoft Teams allows you to interact with {% data variables.copilot.copilot_cloud_agent %} all from within your Teams conversations. Within Teams you can initiate {% data variables.copilot.copilot_cloud_agent_short %} sessions to investigate, plan, write code, and create issues and pull requests, using the context of your conversation. Your team's collaborative decisions stay connected to your code, bridging the gap between where discussions happen and where implementation lives. For information about additional {% data variables.product.prodname_copilot_short %} integrations, see [AUTOTITLE](/copilot/concepts/tools/about-copilot-integrations). -> [!NOTE] -> When you mention @{% data variables.product.github %} in a Teams thread, the agent will capture the entire thread as context for your request, understanding and implementing solutions based on the discussion. This context is stored in the pull request. +## Security considerations + +Before you @mention {% data variables.product.github %} in Teams, consider that {% data variables.copilot.copilot_cloud_agent %} will capture the entire thread as context for your request, understanding and implementing solutions based on the discussion. This context is stored in the artifacts the agent generates. If you want to limit the context, you can send a direct message to the {% data variables.product.github %} app for Teams instead. + +## Understanding collaborative sessions, permissions, and sandboxes + +The identity {% data variables.product.prodname_copilot_short %} uses depends on whether you interact with it in a direct message or a shared context. + +* When you use {% data variables.product.prodname_copilot_short %} in a direct message, it can take actions for you, such as creating pull requests or issues, as well as answer questions. It uses the permissions of your linked {% data variables.product.github %} personal account to take these actions. + +* When you use {% data variables.product.prodname_copilot_short %} in a shared context, such as a group thread or channel, {% data variables.product.prodname_copilot_short %} creates artifacts, such as pull requests, under its app identity rather than your personal account. + + > [!NOTE] + > {% data reusables.copilot.cloud-agent.unattributed-additional-approval-note %} + +Only users with **write** access to a repository can trigger {% data variables.product.prodname_copilot_short %} to make changes, but any conversation participant can provide input. Guest members of a workspace, and outside collaborators to repositories are not able to start or steer a session with {% data variables.product.prodname_copilot_short %} in Teams. + +When {% data variables.copilot.copilot_cloud_agent %} starts work on a task from Teams, {% data variables.product.prodname_copilot_short %} continues working asynchronously in a **secure cloud sandbox**, and posts the result when it's ready. You can keep steering from Teams, or continue the work on the agent-generated artifacts in {% data variables.product.github %}, the terminal, or your preferred code editor. + +{% data variables.product.prodname_copilot_short %} uses all messages in the conversation to inform the work. The entire thread becomes the decision-making context for the artifact. + +When you ask {% data variables.product.prodname_copilot_short %} to perform a task, it will display details about the session, such as the working repository, issue or pull request link, and a task status or summary. + +### Secure cloud sandboxes + +When {% data variables.copilot.copilot_cloud_agent %} starts work on a task from Teams, {% data variables.product.prodname_copilot_short %} continues working asynchronously in a **secure cloud sandbox**, and posts the result when it's ready. + +You can keep steering from Teams, or continue the work on the agent-generated artifacts in {% data variables.product.github %}, the terminal, or your preferred code editor. ## Prerequisites * You must have a {% data variables.product.github %} account with access to {% data variables.product.prodname_copilot_short %} through a paid {% data variables.product.prodname_copilot_short %} plan. -* You must have a Teams account and be a member of a channel. +* You must have a Teams account. +* You must have Microsoft Public Developer Preview enabled for your Microsoft Teams client, see [Public developer preview for Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/dev-preview/developer-preview-intro) in the Microsoft Learn documentation. +{% data reusables.copilot.cloud-agent.cloud-sandboxes-prerequisite-teams %} ## Installing the {% data variables.product.github %} app in Teams @@ -40,32 +68,62 @@ The {% data variables.product.github %} app only needs to be installed once in a ## Connecting the {% data variables.product.github %} app to your {% data variables.product.github %} account -The first time you use the {% data variables.product.github %} app in Teams, you need to connect it to your {% data variables.product.github %} account and set a default repository. The default repository provides the context that {% data variables.product.prodname_copilot_short %} uses when responding to prompts, and it’s also where pull requests created by {% data variables.copilot.copilot_cloud_agent %} sessions will be opened unless you specify a repository in your prompt. +The first time you use the {% data variables.product.github %} app in Teams, you need to connect it to your {% data variables.product.github %} account. Then if prompted, set a default repository. + +The default repository provides the context that {% data variables.product.prodname_copilot_short %} uses when responding to prompts, and it's also where issues and pull requests created by {% data variables.copilot.copilot_cloud_agent %} sessions will be opened unless you specify a repository in your prompt. + +To get started: + +1. In Teams, @mention the app in a message by typing `@{% data variables.product.github %}`. +1. Follow the prompts to connect your {% data variables.product.github %} account, and if prompted, optionally set a default repository. +1. To see what else you can do, in the thread, @mention the app by typing `@{% data variables.product.github %} help`. + +## Starting a {% data variables.product.prodname_copilot %} session from your team conversation + +@Mention the app in any Teams chat by typing `@{% data variables.product.github %}` followed by your task. You can summon the agent for any repository where you have `write` access. The agent responds with a summary of planned changes and a link to the artifacts it creates. + +For example, to ask the agent to create a pull request on a particular branch in a repository, you can type: + +```text +@{% data variables.product.github %} Create a pull request to...YOUR_PROMPT repo=OWNER/REPO_NAME branch=BRANCH_NAME +``` + +The `repo` parameter tells {% data variables.product.prodname_copilot_short %} which repository to use, and the `branch` parameter specifies an existing branch to use as the base branch for a pull request. + +## Iterating on work in the thread + +To refine the pull request, @mention `@{% data variables.product.github %}` in the same thread with your requested changes. {% data variables.product.prodname_copilot_short %} incorporates all messages since the previous @mention to iterate on the work, keeping the discussion and implementation connected. + +## Creating issues with {% data variables.product.prodname_copilot_short %} + +You can ask {% data variables.product.prodname_copilot_short %} to create {% data variables.product.github %} issues directly from Teams, turning conversations into actionable tasks. Just describe what you need in natural language, and {% data variables.product.prodname_copilot_short %} creates the issue for you. + +You can create a single issue or multiple issues at once with child-parent relationships. + +When you @mention the app, it uses the full thread history as context for the issues it creates. To keep the context focused, consider starting a new thread or sending a direct message. + +## Customizing {% data variables.copilot.copilot_cloud_agent %} in Teams -To get started, mention `@{% data variables.product.github %} ` in any Teams thread. The app will guide you through signing in and setting a default repository. Or you can connect your {% data variables.product.github %} account and set the default repository manually by following these steps: +You can customize how {% data variables.copilot.copilot_cloud_agent %} works in your channels and threads using the `settings` parameter. For example, you can set a default repository for a channel. -1. In Teams, mention the app in a thread by typing `@{% data variables.product.github %}`. -1. Click **signin** from the list of suggestions. -1. Follow the prompts to sign in to your {% data variables.product.github %} account. -1. In the thread, mention the app by typing `@{% data variables.product.github %}`. -1. Click **settings** to set the default repository. +1. To see and change your channel settings, mention the app in a message by typing: -## Using the {% data variables.product.prodname_copilot_short %} app in Teams + ```text + @{% data variables.product.github %} settings + ``` -You can interact with the {% data variables.product.github %} app in Teams by mentioning it in a thread. The agent will respond to your messages and perform tasks based on your requests. Only users with **write** access to the default repository—or the repository specified in their prompt—can trigger {% data variables.copilot.copilot_cloud_agent %} to work. Contributors to the thread without **write** access can help guide {% data variables.product.prodname_copilot_short %} by providing input to the conversation, which will be used as context when making changes in the pull request. +1. Then follow the prompts to make your changes. -1. In Teams, mention the app in a thread by typing @{% data variables.product.github %}. -1. Type your message or request, then send it. Optionally, you can specify a repository or branch using the following syntax: +### Setting a default repository for a channel - ```text - @GitHub Add "Hello World" to the README in repo=REPO_OWNER/REPO_NAME branch=BRANCH_NAME - ``` +You can set a default repository for each private or public channel. You cannot set a default repository for direct messages with {% data variables.product.prodname_copilot_short %}. - The `repo` parameter tells {% data variables.copilot.copilot_cloud_agent %} which repository to use for the request, and the `branch` parameter specifies an existing branch of the repository that should be used as the base branch for a pull request. By default, {% data variables.product.prodname_copilot_short %} uses your configured default repository and the repository’s default branch. +If a channel does not have a default repository, {% data variables.product.prodname_copilot_short %} sets the repository you use in your first session in that channel as the channel's default repository. - {% data variables.product.prodname_copilot_short %} will initiate a {% data variables.copilot.copilot_cloud_agent_short %} session and respond with a summary of the changes it plans to make, including a link to the pull request it has created in the repository. +When you do not specify a repository or branch, {% data variables.product.prodname_copilot_short %} uses the channel's default repository and that repository's default branch. -You can continue to iterate on the pull request in the same Teams thread. Mention @{% data variables.product.github %} with your suggested change, and the {% data variables.copilot.copilot_cloud_agent %} will use all of the messages in the thread since the previous mention to iterate on the existing pull request. +1. In the channel, type `@{% data variables.product.github %} settings` and send the message. +1. Follow the prompts to select a default repository for the channel. ## Further reading diff --git a/content/copilot/how-tos/copilot-on-github/use-copilot-agents/research-plan-iterate.md b/content/copilot/how-tos/copilot-on-github/use-copilot-agents/research-plan-iterate.md index 2429cb16b921..bdf874188611 100644 --- a/content/copilot/how-tos/copilot-on-github/use-copilot-agents/research-plan-iterate.md +++ b/content/copilot/how-tos/copilot-on-github/use-copilot-agents/research-plan-iterate.md @@ -23,13 +23,13 @@ redirect_from: Sessions do not create pull requests automatically. To create one immediately, include that in your prompt—for example, "Create a pull request to ...". -> [!NOTE] These capabilities are only available with {% data variables.copilot.copilot_cloud_agent %} on {% data variables.product.prodname_dotcom_the_website %}. {% data variables.copilot.copilot_cloud_agent_short_cap_c %} integrations (such as Azure Boards, JIRA, Linear, Slack, or Teams) only support creating a pull request directly. +> [!NOTE] These capabilities are only available with {% data variables.copilot.copilot_cloud_agent %} on {% data variables.product.prodname_dotcom_the_website %}, and in {% data variables.release-phases.public_preview %} for the Teams integration. Other {% data variables.copilot.copilot_cloud_agent_short_cap_c %} integrations (such as Azure Boards, JIRA, Linear, or Slack) only support creating a pull request directly. ## Perform deep research Ask {% data variables.copilot.copilot_cloud_agent %} questions about a repository to understand how it works, find where to make a change, or confirm assumptions before planning. -1. Start a task from the agents tab, panel, dashboard, or {% data variables.copilot.copilot_chat_short %}. See [AUTOTITLE](/copilot/how-tos/copilot-on-github/use-copilot-agents/kick-off-a-task). +1. Start a task from the agents tab, panel, dashboard, {% data variables.copilot.copilot_chat_short %}, or from within a supported integration. See [AUTOTITLE](/copilot/how-tos/copilot-on-github/use-copilot-agents/kick-off-a-task). 1. Ask a question about the repository. For example: `Investigate performance issues in this app and suggest improvements.` diff --git a/content/copilot/reference/enterprise-administrators/enterprise-managed-settings.md b/content/copilot/reference/enterprise-administrators/enterprise-managed-settings.md index c38a8f497b1c..741ffc89422e 100644 --- a/content/copilot/reference/enterprise-administrators/enterprise-managed-settings.md +++ b/content/copilot/reference/enterprise-administrators/enterprise-managed-settings.md @@ -32,7 +32,7 @@ In {% data variables.copilot.copilot_cli_short %}, the `sandbox` key is an excep | Key | Purpose | {% data variables.copilot.copilot_cli_short %} | {% data variables.product.prodname_vscode_shortname %} | {% data variables.copilot.github_copilot_app %} | {% data variables.copilot.copilot_cloud_agent %} | {% data variables.product.prodname_jetbrains_ides %} | | --- | --- | --- | --- | --- | --- | --- | | `permissions.disableBypassPermissionsMode` | Disables bypass or YOLO-style allow-all behavior | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | -| `permissions.model` | Sets auto model selection as the default for new conversations | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | +| `model` | Sets auto model selection as the default for new conversations | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | | `enabledPlugins` | Enables or disables specific plugins by key | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | | `extraKnownMarketplaces` | Adds plugin marketplaces that users can access | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | | `strictKnownMarketplaces` | Restricts plugin installation to explicitly listed marketplaces | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | @@ -48,7 +48,7 @@ In {% data variables.copilot.copilot_cli_short %}, the `sandbox` key is an excep For server-managed deployments, the enterprise can apply different governance to groups of users based on their enterprise team membership. The enterprise defines all settings—team membership only determines which users receive a given set of values. -To make a key eligible for team-specific values, mark it as overridable in `{% data variables.copilot.managed_setting_file %}` using the `{ "overridable": }` syntax. An overridable key uses the team's value when set, or falls back to your enterprise default when the team leaves it unset. The `{ "overridable": }` syntax applies to the `permissions.model`, `permissions.disableBypassPermissionsMode`, `allowedMcpServers`, and `deniedMcpServers` keys. Keys not marked overridable remain an enterprise-level decision that teams can't modify. +To make a key eligible for team-specific values, mark it as overridable in `{% data variables.copilot.managed_setting_file %}` using the `{ "overridable": }` syntax. An overridable key uses the team's value when set, or falls back to your enterprise default when the team leaves it unset. The `{ "overridable": }` syntax applies to the `model`, `permissions.disableBypassPermissionsMode`, `allowedMcpServers`, and `deniedMcpServers` keys. Keys not marked overridable remain an enterprise-level decision that teams can't modify. `enabledPlugins` and `extraKnownMarketplaces` work additively. The enterprise `{% data variables.copilot.managed_setting_file %}` sets a baseline, and an enterprise team file can add more plugins and marketplaces on top of it. For the full setup steps, see [AUTOTITLE](/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/configure-enterprise-managed-settings#overriding-settings-for-specific-teams). @@ -58,9 +58,9 @@ The following example shows these keys in one managed settings file. ```json { + "model": "auto", "permissions": { - "disableBypassPermissionsMode": "disable", - "model": "auto" + "disableBypassPermissionsMode": "disable" }, "enabledPlugins": { "my-plugin@agent-skills": true @@ -148,6 +148,16 @@ Restricts plugin installation to only the marketplaces explicitly defined by the * `"hostPattern"` — requires `hostPattern` (regex matching marketplace hosts) * `"pathPattern"` — requires `pathPattern` (regex matching marketplace paths) +## model + +Sets auto model selection as the default for new conversations. See [AUTOTITLE](/copilot/concepts/models/auto-model-selection). + +* When you set `model` to `"auto"`, new sessions use Auto model unless the user specifies a different model on a per-conversation basis. +* This key is overridable by enterprise team mapping. In your `{% data variables.copilot.managed_setting_file %}`, use the `{ "overridable": "auto" }` syntax to specialize the key's configuration on a per-team basis. You can then set `"model": "unmanaged"` in a team settings file, providing a specialization that takes precedence over `{% data variables.copilot.managed_setting_file %}` for members of the subject team. + +> [!NOTE] +> `model` was originally documented as `permissions.model`. Clients still read the nested `permissions.model` value when the top-level `model` key is absent, but you should use the top-level `model` key in new configurations. + ## permissions ### disableBypassPermissionsMode @@ -161,13 +171,6 @@ When you set `disableBypassPermissionsMode` to `"disable"`, users cannot turn on * In the {% data variables.copilot.github_copilot_app %}, the "Allow all" setting for "Tool Permissions" is blocked in the sessions settings. * This key is overridable by enterprise team mapping. In your `{% data variables.copilot.managed_setting_file %}`, use the `{ "overridable": "disable" }` syntax to specialize the key's configuration on a per-team basis. You can then set `"disableBypassPermissionsMode": "unmanaged"` in a team settings file, providing a specialization that takes precedence over `{% data variables.copilot.managed_setting_file %}` for members of the subject team. -### model - -Sets auto model selection as the default for new conversations. See [AUTOTITLE](/copilot/concepts/models/auto-model-selection). - -* When you set `permissions.model` to `"auto"`, new sessions use Auto model unless the user specifies a different model on a per-conversation basis. -* This key is overridable by enterprise team mapping. In your `{% data variables.copilot.managed_setting_file %}`, use the `{ "overridable": "auto" }` syntax to specialize the key's configuration on a per-team basis. You can then set `"model": "unmanaged"` in a team settings file, providing a specialization that takes precedence over `{% data variables.copilot.managed_setting_file %}` for members of the subject team. - ## telemetry Configures OpenTelemetry export, routing {% data variables.product.prodname_copilot_short %} usage data to a collector of your choice. diff --git a/content/integrations/concepts/featured-github-integrations.md b/content/integrations/concepts/featured-github-integrations.md index 5fc755e80854..a79e4ea239e5 100644 --- a/content/integrations/concepts/featured-github-integrations.md +++ b/content/integrations/concepts/featured-github-integrations.md @@ -79,8 +79,12 @@ You can also open and close issues, comment on your issues and pull requests, ap For more information, see [AUTOTITLE](/integrations/how-tos/teams). -{% ifversion fpt or ghec %} +{% ifversion copilot %} + +You can also integrate the {% data variables.copilot.copilot_cloud_agent %} with your Microsoft Teams app, enabling you to use AI-powered coding assistance directly within your team's communication platform. + +Use {% data variables.copilot.copilot_cloud_agent %} in Microsoft Teams to collaborate with your team on agent-assisted work. You can @mention {% data variables.product.github %} in channels, threads, and direct messages to work alongside teammates and {% data variables.product.prodname_copilot_short %} on research, planning, and coding tasks. Teammates can add context, steer {% data variables.product.prodname_copilot_short %} sessions, monitor progress, and then review the resulting artifacts. -You can also integrate the {% data variables.copilot.copilot_cloud_agent %} with your Microsoft Teams app, enabling you to use AI-powered coding assistance directly within your team's communication platform. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-teams) for more information. +See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-teams) for more information. {% endif %} diff --git a/content/integrations/how-tos/teams/customize-notifications.md b/content/integrations/how-tos/teams/customize-notifications.md index dfeac8b0b668..d01f0606f26c 100644 --- a/content/integrations/how-tos/teams/customize-notifications.md +++ b/content/integrations/how-tos/teams/customize-notifications.md @@ -15,7 +15,7 @@ You can customize your notifications by subscribing to activity that is relevant ### Notifications enabled by default -The following notifications are enabled by default, but you can disable any of them using the `@GitHub Notifications unsubscribe owner/repo [feature]` command. +The following notifications are enabled by default, but you can disable any of them using the `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe OWNER/REPO [FEATURE]` command. |Feature|Description| |-------|-----------| @@ -31,7 +31,7 @@ The following notifications are enabled by default, but you can disable any of t ### Notifications disabled by default -The following notifications are disabled by default, but you can enable any of them using the `@GitHub Notifications subscribe owner/repo [feature]` command. +The following notifications are disabled by default, but you can enable any of them using the `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe owner/repo [FEATURE]` command. |Feature|Description| |-------|-----------| @@ -39,12 +39,12 @@ The following notifications are disabled by default, but you can enable any of t |`workflows`|{% data variables.product.prodname_actions %} workflow runs and approval notifications.| |`branches`|Branch creation and deletion.| |`discussions`|Discussions created or answered.| -|`+label:"your label"`|Filter issues, pull requests, and comments based on their labels.| +|`+label:"YOUR-LABEL"`|Filter issues, pull requests, and comments based on their labels.| You can subscribe or unsubscribe from multiple settings at once. For example: -* To turn on activity for pull request reviews and comments, use `@GitHub Notifications subscribe owner/repo reviews comments`. -* To turn off activity for issues and pull requests, use `@GitHub Notifications unsubscribe owner/repo issues pulls`. +* To turn on activity for pull request reviews and comments, use `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO reviews comments`. +* To turn off activity for issues and pull requests, use `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe OWNER/REPO issues pulls`. ## Filtering notifications @@ -56,12 +56,12 @@ Branch filters allow you to filter commit notifications based on branch names. B |Example configuration|Description| |-------|-----------| -|`@GitHub Notifications subscribe owner/repo commits`|Receive commit notifications for the default branch.| -|`@GitHub Notifications subscribe owner/repo commits:main`|Only receive commit notifications for the `main` branch.| -|`@GitHub Notifications subscribe owner/repo commits:feature/*`|Receive commit notifications for all branches that start with `feature/`.| -|`@GitHub Notifications subscribe owner/repo commits:*`|Receive commit notifications for all branches.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO commits`|Receive commit notifications for the default branch.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO commits:main`|Only receive commit notifications for the `main` branch.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO commits:feature/*`|Receive commit notifications for all branches that start with `feature/`.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO commits:*`|Receive commit notifications for all branches.| -You can unsubscribe from the commits feature using `@GitHub Notifications unsubscribe owner/repo commits`. +You can unsubscribe from the commits feature using `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe OWNER/REPO commits`. >[!NOTE] You may have previously used the `commits:all` filter to receive commit notifications for all branches. This filter is {% data variables.release-phases.closing_down %}. To receive commit notifications for all branches, use the `commits:*` filter instead. If you have previously set up the `commits:all` filter, it will continue to work until you update your configuration to use the `commits:*` filter. @@ -85,37 +85,37 @@ Currently, it is only possible to have one required label filter per repository. To create a label filter, use the following command format: ```text copy -@GitHub Notifications subscribe [owner/repo] +label:"your label" +@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe [OWNER/REPO] +label:"YOUR-LABEL" ``` -This creates a required-label filter with the value `your label`. Incoming events that support filters are discarded unless they have that label. +This creates a required-label filter with the value `YOUR-LABEL`. Incoming events that support filters are discarded unless they have that label. #### Updating label filters -You can update an existing label filter by specifying a new label value: +You can update an existing label filter by specifying a NEW-LABEL value: ```text copy -@GitHub Notifications subscribe [owner/repo] +label:"new label" +@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe [OWNER/REPO] +label:"NEW-LABEL" ``` -This will replace the "your label" filter with the "new label" filter. +This will replace the "YOUR-LABEL" filter with the "NEW-LABEL" filter. #### Removing label filters You can remove an existing label filter by using the unsubscribe command with the `+label` option: ```text copy -@GitHub Notifications unsubscribe [owner/repo] +label:"new label" +@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe [OWNER/REPO] +label:"NEW-LABEL" ``` -This will remove the "new label" filter, and the channel will receive all notifications for the subscribed events without any label filtering. +This will remove the "NEW-LABEL" filter, and the channel will receive all notifications for the subscribed events without any label filtering. #### Viewing active label filters To view the currently active label filters for a channel, use the following command: ```text copy -@GitHub Notifications subscribe list features +@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe list features ``` #### Valid filters @@ -124,7 +124,7 @@ The {% data variables.product.github %} app in Teams supports the most common sp ## {% data variables.product.prodname_actions %} workflow notifications -You can subscribe to {% data variables.product.prodname_actions %} workflow run notifications from your channel or personal app using "workflows" feature, using the format `@GitHub Notifications subscribe owner/repo workflows`. +You can subscribe to {% data variables.product.prodname_actions %} workflow run notifications from your channel or personal app using "workflows" feature, using the format `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO workflows`. When you are subscribed to "workflows", the following functionality is available: @@ -149,18 +149,18 @@ You can filter workflow notifications by using the following options: You can configure workflow notification filters with the following format: ```text copy -@GitHub Notifications subscribe owner/repo workflows:{name:"your workflow name" event:"workflow event" branch:"branch name" actor:"username"} +@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO workflows:{name:"YOUR-WORKFLOW-NAME" event:"WORKFLOW-EVENT" branch:"BRANCH-NAME" actor:"USERNAME"} ``` You can also pass multiple values for each filter, separated by commas. For example: ```text copy -@GitHub Notifications subscribe owner/repo workflows:{name:"your workflow name","another workflow name" event:"workflow event","another workflow event" branch:"branch name","another branch name" actor:"username","another-username"} +@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO workflows:{name:"YOUR-WORKFLOW-NAME","ANOTHER-WORKFLOW-NAME" event:"WORKFLOW-EVENT","ANOTHER-WORKFLOW-EVENT" branch:"BRANCH-NAME","ANOTHER-BRANCH-NAME" actor:"USERNAME","ANOTHER-USERNAME"} ``` By default, when you configure workflow notifications without passing any filters, it is configured for workflows triggered via pull requests targeting your default branch. You can pass one or multiple entries. -You can unsubscribe from workflow notifications using the command: `@GitHub Notifications unsubscribe owner/repo workflows`. +You can unsubscribe from workflow notifications using the command: `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe OWNER/REPO workflows`. >[!NOTE] To receive {% data variables.product.prodname_actions %} notifications in Teams, the {% data variables.product.github %} app requires additional permissions. When you attempt to subscribe to workflows for the first time, you will be prompted to grant these permissions. @@ -171,8 +171,8 @@ You can also configure separate deployment notifications. These deployments can You can subscribe or unsubscribe to deployment notifications using the following commands: ```text copy -@GitHub Notifications subscribe owner/repo deployments -@GitHub Notifications unsubscribe owner/repo deployments +@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO deployments +@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe OWNER/REPO deployments ``` >[!NOTE] If you are using {% data variables.product.prodname_actions %} and want to track your deployments to environments, the `workflows` feature is recommended, as it provides a more complete picture and the ability to approve your deployments directly from Teams. diff --git a/content/integrations/how-tos/teams/integrate-github-with-teams.md b/content/integrations/how-tos/teams/integrate-github-with-teams.md index 9110289f3071..e75cbd938270 100644 --- a/content/integrations/how-tos/teams/integrate-github-with-teams.md +++ b/content/integrations/how-tos/teams/integrate-github-with-teams.md @@ -13,15 +13,21 @@ category: ## About the {% data variables.product.github %} integration for Teams -The {% data variables.product.github %} integration for Microsoft Teams gives you and your teams visibility into your {% data variables.product.github %} projects directly in Teams channels. You can triage issues, collaborate on pull requests, and keep track of changes without leaving Teams. +The {% data variables.product.github %} integration for Microsoft Teams gives you and your teams visibility into your {% data variables.product.github %} projects directly in Teams channels. You can {% ifversion copilot %}work with {% data variables.copilot.copilot_cloud_agent %} to research, plan and triage in conversations, create artifacts such as issues and pull requests, start and steer agent sessions,{% else %}triage issues, collaborate on pull requests, {% endif %} and keep track of changes without leaving Teams. With the {% data variables.product.github %} integration for Teams, you can: * Get **{% data variables.product.github %} notifications** in Teams channels. * Use **commands** to take actions on {% data variables.product.github %}. * See **previews** when sharing links to {% data variables.product.github %} resources. -{% ifversion fpt or ghec %} -* Initiate a {% data variables.copilot.copilot_cloud_agent %} session from Teams, using the context of a Teams thread. + +{% ifversion copilot %} + +* **Initiate and steer {% data variables.copilot.copilot_cloud_agent %} sessions** in a conversation. Teammates can collaborate with each other and the agent, add context, correct assumptions, continue an agent task, and review the resulting plan, issues, pull requests and other artifacts. + + > [!NOTE] + > * This feature is currently in {% data variables.release-phases.public_preview %} and subject to change. + {% endif %} {% data reusables.integrations.github-teams-permissions %} @@ -33,14 +39,18 @@ To use the {% data variables.product.github %} integration for Teams, you need: * A {% data variables.product.github %} account. * A Teams workspace where you have permission to install apps. -{% ifversion not ghes %} +{% ifversion copilot %} + +* You must have Microsoft Public Developer Preview enabled for your Microsoft Teams client, see [Public developer preview for Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/dev-preview/developer-preview-intro) in the Microsoft Learn documentation. +{% data reusables.copilot.cloud-agent.cloud-sandboxes-prerequisite-teams %} ## Installing the {% data variables.product.github %} integration for Teams in a single workspace 1. Go to the [{% data variables.product.github %} integration for Teams](https://teams.microsoft.com/l/app/ca9e26b7-dce5-44a0-b2b7-a70a3d65ce25) listing in the Teams app store. 1. Click **Add**. 1. Follow the prompts to sign in to Teams and approve access. -1. In Teams, run `@GitHub Notifications signin` and follow the prompts to connect your {% data variables.product.github %} account. +1. In a Teams message or channel, @mention the app by typing `@{% data variables.product.github %}` and follow the prompts to connect your {% data variables.product.github %} account. +1. To see what else you can do, in the thread, @mention the app by typing `@{% data variables.product.github %} help`. {% ifversion ghec %} @@ -99,3 +109,6 @@ To integrate {% data variables.product.prodname_ghe_server %} with Microsoft Tea * [AUTOTITLE](/integrations/how-tos/teams/use-github-in-teams) - Learn how to use the {% data variables.product.github %} integration for Teams. * [AUTOTITLE](/integrations/how-tos/teams/customize-notifications) - Learn how to customize your {% data variables.product.github %} notifications in Teams. +{% ifversion copilot %} +* [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-teams) - Learn about {% data variables.copilot.copilot_cloud_agent %} with Teams. +{% endif %} diff --git a/content/integrations/how-tos/teams/schedule-reminders.md b/content/integrations/how-tos/teams/schedule-reminders.md index ffeecc6cb1a4..5904ea4de0ff 100644 --- a/content/integrations/how-tos/teams/schedule-reminders.md +++ b/content/integrations/how-tos/teams/schedule-reminders.md @@ -15,12 +15,12 @@ You can schedule reminders for pending pull request reviews in Microsoft Teams c ## Scheduling reminders in a channel -1. In a Teams channel, run `@GitHub Notifications schedule ORGANIZATION`. +1. In a Teams channel, run `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} schedule ORGANIZATION`. 1. Select **Create new reminder**. 1. Configure the days, times, timezone, and repository or team filters for the reminder. 1. Save the reminder. -To edit or remove reminders for the organization, run `@GitHub Notifications schedule ORGANIZATION` again. To list all reminders configured in the channel, run `@GitHub Notifications schedule list`. +To edit or remove reminders for the organization, run `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} schedule ORGANIZATION` again. To list all reminders configured in the channel, run `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} schedule list`. ## Scheduling reminders in the personal app diff --git a/content/integrations/how-tos/teams/use-github-in-teams.md b/content/integrations/how-tos/teams/use-github-in-teams.md index 43f42f79177d..1f578e6005d9 100644 --- a/content/integrations/how-tos/teams/use-github-in-teams.md +++ b/content/integrations/how-tos/teams/use-github-in-teams.md @@ -13,35 +13,59 @@ category: The {% data variables.product.github %} integration for Microsoft Teams lets you connect your {% data variables.product.github %} account to the {% data variables.product.github %} app in Teams. Once connected, you can subscribe to notifications, run commands, and collaborate on issues and pull requests directly within Teams. +{% ifversion copilot %} + +You can also use the {% data variables.product.github %} integration to initiate and steer {% data variables.copilot.copilot_cloud_agent %} sessions in a conversation, including asking {% data variables.product.prodname_copilot_short %} to perform deep research, planning and triage tasks within a thread. Teammates can collaborate with each other and the agent, add context, correct assumptions, continue an agent task, and review the resulting artifacts. + +> [!NOTE] +> * {% data variables.product.prodname_copilot %} in Teams is currently in {% data variables.release-phases.public_preview %} and subject to change. + +{% endif %} + ## Connecting your {% data variables.product.github %} account to the {% data variables.product.github %} app in Teams >[!NOTE] Before you can connect your accounts, an admin for your Teams workspace must have installed the {% data variables.product.github %} app. See [AUTOTITLE](/integrations/how-tos/teams/integrate-github-with-teams). 1. In Teams, open a direct message or personal app conversation with the {% data variables.product.github %} app. -1. Run `@GitHub Notifications signin` and follow the prompts in Teams and in your browser to authorize the connection. +1. Run {% ifversion copilot %}`@{% data variables.product.github %}`{% else %}`@{% data variables.product.github %} Notifications signin`{% endif %} and follow the prompts in Teams and in your browser to authorize the connection. Once your {% data variables.product.github %} account is connected, Teams will show you a list of available commands and features. -## Using commands in Teams +## Using commands for notifications in Teams -In channels, start commands with `@GitHub Notifications`. In the personal app, omit the prefix. For the full list of commands, see [AUTOTITLE](/integrations/reference/teams-command-reference). +In channels, start commands with {% ifversion copilot %}`@{% data variables.product.github %}`{% else %}`@{% data variables.product.github %} Notifications`{% endif %}. In the personal app, omit the prefix. For the full list of commands, see [AUTOTITLE](/integrations/reference/teams-command-reference). |Command|Description| |---|---| -|`@GitHub Notifications subscribe owner/repo`|Subscribes the channel to notifications for the specified repository.| -|`@GitHub Notifications unsubscribe owner/repo`|Unsubscribes the channel from notifications for the specified repository.| -|`@GitHub Notifications subscribe list`|Lists all repositories the channel is subscribed to.| -|`@GitHub Notifications subscribe list features`|Lists all repositories and notification features the channel is subscribed to.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO`|Subscribes the channel to notifications for the specified repository.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe OWNER/REPO`|Unsubscribes the channel from notifications for the specified repository.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe list`|Lists all repositories the channel is subscribed to.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe list features`|Lists all repositories and notification features the channel is subscribed to.| >[!NOTE] When you subscribe a channel to a repository, you may be prompted to install the {% data variables.product.github %} app and grant access to the repository or organization. ## Working with issues and pull requests +{% ifversion copilot %} + +You can create, comment on, and manage issues and pull requests directly from Teams with or without using {% data variables.product.prodname_copilot_short %}. + +To have {% data variables.product.prodname_copilot_short %} perform an action, @mention the app in any Teams chat by typing `@{% data variables.product.github %}` followed by your task, and see [Initiating {% data variables.copilot.copilot_cloud_agent %} sessions within Teams](#initiating--data-variablescopilotcopilot_cloud_agent--sessions-within-teams) below. + +> [!NOTE] +> {% data reusables.copilot.cloud-agent.unattributed-additional-approval-note %} + +For step-by-step instructions to work with issues and pull requests independent of {% data variables.product.prodname_copilot_short %}, see [AUTOTITLE](/integrations/tutorials/teams/create-issues) and [AUTOTITLE](/integrations/tutorials/teams/manage-issues). + +{% else %} + You can create, comment on, and manage issues and pull requests directly from Teams. For step-by-step instructions, see: * [AUTOTITLE](/integrations/tutorials/teams/create-issues) * [AUTOTITLE](/integrations/tutorials/teams/manage-issues) +{% endif %} + ## Mentions in Teams When you subscribe to a repository in Teams, you will see yourself mentioned in notifications for repository events in which you have been referenced. Mentions require you to be logged in to your {% data variables.product.github %} account through the {% data variables.product.github %} app in Teams. @@ -79,17 +103,30 @@ Previews of links will not be shown if any of the following apply: ## Personal app experience -The {% data variables.product.github %} personal app in Teams lets you manage subscriptions and receive notifications in a private chat. In the personal app, commands do not require the `@GitHub Notifications` prefix and notifications are not threaded. +The {% data variables.product.github %} personal app in Teams lets you manage subscriptions and receive notifications in a private chat. In the personal app, commands do not require the {% ifversion copilot %}`@{% data variables.product.github %}`{% else %}`@{% data variables.product.github %} Notifications`{% endif %} prefix and notifications are not threaded. ## Scheduling reminders for pull request reviews You can schedule reminders for pending pull request reviews in channels or in the personal app. For instructions, see [AUTOTITLE](/integrations/how-tos/teams/schedule-reminders). -{% ifversion fpt or ghec %} +{% ifversion copilot %} ## Initiating {% data variables.copilot.copilot_cloud_agent %} sessions within Teams -The {% data variables.product.github %} app integrates {% data variables.copilot.copilot_cloud_agent %} into Teams. You can summon {% data variables.copilot.copilot_cloud_agent %} in threads where discussions are taking place and ask it to make changes based on the context of those discussions. For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-teams). +The {% data variables.product.github %} app integrates {% data variables.copilot.copilot_cloud_agent %} into Teams. You can summon {% data variables.copilot.copilot_cloud_agent %} in threads where discussions are taking place and ask it to make changes based on the context of those discussions. + +Use {% data variables.product.prodname_copilot_short %} in direct messages, threads, and channels. Besides creating issues, pull requests and other artifacts, working with {% data variables.product.prodname_copilot_short %} in Teams allows you to: + +* Move directly from discussion to investigation and implementation. +* Ask questions and investigate failures. +* Plan work before implementation. +* Collaboratively steer an agent with teammates. +* Delegate work from any device. +* Let tasks run asynchronously. +* Review the resulting work in the open. +* Resume work on the agent-generated artifacts outside of Teams, in {% data variables.product.github %}, the terminal, or your preferred code editor. + +For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/integrate-cloud-agent-with-teams). {% endif %} diff --git a/content/integrations/reference/teams-command-reference.md b/content/integrations/reference/teams-command-reference.md index 8294babc9b5c..ada7ee382bcd 100644 --- a/content/integrations/reference/teams-command-reference.md +++ b/content/integrations/reference/teams-command-reference.md @@ -12,20 +12,20 @@ category: - Learn about integrations --- -Use these commands in a Microsoft Teams channel by prefixing them with `@GitHub Notifications`. In the {% data variables.product.github %} personal app, omit the prefix. +Use these commands in a Microsoft Teams channel by prefixing them with `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %}`. In the {% data variables.product.github %} personal app, omit the prefix. |Command|Description| |---|---| -|`@GitHub Notifications help`|Display help documentation.| -|`@GitHub Notifications signin`|Connect your {% data variables.product.github %} account.| -|`@GitHub Notifications subscribe owner/repo`|Subscribe a channel to a repository.| -|`@GitHub Notifications subscribe owner/repo [feature]`|Subscribe a channel to specific notification features.| -|`@GitHub Notifications subscribe list`|List subscriptions in the channel.| -|`@GitHub Notifications subscribe list features`|List subscriptions and subscribed features in the channel.| -|`@GitHub Notifications unsubscribe owner/repo`|Unsubscribe a channel from a repository.| -|`@GitHub Notifications unsubscribe owner/repo [feature]`|Unsubscribe a channel from specific features.| -|`@GitHub Notifications schedule ORGANIZATION`|List and manage reminders for the organization in this channel.| -|`@GitHub Notifications schedule list`|List all reminders configured in this channel.| -|`@GitHub Notifications signout`|Disconnect your {% data variables.product.github %} account and remove subscriptions.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} help`|Display help documentation.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} signin`|Connect your {% data variables.product.github %} account.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO`|Subscribe a channel to a repository.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe OWNER/REPO [feature]`|Subscribe a channel to specific notification features.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe list`|List subscriptions in the channel.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} subscribe list features`|List subscriptions and subscribed features in the channel.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe OWNER/REPO`|Unsubscribe a channel from a repository.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} unsubscribe OWNER/REPO [feature]`|Unsubscribe a channel from specific features.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} schedule ORGANIZATION`|List and manage reminders for the organization in this channel.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} schedule list`|List all reminders configured in this channel.| +|`@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %} signout`|Disconnect your {% data variables.product.github %} account and remove subscriptions.| For the list of supported notification features, see [AUTOTITLE](/integrations/how-tos/teams/customize-notifications). diff --git a/content/integrations/reference/teams-permissions.md b/content/integrations/reference/teams-permissions.md index cd4676801d6b..5366ff211cf2 100644 --- a/content/integrations/reference/teams-permissions.md +++ b/content/integrations/reference/teams-permissions.md @@ -21,7 +21,7 @@ When you install the {% data variables.product.github %} app in your Teams works |----------------|--------------| |Access private conversations between you and the App | To message you with instructions. | |Add link previews to {% data variables.product.prodname_dotcom %} to messages| To render rich links to `github.com`.| -|Add {% data variables.product.github %} commands| To add the `@GitHub Notifications` command to your Teams channels. | +|Add {% data variables.product.github %} commands| To add the `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %}` command to your Teams channels. | |View the workspace or organization's name, email domain, and icon| To store subscriptions you set up.| |Post messages as the app| To notify you of activity that happens on {% data variables.product.github %}, in Teams.| @@ -35,7 +35,7 @@ When you connect your {% data variables.product.github %} account to the {% data |Read access to code| To render code snippets in Teams.| |Write access to actions, issues, and pull requests | To take action from Teams with cards and commands.| -{% ifversion fpt or ghec %} +{% ifversion copilot %} ## Additional permissions for {% data variables.copilot.copilot_cloud_agent %} diff --git a/content/integrations/tutorials/teams/create-issues.md b/content/integrations/tutorials/teams/create-issues.md index c91a74ad828b..d8f3cf8d0624 100644 --- a/content/integrations/tutorials/teams/create-issues.md +++ b/content/integrations/tutorials/teams/create-issues.md @@ -25,4 +25,4 @@ With the {% data variables.product.github %} integration in Microsoft Teams, you 1. Click **Create** to create the issue. You will receive a confirmation card in the channel from where you initiated the issue creation. -Alternatively, you can create an issue by invoking `@GitHub Notifications` from the chat in your channel or personal app. +Alternatively, you can create an issue by invoking `@{% data variables.product.github %}{% ifversion ghes %} Notifications{% endif %}` from the chat in your channel or personal app. diff --git a/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets.md b/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets.md index 4cb29eceb63d..669bec1fb20b 100644 --- a/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets.md +++ b/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets.md @@ -132,6 +132,23 @@ Optionally, you can require all comments on the pull request to be resolved befo Optionally, you can require a merge type of merge, squash, or rebase. This means the targeted branches may only be merged based on the allowed type. Additionally if the repository has disabled a merge method and the ruleset required a different method, the merge will be blocked. See [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/about-merge-methods-on-github). {% endif %} +{% ifversion repo-rules-copilot-extra-approval %} + +#### Additional approval for unattributed {% data variables.product.prodname_copilot_short %} pull requests + +> [!NOTE] +> This feature is in {% data variables.release-phases.public_preview %} and subject to change. + +**Require an additional approval for unattributed {% data variables.product.prodname_copilot_short %} pull requests** is enabled by default, for both new and existing rulesets. When {% data variables.product.prodname_copilot_short %} opens a pull request that isn't attributed to a person, the ruleset requires one more approval than the number you configured. For example, a ruleset that requires one approval requires two approvals from people with write access. + +Requiring one approval usually means two people are involved in a change: the person who wrote it and the person who approved it. That assumption doesn't hold when {% data variables.product.prodname_copilot_short %} opens a pull request under its own app identity instead of on behalf of a person, for example when you prompt it from a shared context such as a group thread or channel. See [AUTOTITLE](/copilot/how-tos/copilot-integrations/integrate-cloud-agent-with-slack) and [AUTOTITLE](/copilot/how-tos/copilot-integrations/integrate-cloud-agent-with-teams). + +This setting has no effect if the ruleset requires zero approvals, so repositories that use pull requests as a record of changes rather than to gate on approvals are unaffected. + +If you clear this setting, these pull requests require only the number of approvals you configured. If you also require an approval from someone other than the last person to push, at least one approval must cover the last push and come from someone other than {% data variables.product.prodname_copilot_short %}. + +{% endif %} + {% ifversion repo-rules-required-reviewer %} #### Required reviewers @@ -225,8 +242,8 @@ If your repository has {% data variables.product.prodname_code_quality %} enable This rule blocks a pull request from being merged when either of two code coverage thresholds is not met: -* **Minimum coverage percentage**: the aggregated code coverage for the pull request branch is below the configured percentage. -* **Maximum coverage drop**: code coverage drops by more than the configured number of percentage points relative to the default branch. +* **Minimum line coverage percentage**: the aggregated line coverage for the pull request branch is below the configured percentage. +* **Maximum line coverage drop**: line coverage drops by more than the configured number of percentage points relative to the default branch. For how to configure the thresholds, the prerequisite for uploading coverage data, and how to roll the rule out safely, see [AUTOTITLE](/code-security/how-tos/maintain-quality-code/restrict-code-coverage). diff --git a/data/features/repo-rules-copilot-extra-approval.yml b/data/features/repo-rules-copilot-extra-approval.yml new file mode 100644 index 000000000000..3738d6cd06f5 --- /dev/null +++ b/data/features/repo-rules-copilot-extra-approval.yml @@ -0,0 +1,6 @@ +# Reference: https://github.com/github/repos-security/discussions/1485 +# Public preview for requiring an additional approval on unattributed Copilot pull requests + +versions: + fpt: '*' + ghec: '*' diff --git a/data/reusables/copilot/cloud-agent/cloud-sandboxes-prerequisite-teams.md b/data/reusables/copilot/cloud-agent/cloud-sandboxes-prerequisite-teams.md new file mode 100644 index 000000000000..8989a1cc6f96 --- /dev/null +++ b/data/reusables/copilot/cloud-agent/cloud-sandboxes-prerequisite-teams.md @@ -0,0 +1,4 @@ +* To use {% data variables.copilot.copilot_cloud_agent %}, you must have cloud sandboxes enabled for your {% data variables.product.prodname_copilot_short %} plan. See [Cloud sandboxing for {% data variables.product.prodname_copilot %}](/copilot/concepts/about-cloud-and-local-sandboxes#cloud-sandboxing). + + > [!NOTE] + > Cloud sandbox policies share the same configuration as {% data variables.copilot.copilot_cloud_agent %} policies. Members of an organization or enterprise, including an {% data variables.enterprise.prodname_emu_enterprise %} may need their owner to enable cloud sandboxes and {% data variables.copilot.copilot_cloud_agent %} before they can use {% data variables.product.prodname_copilot_short %} in Teams. See [AUTOTITLE](/copilot/how-tos/cloud-and-local-sandboxes/enabling-or-disabling-cloud-sandboxes-for-your-organization). diff --git a/data/reusables/copilot/cloud-agent/unattributed-additional-approval-note.md b/data/reusables/copilot/cloud-agent/unattributed-additional-approval-note.md new file mode 100644 index 000000000000..04155dc8895d --- /dev/null +++ b/data/reusables/copilot/cloud-agent/unattributed-additional-approval-note.md @@ -0,0 +1 @@ +Pull requests created in a shared context by {% data variables.product.prodname_copilot_short %} use the app's identity. If you use repository rulesets, because these pull requests aren't attributed to a person, one more approval is required before merging, as long as the repository already requires at least one approval. This is enabled by default. See [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#additional-approval-for-unattributed-copilot-pull-requests). diff --git a/data/reusables/copilot/plans/ai-credits-by-plan.md b/data/reusables/copilot/plans/ai-credits-by-plan.md index 533f4e8fdb1a..12d4f645f99d 100644 --- a/data/reusables/copilot/plans/ai-credits-by-plan.md +++ b/data/reusables/copilot/plans/ai-credits-by-plan.md @@ -3,5 +3,3 @@ | {% data variables.copilot.copilot_pro_short %} | {% data variables.copilot.cfi_price_per_month %} | {% data variables.copilot.ai_credits_per_user_pro %} | {% data variables.copilot.ai_credits_per_user_pro_flex %} | {% data variables.copilot.ai_credits_per_user_pro_total %} | | {% data variables.copilot.copilot_pro_plus_short %} | {% data variables.copilot.cpp_price_per_month %} | {% data variables.copilot.ai_credits_per_user_pro_plus %} | {% data variables.copilot.ai_credits_per_user_pro_plus_flex %} | {% data variables.copilot.ai_credits_per_user_pro_plus_total %} | | {% data variables.copilot.copilot_max_short %} | {% data variables.copilot.cm_price_per_month %} | {% data variables.copilot.ai_credits_per_user_max %} | {% data variables.copilot.ai_credits_per_user_max_flex %} | {% data variables.copilot.ai_credits_per_user_max_total %} | - -{% data variables.copilot.copilot_free_short %} and {% data variables.copilot.copilot_student_short %} both have an allowance of {% data variables.product.prodname_ai_credits_short %} and access to models through {% data variables.copilot.copilot_auto_model_selection_short %} only. {% data variables.copilot.copilot_free_short %} includes 2000 code completions per month and {% data variables.copilot.copilot_student_short %} includes unlimited code completions. diff --git a/src/links/lib/link-report.ts b/src/links/lib/link-report.ts index adedb620c92d..1368745ff31d 100644 --- a/src/links/lib/link-report.ts +++ b/src/links/lib/link-report.ts @@ -116,9 +116,14 @@ ${summary} const suggestion = group.suggestion ? `💡 ${group.suggestion}\n\n` : '' - const tableRows = group.occurrences + const listedOccurrences = group.occurrences.slice(0, MAX_FILES_PER_GROUP) + const hiddenOccurrences = group.occurrences.length - listedOccurrences.length + const tableRows = listedOccurrences .map((occ) => `| \`${occ.file}\` | ${occ.lines.join(', ')} |`) .join('\n') + const moreFiles = hiddenOccurrences + ? `\n\nAnd ${hiddenOccurrences} more file${hiddenOccurrences === 1 ? '' : 's'}, listed in the report attached to the workflow run.` + : '' return `### ${icon} \`${group.target}\` @@ -126,7 +131,7 @@ ${statusInfo}${suggestion}**Found in ${count} file${plural}:** | File | Line(s) | |------|---------| -${tableRows}` +${tableRows}${moreFiles}` }, // Self-referential links section @@ -550,6 +555,48 @@ export type FixStrategy = 'codemod' | 'versionless' | 'anchor' | 'decide' */ const MAX_LISTED_CODEMOD_PATHS = 8 +/** + * How many rows of the codemod table to print. The codemod does this work, so the full list + * is reference material, not a task list. Printing all of it costs more than half the issue + * body budget, and the complete list is in the workflow artifact either way. + */ +const MAX_CODEMOD_ROWS = 40 + +/** + * How many stale anchors to print. This bucket is real work, but 70-plus entries is more + * than anyone picks up in a week, and each entry costs several times a table row because it + * lists every file the link appears in. The rest are in the workflow artifact. + */ +const MAX_ANCHOR_GROUPS = 25 + +/** + * How many version-only redirects to print. This bucket needs no action at all, so the list + * exists to show what was ruled out, not to be worked through. + */ +const MAX_VERSIONLESS_ROWS = 25 + +/** + * How many files to list under a single broken link. Nothing bounds how many pages reuse + * one link, so without this a single popular link could fill the issue body on its own. The + * busiest link in the current eight-version data appears in 31 files, so this does not + * trigger today. + */ +const MAX_FILES_PER_GROUP = 20 + +/** + * Split a list at a cap and describe what is missing, so no section can grow without bound. + * GitHub rejects issue bodies over 65,536 characters and the workflow truncates at 60,000 + * with a blind slice, which can cut a table in half. + */ +function capGroups( + groups: GroupedBrokenLinks[], + max: number, +): { listed: GroupedBrokenLinks[]; hidden: number } { + // Most-used links first, so the truncated tail is the least interesting part. + const byOccurrences = [...groups].sort((a, b) => b.occurrences.length - a.occurrences.length) + return { listed: byOccurrences.slice(0, max), hidden: Math.max(0, groups.length - max) } +} + export function classifyFixStrategy(group: GroupedBrokenLinks): FixStrategy { const redirectTargets = group.occurrences .map((occ) => occ.redirectTarget) @@ -624,7 +671,10 @@ function renderCodemodSection(groups: GroupedBrokenLinks[], versionsChecked?: st describeVersions(groupVersions(group), versionsChecked) const showVersions = groups.some((group) => versionFor(group)) - const rows = groups + // Most-used links first, so the truncated tail is the least interesting part. + const { listed, hidden } = capGroups(groups, MAX_CODEMOD_ROWS) + + const rows = listed .map((group) => { const target = group.occurrences.find((occ) => occ.redirectTarget)?.redirectTarget ?? '' const cells = [`\`${group.target}\``, `\`${target}\``, `${group.occurrences.length}`] @@ -633,6 +683,10 @@ function renderCodemodSection(groups: GroupedBrokenLinks[], versionsChecked?: st }) .join('\n') + const truncationNote = hidden + ? `\n\nAnd ${hidden} more. The codemod fixes every one of them, so this list is reference only. The full report is attached to the workflow run.` + : '' + const flags = '--keep-stale-fragments --dont-set-autotitle' const paths = codemodPaths(groups) const tooManyToList = paths.length > MAX_LISTED_CODEMOD_PATHS @@ -664,7 +718,7 @@ Review the diff, then open a pull request. | From | To | Occurrences |${showVersions ? ' Versions |' : ''} |------|-----|-------------|${showVersions ? '----------|' : ''} -${rows} +${rows}${truncationNote}
` } @@ -678,13 +732,18 @@ ${rows} * alone and so should writers. */ function renderVersionlessSection(groups: GroupedBrokenLinks[]): string { - const rows = groups + const { listed, hidden } = capGroups(groups, MAX_VERSIONLESS_ROWS) + const rows = listed .map((group) => { const target = group.occurrences.find((occ) => occ.redirectTarget)?.redirectTarget ?? '' return `| \`${group.target}\` | \`${target}\` |` }) .join('\n') + const truncationNote = hidden + ? `\n\nAnd ${hidden} more in the same state. The list is cut short because this bucket is here to show what was ruled out, not to be worked through. The full report is attached to the workflow run.` + : '' + const plural = groups.length === 1 ? '' : 's' const occurrences = occurrenceCount(groups) @@ -701,7 +760,7 @@ should differ per version. | Link | Resolves to | |------|-------------| -${rows} +${rows}${truncationNote} ` } @@ -712,19 +771,24 @@ function renderManualSection( groups: GroupedBrokenLinks[], isExternal: boolean, versionsChecked?: string[], + maxGroups?: number, ): string { - const sections = groups + const { listed, hidden } = capGroups(groups, maxGroups ?? groups.length) + const sections = listed .map((group) => { const versions = describeVersions(groupVersions(group), versionsChecked) const note = versions ? `\n\n**Only in:** ${versions}` : '' return TEMPLATES.group(group, isExternal) + note }) .join('\n\n') + const truncationNote = hidden + ? `\n\nAnd ${hidden} more, listed in the report attached to the workflow run. Only the busiest are shown here, to keep the issue readable. Fixing the ones above moves some of the rest into view on the next run, but a link that is not shown is not fixed: use the artifact to work through the tail.` + : '' return `## ${heading} (${groups.length} link${groups.length === 1 ? '' : 's'}, ${occurrenceCount(groups)} occurrence${occurrenceCount(groups) === 1 ? '' : 's'}) ${blurb} -${sections}` +${sections}${truncationNote}` } /** @@ -771,6 +835,7 @@ Work top to bottom. Bucket 1 is usually most of the report and costs one command anchors, isExternal, versionsChecked, + MAX_ANCHOR_GROUPS, ), ) } diff --git a/src/links/tests/link-report.ts b/src/links/tests/link-report.ts index 23a5665e3fd4..5752df10ce8b 100644 --- a/src/links/tests/link-report.ts +++ b/src/links/tests/link-report.ts @@ -720,6 +720,45 @@ describe('describeVersions', () => { }) }) +describe('codemod table truncation', () => { + const links: BrokenLink[] = [ + // `/old-0` appears in five files, so it should survive truncation. + ...Array.from({ length: 5 }, (_, f) => ({ + href: '/old-0', + file: `actions/busy-${f}.md`, + lines: [1], + isRedirect: true, + redirectTarget: '/new-0', + })), + ...Array.from({ length: 59 }, (_, i) => ({ + href: `/old-${i + 1}`, + file: `actions/page-${i + 1}.md`, + lines: [1], + isRedirect: true, + redirectTarget: `/new-${i + 1}`, + })), + ] + + const markdown = reportToMarkdown(generateInternalLinkReport(links)) + + test('caps the reference table so the report fits in an issue body', () => { + expect(markdown).toContain('And 20 more.') + }) + + test('keeps the most-used links, dropping only the tail', () => { + expect(markdown).toContain('| `/old-0` | `/new-0` | 5 |') + }) + + test('still counts every link in the heading, not just the listed ones', () => { + expect(markdown).toContain('## 1. Run the codemod (60 links') + }) + + test('says nothing about truncation when everything fits', () => { + const few = reportToMarkdown(generateInternalLinkReport(links.slice(0, 3))) + expect(few).not.toContain('more. The codemod fixes every one of them') + }) +}) + describe('version-only redirects', () => { const versionOnly: BrokenLink[] = [ { @@ -771,6 +810,54 @@ describe('version-only redirects', () => { }) }) +describe('section caps', () => { + test('caps stale anchors, keeping the busiest ones and counting the rest', () => { + const anchors: BrokenLink[] = [ + // `/page-0#gone` appears in four files, so it must survive the cut. + ...Array.from({ length: 4 }, (_, f) => ({ + href: '/page-0#gone', + file: `actions/busy-${f}.md`, + lines: [1], + })), + ...Array.from({ length: 39 }, (_, i) => ({ + href: `/page-${i + 1}#gone`, + file: `actions/page-${i + 1}.md`, + lines: [1], + })), + ] + + const markdown = reportToMarkdown(generateInternalLinkReport(anchors)) + + expect(markdown).toContain('## 2. Stale anchors (40 links, 43 occurrences)') + expect(markdown).toContain('/page-0#gone') + expect(markdown).toContain('And 15 more, listed in the report attached to the workflow run.') + }) + + test('caps version-only redirects, which need no action at all', () => { + const versionOnly: BrokenLink[] = Array.from({ length: 30 }, (_, i) => ({ + href: `/admin/page-${i}`, + file: `actions/page-${i}.md`, + lines: [1], + isRedirect: true, + redirectTarget: `/enterprise-cloud@latest/admin/page-${i}`, + })) + + const markdown = reportToMarkdown(generateInternalLinkReport(versionOnly)) + + expect(markdown).toContain('## 4. Version-only redirects (30 links, 30 occurrences)') + expect(markdown).toContain('And 5 more in the same state.') + }) + + test('says nothing about truncation when every section fits', () => { + const markdown = reportToMarkdown( + generateInternalLinkReport([{ href: '/page#gone', file: 'actions/a.md', lines: [1] }]), + ) + + expect(markdown).toContain('## 2. Stale anchors (1 link, 1 occurrence)') + expect(markdown).not.toContain('more, listed in the report attached') + }) +}) + describe('version-only classification across versions', () => { test('a link that is version-only in one version and renamed in another is codemod work', () => { // Merged reports put every version's occurrences in one group. Classifying on the first @@ -820,6 +907,32 @@ describe('version-only classification across versions', () => { }) }) +describe('per-link file list cap', () => { + test('caps the file table under one link and counts the rest', () => { + // Nothing bounds how many pages reuse a link, so one popular link could otherwise + // fill the whole issue body. + const many: BrokenLink[] = Array.from({ length: 30 }, (_, i) => ({ + href: '/page#gone', + file: `actions/page-${i}.md`, + lines: [1], + })) + + const markdown = reportToMarkdown(generateInternalLinkReport(many)) + + expect(markdown).toContain('**Found in 30 files:**') + expect(markdown).toContain('And 10 more files, listed in the report attached') + expect(markdown).not.toContain('actions/page-29.md') + }) + + test('says nothing when every file fits', () => { + const few: BrokenLink[] = [{ href: '/page#gone', file: 'actions/a.md', lines: [1] }] + const markdown = reportToMarkdown(generateInternalLinkReport(few)) + + expect(markdown).toContain('actions/a.md') + expect(markdown).not.toContain('more files, listed in the report attached') + }) +}) + describe('versions checked when some come back clean', () => { const report = (href: string) => generateInternalLinkReport([{ href, file: 'actions/a.md', lines: [1] }])