diff --git a/app/models/vulnerability.rb b/app/models/vulnerability.rb index c8f9e75a3895f416c7b1006ecbea59798534c2e0..3e307ae77a049a4ac2ee8524aa1922841373488b 100644 --- a/app/models/vulnerability.rb +++ b/app/models/vulnerability.rb @@ -3,12 +3,6 @@ # Placeholder class for model that is implemented in EE class Vulnerability < ApplicationRecord include EachBatch - include IgnorableColumns - - ignore_column %i[due_date due_date_sourcing_milestone_id epic_id milestone_id - last_edited_at last_edited_by_id start_date start_date_sourcing_milestone_id updated_by_id], - remove_with: '16.9', - remove_after: '2024-01-19' alias_attribute :vulnerability_id, :id diff --git a/config/webpack.config.js b/config/webpack.config.js index 5e3425a20eb314bae87b0585e1c5850572ffaa7c..ea26d9baf921e4cd1b96c47b43154570581bbd75 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -369,6 +369,7 @@ module.exports = { { loader: 'worker-loader', options: { + publicPath: './', filename: '[name].[contenthash:8].worker.js', }, }, diff --git a/db/docs/cluster_agents.yml b/db/docs/cluster_agents.yml index 237d8d23bfd7bfdac0bf27478e84d7acd2d50413..1c8417613cf727ca0a2e8cbea1037dc9742f6e5f 100644 --- a/db/docs/cluster_agents.yml +++ b/db/docs/cluster_agents.yml @@ -7,4 +7,12 @@ feature_categories: description: Represents a GitLab Agent for Kubernetes installed in a Kubernetes cluster introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33228 milestone: '13.3' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/docs/cluster_enabled_grants.yml b/db/docs/cluster_enabled_grants.yml index 59f896f198dfab3c0c0569da6fd737f8c9df43cb..7c89d5626087b0c940c91f7a77996702a1cf369c 100644 --- a/db/docs/cluster_enabled_grants.yml +++ b/db/docs/cluster_enabled_grants.yml @@ -4,7 +4,10 @@ classes: - Clusters::ClusterEnabledGrant feature_categories: - deployment_management -description: Persists information about namespaces which got an extended life for certificate based clusters +description: Persists information about namespaces which got an extended life for + certificate based clusters introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87149 milestone: '15.1' gitlab_schema: gitlab_main_cell +sharding_key: + namespace_id: namespaces diff --git a/db/docs/cluster_groups.yml b/db/docs/cluster_groups.yml index 70c11431acfc0090adae672abb60b8ccbcd265c1..ddc157644199ef9605d8146de8662959e602abb7 100644 --- a/db/docs/cluster_groups.yml +++ b/db/docs/cluster_groups.yml @@ -7,4 +7,12 @@ feature_categories: description: "(Deprecated) Join table between 'clusters' and 'namespaces'" introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/0e15eec86d83cbdfefe17966bf5c02e4d419a34d milestone: '11.5' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + group_id: namespaces diff --git a/db/docs/cluster_projects.yml b/db/docs/cluster_projects.yml index 152b60ea87bcdf0f10fc4bd8c24618cce57ca6f0..1313e5938d440f939b15c5a082415ed943fbc6d6 100644 --- a/db/docs/cluster_projects.yml +++ b/db/docs/cluster_projects.yml @@ -7,4 +7,12 @@ feature_categories: description: "(Deprecated) Join table between 'clusters' and 'projects'" introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/d0cff7f5855f91b5479f9fdaa39d8d95ec691a9e milestone: '10.2' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_main_cell +allow_cross_joins: +- gitlab_main_clusterwide +allow_cross_transactions: +- gitlab_main_clusterwide +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/doc/api/import.md b/doc/api/import.md index 3bb3417e212e26ce447a90f39515a2de96f381e8..e378958077a580963268b2dae56af5bd9158d144 100644 --- a/doc/api/import.md +++ b/doc/api/import.md @@ -210,11 +210,6 @@ curl --request POST \ }' ``` -## Automate group and project import **(PREMIUM ALL)** - -For information on automating user, group, and project import API calls, see -[Automate group and project import](../user/project/import/index.md#automate-group-and-project-import). - ## Related topics - [Group migration by direct transfer API](bulk_imports.md). diff --git a/doc/api/project_import_export.md b/doc/api/project_import_export.md index 974694e0808facd06d3bab454305313f55103d1d..1cf276b4f602b7abf501e22210483b97e5bc214f 100644 --- a/doc/api/project_import_export.md +++ b/doc/api/project_import_export.md @@ -11,6 +11,12 @@ Use the project import and export API to import and export projects using file t Before using the project import and export API, you might want to use the [group import and export API](group_import_export.md). +After using the project import and export API, you might want to use the +[Project-level CI/CD variables API](project_level_variables.md). + +You must still migrate your [Container Registry](../user/packages/container_registry/index.md) +over a series of Docker pulls and pushes. Re-run any CI/CD pipelines to retrieve any build artifacts. + ## Prerequisites For prerequisites for project import and export API, see: diff --git a/doc/subscriptions/gitlab_dedicated/index.md b/doc/subscriptions/gitlab_dedicated/index.md index 0cf604f620f0ea5cf1807dbe7dee211f0a1a04ba..e6a6aace3b4ea484321843e6ab005f63418be264 100644 --- a/doc/subscriptions/gitlab_dedicated/index.md +++ b/doc/subscriptions/gitlab_dedicated/index.md @@ -111,11 +111,10 @@ With GitLab Dedicated, you must [install the GitLab Runner application](https:// To help you migrate your data to GitLab Dedicated, you can choose from the following options: 1. When migrating from another GitLab instance, you can either: - - Use the UI, including [group import](../../user/group/import/index.md) and [project import](../../user/project/settings/import_export.md). + - Use the UI, by using [direct transfer](../../user/group/import/index.md) to import groups and projects. - Use APIs, including the [group import API](../../api/group_import_export.md) and [project import API](../../api/project_import_export.md). - - Note: Import functionality behind a feature flag (such as `bulk_import_project`) is not supported in GitLab Dedicated. 1. When migrating from third-party services, you can use [the GitLab importers](../../user/project/import/index.md#supported-import-sources). -1. You can perform a fully-automated migration through the [Congregate Automation Tool](../../user/project/import/index.md#automate-group-and-project-import), which supports migrating from existing GitLab instances as well as third-party services. +1. You can also engage [Professional Services](../../user/project/import/index.md#migrate-by-engaging-professional-services). ## Features that are not available diff --git a/doc/update/package/index.md b/doc/update/package/index.md index 662590e7f783c7e94412cfd4ec89021b1223c1c3..45cce799cb0e5cbab3bcd2e5685fe4b8bc50b4bc 100644 --- a/doc/update/package/index.md +++ b/doc/update/package/index.md @@ -141,21 +141,27 @@ or upgrade command: ```shell # Ubuntu/Debian - sudo apt install gitlab-ee=<version> + sudo apt install gitlab-ee=<version>-ee.0 # RHEL/CentOS 7 and Amazon Linux 2 - yum install gitlab-ee-<version> + sudo yum install gitlab-ee-<version>-ee.0.el7 - # RHEL/Almalinux 8/9 and Amazon Linux 2023 - dnf install gitlab-ee-<version> + # RHEL/Almalinux 8/9 + sudo dnf install gitlab-ee-<version>-ee.0.el8 - # SUSE - zypper install gitlab-ee=<version> + # Amazon Linux 2023 + sudo dnf install gitlab-ee-<version>-ee.0.amazon2023 + + # OpenSUSE Leap 15.5 + sudo zypper install gitlab-ee=<version>-ee.sles15 + + # SUSE Enterprise Server 12.2/12.5 + sudo zypper install gitlab-ee=<version>-ee.0.sles12 ``` NOTE: -For the GitLab Community Edition, replace `gitlab-ee` with -`gitlab-ce`. +For the GitLab Community Edition, replace `ee` with +`ce`. ## Upgrade using a manually-downloaded package diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md index 14c802124221d37cee2645639d134aa5fd1cee88..ffa04c6b916132f4fe525c23c964b52031b01a8d 100644 --- a/doc/user/gitlab_com/index.md +++ b/doc/user/gitlab_com/index.md @@ -243,18 +243,6 @@ which GitLab you use: - GitLab self-managed: no import sources are enabled by default and must be [enabled](../../administration/settings/import_and_export_settings.md#configure-allowed-import-sources). -| Import source | GitLab.com default | GitLab self-managed default | -|:----------------------------------------------------------------------------------------------------|:-----------------------|:----------------------------| -| [Bitbucket Cloud](../project/import/bitbucket.md) | **{check-circle}** Yes | **{dotted-circle}** No | -| [Bitbucket Server](../project/import/bitbucket_server.md) | **{check-circle}** Yes | **{dotted-circle}** No | -| [FogBugz](../project/import/fogbugz.md) | **{check-circle}** Yes | **{dotted-circle}** No | -| [Gitea](../project/import/gitea.md) | **{check-circle}** Yes | **{dotted-circle}** No | -| [GitLab by direct transfer](../group/import/index.md) | **{check-circle}** Yes | **{dotted-circle}** No | -| [GitLab using file exports](../project/settings/import_export.md) | **{check-circle}** Yes | **{dotted-circle}** No | -| [GitHub](../project/import/github.md) | **{check-circle}** Yes | **{dotted-circle}** No | -| [Manifest file](../project/import/manifest.md) | **{check-circle}** Yes | **{dotted-circle}** No | -| [Repository by URL](../project/import/repo_by_url.md) | **{check-circle}** Yes | **{dotted-circle}** No | - ## IP range GitLab.com uses the IP ranges `34.74.90.64/28` and `34.74.226.0/24` for traffic from its Web/API diff --git a/doc/user/group/import/index.md b/doc/user/group/import/index.md index 42a3ce32e8981b8354e386d6d3a0d9cbc4b0ecd5..be9b8f40f97f43d827aa9acf0a803356f8088d93 100644 --- a/doc/user/group/import/index.md +++ b/doc/user/group/import/index.md @@ -60,6 +60,8 @@ groups are in the same GitLab instance. Transferring groups is a faster and more ## Known issues - Because of [issue 406685](https://gitlab.com/gitlab-org/gitlab/-/issues/406685), files with a file name longer than 255 characters are not migrated. +- In GitLab 16.1 and earlier, you should **not** use direct transfer with + [scheduled scan execution policies](../../../user/application_security/policies/scan-execution-policies.md). - For a list of other known issues, see [epic 6629](https://gitlab.com/groups/gitlab-org/-/epics/6629). ## Estimating migration duration @@ -535,8 +537,3 @@ Distributing projects in different groups helps to avoid timeouts. If several la 1. Start separate migrations each group and subgroup. The GitLab UI can only migrate top-level groups. Using the API, you can also migrate subgroups. - -## Automate group and project import **(PREMIUM ALL)** - -For information on automating user, group, and project import API calls, see -[Automate group and project import](../../project/import/index.md#automate-group-and-project-import). diff --git a/doc/user/permissions.md b/doc/user/permissions.md index 36e1ae1e0c8e4ee46151bee9ffc32a8a9d3e2c38..5ac6041d09ea7a42bc6b18bb7c3e7613b57beea6 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -476,7 +476,7 @@ To work around the issue, give these users the Guest role or higher to any proje - Customize permissions on [protected branches](project/protected_branches.md) - [LDAP user permissions](group/access_and_permissions.md#manage-group-memberships-via-ldap) - [Value stream analytics permissions](group/value_stream_analytics/index.md#access-permissions-for-value-stream-analytics) -- [Project aliases](../user/project/import/index.md#project-aliases) +- [Project aliases](../user/project/working_with_projects.md#project-aliases) - [Auditor users](../administration/auditor_users.md) - [Confidential issues](project/issues/confidential_issues.md) - [Container registry permissions](packages/container_registry/index.md#container-registry-visibility-permissions) diff --git a/doc/user/project/import/bitbucket_server.md b/doc/user/project/import/bitbucket_server.md index 572e0edcb90284c12767c9e371744f070b7b58a5..94b0285c54818d480f7f9de2ca3f6fce25b1a397 100644 --- a/doc/user/project/import/bitbucket_server.md +++ b/doc/user/project/import/bitbucket_server.md @@ -145,7 +145,3 @@ for Bitbucket Cloud. If the project import completes but LFS objects can't be downloaded or cloned, you may be using a password or personal access token containing special characters. For more information, see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/337769). - -## Related topics - -- [Automate group and project import](index.md#automate-group-and-project-import) diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md index 0a539d40605aa1efae83dfed9757b4233153f518..1aeece2de4da0b0cd27085cd37b842249c9c18cc 100644 --- a/doc/user/project/import/github.md +++ b/doc/user/project/import/github.md @@ -448,11 +448,6 @@ LoadModule ssl_module lib/httpd/modules/mod_ssl.so </VirtualHost> ``` -## Automate group and project import **(PREMIUM ALL)** - -For information on automating user, group, and project import API calls, see -[Automate group and project import](index.md#automate-group-and-project-import). - ## Troubleshooting ### Manually continue a previously failed import process diff --git a/doc/user/project/import/gitlab_com.md b/doc/user/project/import/gitlab_com.md index 135b51bf81a620d414427b6abe29f065fd7b53d9..32d5eef0d603da629a8f00fcaeebf49e55a58cf8 100644 --- a/doc/user/project/import/gitlab_com.md +++ b/doc/user/project/import/gitlab_com.md @@ -13,5 +13,4 @@ and removed in GitLab 16.0. To import GitLab projects from GitLab.com to a self- ## Related topics -- [Automate group and project import](index.md#automate-group-and-project-import) - [Export a project](../settings/import_export.md#export-a-project-and-its-data) diff --git a/doc/user/project/import/index.md b/doc/user/project/import/index.md index 8c9ba4087990886846698d66f49fd962a8dabc79..cebf5a93f81c8069db266874e14e465538b2cae8 100644 --- a/doc/user/project/import/index.md +++ b/doc/user/project/import/index.md @@ -14,10 +14,12 @@ To bring existing projects to GitLab, or copy GitLab groups and projects to a di ## Migrate from GitLab to GitLab by using direct transfer -The best way to migrate GitLab groups and projects between GitLab instances, or in the same GitLab instance, is +The best way to copy GitLab groups and projects between GitLab instances, or in the same GitLab instance, is [by using direct transfer](../../group/import/index.md). -You can also migrate GitLab projects by using a GitLab file export, which is a supported import source. +Another option is to move GitLab groups using [group transfer](../../group/manage.md#transfer-a-group). + +You can also copy GitLab projects by using a GitLab file export, which is a supported import source. ## Supported import sources @@ -39,28 +41,10 @@ GitLab can import projects from these supported import sources. | [Gitea](gitea.md) | Import Gitea projects. | | [GitHub](github.md) | Import from either GitHub.com or GitHub Enterprise. | | [GitLab export](../settings/import_export.md) | Migrate projects one by one by using a GitLab export file. | -| [Manifest file](manifest.md) | Upload a manifest file. | +| [Manifest file](manifest.md) | Upload a manifest file. | | [Repository by URL](repo_by_url.md) | Provide a Git repository URL to create a new project from. | -## Other import sources - -You can also read information on importing from these other import sources: - -- [ClearCase](clearcase.md) -- [Concurrent Versions System (CVS)](cvs.md) -- [Jira (issues only)](jira.md) -- [Perforce Helix](perforce.md) -- [Team Foundation Version Control (TFVC)](tfvc.md) - -### Import repositories from Subversion - -GitLab can not automatically migrate Subversion repositories to Git. Converting Subversion repositories to Git can be -difficult, but several tools exist including: - -- [`git svn`](https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git), for very small and basic repositories. -- [`reposurgeon`](http://www.catb.org/~esr/reposurgeon/repository-editing.html), for larger and more complex repositories. - -## Security +### Disable unused import sources Only import projects from sources you trust. If you import a project from an untrusted source, an attacker could steal your sensitive data. For example, an imported project @@ -74,31 +58,23 @@ GitLab self-managed administrators can reduce their attack surface by disabling 1. Scroll to **Import sources**. 1. Clear checkboxes for importers that are not required. -In GitLab 16.1 and earlier, you should **not** use direct transfer with [scheduled scan execution policies](../../../user/application_security/policies/scan-execution-policies.md). - -## Migrate using the API - -To migrate all data from self-managed to GitLab.com, you can leverage the [API](../../../api/rest/index.md). -Migrate the assets in this order: - -1. [Groups](../../../api/groups.md) -1. [Projects](../../../api/projects.md) -1. [Project variables](../../../api/project_level_variables.md) +## Other import sources -You must still migrate your [Container Registry](../../packages/container_registry/index.md) -over a series of Docker pulls and pushes. Re-run any CI pipelines to retrieve any build artifacts. +You can also read information on importing from these other import sources: -## Migrate between two self-managed GitLab instances +- [ClearCase](clearcase.md) +- [Concurrent Versions System (CVS)](cvs.md) +- [Jira (issues only)](jira.md) +- [Perforce Helix](perforce.md) +- [Team Foundation Version Control (TFVC)](tfvc.md) -To migrate from an existing self-managed GitLab instance to a new self-managed GitLab instance, -you should [back up](../../../administration/backup_restore/index.md) -the existing instance and restore it on the new instance. For example, you could use this method to migrate a self-managed instance from an old server to a new server. +### Import repositories from Subversion -The backups produced don't depend on the operating system running GitLab. You can therefore use -the restore method to switch between different operating system distributions or versions, as long -as the same GitLab version [is available for installation](../../../administration/package_information/supported_os.md). +GitLab can not automatically migrate Subversion repositories to Git. Converting Subversion repositories to Git can be +difficult, but several tools exist including: -Administrators can use the [Users API](../../../api/users.md) to migrate users. +- [`git svn`](https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git), for very small and basic repositories. +- [`reposurgeon`](http://www.catb.org/~esr/reposurgeon/repository-editing.html), for larger and more complex repositories. ## View project import history @@ -115,57 +91,23 @@ To view project import history: 1. Sign in to GitLab. 1. On the left sidebar, at the top, select **Create new** (**{plus}**) and **New project/repository**. 1. Select **Import project**. -1. In the upper-right corner, select **History**. -1. If there are any errors for a particular import, you can see them by selecting **Details**. +1. In the upper-right corner, select the **History** link. +1. If there are any errors for a particular import, select **Details** to see them. The history also includes projects created from [built-in](../index.md#create-a-project-from-a-built-in-template) or [custom](../index.md#create-a-project-from-a-built-in-template) templates. GitLab uses [import repository by URL](repo_by_url.md) to create a new project from a template. -## LFS authentication +## Importing projects with LFS objects When importing a project that contains LFS objects, if the project has an [`.lfsconfig`](https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-config.adoc) file with a URL host (`lfs.url`) different from the repository URL host, LFS files are not downloaded. -## Project aliases **(PREMIUM SELF)** - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3264) in GitLab 12.1. - -GitLab repositories are usually accessed with a namespace and a project name. When migrating -frequently accessed repositories to GitLab, however, you can use project aliases to access those -repositories with the original name. Accessing repositories through a project alias reduces the risk -associated with migrating such repositories. - -This feature is only available on Git over SSH. Also, only GitLab administrators can create project -aliases, and they can only do so through the API. For more information, see the -[Project Aliases API documentation](../../../api/project_aliases.md). - -After an administrator creates an alias for a project, you can use the alias to clone the -repository. For example, if an administrator creates the alias `gitlab` for the project -`https://gitlab.com/gitlab-org/gitlab`, you can clone the project with -`git clone git@gitlab.com:gitlab.git` instead of `git clone git@gitlab.com:gitlab-org/gitlab.git`. - -## Automate group and project import **(PREMIUM ALL)** - -The GitLab Professional Services team uses [Congregate](https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/congregate) -to orchestrate user, group, and project import API calls. With Congregate, you can migrate data to -GitLab from: - -- Other GitLab instances -- GitHub Enterprise -- GitHub.com -- Bitbucket Server -- Bitbucket Data Center - -For more information, see: - -- Information on paid GitLab [migration services](https://about.gitlab.com/services/migration/). -- [Quick Start](https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/congregate/-/blob/master/docs/using-congregate.md#quick-start). -- [Frequently Asked Migration Questions](https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/congregate/-/blob/master/customer/famq.md), - including settings that need checking afterwards and other limitations. +## Migrate by engaging Professional Services -For support, customers must enter into a paid engagement with GitLab Professional Services. +If you prefer, you can engage GitLab Professional Services to migrate groups and projects to GitLab instead of doing it +yourself. For more information, see the [Professional Services Full Catalog](https://about.gitlab.com/services/catalog/). ## Troubleshooting diff --git a/doc/user/project/import/repo_by_url.md b/doc/user/project/import/repo_by_url.md index 3c5a40b8d27b0b1713063ed136934837d2f3f0f2..92f1a5cbbe76c82eade6744bcbb210814b971273 100644 --- a/doc/user/project/import/repo_by_url.md +++ b/doc/user/project/import/repo_by_url.md @@ -30,8 +30,3 @@ If the repository is too large, the import can timeout. 1. Select **Create project**. Your newly created project is displayed. - -## Automate group and project import **(PREMIUM ALL)** - -For information on automating user, group, and project import API calls, see -[Automate group and project import](index.md#automate-group-and-project-import). diff --git a/doc/user/project/members/share_project_with_groups.md b/doc/user/project/members/share_project_with_groups.md index 71b960b15f8b60689c369a75ffad9c17384ca7a3..420e51f580b52dba799750f936f2b2364c65597d 100644 --- a/doc/user/project/members/share_project_with_groups.md +++ b/doc/user/project/members/share_project_with_groups.md @@ -10,6 +10,19 @@ When you want a group to have access to your project, you can invite [a group](../../group/index.md) to the project. The group's direct and inherited members get access to the project, which becomes a *shared project*. +In this case, inherited members are members that are inherited from parent groups into the groups that are shared. +Only members of the group that is shared get access to the project. +If you want to give members of a subgroup of the group you are sharing access to the project, you have to share the subgroup. + +The following table provides an overview of the group members that get access to a shared project. + +| Group member source | Access to shared project | +|------------------------------------------------------------------|------------------------| +| Direct member of the group that is shared | **{check-circle}** Yes | +| Inherited member of the group that is shared | **{check-circle}** Yes | +| Direct member of a subgroup, but not of the group that is shared | **{dotted-circle}** No | +| Inherited member of a subgroup, but not of the group that is shared | **{dotted-circle}** No | + ## Example For a project that was created by `Group 1`: diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md index 7d8305519e471550b443fbf3ceae20aedfa9e67d..4a6684a72a3c64df4b4b038afc0144fdf9f6f30b 100644 --- a/doc/user/project/working_with_projects.md +++ b/doc/user/project/working_with_projects.md @@ -311,6 +311,22 @@ Prerequisites: 1. To use LDAP groups to manage access to a project, [add the LDAP-synchronized group as a member](../group/manage.md) to the project. +## Project aliases **(PREMIUM SELF)** + +GitLab repositories are usually accessed with a namespace and a project name. When migrating +frequently accessed repositories to GitLab, however, you can use project aliases to access those +repositories with the original name. Accessing repositories through a project alias reduces the risk +associated with migrating such repositories. + +This feature is only available on Git over SSH. Also, only GitLab administrators can create project +aliases, and they can only do so through the API. For more information, see the +[Project Aliases API documentation](../../api/project_aliases.md). + +After an administrator creates an alias for a project, you can use the alias to clone the +repository. For example, if an administrator creates the alias `gitlab` for the project +`https://gitlab.com/gitlab-org/gitlab`, you can clone the project with +`git clone git@gitlab.com:gitlab.git` instead of `git clone git@gitlab.com:gitlab-org/gitlab.git`. + ## Troubleshooting When working with projects, you might encounter the following issues, or require alternate methods to complete specific tasks. diff --git a/ee/app/assets/javascripts/usage_quotas/code_suggestions/constants.js b/ee/app/assets/javascripts/usage_quotas/code_suggestions/constants.js index cfaa61f8af156a5d9d9c929c3728ab6de2441483..2bd4574f6d6094c68f0fbd526d50c080cd47ead2 100644 --- a/ee/app/assets/javascripts/usage_quotas/code_suggestions/constants.js +++ b/ee/app/assets/javascripts/usage_quotas/code_suggestions/constants.js @@ -4,7 +4,7 @@ import { thWidthPercent } from '~/lib/utils/table_utility'; export const ADD_ON_CODE_SUGGESTIONS = 'CODE_SUGGESTIONS'; export const codeSuggestionsLearnMoreLink = `${PROMO_URL}/solutions/code-suggestions/`; -export const salesLink = `${PROMO_URL}/sales/`; +export const salesLink = `${PROMO_URL}/solutions/code-suggestions/sales/`; export const addOnEligibleUserListTableFields = { codeSuggestionsAddon: { diff --git a/ee/app/assets/javascripts/usage_quotas/error_constants.js b/ee/app/assets/javascripts/usage_quotas/error_constants.js index 8816effef615aec7d938932ad73f9683f7a68bc2..50b46a121fc6a912a7faf7adfc0299fb255927ea 100644 --- a/ee/app/assets/javascripts/usage_quotas/error_constants.js +++ b/ee/app/assets/javascripts/usage_quotas/error_constants.js @@ -2,7 +2,7 @@ import { s__ } from '~/locale'; import { PROMO_URL } from 'jh_else_ce/lib/utils/url_utility'; import { convertObjectPropsToLowerCase } from '~/lib/utils/common_utils'; -const salesLink = `${PROMO_URL}/sales/`; +const salesLink = `${PROMO_URL}/solutions/code-suggestions/sales/`; const supportLink = `${PROMO_URL}/support/`; const NO_SEATS_AVAILABLE_ERROR = { diff --git a/spec/scripts/internal_events/cli_spec.rb b/spec/scripts/internal_events/cli_spec.rb index 571517f005be291482725d6799dd51cb4c317022..54169e0dc2decc232a8cd1cc062c4de55bb29b52 100644 --- a/spec/scripts/internal_events/cli_spec.rb +++ b/spec/scripts/internal_events/cli_spec.rb @@ -3,15 +3,14 @@ require 'fast_spec_helper' require 'tty/prompt/test' require_relative '../../../scripts/internal_events/cli' +require_relative '../../support/helpers/wait_helpers' RSpec.describe Cli, feature_category: :service_ping do + include WaitHelpers + let(:prompt) { TTY::Prompt::Test.new } let(:files_to_cleanup) { [] } - - let(:example_timeout) { 3 } - let(:example_error) { Class.new(Timeout::Error) } - let(:interaction_timeout) { 1 } - let(:interaction_error) { Class.new(Timeout::Error) } + let(:max_wait_time) { 20 } let(:event1_filepath) { 'config/events/internal_events_cli_used.yml' } let(:event1_content) { internal_event_fixture('events/event_with_identifiers.yml') } @@ -31,19 +30,6 @@ delete_files(files_to_cleanup) end - around do |example| - Timeout.timeout(example_timeout, example_error) { example.run } - rescue example_error => e - # Override error to include CLI output in error detail - raise e.class, timeout_error_message, e.backtrace - end - - subject(:execute) do - Timeout.timeout(interaction_timeout, interaction_error) { described_class.new(prompt).run } - rescue interaction_error - # Rescue from timeout so we can make assertions on the CLI output - end - # Shared examples used for examples defined in new_events.yml & new_metrics.yml fixtures. # Note: Expects CLI to be exited using the 'Exit' option or completing definition flow shared_examples 'creates the right defintion files' do |description, test_case = {}| @@ -51,6 +37,7 @@ let(:keystrokes) { test_case.dig('inputs', 'keystrokes') || [] } let(:input_files) { test_case.dig('inputs', 'files') || [] } let(:output_files) { test_case.dig('outputs', 'files') || [] } + let(:timeout_error) { 'Internal Events CLI timed out while awaiting completion.' } # Script execution should stop without a reduced timeout let(:interaction_timeout) { example_timeout } @@ -61,7 +48,7 @@ queue_cli_inputs(keystrokes) expect_file_creation - execute + wait_for_cli_completion end private @@ -90,6 +77,12 @@ def expect_file_creation expect(File).not_to receive(:write) end end + + def wait_for_cli_completion + with_cli_thread do |thread| + wait_for(timeout_error, max_wait_time: max_wait_time) { !thread.alive? } + end + end end context 'when creating new events' do @@ -138,10 +131,8 @@ def expect_file_creation "\n" # Copy & continue ]) - execute - # Filter down to "dev" options - expect(plain_last_lines(9)).to eq <<~TEXT.chomp + expected_output = <<~TEXT.chomp ‣ dev:plan:project_management dev:plan:product_planning dev:plan:knowledge @@ -152,6 +143,8 @@ def expect_file_creation dev:create:editor_extensions dev:create:code_creation TEXT + + expect_cli_output { plain_last_lines(9) == expected_output } end it 'filters the product group options based on common section & stage' do @@ -170,16 +163,16 @@ def expect_file_creation "\n" # Copy & continue ]) - execute - # Filter down to "dev:create" options - expect(plain_last_lines(5)).to eq <<~TEXT.chomp + expected_output = <<~TEXT.chomp ‣ dev:create:source_code dev:create:code_review dev:create:ide dev:create:editor_extensions dev:create:code_creation TEXT + + expect_cli_output { plain_last_lines(5) == expected_output } end end @@ -206,10 +199,10 @@ def expect_file_creation "2\n" # Modify attributes ]) - execute - # Filter down to "dev" options - expect(plain_last_lines(50)).to include 'Select one: Which group owns the metric?' + expect_cli_output do + plain_last_lines(50).include?('Select one: Which group owns the metric?') + end end end @@ -221,13 +214,15 @@ def expect_file_creation it 'shows all metrics options' do select_event_from_list - expect(plain_last_lines(5)).to eq <<~TEXT.chomp + expected_output = <<~TEXT.chomp ‣ Monthly/Weekly count of unique users [who triggered internal_events_cli_used] Monthly/Weekly count of unique projects [where internal_events_cli_used occurred] Monthly/Weekly count of unique namespaces [where internal_events_cli_used occurred] Monthly/Weekly count of [internal_events_cli_used occurrences] Total count of [internal_events_cli_used occurrences] TEXT + + expect_cli_output { plain_last_lines(5) == expected_output } end context 'with an existing weekly metric' do @@ -241,7 +236,7 @@ def expect_file_creation it 'partially filters metric options' do select_event_from_list - expect(plain_last_lines(6)).to eq <<~TEXT.chomp + expected_output = <<~TEXT.chomp ‣ Monthly/Weekly count of unique users [who triggered internal_events_cli_used] Monthly/Weekly count of unique projects [where internal_events_cli_used occurred] Monthly/Weekly count of unique namespaces [where internal_events_cli_used occurred] @@ -249,6 +244,8 @@ def expect_file_creation ✘ Weekly count of [internal_events_cli_used occurrences] (already defined) Total count of [internal_events_cli_used occurrences] TEXT + + expect_cli_output { plain_last_lines(6) == expected_output } end end @@ -263,13 +260,15 @@ def expect_file_creation it 'filters whole metric options' do select_event_from_list - expect(plain_last_lines(5)).to eq <<~TEXT.chomp + expected_output = <<~TEXT.chomp ‣ Monthly/Weekly count of unique users [who triggered internal_events_cli_used] Monthly/Weekly count of unique projects [where internal_events_cli_used occurred] Monthly/Weekly count of unique namespaces [where internal_events_cli_used occurred] Monthly/Weekly count of [internal_events_cli_used occurrences] ✘ Total count of [internal_events_cli_used occurrences] (already defined) TEXT + + expect_cli_output { plain_last_lines(5) == expected_output } end end @@ -282,8 +281,6 @@ def select_event_from_list 'internal_events_cli_used', # Filters to this event "\n" # Select: config/events/internal_events_cli_used.yml ]) - - execute end end @@ -300,15 +297,15 @@ def select_event_from_list "\n" # Select: config/events/internal_events_cli_opened.yml ]) - execute - - expect(plain_last_lines(5)).to eq <<~TEXT.chomp + expected_output = <<~TEXT.chomp ✘ Monthly/Weekly count of unique users [who triggered internal_events_cli_opened] (user unavailable) ✘ Monthly/Weekly count of unique projects [where internal_events_cli_opened occurred] (project unavailable) ✘ Monthly/Weekly count of unique namespaces [where internal_events_cli_opened occurred] (namespace unavailable) ‣ Monthly/Weekly count of [internal_events_cli_opened occurrences] Total count of [internal_events_cli_opened occurrences] TEXT + + expect_cli_output { plain_last_lines(5) == expected_output } end end @@ -339,10 +336,9 @@ def select_event_from_list "\n" # Select: config/events/00_event1.yml ]) - execute + expected_output = 'Looks like the potential metrics for this event either already exist or are unsupported.' - expect(plain_last_lines(15)).to include 'Looks like the potential metrics for this event ' \ - 'either already exist or are unsupported.' + expect_cli_output { plain_last_lines(15).include?(expected_output) } end end end @@ -410,13 +406,13 @@ def select_event_from_list "8\n" # Exit ]) - execute + expect_cli_output do + output = plain_last_lines(100) - output = plain_last_lines(100) - - expect(output).to include expected_example_prompt - expect(output).to include expected_rails_example - expect(output).to include expected_rspec_example + output.include?(expected_example_prompt) && + output.include?(expected_rails_example) && + output.include?(expected_rspec_example) + end end end @@ -577,17 +573,17 @@ def select_event_from_list "8\n" # Exit ]) - execute + expect_cli_output do + output = plain_last_lines(1000) - output = plain_last_lines(1000) - - expect(output).to include expected_example_prompt - expect(output).to include expected_rails_example - expect(output).to include expected_rspec_example - expect(output).to include expected_vue_example - expect(output).to include expected_js_example - expect(output).to include expected_vue_template_example - expect(output).to include expected_haml_example + output.include?(expected_example_prompt) && + output.include?(expected_rails_example) && + output.include?(expected_rspec_example) && + output.include?(expected_vue_example) && + output.include?(expected_js_example) && + output.include?(expected_vue_template_example) && + output.include?(expected_haml_example) + end end end @@ -637,13 +633,13 @@ def select_event_from_list "8\n" # Exit ]) - execute - - output = plain_last_lines(300) + expect_cli_output do + output = plain_last_lines(300) - expect(output).to include expected_example_prompt - expect(output).to include expected_event1_example - expect(output).to include expected_event2_example + output.include?(expected_example_prompt) && + output.include?(expected_event1_example) && + output.include?(expected_event2_example) + end end end end @@ -756,9 +752,9 @@ def select_event_from_list "n\n" # No --> Are you trying to track customer usage of a GitLab feature? ]) - execute - - expect(plain_last_lines(50)).to include("Oh no! This probably isn't the tool you need!") + expect_cli_output do + plain_last_lines(50).include?("Oh no! This probably isn't the tool you need!") + end end it "handles when product usage can't be tracked with events" do @@ -768,9 +764,9 @@ def select_event_from_list "n\n" # No --> Can usage for the feature be measured by tracking a specific user action? ]) - execute - - expect(plain_last_lines(50)).to include("Oh no! This probably isn't the tool you need!") + expect_cli_output do + plain_last_lines(50).include?("Oh no! This probably isn't the tool you need!") + end end it 'handles when user needs to add a new event' do @@ -782,9 +778,9 @@ def select_event_from_list "n\n" # No --> Ready to start? ]) - execute - - expect(plain_last_lines(30)).to include("Okay! The next step is adding a new event! (~5 min)") + expect_cli_output do + plain_last_lines(30).include?("Okay! The next step is adding a new event! (~5 min)") + end end it 'handles when user needs to add a new metric' do @@ -796,9 +792,9 @@ def select_event_from_list "n\n" # No --> Ready to start? ]) - execute - - expect(plain_last_lines(30)).to include("Amazing! The next step is adding a new metric! (~8 min)") + expect_cli_output do + plain_last_lines(30).include?("Amazing! The next step is adding a new metric! (~8 min)") + end end end @@ -809,21 +805,6 @@ def queue_cli_inputs(keystrokes) prompt.input.rewind end - def timeout_error_message - <<~TEXT - Awaiting input too long. Entire CLI output: - - #{ - prompt.output.string.lines - .map { |line| "\e[0;37m#{line}\e[0m" } # wrap in white - .join('') - .gsub("\e[1G", "\e[1G ") # align to error indent - } - - - TEXT - end - def plain_last_lines(size) prompt.output.string .lines @@ -873,4 +854,16 @@ def delete_files(files) def internal_event_fixture(filepath) Rails.root.join('spec', 'fixtures', 'scripts', 'internal_events', filepath) end + + def with_cli_thread + thread = Thread.new { described_class.new(prompt).run } + + yield thread + ensure + thread.exit + end + + def expect_cli_output(&blk) + with_cli_thread { wait_for(blk.source, max_wait_time: max_wait_time, &blk) } + end end diff --git a/workhorse/internal/config/config.go b/workhorse/internal/config/config.go index 562ea05bfd0bba42a2dd6d23e891c78faffa0b48..c3b55c2a6e5a5854e72a953b8fad67f9a2803d34 100644 --- a/workhorse/internal/config/config.go +++ b/workhorse/internal/config/config.go @@ -162,6 +162,20 @@ func NewDefaultConfig() *Config { } } +func LoadConfigFromFile(file *string) (*Config, error) { + tomlData := "" + + if *file != "" { + buf, err := os.ReadFile(*file) + if err != nil { + return nil, fmt.Errorf("file: %v", err) + } + tomlData = string(buf) + } + + return LoadConfig(tomlData) +} + func LoadConfig(data string) (*Config, error) { cfg := NewDefaultConfig() diff --git a/workhorse/internal/config/config_test.go b/workhorse/internal/config/config_test.go index d3f000217254afd72841141f79ddab09920c455f..6127a5aae550caf0db2ada6bc54d8f3f3918d1a7 100644 --- a/workhorse/internal/config/config_test.go +++ b/workhorse/internal/config/config_test.go @@ -1,6 +1,7 @@ package config import ( + "os" "path/filepath" "testing" @@ -196,3 +197,30 @@ func TestDefaultConfig(t *testing.T) { require.Equal(t, uint64(250000), cfg.ImageResizerConfig.MaxFilesize) } + +func TestLoadConfigFromFile(t *testing.T) { + config := ` +[image_resizer] +max_filesize = 350000 +` + + fileName := createTempFile(t, []byte(config)) + + cfg, err := LoadConfigFromFile(&fileName) + require.NoError(t, err) + + require.Equal(t, uint64(350000), cfg.ImageResizerConfig.MaxFilesize) +} + +func createTempFile(t *testing.T, contents []byte) string { + t.Helper() + + tmpFile, err := os.CreateTemp(t.TempDir(), "config.toml") + require.NoError(t, err) + defer tmpFile.Close() + + _, err = tmpFile.Write(contents) + require.NoError(t, err) + + return tmpFile.Name() +} diff --git a/workhorse/main.go b/workhorse/main.go index 0c470d36e3e30cfd15fdcab57b3c0e3a48af6dfd..4d14d60df92da5fe0934cd3b2ae93c024b45ba37 100644 --- a/workhorse/main.go +++ b/workhorse/main.go @@ -138,16 +138,7 @@ func buildConfig(arg0 string, args []string) (*bootConfig, *config.Config, error cfg.CableBackend = cfg.Backend } - tomlData := "" - if *configFile != "" { - buf, err := os.ReadFile(*configFile) - if err != nil { - return nil, nil, fmt.Errorf("configFile: %v", err) - } - tomlData = string(buf) - } - - cfgFromFile, err := config.LoadConfig(tomlData) + cfgFromFile, err := config.LoadConfigFromFile(configFile) if err != nil { return nil, nil, fmt.Errorf("configFile: %v", err) }