From f23fdac293b8c67ee428a0d4cf73362f8143968d Mon Sep 17 00:00:00 2001 From: Isaac Brown <101839405+isaacmbrown@users.noreply.github.com> Date: Mon, 3 Aug 2026 19:07:18 +0100 Subject: [PATCH 1/6] Migrate GitLab Repositories to GitHub with GitHub Enterprise Importer (GEI) (#62399) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Vanessa Copilot-Session: 62b23e1f-4447-4dde-a731-2687ded70c66 --- ...a-residency-for-github-enterprise-cloud.md | 2 +- content/migrations/ado/follow-up-tasks.md | 43 +--- ...-migrations-from-azure-devops-to-github.md | 19 +- .../overview/migration-paths-to-github.md | 11 +- ...nnequins-for-github-enterprise-importer.md | 41 ++++ .../using-github-enterprise-importer/index.md | 1 + .../migrate-from-gitlab/configure-storage.md | 46 ++++ .../migrate-from-gitlab/follow-up-tasks.md | 11 + .../grant-the-migrator-role.md | 26 +++ .../migrate-from-gitlab/index.md | 40 ++++ ...nd-configure-github-enterprise-importer.md | 38 ++++ .../migrate-from-gitlab/manage-access.md | 51 +++++ .../migrate-your-repositories.md | 130 +++++++++++ .../plan-your-migration.md | 55 +++++ .../understand-migrations.md | 67 ++++++ .../migrate-from-gitlab/use-graphql.md | 209 ++++++++++++++++++ .../add-target-uploads-url.md | 1 + .../follow-up-tasks-common.md | 42 ++++ .../github-pat-required-scopes.md | 6 +- .../gl2gh-install-and-update.md | 14 ++ .../grant-migrator-role-ghecom.md | 2 +- .../migration-data-limitations.md | 19 ++ .../organization-structure-tasks.md | 2 +- .../supported-migration-paths.md | 1 + data/variables/product.yml | 6 +- 25 files changed, 807 insertions(+), 76 deletions(-) create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-storage.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/follow-up-tasks.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/grant-the-migrator-role.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/index.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/install-and-configure-github-enterprise-importer.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/migrate-your-repositories.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/plan-your-migration.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations.md create mode 100644 content/migrations/using-github-enterprise-importer/migrate-from-gitlab/use-graphql.md create mode 100644 data/reusables/enterprise-migration-tool/add-target-uploads-url.md create mode 100644 data/reusables/enterprise-migration-tool/follow-up-tasks-common.md create mode 100644 data/reusables/enterprise-migration-tool/gl2gh-install-and-update.md create mode 100644 data/reusables/enterprise-migration-tool/migration-data-limitations.md diff --git a/content/admin/data-residency/getting-started-with-data-residency-for-github-enterprise-cloud.md b/content/admin/data-residency/getting-started-with-data-residency-for-github-enterprise-cloud.md index cd9f29213930..791be6b1386d 100644 --- a/content/admin/data-residency/getting-started-with-data-residency-for-github-enterprise-cloud.md +++ b/content/admin/data-residency/getting-started-with-data-residency-for-github-enterprise-cloud.md @@ -115,7 +115,7 @@ To migrate existing data to your new enterprise on {% data variables.enterprise. Optionally, you can migrate data to {% data variables.enterprise.data_residency_site %} during your trial. However, migrated organizations will count towards the limit of three new organizations during the trial. -* If you're migrating from {% data variables.product.prodname_dotcom_the_website %}, {% data variables.product.prodname_ghe_server %}, Azure DevOps, or Bitbucket Server, you can migrate source code history and metadata with {% data variables.product.prodname_importer_proper_name %}. See [AUTOTITLE](/migrations/using-github-enterprise-importer/understanding-github-enterprise-importer/about-github-enterprise-importer). +* If you're migrating from {% data variables.product.prodname_dotcom_the_website %}, {% data variables.product.prodname_ghe_server %}, Azure DevOps, Bitbucket Server, or GitLab, you can migrate source code history and metadata with {% data variables.product.prodname_importer_proper_name %}. See [AUTOTITLE](/migrations/using-github-enterprise-importer/understanding-github-enterprise-importer/about-github-enterprise-importer). * For migrations from {% data variables.product.prodname_ghe_server %} 3.17 and later, you can use {% data variables.product.prodname_elm %}. This offers less downtime and better support for complex monorepos. See [AUTOTITLE](/migrations/elm/about-live-migrations). * If you're migrating from a different platform, see [AUTOTITLE](/migrations/overview/migration-paths-to-github#migrations-to-ghecom). diff --git a/content/migrations/ado/follow-up-tasks.md b/content/migrations/ado/follow-up-tasks.md index 6985c7d4a0d6..61847a73e897 100644 --- a/content/migrations/ado/follow-up-tasks.md +++ b/content/migrations/ado/follow-up-tasks.md @@ -12,48 +12,7 @@ redirect_from: - /migrations/ado/phase-6-follow-up-tasks --- -## Checking the migration status - -First, check whether your migration succeeded or failed. - -The way you check the status of your migration depends on how you ran the migration. - -* If you ran the migration using the {% data variables.product.prodname_cli %}, by default, the process will display whether the migration succeeded or failed once the migration is complete. If the migration failed, you will see the reason for failure. - - ```text - Migration completed (ID: RM_123)! State: SUCCEEDED - ``` - -* If you ran the migration using the {% data variables.product.prodname_cli %} with the optional `--queue-only` argument, the process will exit immediately after queueing the migration, and will not tell you if the migration succeeded or failed. You can check a migration's status using the `wait-for-migration` command, or by reviewing the migration log. - -## Reviewing the migration log - -You should review the migration log for each migrated repository. People with read access to a repository can access the migration log for the repository on {% data variables.product.prodname_dotcom %}. - -1. Navigate to the migrated repository in your destination organization. -{% data reusables.repositories.sidebar-issues %} -1. Click the issue with the title "Migration Log." - -For more information, see [AUTOTITLE](/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/accessing-your-migration-logs-for-github-enterprise-importer). - -## Setting repository visibility - -{% data reusables.enterprise-migration-tool.setting-repository-visibility %} - - For example, replace YOUR_ORG with your organization name, and the command below will set all of the organization's repositories to internal visibility. - - ```bash copy - export ORG=YOUR_ORG - gh repo list "$ORG" --limit 100000 --json name -q '.[].name' | xargs -I{} gh repo edit "$ORG/{}" --visibility internal - ``` - -## Reclaiming mannequins - -{% data reusables.enterprise-migration-tool.reclaiming-mannequins %} - -## Configuring IP allow lists - -If you added the IP ranges for {% data variables.product.prodname_importer_proper_name %} to the IP allow list for your destination organization, you can remove those entries. {% data reusables.enterprise-migration-tool.reenable-idp-ip-restrictions %} +{% data reusables.enterprise-migration-tool.follow-up-tasks-common %} ## Configure Azure Pipelines and Azure Boards diff --git a/content/migrations/ado/understand-migrations-from-azure-devops-to-github.md b/content/migrations/ado/understand-migrations-from-azure-devops-to-github.md index 1c8415a4f6e5..38b7de91d0b0 100644 --- a/content/migrations/ado/understand-migrations-from-azure-devops-to-github.md +++ b/content/migrations/ado/understand-migrations-from-azure-devops-to-github.md @@ -46,21 +46,4 @@ If you want to migrate Azure Pipelines to {% data variables.product.prodname_act * Attachments on pull requests * Branch policies for the repository (user-scoped branch policies and cross-repo branch policies are not included) -## Limitations on migrated data - -There are limits to what {% data variables.product.prodname_importer_proper_name %} can migrate. Some are due to limitations of {% data variables.product.prodname_dotcom %}, while others are limitations of {% data variables.product.prodname_importer_proper_name %} itself. - -### Limitations of {% data variables.product.prodname_dotcom %} - -* **2 GiB size limit for a single Git commit:** No single commit in your Git repository can be larger than 2 GiB. If any of your commits are larger than 2 GiB, you will need to split the commit into smaller commits that are each 2 GiB or smaller. -* **255 byte limit for Git references:** No single Git reference, commonly known as a "ref", can have a name larger than 255 bytes. Usually, this means that your references cannot be more than 255 characters long, but any non-ASCII characters, such as emojis, may consume more than one byte. If any of your Git references are too large, we'll return a clear error message. -* **100 MiB file size limit:** After you complete your migration, no single file in your Git repository can be larger than 100 MiB. During repository migration this limit is increased to 400 MiB. Consider using {% data variables.large_files.product_name_short %} to store large files. - -### Limitations of {% data variables.product.prodname_importer_proper_name %} - -* {% data reusables.enterprise-migration-tool.git-repo-size-limit %} -* **400 MiB file size limit:** When migrating a repository with {% data variables.product.prodname_importer_proper_name %}, no single file in your Git repository can be larger than 400 MiB. Consider using {% data variables.large_files.product_name_short %} for storing large files. -* **{% data variables.large_files.product_name_short %} objects not migrated:** The {% data variables.product.prodname_importer_secondary_name %} can migrate repositories that use {% data variables.large_files.product_name_short %}, but the LFS objects themselves will not be migrated. They can be pushed to your migration destination as a follow-up task after the migration is complete. -* **Delayed code search functionality:** Re-indexing the search index can take a few hours after a repository is migrated, and code searches may return unexpected results until re-indexing is complete. -* **Rulesets configured for your organization can cause migrations to fail:** For example, if you configured a rule that requires email addresses for commit authors to end with `@monalisa.cat`, and the repository you're migrating contains commits that don't comply with this rule, your migration will fail. -* **Mannequin content might not be searchable:** Mannequins are placeholder users to which imported content (such as issues, pull requests, comments, etc.) is associated. When you search for content associated with a mannequin, such as assigned issues, the issues may not be found. Once a mannequin is reclaimed, the content should be found via the new owner. +{% data reusables.enterprise-migration-tool.migration-data-limitations %} diff --git a/content/migrations/overview/migration-paths-to-github.md b/content/migrations/overview/migration-paths-to-github.md index 0ae574d44b1e..60f8e2bbf58c 100644 --- a/content/migrations/overview/migration-paths-to-github.md +++ b/content/migrations/overview/migration-paths-to-github.md @@ -101,10 +101,7 @@ Migrations from {% data variables.product.prodname_dotcom_the_website %} include * **Scope:** Source, history, and metadata * **Tooling:** {% data variables.product.prodname_importer_proper_name %} -* **More information:** [{% data variables.product.prodname_expert_services %}](https://github.com/services/) website -* **Caveats:** - * If you want to migrate GitLab repositories to GitHub using {% data variables.product.prodname_importer_proper_name %}, please contact our {% data variables.product.prodname_expert_services %} team. - * {% data reusables.migrations.migration-instructions-for-any-git-repository-to-githubcom %} +* **More information:** [AUTOTITLE]({% ifversion ghes %}/free-pro-team@latest{% endif %}/migrations/using-github-enterprise-importer/migrate-from-gitlab) ### Any Git repository to {% data variables.product.prodname_dotcom_the_website %} @@ -233,10 +230,8 @@ Follow a link below to review the scope and tooling for your migration to {% dat ### GitLab to {% data variables.enterprise.data_residency_site %} * **Scope:** Source, history, and metadata -* **Tooling:** Contact {% data variables.product.prodname_expert_services %} -* **More information:** [{% data variables.product.prodname_expert_services %}](https://github.com/services/) website -* **Caveats:** - * {% data reusables.migrations.migration-instructions-for-any-git-repository-to-ghecom %} +* **Tooling:** {% data variables.product.prodname_importer_proper_name %} +* **More information:** [AUTOTITLE]({% ifversion ghes %}/free-pro-team@latest{% endif %}/migrations/using-github-enterprise-importer/migrate-from-gitlab) ### Any Git repository to {% data variables.enterprise.data_residency_site %} diff --git a/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/reclaiming-mannequins-for-github-enterprise-importer.md b/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/reclaiming-mannequins-for-github-enterprise-importer.md index 5bad31b13ef1..ce0dc182e711 100644 --- a/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/reclaiming-mannequins-for-github-enterprise-importer.md +++ b/content/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/reclaiming-mannequins-for-github-enterprise-importer.md @@ -38,6 +38,9 @@ The exact command you need to use depends on which extension of the {% data vari * [Reclaiming mannequins with the {% data variables.product.prodname_gei_cli_short %}](#reclaiming-mannequins-with-the-gei-extension) * [Reclaiming mannequins with the {% data variables.product.prodname_ado2gh_cli_short %}](#reclaiming-mannequins-with-the-ado2gh-extension) * [Reclaiming mannequins with the {% data variables.product.prodname_bbs2gh_cli_short %}](#reclaiming-mannequins-with-the-bbs2gh-extension) +{%- ifversion fpt or ghec %} +* [Reclaiming mannequins with the {% data variables.product.prodname_gl2gh_cli_short %}](#reclaiming-mannequins-with-the-gl2gh-extension) +{%- endif %} #### Reclaiming mannequins with the {% data variables.product.prodname_gei_cli_short %} @@ -141,6 +144,44 @@ If your migration source is Bitbucket Server, you can reclaim mannequins with th {% data reusables.enterprise-migration-tool.mannequin-reclaim-must-accept %} +{% ifversion fpt or ghec %} + +#### Reclaiming mannequins with the {% data variables.product.prodname_gl2gh_cli_short %} + +If your migration source is GitLab, you can reclaim mannequins with the {% data variables.product.prodname_gl2gh_cli %}. + +* If you don't already have a `GH_PAT` environment variable set for a {% data variables.product.pat_generic %} with access to the destination organization, add `--github-pat TOKEN` to each command below, replacing `TOKEN` with the {% data variables.product.pat_generic %}. For {% data variables.product.pat_generic %} requirements, see [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access). +* {% data reusables.enterprise-migration-tool.add-target-api-url %} + +{% data reusables.enterprise-migration-tool.create-csv-mannequins %} + + * To generate a CSV file with a list of mannequins for an organization, use the `gh gl2gh generate-mannequin-csv` command, replacing DESTINATION with the destination organization and FILENAME with a file name for the resulting CSV file. + + {% data reusables.enterprise-migration-tool.include-reclaimed %} + + ```shell copy + gh gl2gh generate-mannequin-csv --github-org DESTINATION --output FILENAME.csv + ``` + + {% data reusables.enterprise-migration-tool.edit-csv %} +1. To reclaim mannequins, use the `gh gl2gh reclaim-mannequin` command. + + {% data reusables.enterprise-migration-tool.reclaim-bulk-csv %} + + ```shell copy + gh gl2gh reclaim-mannequin --github-org DESTINATION --csv FILENAME.csv + ``` + + {% data reusables.enterprise-migration-tool.reclaim-individual-mannequin %} + + ```shell copy + gh gl2gh reclaim-mannequin --github-org DESTINATION --mannequin-user MANNEQUIN --target-user USERNAME + ``` + +{% data reusables.enterprise-migration-tool.mannequin-reclaim-must-accept %} + +{% endif %} + ### Reclaiming mannequins in your browser {% data reusables.elm.reclaim-mannequins-in-browser %} diff --git a/content/migrations/using-github-enterprise-importer/index.md b/content/migrations/using-github-enterprise-importer/index.md index 3806039e80dd..3d2b8e37bf8f 100644 --- a/content/migrations/using-github-enterprise-importer/index.md +++ b/content/migrations/using-github-enterprise-importer/index.md @@ -10,6 +10,7 @@ children: - /understanding-github-enterprise-importer - /migrating-from-bitbucket-server-to-github-enterprise-cloud - /migrating-between-github-products + - /migrate-from-gitlab - /completing-your-migration-with-github-enterprise-importer redirect_from: - /early-access/github/migrating-with-github-enterprise-importer diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-storage.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-storage.md new file mode 100644 index 000000000000..2ee3f8be63b2 --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-storage.md @@ -0,0 +1,46 @@ +--- +title: "Configure blob storage" +allowTitleToDifferFromFilename: true +shortTitle: "5. Configure storage" +intro: "Archives from GitLab need to be temporarily stored so {% data variables.product.github %} can read them." +versions: + fpt: '*' + ghec: '*' +contentType: other +--- + +For most customers, we recommend storing archives with {% data variables.product.prodname_ghos %}. This is the simplest path and does not require any extra configuration. + +However, you may want to configure storage with an external provider if you have firewall requirements or need to retain archives after the migration is complete. + +## Choosing where to stage archives + +The {% data variables.product.prodname_gl2gh_cli_short %} exports each GitLab project to an archive, then uploads the archive to blob storage that {% data variables.product.prodname_dotcom %} can read from. You choose the storage backend when you run a migration. + +Storage option | How to select it | Notes +-------------- | ---------------- | ----- +{% data variables.product.prodname_ghos %} (recommended) | `--use-github-storage` | No setup required. {% data variables.product.prodname_dotcom %} deletes the archive automatically after a successful migration, or seven days after a failed migration. +AWS S3 | `--aws-bucket-name` (with the `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY` environment variables, and optionally `AWS_SESSION_TOKEN`) | You own the bucket and its lifecycle. {% data variables.product.prodname_dotcom %} does not delete archives from your storage. +Azure Blob Storage | `AZURE_STORAGE_CONNECTION_STRING` environment variable (for a single `migrate-repo` command, you can instead use `--azure-storage-connection-string`) | Only storage-account access-key connection strings are supported (not SAS). {% data variables.product.prodname_dotcom %} does not delete archives from your storage. + +## Configuring blob storage + +If you are using {% data variables.product.prodname_ghos %}, you do not need to configure anything. You will use the `--use-github-storage` flag to select this method with the CLI. However, you may want to set the `GITHUB_OWNED_STORAGE_MULTIPART_MEBIBYTES` variable (default 100 MiB, minimum 5 MiB) to a lower number if you have a slow or proxied connection. + +If you are using external blob storage, you will need to set this up. + +### Setting up an AWS S3 storage bucket + +{% data reusables.enterprise-migration-tool.set-up-aws-bucket %} + +{% data reusables.enterprise-migration-tool.aws-credentials-cli %} + +### Setting up an Azure Blob Storage storage account + +{% data reusables.enterprise-migration-tool.set-up-azure-storage-account %} + +{% data reusables.enterprise-migration-tool.azure-credentials-cli %} + +### Allowing network access + +If you have configured firewall rules on your storage account, ensure you have allowed access to the IP ranges for your migration destination. See [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access#configure-ip-allow-lists-on-github). \ No newline at end of file diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/follow-up-tasks.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/follow-up-tasks.md new file mode 100644 index 000000000000..8233f57ce0e2 --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/follow-up-tasks.md @@ -0,0 +1,11 @@ +--- +title: "Follow-up tasks" +shortTitle: "7. Follow-up tasks" +intro: "After each migration has finished, you'll need to complete some additional tasks before the repository is ready for work." +versions: + fpt: '*' + ghec: '*' +contentType: other +--- + +{% data reusables.enterprise-migration-tool.follow-up-tasks-common %} diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/grant-the-migrator-role.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/grant-the-migrator-role.md new file mode 100644 index 000000000000..1167233bae01 --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/grant-the-migrator-role.md @@ -0,0 +1,26 @@ +--- +title: "Granting the migrator role" +allowTitleToDifferFromFilename: true +shortTitle: Migrator role +intro: "The migrator role gives a user or team the ability to run migrations on behalf of an organization." +versions: + fpt: '*' + ghec: '*' +contentType: other +--- + +To allow someone other than an organization owner to run a migration or download migration logs, you can grant the migrator role to a user or team. + +To grant the migrator role using the CLI, you can use the {% data variables.product.prodname_gl2gh_cli %}. + +{% data reusables.enterprise-migration-tool.gl2gh-install-and-update %} + +1. On {% data variables.product.prodname_dotcom %}, create and record a {% data variables.product.pat_generic %} that has the `admin:org` scope. +{% data reusables.enterprise-migration-tool.grant-migrator-role-pat %} +1. Use the `gh gl2gh grant-migrator-role` command, replacing ORGANIZATION with the organization you want to grant the migrator role for, ACTOR with the user or team name, and TYPE with `USER` or `TEAM`. + + ```shell copy + gh gl2gh grant-migrator-role --github-org ORGANIZATION --actor ACTOR --actor-type TYPE + ``` + + {% data reusables.enterprise-migration-tool.grant-migrator-role-ghecom %} diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/index.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/index.md new file mode 100644 index 000000000000..81e63923abb9 --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/index.md @@ -0,0 +1,40 @@ +--- +title: Migrating from GitLab to GitHub +shortTitle: Migrate from GitLab +intro: Plan and execute a migration from GitLab to {% data variables.product.prodname_ghe_cloud %}. This guide explains how to configure access, migrate, and the follow-up tasks needed to get your repositories ready for work. +versions: + fpt: '*' + ghec: '*' +children: + - /understand-migrations + - /plan-your-migration + - /manage-access + - /install-and-configure-github-enterprise-importer + - /configure-storage + - /migrate-your-repositories + - /follow-up-tasks + - /use-graphql + - /grant-the-migrator-role +contentType: tutorials +heroImage: /assets/images/banner-images/hero-2 +introLinks: + plan_your_migration: /migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations +sidebarLink: + text: Get started + href: /migrations/using-github-enterprise-importer/migrate-from-gitlab +layout: journey-landing +journeyArticlesHeading: "Steps to completing your migration" +journeyTracks: + - id: gitlab_migration + title: Run your migration + description: Migrate your repositories from GitLab to GitHub. + guides: + - href: /migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations + - href: /migrations/using-github-enterprise-importer/migrate-from-gitlab/plan-your-migration + - href: /migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access + - href: /migrations/using-github-enterprise-importer/migrate-from-gitlab/install-and-configure-github-enterprise-importer + - href: /migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-storage + - href: /migrations/using-github-enterprise-importer/migrate-from-gitlab/migrate-your-repositories + - href: /migrations/using-github-enterprise-importer/migrate-from-gitlab/follow-up-tasks +--- + diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/install-and-configure-github-enterprise-importer.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/install-and-configure-github-enterprise-importer.md new file mode 100644 index 000000000000..2dc75ba3f049 --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/install-and-configure-github-enterprise-importer.md @@ -0,0 +1,38 @@ +--- +title: "Install and configure GitHub Enterprise Importer" +shortTitle: "4. Configure GitHub Enterprise Importer" +intro: "Install the {% data variables.product.prodname_gl2gh_cli %} and configure your environment for the migration." +versions: + fpt: '*' + ghec: '*' +contentType: other +--- + +## Step 1: Install the {% data variables.product.prodname_gl2gh_cli %} + +{% data variables.product.prodname_importer_proper_name %} is a collection of extensions for {% data variables.product.prodname_cli %}. If this is your first migration, you'll need to install {% data variables.product.prodname_cli %} and the {% data variables.product.prodname_gl2gh_cli_short %}. + +{% data reusables.enterprise-migration-tool.gl2gh-install-and-update %} + +## Step 2: Set environment variables + +Before you can use the {% data variables.product.prodname_gl2gh_cli_short %} to migrate to {% data variables.product.prodname_ghe_cloud %}, you must create {% data variables.product.pat_generic %}s that can access the source and destination, then set the {% data variables.product.pat_generic %}s as environment variables. + +1. Make sure you have your {% data variables.product.pat_generic %}s for both {% data variables.product.github %} and GitLab ready. See [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access) if you haven't already created a token. +1. Set environment variables for the {% data variables.product.pat_generic %}s, replacing TOKEN in the commands below with the {% data variables.product.pat_generic %}s you previously created. Use `GH_PAT` for the destination organization and `GITLAB_PAT` for the source GitLab instance. + + * If you're using Terminal, use the `export` command. + + ```shell copy + export GH_PAT="TOKEN" + export GITLAB_PAT="TOKEN" + ``` + + * If you're using PowerShell, use the `$env` command. + + ```shell copy + $env:GH_PAT="TOKEN" + $env:GITLAB_PAT="TOKEN" + ``` + +{% data reusables.enterprise-migration-tool.set-target-api-url %} diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access.md new file mode 100644 index 000000000000..239a74883512 --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access.md @@ -0,0 +1,51 @@ +--- +title: "Manage access for a migration from GitLab to GitHub" +shortTitle: "3. Manage access" +intro: "Set up the required access for migrating from GitLab to {% data variables.product.github %}." +versions: + fpt: '*' + ghec: '*' +contentType: other +allowTitleToDifferFromFilename: true +--- + +To migrate repositories from GitLab to {% data variables.product.github %}, you need sufficient access to the **source** (a project on GitLab) and the **destination** (an organization on {% data variables.product.github %}). After you complete the steps in this article, your access and permissions will be ready for your migration. + +## Decide who will perform the migration + +If the person who will perform the migration is **not** a {% data variables.product.github %} organization owner, a {% data variables.product.github %} organization owner must first grant them the migrator role. + +* If you're a {% data variables.product.github %} organization owner, and intend to perform the migration yourself, you can continue reading this guide. +* If you wish to assign the migrator role to someone else, do that now. Then, the migrator should perform the rest of the steps in these guides. See [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/grant-the-migrator-role). + +## Create a {% data variables.product.pat_v1 %} on {% data variables.product.github %} + +Next, you will need to create a {% data variables.product.pat_v1 %} which the {% data variables.product.prodname_gl2gh_cli %} will use to communicate with {% data variables.product.github %}. {% data reusables.enterprise-migration-tool.github-pat-required-scopes %} + +To learn how to create the token, see [AUTOTITLE](/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic). + +## Create a {% data variables.product.pat_generic %} on GitLab + +Your GitLab {% data variables.product.pat_generic %} must have the `api` and `read_repository` scopes. + +For self-managed GitLab instances, the token must belong to an **administrator**, so that the export is complete and user attribution is preserved. + +To learn how to create the token, see [{% data variables.product.pat_generic_caps_plural %}](https://docs.gitlab.com/user/profile/personal_access_tokens/) in the GitLab documentation. + +## Configure IP allow lists on {% data variables.product.github %} + +If you use {% data variables.product.company_short %}'s IP allow list feature, you must add the {% data variables.product.prodname_dotcom %} IP ranges below to the allow list for the destination organization. See [AUTOTITLE](/enterprise-cloud@latest/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/managing-allowed-ip-addresses-for-your-organization) or [AUTOTITLE](/enterprise-cloud@latest/admin/configuring-settings/hardening-security-for-your-enterprise/restricting-network-traffic-to-your-enterprise-with-an-ip-allow-list). + +If your destination organization is on **{% data variables.product.prodname_dotcom_the_website %}**, you will need to allow the following IP addresses: + +{% data reusables.enterprise-migration-tool.gei-ip-list %} + +If your destination organization is on **{% data variables.enterprise.data_residency_site %}**, the ranges you need to allow depend on your data residency region. You can get an up-to-date list of IP ranges used by {% data variables.product.prodname_importer_proper_name %} with the `/meta` endpoint of the REST API. The `github_enterprise_importer` key in the response contains a list of IP ranges used for migrations. + +## Allow migrations to bypass repository rulesets + +{% data reusables.enterprise-migration-tool.repository-migrations-bypass %} + +## Enable exports on GitLab + +The GitLab projects you want to migrate must be enabled for exports. See [Enable project export](https://docs.gitlab.com/administration/settings/import_and_export_settings/#enable-project-export) and [Sidekiq configuration for imports](https://docs.gitlab.com/administration/sidekiq/configuration_for_imports/) in the GitLab documentation. diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/migrate-your-repositories.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/migrate-your-repositories.md new file mode 100644 index 000000000000..7ced536c6484 --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/migrate-your-repositories.md @@ -0,0 +1,130 @@ +--- +title: "Migrate your repositories from GitLab to GitHub" +allowTitleToDifferFromFilename: true +shortTitle: "6. Migrate repositories" +intro: Perform a trial run and then migrate your repositories from GitLab to {% data variables.product.github %}. +versions: + fpt: '*' + ghec: '*' +contentType: other +--- + +## Prerequisites + +* You must have completed all previous phases of this guide. +* The GitLab project must be enabled for exports. See [Enable project export](https://docs.gitlab.com/administration/settings/import_and_export_settings/#enable-project-export) and [Sidekiq configuration for imports](https://docs.gitlab.com/administration/sidekiq/configuration_for_imports/) in the GitLab documentation. +* {% data reusables.enterprise-migration-tool.link-to-support-limitations %} For more information, see [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations). +* {% data reusables.enterprise-migration-tool.delta-migrations-not-supported %} + +## Performing a trial run + +{% data reusables.enterprise-migration-tool.running-your-migrations %} + +1. Create a test organization for your trial migrations. + + You can use a single organization for all trial runs, or you can create one test organization for each intended destination organization. Consider including `-sandbox` at the end of the organization names, to clarify that the organizations are intended only for migration validation and not for production. You can delete the test organizations after you're done. + +1. Run the trial migrations. +1. Confirm that you are able to complete the follow-up tasks in [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/follow-up-tasks). +1. Ask users to validate the results of the migrations. +1. Resolve any issues uncovered by your trial migrations. +{% data reusables.enterprise-migration-tool.delete-test-organization %} + +## Migrating a single repository + +To migrate one repository, use the `gh gl2gh migrate-repo` command. + +```shell copy +gh gl2gh migrate-repo \ + --gitlab-server-url GITLAB_SERVER_URL \ + --gitlab-group SOURCE_GROUP \ + --gitlab-project SOURCE_PROJECT \ + --github-org DESTINATION \ + --github-repo NEW_REPO_NAME \ + --use-github-storage +``` + +Replace the placeholders in the command above with the following values. + +Placeholder | Value +----------- | ----- +GITLAB_SERVER_URL | The full URL of your GitLab instance, such as `https://gitlab.com` or `https://gitlab.example.com`. +SOURCE_GROUP | The full path of the group or namespace that contains the project. For nested subgroups, use the full path, such as `parent-group/subgroup`. +SOURCE_PROJECT | The GitLab project to migrate. +DESTINATION | The destination organization on {% data variables.product.github %}. +NEW_REPO_NAME | The name for the repository on {% data variables.product.github %}. + +If you are not using {% data variables.product.prodname_ghos %}, see [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-storage). + +### Additional arguments + +| Argument | Description | +| -------- | ----------- | +| `--target-repo-visibility` | Sets the visibility of the new repository to `public`, `private`, or `internal`. Defaults to `private`. | +| `--target-api-url TARGET-API-URL` | {% data reusables.enterprise-migration-tool.add-target-api-url %} | +| `--target-uploads-url TARGET-UPLOADS-URL` | {% data reusables.enterprise-migration-tool.add-target-uploads-url %} | +| `--no-ssl-verify` | Disables SSL verification when the {% data variables.product.prodname_gl2gh_cli_short %} talks to your GitLab instance. Use this only if your GitLab instance uses a self-signed certificate. All other steps still verify SSL. | +| `--archive-url URL` | Imports a previously exported archive from a URL, instead of exporting the project from GitLab again. | +| `--archive-path PATH` | Imports a previously exported archive from a local file path, instead of exporting the project from GitLab again. | +| `--keep-archive` | Retains the export archive locally instead of deleting it after a successful upload. | + +## Generating a migration script + +If you want to migrate multiple repositories to {% data variables.product.prodname_ghe_cloud %} at once, use the {% data variables.product.prodname_cli %} to generate a migration script. The resulting script contains one `migrate-repo` command per repository. + +To generate a migration script, run the `gh gl2gh generate-script` command. + +```shell copy +gh gl2gh generate-script \ + --gitlab-server-url GITLAB_SERVER_URL \ + --github-org DESTINATION \ + --output FILENAME \ + --use-github-storage +``` + +Replace the placeholders in the command above with the following values. + +Placeholder | Value +----------- | ----- +GITLAB_SERVER_URL | The full URL of your GitLab instance, such as `https://gitlab.com` or `https://gitlab.example.com`. +DESTINATION | The destination organization on {% data variables.product.github %}. +{% data reusables.enterprise-migration-tool.filename-placeholder %} + +By default, the script includes every project the token can access. To scope the script, add `--gitlab-group GROUP`, or `--gitlab-group GROUP --gitlab-project PROJECT` for a single project. + +If you are not using {% data variables.product.prodname_ghos %}, see [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-storage). + +### Additional arguments + +| Argument | Description | +| -------- | ----------- | +| `--target-api-url TARGET-API-URL` | {% data reusables.enterprise-migration-tool.add-target-api-url %} | +| `--target-uploads-url TARGET-UPLOADS-URL` | {% data reusables.enterprise-migration-tool.add-target-uploads-url %} | + +### Reviewing the migration script + +After you generate the script, review the file and, optionally, edit the script. + +* If there are any repositories you don't want to migrate, delete or comment out the corresponding lines. +* If you want any repositories to have a different name in the destination organization, update the value for the corresponding `--github-repo` flag. +* If you want to change the visibility of a new repository, add or update the corresponding `--target-repo-visibility` flag. + +### Migrate repositories + +If your trial run was successful, and you were able to complete the follow-up tasks, you can proceed to the real migration. + +>[!WARNING] We recommend halting work in the repositories you are migrating. Any changes made during or after the migration will need to be manually migrated. + +Run the script you generated. Replace FILENAME in the commands below with the filename you provided when generating the script. + +* If you're using Terminal, use `./`. + + ```shell copy + ./FILENAME + ``` + +* If you're using PowerShell, use `.\`. + + ```shell copy + .\FILENAME + ``` diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/plan-your-migration.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/plan-your-migration.md new file mode 100644 index 000000000000..6686579ad25b --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/plan-your-migration.md @@ -0,0 +1,55 @@ +--- +title: "Plan your migration from GitLab to GitHub" +allowTitleToDifferFromFilename: true +shortTitle: "2. Plan your migration" +intro: Plan your migration by understanding your timeline, what data will be migrated, and your organizational structure. +versions: + fpt: '*' + ghec: '*' +contentType: other +--- + +## Determine how much you have to migrate + +Figure out your timeline first, since it will largely shape your approach. The first step for determining your timeline is to get an inventory of what you need to migrate. + +* Number of repositories (projects) +* Number of merge requests + +>[!NOTE] Migration timing is largely based on the number of merge requests in a repository. If you want to migrate 1,000 repositories, and each repository has 100 merge requests on average, your migration will likely be very quick. If you want to migrate only 100 repositories, but the repositories each have 75,000 merge requests on average, the migration will take much longer and require more planning and testing. + +We recommend the `inventory-report` command in the {% data variables.product.prodname_gl2gh_cli %}. This command connects to the GitLab API and creates two CSV files. `groups.csv` lists your GitLab groups, and `projects.csv` lists your projects, including the number of merge requests. + +To produce the CSV files, use the following command, replacing `GITLAB_SERVER_URL` with the URL of your GitLab server (for example, `https://gitlab.com`) and `YOUR_GITLAB_GROUP` with the group you want to report on. To report on all projects you can access, omit `--gitlab-group`. For all available options, run `gh gl2gh inventory-report --help`. + +```shell copy +gh gl2gh inventory-report --gitlab-server-url GITLAB_SERVER_URL --gitlab-group YOUR_GITLAB_GROUP +``` + +After you take inventory of the repositories you need to migrate, weigh your inventory data against your desired timeline. + +* If your organization can withstand a higher degree of change, then you might be able to migrate all your repositories at once, completing your migration efforts in a few days. +* If you have teams that are not able to migrate at the same time, you might want to batch and stagger your migrations to fit the teams' timelines, extending your migration effort. + +## Determine {% data variables.product.github %} organizational structure + +Next, plan the organizational structure you'll create in {% data variables.product.github %}. GitLab and {% data variables.product.github %} have different ways of organizing an enterprise's work. + +* GitLab: instance > groups > subgroups (which can be nested up to 20 levels deep) > projects (repositories) +* {% data variables.product.github %}: enterprise > organization > repositories + +After migrating to {% data variables.product.github %}, you should have only one enterprise account and a number of organizations owned by that enterprise. Each top-level group from GitLab typically corresponds to a single organization on {% data variables.product.github %}. For guidance on how many organizations to create, see [AUTOTITLE](/enterprise-cloud@latest/admin/concepts/enterprise-best-practices/organize-work). + +>[!NOTE] {% data variables.product.github %} does not have an equivalent of GitLab's nested subgroups. We do not recommend creating an organization on {% data variables.product.github %} for each subgroup, as this may result in a large list of ungrouped repositories within each organization. Instead, you can manage access to groups of repositories by creating teams. + +If you want to break your migration effort into batches, the new structure can help you determine them. If you have more than one group in GitLab, and each group's repositories are reasonably sized batches, consider batching by group. + +{% data reusables.enterprise-migration-tool.organization-structure-tasks %} + +## Configuring repository permissions + +Because permissions work differently in {% data variables.product.prodname_dotcom %} than in GitLab, {% data variables.product.prodname_importer_proper_name %} does not migrate repository permissions, group settings, or group membership from GitLab. + +In GitLab, members are granted roles (such as Guest, Reporter, Developer, Maintainer, or Owner) at the group, subgroup, or project level, and these roles are inherited down the hierarchy. These roles do not map directly to {% data variables.product.prodname_dotcom %}, so you'll need to recreate access after migrating. + +To give people access to migrated repositories on {% data variables.product.prodname_dotcom %}, we recommend creating teams and granting each team the appropriate level of access to the relevant organizations and repositories. You can then add people to those teams. See [AUTOTITLE](/enterprise-cloud@latest/admin/concepts/enterprise-fundamentals/teams-in-an-enterprise). diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations.md new file mode 100644 index 000000000000..dc87f5471461 --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations.md @@ -0,0 +1,67 @@ +--- +title: Understand migrations from GitLab to GitHub +allowTitleToDifferFromFilename: true +shortTitle: 1. Understand migrations +intro: '{% data variables.product.prodname_importer_proper_name %} automates migrations from GitLab.' +versions: + fpt: '*' + ghec: '*' +contentType: other +--- + +## About migrations from GitLab + +You can use {% data variables.product.prodname_importer_proper_name %} to migrate repositories from GitLab to {% data variables.product.prodname_ghe_cloud %} ({% data variables.product.prodname_dotcom_the_website %} or {% data variables.enterprise.data_residency_site %}). + +Migrations are performed with the {% data variables.product.prodname_gl2gh_cli %}, a cross-platform command-line wrapper around the {% data variables.product.prodname_dotcom %} migration APIs. For each repository, the {% data variables.product.prodname_gl2gh_cli_short %}: + +1. **Exports** the GitLab project to a `.tar.gz` archive containing the Git repository plus project metadata (such as issues, merge requests, labels, milestones, and releases). +1. **Stages** the archive locally on the machine where you run the command. +1. **Uploads** the archive to blob storage that {% data variables.product.prodname_dotcom %} can read from (either {% data variables.product.prodname_ghos %} or a storage account you own in AWS S3 or Azure Blob Storage). +1. **Imports** the archive into the destination organization, transforming GitLab entities into their {% data variables.product.prodname_dotcom %} equivalents. + +Before you create your enterprise account on {% data variables.product.prodname_dotcom %}, decide whether your enterprise will use {% data variables.product.prodname_emus %}. This affects how your members authenticate and how you manage identities and access. See [AUTOTITLE](/enterprise-cloud@latest/enterprise-onboarding/getting-started-with-your-enterprise/choose-an-enterprise-type). + +## Supported GitLab versions + +You can migrate from both GitLab.com and self-managed GitLab instances. + +{% data variables.product.prodname_importer_proper_name %} supports currently maintained (non-end-of-life) versions of GitLab. For the list of maintained versions, see [Statement of support](https://docs.gitlab.com/policy/maintenance/) in the GitLab documentation. Older versions have not been tested or evaluated. + +## Data that is migrated + +When the data is present in the GitLab export archive, {% data variables.product.prodname_importer_proper_name %} migrates the following data from GitLab to {% data variables.product.prodname_ghe_cloud %}. + +* Git source (including commit history) and the repository wiki +* Commit comments +* Project configuration that maps cleanly, such as the default branch +* Issues and issue comments, including issue state and milestone events + * Threaded discussions are migrated as flat comments with context of the original thread +* Merge requests, which are converted to pull requests, including: + * Comments (migrated as review comments only when diff data is present, otherwise as flat issue comments; only the latest diff is present in the export) + * Reviewers and approvers + * Merge request state events +* Milestones +* Timeline events +* Emoji reactions +* Uploads (attachments) +* Releases and release assets +* Project members (migrated as mannequins) + +## Data that is not migrated + +The following data is not migrated. + +* {% data variables.large_files.product_name_short %} objects: Pointer files travel with the Git history, but the binary objects must be pushed to your migration destination separately as a follow-up task. For more information, see [AUTOTITLE](/repositories/creating-and-managing-repositories/duplicating-a-repository#mirroring-a-repository-that-contains-git-large-file-storage-objects). +* Repository policies, including merge trains, pipeline gates, required approvals, topics, avatars, and mirroring +* Group settings and group membership +* Snippets, issue boards, time-tracking data, and design-management data +* CI/CD pipelines and pipeline schedules (`.gitlab-ci.yml` has no automatic {% data variables.product.prodname_actions %} equivalent) +* Vulnerability reports +* Data that GitLab does not include in the export at all, such as webhooks, CI/CD variables, job traces and artifacts, child-pipeline history, and pipeline triggers + +{% data reusables.enterprise-migration-tool.migration-data-limitations %} + +### Limitations of GitLab + +* **40 GB limit for the GitLab export archive:** GitLab's project export API will not produce an archive larger than 40 GB on GitLab.com. Unlike the {% data variables.product.prodname_dotcom %} source-size limit, this applies to the entire export archive, including project metadata as well as the Git source. This limit is set by GitLab and may differ on self-managed instances. diff --git a/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/use-graphql.md b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/use-graphql.md new file mode 100644 index 000000000000..684e7793da3a --- /dev/null +++ b/content/migrations/using-github-enterprise-importer/migrate-from-gitlab/use-graphql.md @@ -0,0 +1,209 @@ +--- +title: Use GraphQL to migrate repositories from GitLab to GitHub Enterprise Cloud +allowTitleToDifferFromFilename: true +shortTitle: Migrate with GraphQL API +intro: You can build your own tooling to migrate repositories from GitLab to {% data variables.product.prodname_ghe_cloud %} using the GraphQL API. +versions: + fpt: '*' + ghec: '*' +contentType: other +--- + +> [!NOTE] You can also use {% data variables.product.prodname_gl2gh_cli %} to perform your migration. See [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations). + +## Step 0: Get ready to use the {% data variables.product.prodname_dotcom %} GraphQL API + +{% data reusables.enterprise-migration-tool.migration-query-method %} + +## Step 1: Get the `ownerId` for your migration destination + +{% data reusables.enterprise-migration-tool.get-destination-ownerId-ec %} + +{% data reusables.enterprise-migration-tool.migration-destination-query %} + +## Step 2: Identify where you're migrating from + +{% data reusables.enterprise-migration-tool.identify-migration-source-intro %} + +Your migration source is your GitLab instance. + +### `createMigrationSource` mutation + +```graphql +mutation createMigrationSource($name: String!, $url: String!, $ownerId: ID!) { + createMigrationSource(input: {name: $name, url: $url, ownerId: $ownerId, type: GITLAB}) { + migrationSource { + id + name + url + type + } + } +} +``` + +Set `url` to the full URL of your GitLab instance, such as `https://gitlab.com` or `https://gitlab.example.com`. Make sure to use `GITLAB` for `type`. + +{% data reusables.enterprise-migration-tool.createMigrationSource-table-ec %} + +### `createMigrationSource` response + +```json +{ + "data": { + "createMigrationSource": { + "migrationSource": { + "id": "MS_kgDaACQxYmYxOWU4Yi0wNzZmLTQ3NTMtOTdkZC1hNGUzZmYxN2U2YzA", + "name": "GitLab Source", + "url": "https://gitlab.com", + "type": "GITLAB" + } + } + } +} +``` + +In this example, `MS_kgDaACQxYmYxOWU4Yi0wNzZmLTQ3NTMtOTdkZC1hNGUzZmYxN2U2YzA` is the migration source ID, which we'll use in a later step. + +## Step 3: Generate and host your migration archive + +Migrations from GitLab are archive-based. Instead of connecting to your GitLab instance during the migration, {% data variables.product.prodname_importer_proper_name %} imports a migration archive that you generate from your GitLab project. A GitLab archive is a single file that contains both the Git source and the repository's metadata. + +Before you start the migration, you must: + +1. Generate a migration archive for the GitLab project you want to migrate. +1. Host the archive at a URL that {% data variables.product.prodname_ghe_cloud %} can access. + +You'll provide this URL as the `gitArchiveUrl` value in the next step. + +### Generating a migration archive + +Use the GitLab [project export API](https://docs.gitlab.com/api/project_import_export/) to export the project you want to migrate. The token you use must have the `api` scope and a role with permission to export the project. For more information, see [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access). + +In the following requests, set the `GITLAB_PAT` environment variable to the token you created in [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access). Replace `GITLAB-SERVER` with the host of your GitLab instance, such as `gitlab.com`, and replace `GROUP%2FPROJECT` with the URL-encoded path of your project. For example, the project `acme-group/my-project` is encoded as `acme-group%2Fmy-project`. For nested subgroups, include the full path, such as `parent-group%2Fsubgroup%2Fmy-project`. + +1. Schedule the export. + + ```shell + curl --request POST \ + --header "PRIVATE-TOKEN: $GITLAB_PAT" \ + "https://GITLAB-SERVER/api/v4/projects/GROUP%2FPROJECT/export" + ``` + +1. Check the status of the export. Repeat this request until `export_status` is `finished`. + + ```shell + curl --header "PRIVATE-TOKEN: $GITLAB_PAT" \ + "https://GITLAB-SERVER/api/v4/projects/GROUP%2FPROJECT/export" + ``` + +1. Download the archive. + + ```shell + curl --location \ + --header "PRIVATE-TOKEN: $GITLAB_PAT" \ + --output archive.tar.gz \ + "https://GITLAB-SERVER/api/v4/projects/GROUP%2FPROJECT/export/download" + ``` + +### Hosting the archive + +You must host the archive at a URL that {% data variables.product.prodname_ghe_cloud %} can access. You can either upload the archive to {% data variables.product.prodname_ghos %} or use an external blob storage provider. For information about external providers, see [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-storage). + +To upload the archive to {% data variables.product.prodname_ghos %}, you'll need the database ID of your organization on {% data variables.product.prodname_ghe_cloud %}. Replace `ORGANIZATION` with the name of your organization to get this ID from the `id` field in the response. + +```shell +curl --header "Authorization: Bearer YOUR-TOKEN" \ + "{% data variables.product.rest_url %}/orgs/ORGANIZATION" +``` + +> [!NOTE] If you're migrating to {% data variables.enterprise.data_residency_site %}, replace `{% data variables.product.rest_url %}` with the base API URL for your enterprise's subdomain, such as `https://api.{% data variables.enterprise.data_residency_example_domain %}`. + +Upload the archive with a `POST` request, replacing `ORGANIZATION-ID` with your organization's database ID. This request works for archives up to 100 MiB. For larger archives, use an external blob storage provider. + +```shell +curl --request POST \ + --header "Authorization: Bearer YOUR-TOKEN" \ + --header "Content-Type: application/octet-stream" \ + --data-binary @archive.tar.gz \ + "https://uploads.github.com/organizations/ORGANIZATION-ID/gei/archive?name=archive.tar.gz" +``` + +> [!NOTE] If you're migrating to {% data variables.enterprise.data_residency_site %}, replace `uploads.github.com` with the uploads host for your enterprise's subdomain, such as `uploads.{% data variables.enterprise.data_residency_example_domain %}`. + +The response includes a `uri` in the format `gei://archive/GUID`. Use this value as the `gitArchiveUrl` in the next step. + +```json +{ + "guid": "ff7b1a25-aa10-41a9-8e42-f170304b1c0d", + "node_id": "MA_kgDaACRmZjdiMWEyNS1hYTEwLTQxYTktOGU0Mi1mMTcwMzA0YjFjMGQ", + "name": "archive.tar.gz", + "size": 7103, + "uri": "gei://archive/ff7b1a25-aa10-41a9-8e42-f170304b1c0d", + "created_at": "2024-11-13T12:35:45.761-08:00" +} +``` + +## Step 4: Start your repository migration + +{% data reusables.enterprise-migration-tool.start-repository-migration-ec %} + +### `startRepositoryMigration` mutation + +```graphql +mutation startRepositoryMigration ( + $sourceId: ID!, + $ownerId: ID!, + $sourceRepositoryUrl: URI!, + $repositoryName: String!, + $continueOnError: Boolean!, + $accessToken: String!, + $githubPat: String!, + $gitArchiveUrl: String!, + $targetRepoVisibility: String! +){ + startRepositoryMigration( input: { + sourceId: $sourceId, + ownerId: $ownerId, + repositoryName: $repositoryName, + continueOnError: $continueOnError, + accessToken: $accessToken, + githubPat: $githubPat, + targetRepoVisibility: $targetRepoVisibility, + gitArchiveUrl: $gitArchiveUrl, + sourceRepositoryUrl: $sourceRepositoryUrl, + }) { + repositoryMigration { + id + migrationSource { + id + name + type + } + sourceUrl + } + } +} +``` + +{% data reusables.enterprise-migration-tool.startRepositoryMigration-table-ec %} +| `gitArchiveUrl` | A {% data variables.product.prodname_ghe_cloud %}-accessible URL to the migration archive you generated in the previous step. GitLab migrations use a single archive that contains both the Git source and metadata, so you don't need to provide a separate `metadataArchiveUrl`. +| `sourceRepositoryUrl` | The URL of your source repository on GitLab, using the format `https://GITLAB-SERVER/{group}/{project}`. For nested subgroups, include the full path, such as `https://GITLAB-SERVER/{parent-group}/{subgroup}/{project}`. {% data variables.product.prodname_ghe_cloud %} does not connect to this URL during the migration; it's recorded for reference. + +Because GitLab migrations are archive-based, {% data variables.product.prodname_ghe_cloud %} does not connect to GitLab during the migration. The `accessToken` variable is required by the mutation but isn't used, so you can set it to any placeholder value, such as `not-used`. + +For {% data variables.product.pat_generic %} requirements, see [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access). + +{% data reusables.enterprise-migration-tool.next-check-status %} + +## Step 5: Check the status of your migration + +{% data reusables.enterprise-migration-tool.check-migration %} + +## Step 6: Validate your migration and check the error log + +{% data reusables.enterprise-migration-tool.validate-migration-log %} + +## Further reading + +* [AUTOTITLE](/migrations/using-github-enterprise-importer/migrate-from-gitlab/follow-up-tasks) diff --git a/data/reusables/enterprise-migration-tool/add-target-uploads-url.md b/data/reusables/enterprise-migration-tool/add-target-uploads-url.md new file mode 100644 index 000000000000..40b68d0e66e5 --- /dev/null +++ b/data/reusables/enterprise-migration-tool/add-target-uploads-url.md @@ -0,0 +1 @@ +If you're migrating to {% data variables.enterprise.data_residency_site %} and using {% data variables.product.prodname_ghos %}, also add `--target-uploads-url TARGET-UPLOADS-URL`, where TARGET-UPLOADS-URL is the base uploads API URL for your enterprise's subdomain. For example: `https://uploads.{% data variables.enterprise.data_residency_example_domain %}`. This defaults to `https://uploads.github.com`. diff --git a/data/reusables/enterprise-migration-tool/follow-up-tasks-common.md b/data/reusables/enterprise-migration-tool/follow-up-tasks-common.md new file mode 100644 index 000000000000..791b363dbb56 --- /dev/null +++ b/data/reusables/enterprise-migration-tool/follow-up-tasks-common.md @@ -0,0 +1,42 @@ +## Checking the migration status + +First, check whether your migration succeeded or failed. + +The way you check the status of your migration depends on how you ran the migration. + +* If you ran the migration using the {% data variables.product.prodname_cli %}, by default, the process will display whether the migration succeeded or failed once the migration is complete. If the migration failed, you will see the reason for failure. + + ```text + Migration completed (ID: RM_123)! State: SUCCEEDED + ``` + +* If you ran the migration using the {% data variables.product.prodname_cli %} with the optional `--queue-only` argument, the process will exit immediately after queueing the migration, and will not tell you if the migration succeeded or failed. You can check a migration's status using the `wait-for-migration` command, or by reviewing the migration log. + +## Reviewing the migration log + +You should review the migration log for each migrated repository. People with read access to a repository can access the migration log for the repository on {% data variables.product.prodname_dotcom %}. + +1. Navigate to the migrated repository in your destination organization. +{% data reusables.repositories.sidebar-issues %} +1. Click the issue with the title "Migration Log." + +For more information, see [AUTOTITLE](/migrations/using-github-enterprise-importer/completing-your-migration-with-github-enterprise-importer/accessing-your-migration-logs-for-github-enterprise-importer). + +## Setting repository visibility + +{% data reusables.enterprise-migration-tool.setting-repository-visibility %} + + For example, replace YOUR_ORG with your organization name, and the command below will set all of the organization's repositories to internal visibility. + + ```bash copy + export ORG=YOUR_ORG + gh repo list "$ORG" --limit 100000 --json name -q '.[].name' | xargs -I{} gh repo edit "$ORG/{}" --visibility internal + ``` + +## Reclaiming mannequins + +{% data reusables.enterprise-migration-tool.reclaiming-mannequins %} + +## Configuring IP allow lists + +If you added the IP ranges for {% data variables.product.prodname_importer_proper_name %} to the IP allow list for your destination organization, you can remove those entries. {% data reusables.enterprise-migration-tool.reenable-idp-ip-restrictions %} diff --git a/data/reusables/enterprise-migration-tool/github-pat-required-scopes.md b/data/reusables/enterprise-migration-tool/github-pat-required-scopes.md index 591a3d5cd2b8..3981ab289f23 100644 --- a/data/reusables/enterprise-migration-tool/github-pat-required-scopes.md +++ b/data/reusables/enterprise-migration-tool/github-pat-required-scopes.md @@ -6,6 +6,6 @@ The scopes that are required for your {% data variables.product.prodname_dotcom Task | Organization owner | Migrator ---- | -------- | ----- | Assigning the migrator role for repository migrations | `admin:org` | {% octicon "dash" aria-label="Not applicable" %} -Running a repository migration (destination organization) | `repo`, `admin:org`, `workflow` | `repo`, `read:org`, `workflow` -Downloading a migration log | `repo`, `admin:org`, `workflow` | `repo`, `read:org`, `workflow` -Reclaiming mannequins | `repo`, `admin:org`, `workflow` | {% octicon "dash" aria-label="Not applicable" %} +Running a repository migration (destination organization) | `repo`, `workflow`, `admin:org` | `repo`, `workflow`, `read:org` +Downloading a migration log | `repo`, `workflow`, `admin:org` | `repo`, `workflow`, `read:org` +Reclaiming mannequins | `repo`, `workflow`, `admin:org` | {% octicon "dash" aria-label="Not applicable" %} diff --git a/data/reusables/enterprise-migration-tool/gl2gh-install-and-update.md b/data/reusables/enterprise-migration-tool/gl2gh-install-and-update.md new file mode 100644 index 000000000000..8a25e401f68c --- /dev/null +++ b/data/reusables/enterprise-migration-tool/gl2gh-install-and-update.md @@ -0,0 +1,14 @@ +1. Install the {% data variables.product.prodname_cli %}. + * {% data reusables.cli.cli-installation %} + * If you already have {% data variables.product.prodname_cli %} installed, run `gh --version` to ensure you're running version 2.4.0 or newer. If you have an older version, visit the [{% data variables.product.prodname_cli %} repository](https://github.com/cli/cli#installation) for upgrade instructions. +1. Install the {% data variables.product.prodname_gl2gh_cli_short %}. + + ```shell copy + gh extension install github/gh-gl2gh + ``` + +1. The {% data variables.product.prodname_gl2gh_cli %} is updated frequently. {% data reusables.enterprise-migration-tool.update-your-extension %} + + ```shell copy + gh extension upgrade github/gh-gl2gh + ``` diff --git a/data/reusables/enterprise-migration-tool/grant-migrator-role-ghecom.md b/data/reusables/enterprise-migration-tool/grant-migrator-role-ghecom.md index 0065f4eafbb6..22eac37396a6 100644 --- a/data/reusables/enterprise-migration-tool/grant-migrator-role-ghecom.md +++ b/data/reusables/enterprise-migration-tool/grant-migrator-role-ghecom.md @@ -1 +1 @@ ->[!NOTE] If you're the granting the migrator role for {% data variables.enterprise.data_residency_site %}, you must also include the target API URL for your enterprise's subdomain. For example: `--target-api-url https://api.{% data variables.enterprise.data_residency_example_domain %}`. +>[!NOTE] If you're granting the migrator role for {% data variables.enterprise.data_residency_site %}, you must also include the target API URL for your enterprise's subdomain. For example: `--target-api-url https://api.{% data variables.enterprise.data_residency_example_domain %}`. diff --git a/data/reusables/enterprise-migration-tool/migration-data-limitations.md b/data/reusables/enterprise-migration-tool/migration-data-limitations.md new file mode 100644 index 000000000000..be522522d14e --- /dev/null +++ b/data/reusables/enterprise-migration-tool/migration-data-limitations.md @@ -0,0 +1,19 @@ +## Limitations on migrated data + +There are limits to what {% data variables.product.prodname_importer_proper_name %} can migrate. Some are due to limitations of {% data variables.product.prodname_dotcom %}, while others are limitations of {% data variables.product.prodname_importer_proper_name %} itself. + +### Limitations of {% data variables.product.prodname_dotcom %} + +* **2 GiB size limit for a single Git commit:** No single commit in your Git repository can be larger than 2 GiB. If any of your commits are larger than 2 GiB, you will need to split the commit into smaller commits that are each 2 GiB or smaller. +* **2 GiB size limit for a single push:** No single push can be larger than 2 GiB. Larger pushes fail with a `pack exceeds maximum allowed size` error. +* **255 byte limit for Git references:** No single Git reference, commonly known as a "ref", can have a name larger than 255 bytes. Usually, this means that your references cannot be more than 255 characters long, but any non-ASCII characters, such as emojis, may consume more than one byte. If any of your Git references are too large, we'll return a clear error message. +* **100 MiB file size limit:** After you complete your migration, no single file in your Git repository can be larger than 100 MiB. During repository migration this limit is increased to 400 MiB. Consider using {% data variables.large_files.product_name_short %} to store large files. + +### Limitations of {% data variables.product.prodname_importer_proper_name %} + +* {% data reusables.enterprise-migration-tool.git-repo-size-limit %} +* **400 MiB file size limit:** When migrating a repository with {% data variables.product.prodname_importer_proper_name %}, no single file in your Git repository can be larger than 400 MiB. Consider using {% data variables.large_files.product_name_short %} for storing large files. +* **{% data variables.large_files.product_name_short %} objects not migrated:** The {% data variables.product.prodname_importer_secondary_name %} can migrate repositories that use {% data variables.large_files.product_name_short %}, but the LFS objects themselves will not be migrated. They can be pushed to your migration destination as a follow-up task after the migration is complete. +* **Delayed code search functionality:** Re-indexing the search index can take a few hours after a repository is migrated, and code searches may return unexpected results until re-indexing is complete. +* **Rulesets configured for your organization can cause migrations to fail:** For example, if you configured a rule that requires email addresses for commit authors to end with `@monalisa.cat`, and the repository you're migrating contains commits that don't comply with this rule, your migration will fail. +* **Mannequin content might not be searchable:** Mannequins are placeholder users to which imported content (such as issues, pull requests, comments, etc.) is associated. When you search for content associated with a mannequin, such as assigned issues, the issues may not be found. Once a mannequin is reclaimed, the content should be found via the new owner. diff --git a/data/reusables/enterprise-migration-tool/organization-structure-tasks.md b/data/reusables/enterprise-migration-tool/organization-structure-tasks.md index f416f0a7be1f..a5f1ae3e971f 100644 --- a/data/reusables/enterprise-migration-tool/organization-structure-tasks.md +++ b/data/reusables/enterprise-migration-tool/organization-structure-tasks.md @@ -1,3 +1,3 @@ -1. Decide what your new organization structural will be. +1. Decide what your new organization structure will be. 1. Decide if you need to break up your migration effort into smaller batches. 1. If so, decide how you want to break up your migrations. diff --git a/data/reusables/enterprise-migration-tool/supported-migration-paths.md b/data/reusables/enterprise-migration-tool/supported-migration-paths.md index a0b2ee0f606e..63be17ea913d 100644 --- a/data/reusables/enterprise-migration-tool/supported-migration-paths.md +++ b/data/reusables/enterprise-migration-tool/supported-migration-paths.md @@ -4,6 +4,7 @@ * Bitbucket Server and Bitbucket Data Center 5.14+ * {% data variables.product.prodname_dotcom_the_website %} * {% data variables.product.prodname_ghe_server %} (GHES) 3.4.1+ +* GitLab (GitLab.com or [maintained self-hosted versions](https://docs.gitlab.com/policy/maintenance/#maintained-versions)) > [!NOTE] > {% data variables.product.prodname_importer_proper_name %} does not currently support migrations **from {% data variables.enterprise.data_residency_site %}.** diff --git a/data/variables/product.yml b/data/variables/product.yml index 02cb88cf85f3..801392674734 100644 --- a/data/variables/product.yml +++ b/data/variables/product.yml @@ -51,6 +51,9 @@ prodname_ado2gh_cli_short: ADO2GH extension prodname_bbs2gh: BBS2GH prodname_bbs2gh_cli: BBS2GH extension of the GitHub CLI prodname_bbs2gh_cli_short: BBS2GH extension +prodname_gl2gh_cli: GL2GH extension of the GitHub CLI +prodname_gl2gh_cli_short: GL2GH extension +prodname_gl2gh: GL2GH prodname_ghos: GitHub-owned blob storage ## Enterprise Live Migrations @@ -124,8 +127,7 @@ pat_v2: 'fine-grained personal access token' pat_v2_plural: 'fine-grained personal access tokens' pat_v2_caps: 'Fine-grained personal access token' pat_v2_caps_plural: 'Fine-grained personal access tokens' -pat_v1: >- - personal access token (classic) +pat_v1: 'personal access token (classic)' pat_v1_plural: >- personal access tokens (classic) pat_v1_caps: >- From 37765958a3796bbcab1fa001b73f92ac1c0c08ec Mon Sep 17 00:00:00 2001 From: docs-bot <77750099+docs-bot@users.noreply.github.com> Date: Mon, 3 Aug 2026 11:15:19 -0700 Subject: [PATCH 2/6] fix: add 4 new translation correction patterns (es/fr/ko) (#62599) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kevin Heis Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../lib/correct-translation-content.ts | 40 +++++++++++ .../tests/correct-translation-content.ts | 70 +++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/src/languages/lib/correct-translation-content.ts b/src/languages/lib/correct-translation-content.ts index e1497645e648..3aed65d7592d 100644 --- a/src/languages/lib/correct-translation-content.ts +++ b/src/languages/lib/correct-translation-content.ts @@ -249,6 +249,17 @@ export function correctTranslatedContentStrings( '{% ifversion ghec %}SCIM{% else %} con Okta', '{% ifversion ghec %}SCIM{% else %} con Okta{% endif %}', ) + + // data/reusables/repositories/you-can-fork.md: translation starts with + // `{% elsif ghes or ghec %}` instead of `{% ifversion ghes or ghec %}` — + // the opening `{% ifversion %}` was replaced with `{% elsif %}`, leaving no + // opener and causing "elsif not found" errors in fork-a-repo.md and forks.md. + if ( + context.dottedPath === 'reusables.repositories.you-can-fork' || + context.relativePath?.endsWith('data/reusables/repositories/you-can-fork.md') + ) { + content = content.replace(/^\{%-?\s*elsif\s+/, '{% ifversion ') + } } if (context.code === 'ja') { @@ -1504,6 +1515,24 @@ export function correctTranslatedContentStrings( '{%- collaborateurs invités ifversion %}', '{%- ifversion guest-collaborators %}', ) + + // `{% ifversion { + test('replaces leading elsif with ifversion', () => { + const broken = '{% elsif ghes or ghec %} Puedes bifurcar...' + const fixed = '{% ifversion ghes or ghec %} Puedes bifurcar...' + const ctx = { + code: 'es', + relativePath: 'data/reusables/repositories/you-can-fork.md', + skipOrphanStripping: true, + } + expect(correctTranslatedContentStrings(broken, '', ctx)).toBe(fixed) + // already correct input is unchanged + expect(correctTranslatedContentStrings(fixed, '', ctx)).toBe(fixed) + }) + + test('does not affect other es content', () => { + const other = '{% elsif ghes or ghec %} other content' + expect(fix(other, 'es')).toBe(other) + }) + }) + + describe('fr: stray < before plan name in ifversion', () => { + test('removes stray < before plan name in ifversion', () => { + expect(fix('{% ifversion { + expect(fix('{% ifversion ghec %}foo{% endif %}', 'fr')).toBe( + '{% ifversion ghec %}foo{% endif %}', + ) + }) + }) + + describe('fr: translated classroom reusable per-file fix', () => { + test('restores canonical reusable tag', () => { + const broken = '{% reusable (fr) classroom.vous-pouvez-créer-une-pull-request-pour-retour %}' + const fixed = '{% data reusables.classroom.you-can-create-a-pull-request-for-feedback %}' + expect(fix(broken, 'fr')).toBe(fixed) + // already correct is unchanged + expect(fix(fixed, 'fr')).toBe(fixed) + }) + }) + + describe('ko: about-READMEs.md per-file fix', () => { + test('removes orphan endif before first ifversion', () => { + const broken = '파일{% endif %}{% ifversion fpt or ghec %}, 기여' + const fixed = '파일{% ifversion fpt or ghec %}, 기여' + const ctx = { + code: 'ko', + relativePath: 'data/reusables/repositories/about-READMEs.md', + skipOrphanStripping: true, + } + expect(correctTranslatedContentStrings(broken, '', ctx)).toBe(fixed) + // already correct is unchanged + expect(correctTranslatedContentStrings(fixed, '', ctx)).toBe(fixed) + }) + + test('does not affect other ko content', () => { + const other = 'foo{% endif %}{% ifversion fpt or ghec %}, bar' + expect(fix(other, 'ko')).toBe(other) + }) + }) }) From 477d75c3badb2bfcda521a7a181b3a9e07422dd4 Mon Sep 17 00:00:00 2001 From: Kevin Heis Date: Mon, 3 Aug 2026 11:17:37 -0700 Subject: [PATCH 3/6] Stop the sidebar rail from clobbering #anchor scrolling (#62598) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9c1583e3-83c9-45ea-93f9-76f7bb3a2a47 --- .../get-started/foo/anchor-scrolling.md | 74 +++++++++++++++++++ .../content/get-started/foo/for-playwright.md | 3 + .../fixtures/content/get-started/foo/index.md | 1 + .../tests/playwright-rendering.spec.ts | 53 +++++++++++++ src/landings/components/SidebarProduct.tsx | 41 ++++++++-- 5 files changed, 165 insertions(+), 7 deletions(-) create mode 100644 src/fixtures/fixtures/content/get-started/foo/anchor-scrolling.md diff --git a/src/fixtures/fixtures/content/get-started/foo/anchor-scrolling.md b/src/fixtures/fixtures/content/get-started/foo/anchor-scrolling.md new file mode 100644 index 000000000000..2fcd22b34f48 --- /dev/null +++ b/src/fixtures/fixtures/content/get-started/foo/anchor-scrolling.md @@ -0,0 +1,74 @@ +--- +title: Anchor scrolling +intro: Exists for a Playwright test that a #anchor in the URL scrolls to the right heading. +versions: + fpt: '*' + ghes: '*' + ghec: '*' +--- + +This page is deliberately tall, with the target heading in the middle rather than at the end. That lets a test tell the difference between "scrolled to the anchor" and "still at the top of the article", and stops the assertion passing by accident when the browser clamps to the maximum scroll offset. + +## Filler heading before target 1 + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +## Filler heading before target 2 + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +## Filler heading before target 3 + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +## Target heading + +The Playwright test links to `#target-heading` and asserts this heading ends up near the top of the viewport. + +## Filler heading after target 1 + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +## Filler heading after target 2 + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +## Filler heading after target 3 + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. + +Filler paragraph so the article is taller than the viewport. Without enough height the browser has nowhere to scroll, and a test asserting the scroll position of an anchor target would pass no matter what the page does. Repeat this a few times per section to build up some height. diff --git a/src/fixtures/fixtures/content/get-started/foo/for-playwright.md b/src/fixtures/fixtures/content/get-started/foo/for-playwright.md index 0b71689d6720..7f6300a64717 100644 --- a/src/fixtures/fixtures/content/get-started/foo/for-playwright.md +++ b/src/fixtures/fixtures/content/get-started/foo/for-playwright.md @@ -14,3 +14,6 @@ This page exists to serve a Playwright test to view an article page. ## Second heading This is the second heading. + +For a Playwright test of cross-page anchor navigation, here is a link to the +[target heading](/get-started/foo/anchor-scrolling#target-heading). diff --git a/src/fixtures/fixtures/content/get-started/foo/index.md b/src/fixtures/fixtures/content/get-started/foo/index.md index 198a9293a549..d774a1ca7913 100644 --- a/src/fixtures/fixtures/content/get-started/foo/index.md +++ b/src/fixtures/fixtures/content/get-started/foo/index.md @@ -20,4 +20,5 @@ children: - /code-snippet-with-hashbang - /journey-test-article - /broken-frontmatter-translation + - /anchor-scrolling --- diff --git a/src/fixtures/tests/playwright-rendering.spec.ts b/src/fixtures/tests/playwright-rendering.spec.ts index 114e37a198ea..9e74522d9403 100644 --- a/src/fixtures/tests/playwright-rendering.spec.ts +++ b/src/fixtures/tests/playwright-rendering.spec.ts @@ -859,6 +859,59 @@ test.describe('secondary-bar breadcrumb scroller', () => { }) }) +test.describe('anchor link scrolling', () => { + // The doc-tree rail only renders at the xxl breakpoint (1400px) and up. Its + // "centre the active item" effect used to call scrollIntoView, which scrolls + // every scrollable ancestor including the document, so it undid the browser's + // scroll to the #anchor and dumped the reader at the top of the article. + // These tests only mean anything with the rail on screen. + const WIDE = { width: 1400, height: 720 } + + // The heading is offset from the top of the viewport by `scroll-margin-top` + // (109px at xxl, see src/frame/stylesheets/scroll-top.scss). Allow slack for + // rounding and sticky-header tweaks, but stay well clear of "not scrolled". + const expectScrolledToTarget = async (page: import('@playwright/test').Page) => { + const heading = page.locator('#target-heading') + await expect(heading).toBeVisible() + await expect.poll(async () => Math.round((await heading.boundingBox())!.y)).toBeLessThan(200) + expect(await page.evaluate(() => Math.round(window.scrollY))).toBeGreaterThan(300) + } + + test('a direct load of a URL with an #anchor scrolls to that section', async ({ page }) => { + page.setViewportSize(WIDE) + await page.goto('/get-started/foo/anchor-scrolling#target-heading') + await expect(page.getByTestId('sidebar')).toBeVisible() + await expectScrolledToTarget(page) + + // Guard the setup: the regression only shows when the rail has actually + // scrolled its own container to centre the active item. If a fixture change + // ever makes the rail short enough that it doesn't need to scroll, these + // tests would keep passing while covering nothing — fail loudly instead. + const railScrollTop = await page + .getByTestId('sidebar') + .evaluate((el) => el.closest('[role="region"]')!.scrollTop) + expect(railScrollTop).toBeGreaterThan(0) + }) + + test('clicking a cross-page #anchor link scrolls to that section', async ({ page }) => { + page.setViewportSize(WIDE) + await page.goto('/get-started/foo/for-playwright') + await page.locator('main a[href$="/get-started/foo/anchor-scrolling#target-heading"]').click() + await expect(page).toHaveURL(/anchor-scrolling#target-heading/) + await expectScrolledToTarget(page) + }) + + test('navigating to a page without an #anchor still lands at the top', async ({ page }) => { + page.setViewportSize(WIDE) + await page.goto('/get-started/foo/anchor-scrolling#target-heading') + await expectScrolledToTarget(page) + + await page.getByTestId('sidebar').getByRole('link', { name: 'Bar', exact: true }).click() + await expect(page).toHaveURL(/\/en\/get-started\/foo\/bar$/) + await expect.poll(async () => page.evaluate(() => Math.round(window.scrollY))).toBe(0) + }) +}) + test.describe('survey', () => { test.skip(!ANALYTICS_ENABLED, 'Analytics are disabled') diff --git a/src/landings/components/SidebarProduct.tsx b/src/landings/components/SidebarProduct.tsx index 233317f16983..13d60f687e6a 100644 --- a/src/landings/components/SidebarProduct.tsx +++ b/src/landings/components/SidebarProduct.tsx @@ -8,6 +8,7 @@ import { useContext, useEffect, useMemo, + useRef, useState, } from 'react' import { NavList } from '@primer/react-brand' @@ -21,6 +22,22 @@ import { flattenDescendants, MAX_NAVLIST_LEVEL } from './sidebar-navlist-depth' import styles from './SidebarProduct.module.scss' +// The nearest ancestor that actually scrolls vertically. Brand's NavList.SubNav +// wrappers use `overflow-y: hidden`, so match only auto/scroll to skip past them +// and land on the sidebar's own overflow container. Returns null when the rail is +// hidden (below the xxl breakpoint it is `display: none`, so nothing scrolls). +function findScrollableAncestor(element: Element): HTMLElement | null { + let node = element.parentElement + while (node) { + const { overflowY } = getComputedStyle(node) + if ((overflowY === 'auto' || overflowY === 'scroll') && node.scrollHeight > node.clientHeight) { + return node + } + node = node.parentElement + } + return null +} + type Router = ReturnType // Brand NavList.Item renders a plain (its `as` prop only accepts 'a' | 'button', @@ -148,6 +165,7 @@ export const SidebarProduct = () => { [routePath, pendingHref, navigate, prefetch], ) const restNavValue = useMemo(() => ({ asPath, query }), [asPath, query]) + const rootRef = useRef(null) useEffect(() => { // Clear the optimistic highlight if a navigation genuinely fails, so it doesn't @@ -165,13 +183,22 @@ export const SidebarProduct = () => { // Brand NavList auto-expands the whole ancestor chain of the active item, so // scroll to the item marked aria-current="page" (the active article) rather // than the top-most expanded section. - const activeArticle = document.querySelector('[aria-current="page"]') + const activeArticle = rootRef.current?.querySelector('[aria-current="page"]') + if (!activeArticle) return + + // Scroll the sidebar's own overflow container by hand. `scrollIntoView` would + // scroll every scrollable ancestor, including the document, which cancels the + // browser's scroll to a #anchor on load and leaves the reader at the top of + // the article. See BreadcrumbsScroller for the same approach. + const container = findScrollableAncestor(activeArticle) + if (!container) return + + const containerRect = container.getBoundingClientRect() + const activeRect = activeArticle.getBoundingClientRect() // Setting to the top doesn't give enough context of surrounding categories - activeArticle?.scrollIntoView({ block: 'center' }) - // scrollIntoView affects some articles that are very low in the sidebar - // The content scrolls down a bit. This sets the article content back up - // top unless the route contains a link heading. - if (!router.asPath.includes('#')) window?.scrollTo(0, 0) + const delta = + activeRect.top - containerRect.top - (container.clientHeight - activeRect.height) / 2 + container.scrollBy({ top: delta, behavior: 'instant' }) }, []) if (!sidebarTree) { @@ -221,7 +248,7 @@ export const SidebarProduct = () => { } return ( -
+
{isRestPage ? restSection() : productSection()} From 85008072b6466ccf51ac7d7d03588d6e9245d636 Mon Sep 17 00:00:00 2001 From: Madison Ficorilli Date: Mon, 3 Aug 2026 15:15:04 -0400 Subject: [PATCH 4/6] Advisory Database malware expansion (#62500) Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- .../github-advisory-database.md | 33 +++++++++++-------- ...endabot-malware-alerts-multi-ecosystem.yml | 6 ++++ .../advisory-database/malware-overview.md | 4 +++ 3 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 data/features/dependabot-malware-alerts-multi-ecosystem.yml diff --git a/content/code-security/concepts/vulnerability-reporting-and-management/github-advisory-database.md b/content/code-security/concepts/vulnerability-reporting-and-management/github-advisory-database.md index 4c7c818350bc..8db7949f1865 100644 --- a/content/code-security/concepts/vulnerability-reporting-and-management/github-advisory-database.md +++ b/content/code-security/concepts/vulnerability-reporting-and-management/github-advisory-database.md @@ -41,17 +41,17 @@ Both of these advisory types are public information about open source packages. Generally, we name our supported ecosystems after the software programming language's associated package registry. We review advisories if they are for a vulnerability in a package that comes from a supported registry. -* Composer (registry: https://packagist.org/) -* Erlang (registry: https://hex.pm/) -* Go (registry: https://pkg.go.dev/) -* GitHub Actions (https://github.com/marketplace?type=actions/) -* Maven (registry: https://repo.maven.apache.org/maven2) -* Npm (registry: https://www.npmjs.com/) -* NuGet (registry: https://www.nuget.org/) -* Pip (registry: https://pypi.org/) -* Pub (registry: https://pub.dev/packages/registry) -* RubyGems (registry: https://rubygems.org/) -* Rust (registry: https://crates.io/) +* Composer (registry: [https://packagist.org/](https://packagist.org/)) +* Erlang (registry: [https://hex.pm/](https://hex.pm/)) +* Go (registry: [https://pkg.go.dev/](https://pkg.go.dev/)) +* GitHub Actions ([https://github.com/marketplace?type=actions](https://github.com/marketplace?type=actions)) +* Maven (registry: [https://repo.maven.apache.org/maven2](https://repo.maven.apache.org/maven2)) +* Npm (registry: [https://www.npmjs.com/](https://www.npmjs.com/)) +* NuGet (registry: [https://www.nuget.org/](https://www.nuget.org/)) +* Pip (registry: [https://pypi.org/](https://pypi.org/)) +* Pub (registry: [https://pub.dev/packages/registry](https://pub.dev/packages/registry)) +* RubyGems (registry: [https://rubygems.org/](https://rubygems.org/)) +* Rust (registry: [https://crates.io/](https://crates.io/)) * Swift (registry: N/A) If you have a suggestion for a new ecosystem we should support, please open an [issue](https://github.com/github/advisory-database/issues) for discussion. @@ -68,7 +68,13 @@ If you enable {% data variables.product.prodname_dependabot_alerts %} for your r {% data reusables.advisory-database.malware-overview %} -{% data variables.product.prodname_dependabot %} doesn't generate alerts when malware is detected as most of the vulnerabilities cannot be resolved by downstream users. You can view malware advisories by searching for `type:malware` in the {% data variables.product.prodname_advisory_database %}. +{% ifversion dependabot-malware-alerts-multi-ecosystem %} + +When malware alerts are enabled, {% data variables.product.prodname_dependabot %} generates an alert when malware is detected. For more information, see [AUTOTITLE](/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/configure-malware-alerts). + +{% endif %} + +You can view malware advisories by searching for `type:malware` in the {% data variables.product.prodname_advisory_database %}. Our malware advisories are mostly about substitution attacks. During this type of attack, an attacker publishes a package to the public registry with the same name as a dependency that users rely on from a third party or private registry, with the hope that the malicious version is consumed. {% data variables.product.prodname_dependabot %} doesn't look at project configurations to determine if the packages are coming from a private registry, so we can't determine whether you're using the malicious version or a non-malicious version that has the same name. Users who have their dependencies appropriately scoped should not be affected by malware. @@ -100,6 +106,7 @@ The {% data variables.product.prodname_advisory_database %} supports both CVSS v Each security advisory contains information about the vulnerability or malware, which may include the description, severity, affected package, package ecosystem, affected versions and patched versions, impact, and optional information such as references, workarounds, and credits. In addition, advisories from the National Vulnerability Database list contain a link to the CVE record, where you can read more details about the vulnerability, its CVSS scores, and its qualitative severity level. For more information, see the [National Vulnerability Database](https://nvd.nist.gov/) from the National Institute of Standards and Technology. The severity level is one of four possible levels defined in the [Common Vulnerability Scoring System (CVSS), Section 5](https://www.first.org/cvss/specification-document). + * Low * Medium/Moderate * High @@ -111,7 +118,7 @@ The {% data variables.product.prodname_advisory_database %} uses the CVSS levels ### EPSS scores -The Exploit Prediction Scoring System, or EPSS, is a system devised by the global Forum of Incident Response and Security Teams (FIRST) for quantifying the likelihood of vulnerability exploit. The model produces a probability score between 0 and 1 (0 and 100%), where the higher the score, the greater the probability that a vulnerability will be exploited. For more information about FIRST, see https://www.first.org/. +The Exploit Prediction Scoring System, or EPSS, is a system devised by the global Forum of Incident Response and Security Teams (FIRST) for quantifying the likelihood of vulnerability exploit. The model produces a probability score between 0 and 1 (0 and 100%), where the higher the score, the greater the probability that a vulnerability will be exploited. For more information about FIRST, see [https://www.first.org/](https://www.first.org/). The {% data variables.product.prodname_advisory_database %} includes EPSS scores from FIRST for advisories containing CVEs with corresponding EPSS data. {% data variables.product.company_short %} also displays the EPSS score percentile, which is the proportion of all scored vulnerabilities with the same or a lower EPSS score. diff --git a/data/features/dependabot-malware-alerts-multi-ecosystem.yml b/data/features/dependabot-malware-alerts-multi-ecosystem.yml new file mode 100644 index 000000000000..854b1486c1ac --- /dev/null +++ b/data/features/dependabot-malware-alerts-multi-ecosystem.yml @@ -0,0 +1,6 @@ +# Reference: #23167 +# Expand ADB malware advisory support using OpenSSF malicious-packages [GA] +versions: + fpt: '*' + ghec: '*' + ghes: '> 3.22' diff --git a/data/reusables/advisory-database/malware-overview.md b/data/reusables/advisory-database/malware-overview.md index db5beb23a3a8..f084724d4971 100644 --- a/data/reusables/advisory-database/malware-overview.md +++ b/data/reusables/advisory-database/malware-overview.md @@ -1 +1,5 @@ +{% ifversion dependabot-malware-alerts-multi-ecosystem %} +**Malware** advisories are advisories about malicious open source packages. We publish them automatically into the {% data variables.product.prodname_advisory_database %} from the npm security team and the [OpenSSF Malicious Packages](https://github.com/ossf/malicious-packages) repository. +{% else %} **Malware** advisories relate to vulnerabilities caused by malware and are exclusive to the **npm** ecosystem. We publish them automatically into the {% data variables.product.prodname_advisory_database %}, directly from information provided by the npm security team. +{% endif %} From fc64d1891ca0524a3dcc49502e65fa403a6130e3 Mon Sep 17 00:00:00 2001 From: Steve Ward Date: Mon, 3 Aug 2026 15:33:55 -0400 Subject: [PATCH 5/6] Add CTAs to search links in "Searching issues and Pull Requests" (#62397) --- .../searching-issues-and-pull-requests.md | 168 +++++++++--------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/content/search-github/searching-on-github/searching-issues-and-pull-requests.md b/content/search-github/searching-on-github/searching-issues-and-pull-requests.md index a370fb279190..284bc3625c46 100644 --- a/content/search-github/searching-on-github/searching-issues-and-pull-requests.md +++ b/content/search-github/searching-on-github/searching-issues-and-pull-requests.md @@ -30,10 +30,10 @@ By default, {% data variables.product.github %} search will return both issues a | Qualifier | Example | ------------- | ------------- -| `type:pr` | [**cat type:pr**](https://github.com/search?q=cat+type%3Apr&type=Issues) matches pull requests with the word "cat." -| `type:issue` | [**github commenter:defunkt type:issue**](https://github.com/search?q=github+commenter%3Adefunkt+type%3Aissue&type=Issues) matches issues that contain the word "github," and have a comment by @defunkt. -| `is:pr` | [**event is:pr**](https://github.com/search?utf8=%E2%9C%93&q=event+is%3Apr&type=) matches pull requests with the word "event." -| `is:issue` | [**is:issue label:bug is:closed**](https://github.com/search?utf8=%E2%9C%93&q=is%3Aissue+label%3Abug+is%3Aclosed&type=) matches closed issues with the label "bug." +| `type:pr` | [**cat type:pr**](https://github.com/search?q=cat+type%3Apr&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests with the word "cat." +| `type:issue` | [**github commenter:defunkt type:issue**](https://github.com/search?q=github+commenter%3Adefunkt+type%3Aissue&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues that contain the word "github," and have a comment by @defunkt. +| `is:pr` | [**event is:pr**](https://github.com/search?utf8=%E2%9C%93&q=event+is%3Apr&type=&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests with the word "event." +| `is:issue` | [**is:issue label:bug is:closed**](https://github.com/search?utf8=%E2%9C%93&q=is%3Aissue+label%3Abug+is%3Aclosed&type=&ref_product=github&ref_type=engagement&ref_style=text) matches closed issues with the label "bug." ## Search by the title, body, or comments @@ -41,9 +41,9 @@ With the `in` qualifier you can restrict your search to the title, body, comment | Qualifier | Example | ------------- | ------------- -| `in:title` | [**warning in:title**](https://github.com/search?q=warning+in%3Atitle&type=Issues) matches issues with "warning" in their title. -| `in:body` | [**error in:title,body**](https://github.com/search?q=error+in%3Atitle%2Cbody&type=Issues) matches issues with "error" in their title or body. -| `in:comments` | [**shipit in:comments**](https://github.com/search?q=shipit+in%3Acomment&type=Issues) matches issues mentioning "shipit" in their comments. +| `in:title` | [**warning in:title**](https://github.com/search?q=warning+in%3Atitle&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with "warning" in their title. +| `in:body` | [**error in:title,body**](https://github.com/search?q=error+in%3Atitle%2Cbody&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with "error" in their title or body. +| `in:comments` | [**shipit in:comments**](https://github.com/search?q=shipit+in%3Acomment&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues mentioning "shipit" in their comments. ## Search within a user's or organization's repositories @@ -53,9 +53,9 @@ To search issues and pull requests in all repositories owned by a certain user o | Qualifier | Example | ------------- | ------------- -| user:USERNAME | [**user:defunkt ubuntu**](https://github.com/search?q=user%3Adefunkt+ubuntu&type=Issues) matches issues with the word "ubuntu" from repositories owned by @defunkt. -| org:ORGNAME | [**org:github**](https://github.com/search?q=org%3Agithub&type=Issues&utf8=%E2%9C%93) matches issues in repositories owned by the GitHub organization. -| repo:USERNAME/REPOSITORY | [**repo:mozilla/shumway created:<2012-03-01**](https://github.com/search?q=repo%3Amozilla%2Fshumway+created%3A%3C2012-03-01&type=Issues) matches issues from @mozilla's shumway project that were created before March 2012. +| user:USERNAME | [**user:defunkt ubuntu**](https://github.com/search?q=user%3Adefunkt+ubuntu&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the word "ubuntu" from repositories owned by @defunkt. +| org:ORGNAME | [**org:github**](https://github.com/search?q=org%3Agithub&type=Issues&utf8=%E2%9C%93&ref_product=github&ref_type=engagement&ref_style=text) matches issues in repositories owned by the GitHub organization. +| repo:USERNAME/REPOSITORY | [**repo:mozilla/shumway created:<2012-03-01**](https://github.com/search?q=repo%3Amozilla%2Fshumway+created%3A%3C2012-03-01&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues from @mozilla's shumway project that were created before March 2012. ## Search by open or closed state @@ -63,10 +63,10 @@ You can filter issues and pull requests based on whether they're open or closed | Qualifier | Example | ------------- | ------------- -| `state:open` | [**libraries state:open mentions:vmg**](https://github.com/search?utf8=%E2%9C%93&q=libraries+state%3Aopen+mentions%3Avmg&type=Issues) matches open issues that mention @vmg with the word "libraries." -| `state:closed` | [**design state:closed in:body**](https://github.com/search?utf8=%E2%9C%93&q=design+state%3Aclosed+in%3Abody&type=Issues) matches closed issues with the word "design" in the body. -| `is:open` | [**performance is:open is:issue**](https://github.com/search?q=performance+is%3Aopen+is%3Aissue&type=Issues) matches open issues with the word "performance." -| `is:closed` | [**android is:closed**](https://github.com/search?utf8=%E2%9C%93&q=android+is%3Aclosed&type=) matches closed issues and pull requests with the word "android." +| `state:open` | [**libraries state:open mentions:vmg**](https://github.com/search?utf8=%E2%9C%93&q=libraries+state%3Aopen+mentions%3Avmg&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches open issues that mention @vmg with the word "libraries." +| `state:closed` | [**design state:closed in:body**](https://github.com/search?utf8=%E2%9C%93&q=design+state%3Aclosed+in%3Abody&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches closed issues with the word "design" in the body. +| `is:open` | [**performance is:open is:issue**](https://github.com/search?q=performance+is%3Aopen+is%3Aissue&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches open issues with the word "performance." +| `is:closed` | [**android is:closed**](https://github.com/search?utf8=%E2%9C%93&q=android+is%3Aclosed&type=&ref_product=github&ref_type=engagement&ref_style=text) matches closed issues and pull requests with the word "android." {% ifversion archive-pull-requests %} @@ -76,7 +76,7 @@ Repository administrators can archive a pull request to remove it from public vi | Qualifier | Example | ------------- | ------------- -| `is:archived` | [**is:archived is:pr spam**](https://github.com/search?q=is%3Aarchived+is%3Apr+spam) matches archived pull requests that contain the word "spam" in repositories where you are a repository administrator. +| `is:archived` | [**is:archived is:pr spam**](https://github.com/search?q=is%3Aarchived+is%3Apr+spam&ref_product=github&ref_type=engagement&ref_style=text) matches archived pull requests that contain the word "spam" in repositories where you are a repository administrator. {% endif %} @@ -86,7 +86,7 @@ You can also use the `is` qualifier to find pull requests that are queued to mer | Qualifier | Example | | --- | --- | -| `is:queued` | [**is:queued**](https://github.com/search?q=is%3Aqueued&type=pullrequests) matches pull requests that are currently queued to merge. +| `is:queued` | [**is:queued**](https://github.com/search?q=is%3Aqueued&type=pullrequests&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that are currently queued to merge. ## Search by the reason an issue was closed @@ -94,8 +94,8 @@ You can filter issues based on the reason given when the issue was closed, using | Qualifier | Example | ------------- | ------------- -| `reason:completed` | [**libraries is:closed reason:completed**](https://github.com/search?q=libraries+is%3Aclosed+reason%3Acompleted&type=Issues) matches issues with the word "libraries" that were closed as "completed." -| `reason:"not planned"` | [**libraries is:closed reason:"not planned"**](https://github.com/search?q=libraries+is%3Aclosed+reason%3A%22not+planned%22&type=Issues) matches issues with the word "libraries" that were closed as "not planned." +| `reason:completed` | [**libraries is:closed reason:completed**](https://github.com/search?q=libraries+is%3Aclosed+reason%3Acompleted&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the word "libraries" that were closed as "completed." +| `reason:"not planned"` | [**libraries is:closed reason:"not planned"**](https://github.com/search?q=libraries+is%3Aclosed+reason%3A%22not+planned%22&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the word "libraries" that were closed as "not planned." ## Filter by repository visibility @@ -103,11 +103,11 @@ You can filter by the visibility of the repository containing the issues and pul | Qualifier | Example | | ------------- | ------------- | -| `is:public` | [**is:public**](https://github.com/search?q=is%3Apublic&type=Issues) matches issues and pull requests in public repositories. | +| `is:public` | [**is:public**](https://github.com/search?q=is%3Apublic&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests in public repositories. | | {% ifversion ghes or ghec %} | -| `is:internal` | [**is:internal**](https://github.com/search?q=is%3Ainternal&type=Issues) matches issues and pull requests in internal repositories. | +| `is:internal` | [**is:internal**](https://github.com/search?q=is%3Ainternal&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests in internal repositories. | | {% endif %} | -| `is:private` | [**is:private cupcake**](https://github.com/search?q=is%3Aprivate+cupcake&type=Issues) matches issues and pull requests that contain the word "cupcake" in private repositories you can access. +| `is:private` | [**is:private cupcake**](https://github.com/search?q=is%3Aprivate+cupcake&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests that contain the word "cupcake" in private repositories you can access. ## Search by author @@ -115,10 +115,10 @@ The `author` qualifier finds issues and pull requests created by a certain user | Qualifier | Example | ------------- | ------------- -| author:USERNAME | [**cool author:gjtorikian**](https://github.com/search?q=cool+author%3Agjtorikian&type=Issues) matches issues and pull requests with the word "cool" that were created by @gjtorikian. -| `in:body` author:USERNAME | [**bootstrap in:body author:mdo**](https://github.com/search?q=bootstrap+in%3Abody+author%3Amdo&type=Issues) matches issues written by @mdo that contain the word "bootstrap" in the body. -| author:app/USERNAME | [**author:app/robot**](https://github.com/search?q=author%3Aapp%2Frobot&type=Issues) matches issues created by the integration account named "robot." -| -author:app/USERNAME | [**-author:app/robot**](https://github.com/search?q=-author%3Aapp%2Frobot&type=Issues) matches issues created by any user other than the integration account named "robot." The minus sign, or dash character (-) before the qualifier signifies a logical NOT for the qualifier in the search query. +| author:USERNAME | [**cool author:gjtorikian**](https://github.com/search?q=cool+author%3Agjtorikian&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests with the word "cool" that were created by @gjtorikian. +| `in:body` author:USERNAME | [**bootstrap in:body author:mdo**](https://github.com/search?q=bootstrap+in%3Abody+author%3Amdo&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues written by @mdo that contain the word "bootstrap" in the body. +| author:app/USERNAME | [**author:app/robot**](https://github.com/search?q=author%3Aapp%2Frobot&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues created by the integration account named "robot." +| -author:app/USERNAME | [**-author:app/robot**](https://github.com/search?q=-author%3Aapp%2Frobot&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues created by any user other than the integration account named "robot." The minus sign, or dash character (-) before the qualifier signifies a logical NOT for the qualifier in the search query. ## Search by assignee @@ -126,7 +126,7 @@ The `assignee` qualifier finds issues and pull requests that are assigned to a c | Qualifier | Example | ------------- | ------------- -| assignee:USERNAME | [**assignee:vmg repo:libgit2/libgit2**](https://github.com/search?utf8=%E2%9C%93&q=assignee%3Avmg+repo%3Alibgit2%2Flibgit2&type=Issues) matches issues and pull requests in libgit2's project libgit2 that are assigned to @vmg. +| assignee:USERNAME | [**assignee:vmg repo:libgit2/libgit2**](https://github.com/search?utf8=%E2%9C%93&q=assignee%3Avmg+repo%3Alibgit2%2Flibgit2&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests in libgit2's project libgit2 that are assigned to @vmg. | assignee:* | [**is:open is:issue assignee:\***](https://github.com/openssl/openssl/issues/assigned/*) matches open issues within a single repository that are assigned to any user. ## Search by mention @@ -135,7 +135,7 @@ The `mentions` qualifier finds issues that mention a certain user. For more info | Qualifier | Example | ------------- | ------------- -| mentions:USERNAME | [**`resque mentions:defunkt`**](https://github.com/search?q=resque+mentions%3Adefunkt&type=Issues) matches issues with the word "resque" that mention @defunkt. +| mentions:USERNAME | [**`resque mentions:defunkt`**](https://github.com/search?q=resque+mentions%3Adefunkt&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the word "resque" that mention @defunkt. ## Search by team mention @@ -152,7 +152,7 @@ The `commenter` qualifier finds issues that contain a comment from a certain use | Qualifier | Example | ------------- | ------------- -| commenter:USERNAME | [**github commenter:defunkt org:github**](https://github.com/search?utf8=%E2%9C%93&q=github+commenter%3Adefunkt+org%3Agithub&type=Issues) matches issues in repositories owned by GitHub, that contain the word "github," and have a comment by @defunkt. +| commenter:USERNAME | [**github commenter:defunkt org:github**](https://github.com/search?utf8=%E2%9C%93&q=github+commenter%3Adefunkt+org%3Agithub&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues in repositories owned by GitHub, that contain the word "github," and have a comment by @defunkt. ## Search by a user that's involved in an issue or pull request @@ -160,8 +160,8 @@ You can use the `involves` qualifier to find issues that in some way involve a c | Qualifier | Example | ------------- | ------------- -| involves:USERNAME | **[involves:defunkt involves:jlord](https://github.com/search?q=involves%3Adefunkt+involves%3Ajlord&type=Issues)** matches issues either @defunkt or @jlord are involved in. -| `in:body` involves:USERNAME | [**NOT bootstrap in:body involves:mdo**](https://github.com/search?q=NOT+bootstrap+in%3Abody+involves%3Amdo&type=Issues) matches issues @mdo is involved in that do not contain the word "bootstrap" in the body. +| involves:USERNAME | **[involves:defunkt involves:jlord](https://github.com/search?q=involves%3Adefunkt+involves%3Ajlord&type=Issues&ref_product=github&ref_type=engagement&ref_style=text)** matches issues either @defunkt or @jlord are involved in. +| `in:body` involves:USERNAME | [**NOT bootstrap in:body involves:mdo**](https://github.com/search?q=NOT+bootstrap+in%3Abody+involves%3Amdo&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues @mdo is involved in that do not contain the word "bootstrap" in the body. ## Search for my issues and pull requests @@ -169,8 +169,8 @@ You can search for issues and pull requests you have created or have interacted | Qualifier | Example | ------------- | ------------- -| author:@me | **[author:@me](https://github.com/search?q=author%3A%40me)** matches issues and pull requests you have authored. -| is:pr commenter:@me | **[is:pr commenter:@me](https://github.com/search?q=is%3Apr+commenter%3A%40me&type=pullrequests)** matches pull requests you have commented on. +| author:@me | **[author:@me](https://github.com/search?q=author%3A%40me&ref_product=github&ref_type=engagement&ref_style=text)** matches issues and pull requests you have authored. +| is:pr commenter:@me | **[is:pr commenter:@me](https://github.com/search?q=is%3Apr+commenter%3A%40me&type=pullrequests&ref_product=github&ref_type=engagement&ref_style=text)** matches pull requests you have commented on. ## Search for linked issues and pull requests @@ -178,10 +178,10 @@ You can narrow your results to only include issues that are linked to a pull req | Qualifier | Example | | ------------- | ------------- | -| `linked:pr` | [**repo:desktop/desktop is:open linked:pr**](https://github.com/search?q=repo%3Adesktop%2Fdesktop+is%3Aopen+linked%3Apr) matches open issues in the `desktop/desktop` repository that are linked to a pull request by a closing reference. | -| `linked:issue` | [**repo:desktop/desktop is:closed linked:issue**](https://github.com/search?q=repo%3Adesktop%2Fdesktop+is%3Aclosed+linked%3Aissue) matches closed pull requests in the `desktop/desktop` repository that were linked to an issue that the pull request may have closed. | -| `-linked:pr` | [**repo:desktop/desktop is:open -linked:pr**](https://github.com/search?q=repo%3Adesktop%2Fdesktop+is%3Aopen+-linked%3Apr) matches open issues in the `desktop/desktop` repository that are not linked to a pull request by a closing reference. | -| `-linked:issue` | [**repo:desktop/desktop is:open -linked:issue**](https://github.com/search?q=repo%3Adesktop%2Fdesktop+is%3Aopen+-linked%3Aissue) matches open pull requests in the `desktop/desktop` repository that are not linked to an issue that the pull request may close. | +| `linked:pr` | [**repo:desktop/desktop is:open linked:pr**](https://github.com/search?q=repo%3Adesktop%2Fdesktop+is%3Aopen+linked%3Apr&ref_product=github&ref_type=engagement&ref_style=text) matches open issues in the `desktop/desktop` repository that are linked to a pull request by a closing reference. | +| `linked:issue` | [**repo:desktop/desktop is:closed linked:issue**](https://github.com/search?q=repo%3Adesktop%2Fdesktop+is%3Aclosed+linked%3Aissue&ref_product=github&ref_type=engagement&ref_style=text) matches closed pull requests in the `desktop/desktop` repository that were linked to an issue that the pull request may have closed. | +| `-linked:pr` | [**repo:desktop/desktop is:open -linked:pr**](https://github.com/search?q=repo%3Adesktop%2Fdesktop+is%3Aopen+-linked%3Apr&ref_product=github&ref_type=engagement&ref_style=text) matches open issues in the `desktop/desktop` repository that are not linked to a pull request by a closing reference. | +| `-linked:issue` | [**repo:desktop/desktop is:open -linked:issue**](https://github.com/search?q=repo%3Adesktop%2Fdesktop+is%3Aopen+-linked%3Aissue&ref_product=github&ref_type=engagement&ref_style=text) matches open pull requests in the `desktop/desktop` repository that are not linked to an issue that the pull request may close. | ## Search by label @@ -189,10 +189,10 @@ You can narrow your results by labels, using the `label` qualifier. Since issues | Qualifier | Example | ------------- | ------------- -| label:LABEL | [**label:"help wanted" language:ruby**](https://github.com/search?utf8=%E2%9C%93&q=label%3A%22help+wanted%22+language%3Aruby&type=Issues) matches issues with the label "help wanted" that are in Ruby repositories. -| `in:body` -label:LABEL label:LABEL | [**broken in:body -label:bug label:priority**](https://github.com/search?q=broken+in%3Abody+-label%3Abug+label%3Apriority&type=Issues) matches issues with the word "broken" in the body, that lack the label "bug", but _do_ have the label "priority." -| label:LABEL label:LABEL | [**label:bug label:resolved**](https://github.com/search?l=&q=label%3Abug+label%3Aresolved&type=Issues) matches issues with the labels "bug" and "resolved." -| label:LABEL,LABEL | [**label:bug,resolved**](https://github.com/search?q=label%3Abug%2Cresolved&type=Issues) matches issues with the label "bug" or the label "resolved." +| label:LABEL | [**label:"help wanted" language:ruby**](https://github.com/search?utf8=%E2%9C%93&q=label%3A%22help+wanted%22+language%3Aruby&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the label "help wanted" that are in Ruby repositories. +| `in:body` -label:LABEL label:LABEL | [**broken in:body -label:bug label:priority**](https://github.com/search?q=broken+in%3Abody+-label%3Abug+label%3Apriority&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the word "broken" in the body, that lack the label "bug", but _do_ have the label "priority." +| label:LABEL label:LABEL | [**label:bug label:resolved**](https://github.com/search?l=&q=label%3Abug+label%3Aresolved&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the labels "bug" and "resolved." +| label:LABEL,LABEL | [**label:bug,resolved**](https://github.com/search?q=label%3Abug%2Cresolved&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the label "bug" or the label "resolved." ## Search by milestone @@ -200,8 +200,8 @@ The `milestone` qualifier finds issues or pull requests that are a part of a [mi | Qualifier | Example | ------------- | ------------- -| milestone:MILESTONE | [**milestone:"overhaul"**](https://github.com/search?utf8=%E2%9C%93&q=milestone%3A%22overhaul%22&type=Issues) matches issues that are in a milestone named "overhaul." -| milestone:MILESTONE | [**milestone:"bug fix"**](https://github.com/search?utf8=%E2%9C%93&q=milestone%3A%22bug+fix%22&type=Issues) matches issues that are in a milestone named "bug fix." +| milestone:MILESTONE | [**milestone:"overhaul"**](https://github.com/search?utf8=%E2%9C%93&q=milestone%3A%22overhaul%22&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues that are in a milestone named "overhaul." +| milestone:MILESTONE | [**milestone:"bug fix"**](https://github.com/search?utf8=%E2%9C%93&q=milestone%3A%22bug+fix%22&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues that are in a milestone named "bug fix." ## Search by project @@ -217,9 +217,9 @@ You can filter pull requests based on the status of the commits. This is especia | Qualifier | Example | ------------- | ------------- -| `status:pending` | [**language:go status:pending**](https://github.com/search?utf8=%E2%9C%93&q=language%3Ago+status%3Apending) matches pull requests opened into Go repositories where the status is pending. -| `status:success` | [**is:open status:success finally in:body**](https://github.com/search?utf8=%E2%9C%93&q=is%3Aopen+status%3Asuccess+finally+in%3Abody&type=Issues) matches open pull requests with the word "finally" in the body with a successful status. -| `status:failure` | [**created:2015-05-01..2015-05-30 status:failure**](https://github.com/search?utf8=%E2%9C%93&q=created%3A2015-05-01..2015-05-30+status%3Afailure&type=Issues) matches pull requests opened on May 2015 with a failed status. +| `status:pending` | [**language:go status:pending**](https://github.com/search?utf8=%E2%9C%93&q=language%3Ago+status%3Apending&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests opened into Go repositories where the status is pending. +| `status:success` | [**is:open status:success finally in:body**](https://github.com/search?utf8=%E2%9C%93&q=is%3Aopen+status%3Asuccess+finally+in%3Abody&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches open pull requests with the word "finally" in the body with a successful status. +| `status:failure` | [**created:2015-05-01..2015-05-30 status:failure**](https://github.com/search?utf8=%E2%9C%93&q=created%3A2015-05-01..2015-05-30+status%3Afailure&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests opened on May 2015 with a failed status. ## Search by commit SHA @@ -227,8 +227,8 @@ If you know the specific SHA hash of a commit, you can use it to search for pull | Qualifier | Example | ------------- | ------------- -| SHA | [**e1109ab**](https://github.com/search?q=e1109ab&type=Issues) matches pull requests with a commit SHA that starts with `e1109ab`. -| SHA `is:merged` | [**0eff326d6213c is:merged**](https://github.com/search?q=0eff326d+is%3Amerged&type=Issues) matches merged pull requests with a commit SHA that starts with `0eff326d6213c`. +| SHA | [**e1109ab**](https://github.com/search?q=e1109ab&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests with a commit SHA that starts with `e1109ab`. +| SHA `is:merged` | [**0eff326d6213c is:merged**](https://github.com/search?q=0eff326d+is%3Amerged&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches merged pull requests with a commit SHA that starts with `0eff326d6213c`. ## Search by branch name @@ -236,8 +236,8 @@ You can filter pull requests based on the branch they came from (the "head" bran | Qualifier | Example | ------------- | ------------- -| head:HEAD_BRANCH | [**head:change is:closed is:unmerged**](https://github.com/search?utf8=%E2%9C%93&q=head%3Achange+is%3Aclosed+is%3Aunmerged) matches pull requests opened from branch names beginning with the word "change" that are closed. -| base:BASE_BRANCH | [**base:gh-pages**](https://github.com/search?utf8=%E2%9C%93&q=base%3Agh-pages) matches pull requests that are being merged into the `gh-pages` branch. +| head:HEAD_BRANCH | [**head:change is:closed is:unmerged**](https://github.com/search?utf8=%E2%9C%93&q=head%3Achange+is%3Aclosed+is%3Aunmerged&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests opened from branch names beginning with the word "change" that are closed. +| base:BASE_BRANCH | [**base:gh-pages**](https://github.com/search?utf8=%E2%9C%93&q=base%3Agh-pages&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that are being merged into the `gh-pages` branch. ## Search by language @@ -245,7 +245,7 @@ With the `language` qualifier you can search for issues and pull requests within | Qualifier | Example | ------------- | ------------- -| language:LANGUAGE | [**language:ruby state:open**](https://github.com/search?q=language%3Aruby+state%3Aopen&type=Issues) matches open issues that are in Ruby repositories. +| language:LANGUAGE | [**language:ruby state:open**](https://github.com/search?q=language%3Aruby+state%3Aopen&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches open issues that are in Ruby repositories. ## Search by number of comments @@ -253,8 +253,8 @@ You can use the `comments` qualifier along with [greater than, less than, and ra | Qualifier | Example | ------------- | ------------- -| comments:n | [**state:closed comments:>100**](https://github.com/search?q=state%3Aclosed+comments%3A%3E100&type=Issues) matches closed issues with more than 100 comments. -| comments:n..n | [**comments:500..1000**](https://github.com/search?q=comments%3A500..1000&type=Issues) matches issues with comments ranging from 500 to 1,000. +| comments:n | [**state:closed comments:>100**](https://github.com/search?q=state%3Aclosed+comments%3A%3E100&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches closed issues with more than 100 comments. +| comments:n..n | [**comments:500..1000**](https://github.com/search?q=comments%3A500..1000&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with comments ranging from 500 to 1,000. ## Search by number of interactions @@ -262,8 +262,8 @@ You can filter issues and pull requests by the number of interactions with the ` | Qualifier | Example | ------------- | ------------- -| interactions:n | [**interactions:>2000**](https://github.com/search?q=interactions%3A%3E2000) matches pull requests or issues with more than 2000 interactions. -| interactions:n..n | [**interactions:500..1000**](https://github.com/search?q=interactions%3A500..1000) matches pull requests or issues with interactions ranging from 500 to 1,000. +| interactions:n | [**interactions:>2000**](https://github.com/search?q=interactions%3A%3E2000&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests or issues with more than 2000 interactions. +| interactions:n..n | [**interactions:500..1000**](https://github.com/search?q=interactions%3A500..1000&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests or issues with interactions ranging from 500 to 1,000. ## Search by number of reactions @@ -271,8 +271,8 @@ You can filter issues and pull requests by the number of reactions using the `re | Qualifier | Example | ------------- | ------------- -| reactions:n | [**reactions:>1000**](https://github.com/search?q=reactions%3A%3E1000&type=Issues) matches issues with more than 1000 reactions. -| reactions:n..n | [**reactions:500..1000**](https://github.com/search?q=reactions%3A500..1000) matches issues with reactions ranging from 500 to 1,000. +| reactions:n | [**reactions:>1000**](https://github.com/search?q=reactions%3A%3E1000&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with more than 1000 reactions. +| reactions:n..n | [**reactions:500..1000**](https://github.com/search?q=reactions%3A500..1000&ref_product=github&ref_type=engagement&ref_style=text) matches issues with reactions ranging from 500 to 1,000. ## Search for draft pull requests @@ -280,8 +280,8 @@ You can filter for draft pull requests. For more information, see [AUTOTITLE](/p | Qualifier | Example | ------------- | ------------- -| `draft:true` | [**draft:true**](https://github.com/search?q=draft%3Atrue) matches draft pull requests. -| `draft:false` | [**draft:false**](https://github.com/search?q=draft%3Afalse) matches pull requests that are ready for review. +| `draft:true` | [**draft:true**](https://github.com/search?q=draft%3Atrue&ref_product=github&ref_type=engagement&ref_style=text) matches draft pull requests. +| `draft:false` | [**draft:false**](https://github.com/search?q=draft%3Afalse&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that are ready for review. ## Search by pull request review status and reviewer @@ -289,18 +289,18 @@ You can filter pull requests based on their [review status](/pull-requests/colla | Qualifier | Example | ------------- | ------------- -| `review:none` | [**type:pr review:none**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review%3Anone&type=Issues) matches pull requests that have not been reviewed. -| `review:required` | [**type:pr review:required**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review%3Arequired&type=Issues) matches pull requests that require a review before they can be merged. -| `review:approved` | [**type:pr review:approved**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review%3Aapproved&type=Issues) matches pull requests that a reviewer has approved. -| `review:changes_requested` | [**type:pr review:changes_requested**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review%3Achanges_requested&type=Issues) matches pull requests in which a reviewer has asked for changes. -| reviewed-by:USERNAME | [**type:pr reviewed-by:gjtorikian**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+reviewed-by%3Agjtorikian&type=Issues) matches pull requests reviewed by a particular person. -| review-requested:USERNAME | [**type:pr review-requested:benbalter**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review-requested%3Abenbalter&type=Issues) matches pull requests where a specific person is requested for review. Requested reviewers are no longer listed in the search results after they review a pull request. If the requested person is on a team that is requested for review, then review requests for that team will also appear in the search results. +| `review:none` | [**type:pr review:none**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review%3Anone&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that have not been reviewed. +| `review:required` | [**type:pr review:required**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review%3Arequired&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that require a review before they can be merged. +| `review:approved` | [**type:pr review:approved**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review%3Aapproved&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that a reviewer has approved. +| `review:changes_requested` | [**type:pr review:changes_requested**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review%3Achanges_requested&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests in which a reviewer has asked for changes. +| reviewed-by:USERNAME | [**type:pr reviewed-by:gjtorikian**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+reviewed-by%3Agjtorikian&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests reviewed by a particular person. +| review-requested:USERNAME | [**type:pr review-requested:benbalter**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review-requested%3Abenbalter&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests where a specific person is requested for review. Requested reviewers are no longer listed in the search results after they review a pull request. If the requested person is on a team that is requested for review, then review requests for that team will also appear in the search results. | {% ifversion review-involves-search %} | -| review-involves:USERNAME | [**type:pr review-involves:gjtorikian**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review-involves%3Agjtorikian&type=pullrequests) matches pull requests that a particular person is involved in reviewing, whether they were asked to review directly, are on a team that was asked, or have already reviewed. Unlike with `review-requested`, these pull requests remain in the results after the person or a teammate has reviewed them. +| review-involves:USERNAME | [**type:pr review-involves:gjtorikian**](https://github.com/search?utf8=%E2%9C%93&q=type%3Apr+review-involves%3Agjtorikian&type=pullrequests&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that a particular person is involved in reviewing, whether they were asked to review directly, are on a team that was asked, or have already reviewed. Unlike with `review-requested`, these pull requests remain in the results after the person or a teammate has reviewed them. | {% endif %} | -| user-review-requested:@me | [**type:pr user-review-requested:@me**](https://github.com/search?q=is%3Apr+user-review-requested%3A%40me+) matches pull requests that you have directly been asked to review. -| team-review-requested:TEAMNAME | [**type:pr team-review-requested:github/docs**](https://github.com/search?q=type%3Apr+team-review-requested%3Agithub%2Fdocs&type=pullrequests) matches pull requests that have review requests from the team `github/docs`. Requested reviewers are no longer listed in the search results after they review a pull request. -| team-review-requested-user:USERNAME | [**type:pr team-review-requested-user:benbalter**](https://github.com/search?q=type%3Apr+team-review-requested-user%3Abenbalter&type=pullrequests) matches pull requests that have review requests from any team that a specific person is a member of. Review requests directed at the user specifically are not included. Requested reviewers are no longer listed in the search results after they review a pull request. +| user-review-requested:@me | [**type:pr user-review-requested:@me**](https://github.com/search?q=is%3Apr+user-review-requested%3A%40me+&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that you have directly been asked to review. +| team-review-requested:TEAMNAME | [**type:pr team-review-requested:github/docs**](https://github.com/search?q=type%3Apr+team-review-requested%3Agithub%2Fdocs&type=pullrequests&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that have review requests from the team `github/docs`. Requested reviewers are no longer listed in the search results after they review a pull request. +| team-review-requested-user:USERNAME | [**type:pr team-review-requested-user:benbalter**](https://github.com/search?q=type%3Apr+team-review-requested-user%3Abenbalter&type=pullrequests&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests that have review requests from any team that a specific person is a member of. Review requests directed at the user specifically are not included. Requested reviewers are no longer listed in the search results after they review a pull request. ## Search by when an issue or pull request was created or last updated @@ -312,8 +312,8 @@ Both take a date as a parameter. {% data reusables.time_date.date_format %} {% d | Qualifier | Example | ------------- | ------------- -| created:YYYY-MM-DD | [**language:c# created:<2011-01-01 state:open**](https://github.com/search?q=language%3Ac%23+created%3A%3C2011-01-01+state%3Aopen&type=Issues) matches open issues that were created before 2011 in repositories written in C#. -| updated:YYYY-MM-DD | [**weird in:body updated:>=2013-02-01**](https://github.com/search?q=weird+in%3Abody+updated%3A%3E%3D2013-02-01&type=Issues) matches issues with the word "weird" in the body that were updated after February 2013. +| created:YYYY-MM-DD | [**language:c# created:<2011-01-01 state:open**](https://github.com/search?q=language%3Ac%23+created%3A%3C2011-01-01+state%3Aopen&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches open issues that were created before 2011 in repositories written in C#. +| updated:YYYY-MM-DD | [**weird in:body updated:>=2013-02-01**](https://github.com/search?q=weird+in%3Abody+updated%3A%3E%3D2013-02-01&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues with the word "weird" in the body that were updated after February 2013. ## Search by when an issue or pull request was closed @@ -325,8 +325,8 @@ This qualifier takes a date as its parameter. {% data reusables.time_date.date_f | Qualifier | Example | ------------- | ------------- -| closed:>YYYY-MM-DD | [**language:swift closed:>2014-06-11**](https://github.com/search?q=language%3Aswift+closed%3A%3E2014-06-11&type=Issues) matches issues and pull requests in Swift that were closed after June 11, 2014. -| in:body closed:<YYYY-MM-DD | [**data in:body closed:<2012-10-01**](https://github.com/search?utf8=%E2%9C%93&q=data+in%3Abody+closed%3A%3C2012-10-01+&type=Issues) matches issues and pull requests with the word "data" in the body that were closed before October 2012. +| closed:>YYYY-MM-DD | [**language:swift closed:>2014-06-11**](https://github.com/search?q=language%3Aswift+closed%3A%3E2014-06-11&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests in Swift that were closed after June 11, 2014. +| in:body closed:<YYYY-MM-DD | [**data in:body closed:<2012-10-01**](https://github.com/search?utf8=%E2%9C%93&q=data+in%3Abody+closed%3A%3C2012-10-01+&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests with the word "data" in the body that were closed before October 2012. ## Search by when a pull request was merged @@ -338,8 +338,8 @@ This qualifier takes a date as its parameter. {% data reusables.time_date.date_f | Qualifier | Example | ------------- | ------------- -| language:LANGUAGE merged:<YYYY-MM-DD | [**`language:javascript merged:<2011-01-01`**](https://github.com/search?q=language%3Ajavascript+merged%3A%3C2011-01-01+&type=Issues) matches pull requests in JavaScript repositories that were merged before 2011. -| `in:title` language:LANGUAGE merged:>YYYY-MM-DD | [**fast in:title language:ruby merged:>=2014-05-01**](https://github.com/search?q=fast+in%3Atitle+language%3Aruby+merged%3A%3E%3D2014-05-01+&type=Issues) matches pull requests in Ruby with the word "fast" in the title that were merged after May 2014. +| language:LANGUAGE merged:<YYYY-MM-DD | [**`language:javascript merged:<2011-01-01`**](https://github.com/search?q=language%3Ajavascript+merged%3A%3C2011-01-01+&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests in JavaScript repositories that were merged before 2011. +| `in:title` language:LANGUAGE merged:>YYYY-MM-DD | [**fast in:title language:ruby merged:>=2014-05-01**](https://github.com/search?q=fast+in%3Atitle+language%3Aruby+merged%3A%3E%3D2014-05-01+&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests in Ruby with the word "fast" in the title that were merged after May 2014. ## Search based on whether a pull request is merged or unmerged @@ -347,8 +347,8 @@ You can filter pull requests based on whether they're merged or unmerged using t | Qualifier | Example | ------------- | ------------- -| `is:merged` | [**bug is:pr is:merged**](https://github.com/search?utf8=%E2%9C%93&q=bugfix+is%3Apr+is%3Amerged&type=) matches merged pull requests with the word "bug." -| `is:unmerged` | [**error is:unmerged**](https://github.com/search?utf8=%E2%9C%93&q=error+is%3Aunmerged&type=) matches pull requests with the word "error" that are either open or were closed without being merged. +| `is:merged` | [**bug is:pr is:merged**](https://github.com/search?utf8=%E2%9C%93&q=bugfix+is%3Apr+is%3Amerged&type=&ref_product=github&ref_type=engagement&ref_style=text) matches merged pull requests with the word "bug." +| `is:unmerged` | [**error is:unmerged**](https://github.com/search?utf8=%E2%9C%93&q=error+is%3Aunmerged&type=&ref_product=github&ref_type=engagement&ref_style=text) matches pull requests with the word "error" that are either open or were closed without being merged. ## Search based on whether a repository is archived @@ -356,8 +356,8 @@ The `archived` qualifier filters your results based on whether an issue or pull | Qualifier | Example | ------------- | ------------- -| `archived:true` | [**archived:true GNOME**](https://github.com/search?q=archived%3Atrue+GNOME&type=) matches issues and pull requests that contain the word "GNOME" in archived repositories you have access to. -| `archived:false` | [**archived:false GNOME**](https://github.com/search?q=archived%3Afalse+GNOME&type=) matches issues and pull requests that contain the word "GNOME" in unarchived repositories you have access to. +| `archived:true` | [**archived:true GNOME**](https://github.com/search?q=archived%3Atrue+GNOME&type=&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests that contain the word "GNOME" in archived repositories you have access to. +| `archived:false` | [**archived:false GNOME**](https://github.com/search?q=archived%3Afalse+GNOME&type=&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests that contain the word "GNOME" in unarchived repositories you have access to. ## Search based on whether a conversation is locked @@ -365,8 +365,8 @@ You can search for an issue or pull request that has a locked conversation using | Qualifier | Example | ------------- | ------------- -| `is:locked` | [**code of conduct is:locked is:issue archived:false**](https://github.com/search?q=code+of+conduct+is%3Alocked+is%3Aissue+archived%3Afalse) matches issues or pull requests with the words "code of conduct" that have a locked conversation in a repository that is not archived. -| `is:unlocked` | [**code of conduct is:unlocked is:issue archived:false**](https://github.com/search?q=code+of+conduct+is%3Aunlocked+archived%3Afalse) matches issues or pull requests with the words "code of conduct" that have an unlocked conversation in a repository that is not archived. +| `is:locked` | [**code of conduct is:locked is:issue archived:false**](https://github.com/search?q=code+of+conduct+is%3Alocked+is%3Aissue+archived%3Afalse&ref_product=github&ref_type=engagement&ref_style=text) matches issues or pull requests with the words "code of conduct" that have a locked conversation in a repository that is not archived. +| `is:unlocked` | [**code of conduct is:unlocked is:issue archived:false**](https://github.com/search?q=code+of+conduct+is%3Aunlocked+archived%3Afalse&ref_product=github&ref_type=engagement&ref_style=text) matches issues or pull requests with the words "code of conduct" that have an unlocked conversation in a repository that is not archived. ## Search by missing metadata @@ -379,10 +379,10 @@ You can narrow your search to issues and pull requests that are missing certain | Qualifier | Example | ------------- | ------------- -| `no:label` | [**priority no:label**](https://github.com/search?q=priority+no%3Alabel&type=Issues) matches issues and pull requests with the word "priority" that also don't have any labels. -| `no:milestone` | [**sprint no:milestone type:issue**](https://github.com/search?q=sprint+no%3Amilestone+type%3Aissue&type=Issues) matches issues not associated with a milestone containing the word "sprint." -| `no:assignee` | [**important no:assignee language:java type:issue**](https://github.com/search?q=important+no%3Aassignee+language%3Ajava+type%3Aissue&type=Issues) matches issues not associated with an assignee, containing the word "important," and in Java repositories. -| `no:project` | [**build no:project**](https://github.com/search?utf8=%E2%9C%93&q=build+no%3Aproject&type=Issues) matches issues not associated with a {% data variables.projects.project_v2 %}, containing the word "build." +| `no:label` | [**priority no:label**](https://github.com/search?q=priority+no%3Alabel&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues and pull requests with the word "priority" that also don't have any labels. +| `no:milestone` | [**sprint no:milestone type:issue**](https://github.com/search?q=sprint+no%3Amilestone+type%3Aissue&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues not associated with a milestone containing the word "sprint." +| `no:assignee` | [**important no:assignee language:java type:issue**](https://github.com/search?q=important+no%3Aassignee+language%3Ajava+type%3Aissue&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues not associated with an assignee, containing the word "important," and in Java repositories. +| `no:project` | [**build no:project**](https://github.com/search?utf8=%E2%9C%93&q=build+no%3Aproject&type=Issues&ref_product=github&ref_type=engagement&ref_style=text) matches issues not associated with a {% data variables.projects.project_v2 %}, containing the word "build." ## Further reading From b3b8fb0b28623d0b70bb95611d43afb099406f3a Mon Sep 17 00:00:00 2001 From: kbukum1 Date: Mon, 3 Aug 2026 14:47:00 -0500 Subject: [PATCH 6/6] Sync Dependabot supported versions with dependabot-core (pip, Terraform, npm, Bun) (#62326) Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80a6ab3e-9bd8-4cae-abf5-2b2999b94b59 --- .../dependabot-options-reference.md | 10 +++++----- .../reusables/dependabot/supported-package-managers.md | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/content/code-security/reference/supply-chain-security/dependabot-options-reference.md b/content/code-security/reference/supply-chain-security/dependabot-options-reference.md index 45d625ca6da3..8746dd98ee72 100644 --- a/content/code-security/reference/supply-chain-security/dependabot-options-reference.md +++ b/content/code-security/reference/supply-chain-security/dependabot-options-reference.md @@ -563,7 +563,7 @@ Package manager | YAML value | Supported versions | | {% ifversion dependabot-bazel-support %} | | Bazel | `bazel` | v7, v8, v9 | | {% endif %} | -| Bun | `bun` | >=v1.2.5 | +| Bun | `bun` | >=v1.1.39 | | Bundler | `bundler` | v2 | | Cargo | `cargo` | v1 | | Composer | `composer` | v2 | @@ -593,14 +593,14 @@ Package manager | YAML value | Supported versions | | {% ifversion dependabot-nix-support %} | | Nix flakes | `nix` | Not applicable | | {% endif %} | -| npm | `npm` | v7, v8, v9, v10 | +| npm | `npm` | v7, v8, v9, v10, v11 | | NuGet | `nuget` | <=6.12.0 | | {% ifversion dependabot-opentofu-support %} | | OpenTofu | `opentofu` | Not applicable | | {% endif %} | -| pip | `pip` | 24.2 | +| pip | `pip` | 26.1.1 | | pip-compile | `pip` | 7.5.3 | -| pipenv | `pip` | <= 2024.4.1 | +| pipenv | `pip` | 2024.4.1 | | pnpm | `npm` | v7, v8, v9, v10 | | poetry | `pip` | v2 | | {% ifversion dependabot-pre-commit-support %} | @@ -614,7 +614,7 @@ Package manager | YAML value | Supported versions | | sbt | `sbt` | Not applicable | | {% endif %} | | Swift | `swift` | v5 | -| Terraform | `terraform` | >= 0.13, <= 1.10.x | +| Terraform | `terraform` | >= 0.13, <= 1.15.x | | uv | `uv` | v0 | | {% ifversion dependabot-vcpkg-support %} | | vcpkg | `vcpkg` | Not applicable | diff --git a/data/reusables/dependabot/supported-package-managers.md b/data/reusables/dependabot/supported-package-managers.md index a704d4381c77..2f62085428f8 100644 --- a/data/reusables/dependabot/supported-package-managers.md +++ b/data/reusables/dependabot/supported-package-managers.md @@ -38,7 +38,7 @@ npm | `npm` | v7, v8, v9, v10, v11 | {% octicon "check" | {% ifversion dependabot-opentofu-support %} | [OpenTofu](#opentofu) | `opentofu` | Not applicable | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | Not applicable | | {% endif %} | -[pip](#pip-and-pip-compile) | `pip` | 24.2 | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | +[pip](#pip-and-pip-compile) | `pip` | 26.1.1 | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | pipenv | `pip` | 2024.4.1 | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | [pip-compile](#pip-and-pip-compile) | `pip` | 7.5.3 | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | | pnpm | `npm` | v7, v8, v9, v10 | {% 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" %} | @@ -54,7 +54,7 @@ pipenv | `pip` | 2024.4.1 | {% octicon "check" aria-label=" [sbt](#sbt) | `sbt` | Not applicable | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | | {% endif %} | [Swift](#swift) | `swift` | v5 | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} (git only) | {% octicon "x" aria-label="Not supported" %} | -[Terraform](#terraform) | `terraform` | >= 0.13, <= 1.13.x | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | Not applicable | +[Terraform](#terraform) | `terraform` | >= 0.13, <= 1.15.x | {% octicon "check" aria-label="Supported" %} | {% octicon "x" aria-label="Not supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | Not applicable | | {% ifversion dependabot-uv-security-support %} | uv | `uv` | v0 | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | {% octicon "check" aria-label="Supported" %} | Not applicable | | {% elsif dependabot-uv-support %} |