From 47ef8c6c530ee1cac0e1046b098755ec949da894 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 26 May 2022 03:09:21 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- app/models/namespace.rb | 2 +- app/models/namespaces/project_namespace.rb | 7 ++ app/models/project.rb | 24 +++-- app/models/protected_tag.rb | 6 +- app/serializers/linked_issue_entity.rb | 9 ++ config/gitlab.yml.example | 2 +- doc/api/access_requests.md | 6 +- doc/api/groups.md | 22 ++-- doc/api/issues.md | 2 +- doc/api/templates/gitlab_ci_ymls.md | 2 +- doc/ci/pipelines/settings.md | 2 +- doc/development/refactoring_guide/index.md | 2 +- doc/development/shell_commands.md | 2 +- doc/install/azure/index.md | 2 +- doc/integration/jira/issues.md | 7 +- doc/integration/saml.md | 1 - doc/raketasks/backup_restore.md | 4 +- .../application_security/terminology/index.md | 100 ++++++++++++++++++ .../merge_when_pipeline_succeeds.md | 21 ++-- .../test_coverage_visualization.md | 2 +- lib/gitlab/ci/templates/Crystal.gitlab-ci.yml | 2 +- lib/gitlab/ci/templates/Django.gitlab-ci.yml | 2 +- lib/gitlab/ci/templates/Elixir.gitlab-ci.yml | 2 +- lib/gitlab/ci/templates/Laravel.gitlab-ci.yml | 2 +- lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml | 2 +- lib/gitlab/ci/templates/PHP.gitlab-ci.yml | 2 +- lib/gitlab/ci/templates/Ruby.gitlab-ci.yml | 2 +- lib/gitlab/ci/templates/Rust.gitlab-ci.yml | 2 +- lib/sidebars/projects/menus/settings_menu.rb | 2 +- spec/models/project_spec.rb | 54 +++++----- spec/models/protected_tag_spec.rb | 52 +++++++++ .../projects/issue_links_controller_spec.rb | 5 +- .../linked_project_issue_entity_spec.rb | 16 +++ 33 files changed, 285 insertions(+), 85 deletions(-) diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 865ca85d982..ec4b9786945 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -632,7 +632,7 @@ class Namespace < ApplicationRecord return end - if parent.project_namespace? + if parent&.project_namespace? errors.add(:parent_id, _('project namespace cannot be the parent of another namespace')) end diff --git a/app/models/namespaces/project_namespace.rb b/app/models/namespaces/project_namespace.rb index fbd87e3232d..2a2ea11ddc5 100644 --- a/app/models/namespaces/project_namespace.rb +++ b/app/models/namespaces/project_namespace.rb @@ -2,6 +2,13 @@ module Namespaces class ProjectNamespace < Namespace + # These aliases are added to make it easier to sync parent/parent_id attribute with + # project.namespace/project.namespace_id attribute. + # + # TODO: we can remove these attribute aliases when we no longer need to sync these with project model, + # see project#sync_attributes + alias_attribute :namespace, :parent + alias_attribute :namespace_id, :parent_id has_one :project, foreign_key: :project_namespace_id, inverse_of: :project_namespace def self.sti_name diff --git a/app/models/project.rb b/app/models/project.rb index e46f2a38cb0..759e3d348fb 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -3104,7 +3104,6 @@ class Project < ApplicationRecord # create project_namespace when project is created build_project_namespace if project_namespace_creation_enabled? - # we need to keep project and project namespace in sync if there is one sync_attributes(project_namespace) if sync_project_namespace? end @@ -3117,11 +3116,24 @@ class Project < ApplicationRecord end def sync_attributes(project_namespace) - project_namespace.name = name - project_namespace.path = path - project_namespace.parent = namespace - project_namespace.shared_runners_enabled = shared_runners_enabled - project_namespace.visibility_level = visibility_level + attributes_to_sync = changes.slice(*%w(name path namespace_id namespace visibility_level shared_runners_enabled)) + .transform_values { |val| val[1] } + + # if visibility_level is not set explicitly for project, it defaults to 0, + # but for namespace visibility_level defaults to 20, + # so it gets out of sync right away if we do not set it explicitly when creating the project namespace + attributes_to_sync['visibility_level'] ||= visibility_level if new_record? + + # when a project is associated with a group while the group is created we need to ensure we associate the new + # group with the project namespace as well. + # E.g. + # project = create(:project) <- project is saved + # create(:group, projects: [project]) <- associate project with a group that is not yet created. + if attributes_to_sync.has_key?('namespace_id') && attributes_to_sync['namespace_id'].blank? && namespace.present? + attributes_to_sync['parent'] = namespace + end + + project_namespace.assign_attributes(attributes_to_sync) end # SyncEvents are created by PG triggers (with the function `insert_projects_sync_event`) diff --git a/app/models/protected_tag.rb b/app/models/protected_tag.rb index 6b507429e57..5b2467daddc 100644 --- a/app/models/protected_tag.rb +++ b/app/models/protected_tag.rb @@ -8,7 +8,11 @@ class ProtectedTag < ApplicationRecord protected_ref_access_levels :create def self.protected?(project, ref_name) - refs = project.protected_tags.select(:name) + return false if ref_name.blank? + + refs = Gitlab::SafeRequestStore.fetch("protected-tag:#{project.cache_key}:refs") do + project.protected_tags.select(:name) + end self.matching(ref_name, protected_refs: refs).present? end diff --git a/app/serializers/linked_issue_entity.rb b/app/serializers/linked_issue_entity.rb index 769e3ed7310..4a28213fbac 100644 --- a/app/serializers/linked_issue_entity.rb +++ b/app/serializers/linked_issue_entity.rb @@ -3,6 +3,10 @@ class LinkedIssueEntity < Grape::Entity include RequestAwareEntity + format_with(:upcase) do |item| + item.try(:upcase) + end + expose :id, :confidential, :title expose :assignees, using: UserEntity @@ -21,6 +25,11 @@ class LinkedIssueEntity < Grape::Entity Gitlab::UrlBuilder.build(link, only_path: true) end + expose :issue_type, + as: :type, + format_with: :upcase, + documentation: { type: "String", desc: "One of #{::WorkItems::Type.base_types.keys.map(&:upcase)}" } + expose :relation_path expose :due_date, :created_at, :closed_at diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 54a92f5b8b4..841e7670e45 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -1172,7 +1172,7 @@ production: &base # keep_time: 604800 # default: 0 (forever) (in seconds) # pg_schema: public # default: nil, it means that all schemas will be backed up # upload: - # # Fog storage connection settings, see http://fog.io/storage/ . + # # Fog storage connection settings, see https://fog.io/storage/ . # connection: # provider: AWS # region: eu-west-1 diff --git a/doc/api/access_requests.md b/doc/api/access_requests.md index 08f3b78787b..32411a2f557 100644 --- a/doc/api/access_requests.md +++ b/doc/api/access_requests.md @@ -71,9 +71,9 @@ POST /groups/:id/access_requests POST /projects/:id/access_requests ``` -| Attribute | Type | Required | Description | -| --------- | -------------- | -------- | ----------- | -| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user | +| Attribute | Type | Required | Description | +| --------- | -------------- | -------- |-----------------------------------------------------------------------------------------| +| `id` | integer/string | yes | The ID or [URL-encoded path of the group or project](index.md#namespaced-path-encoding) | Example request: diff --git a/doc/api/groups.md b/doc/api/groups.md index b565e714285..7606ee5f2f6 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -389,9 +389,9 @@ Example response: "tag_list":[], //deprecated, use `topics` instead "topics":[], "ssh_url_to_repo":"ssh://git@gitlab.com/h5bp/html5-boilerplate.git", - "http_url_to_repo":"http://gitlab.com/h5bp/html5-boilerplate.git", - "web_url":"http://gitlab.com/h5bp/html5-boilerplate", - "readme_url":"http://gitlab.com/h5bp/html5-boilerplate/-/blob/master/README.md", + "http_url_to_repo":"https://gitlab.com/h5bp/html5-boilerplate.git", + "web_url":"https://gitlab.com/h5bp/html5-boilerplate", + "readme_url":"https://gitlab.com/h5bp/html5-boilerplate/-/blob/master/README.md", "avatar_url":null, "star_count":0, "forks_count":4, @@ -404,16 +404,16 @@ Example response: "full_path":"h5bp", "parent_id":null, "avatar_url":null, - "web_url":"http://gitlab.com/groups/h5bp" + "web_url":"https://gitlab.com/groups/h5bp" }, "_links":{ - "self":"http://gitlab.com/api/v4/projects/8", - "issues":"http://gitlab.com/api/v4/projects/8/issues", - "merge_requests":"http://gitlab.com/api/v4/projects/8/merge_requests", - "repo_branches":"http://gitlab.com/api/v4/projects/8/repository/branches", - "labels":"http://gitlab.com/api/v4/projects/8/labels", - "events":"http://gitlab.com/api/v4/projects/8/events", - "members":"http://gitlab.com/api/v4/projects/8/members" + "self":"https://gitlab.com/api/v4/projects/8", + "issues":"https://gitlab.com/api/v4/projects/8/issues", + "merge_requests":"https://gitlab.com/api/v4/projects/8/merge_requests", + "repo_branches":"https://gitlab.com/api/v4/projects/8/repository/branches", + "labels":"https://gitlab.com/api/v4/projects/8/labels", + "events":"https://gitlab.com/api/v4/projects/8/events", + "members":"https://gitlab.com/api/v4/projects/8/members" }, "empty_repo":false, "archived":false, diff --git a/doc/api/issues.md b/doc/api/issues.md index 44b947f14dc..e7442b97582 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -227,7 +227,7 @@ Issues created by users on GitLab Premium or higher include the `iteration` prop "updated_at":"2022-03-14T05:21:11.929Z", "start_date":"2022-03-08", "due_date":"2022-03-14", - "web_url":"http://gitlab.com/groups/my-group/-/iterations/90" + "web_url":"https://gitlab.com/groups/my-group/-/iterations/90" } ... } diff --git a/doc/api/templates/gitlab_ci_ymls.md b/doc/api/templates/gitlab_ci_ymls.md index 8a55ee84402..7f69818da8a 100644 --- a/doc/api/templates/gitlab_ci_ymls.md +++ b/doc/api/templates/gitlab_ci_ymls.md @@ -135,7 +135,7 @@ Example response: ```json { "name": "Ruby", - "content": "# This file is a template, and might need editing before it works on your project.\n# To contribute improvements to CI/CD templates, please follow the Development guide at:\n# https://docs.gitlab.com/ee/development/cicd/templates.html\n# This specific template is located at:\n# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml\n\n# Official language image. Look for the different tagged releases at:\n# https://hub.docker.com/r/library/ruby/tags/\nimage: ruby:latest\n\n# Pick zero or more services to be used on all builds.\n# Only needed when using a docker container to run your tests in.\n# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service\nservices:\n - mysql:latest\n - redis:latest\n - postgres:latest\n\nvariables:\n POSTGRES_DB: database_name\n\n# Cache gems in between builds\ncache:\n paths:\n - vendor/ruby\n\n# This is a basic example for a gem or script which doesn't use\n# services such as redis or postgres\nbefore_script:\n - ruby -v # Print out ruby version for debugging\n # Uncomment next line if your rails app needs a JS runtime:\n # - apt-get update -q && apt-get install nodejs -yqq\n - bundle config set path 'vendor' # Install dependencies into ./vendor/ruby\n - bundle install -j $(nproc)\n\n# Optional - Delete if not using `rubocop`\nrubocop:\n script:\n - rubocop\n\nrspec:\n script:\n - rspec spec\n\nrails:\n variables:\n DATABASE_URL: \"postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB\"\n script:\n - rails db:migrate\n - rails db:seed\n - rails test\n\n# This deploy job uses a simple deploy flow to Heroku, other providers, e.g. AWS Elastic Beanstalk\n# are supported too: https://github.com/travis-ci/dpl\ndeploy:\n stage: deploy\n environment: production\n script:\n - gem install dpl\n - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_PRODUCTION_KEY\n" + "content": "# This file is a template, and might need editing before it works on your project.\n# To contribute improvements to CI/CD templates, please follow the Development guide at:\n# https://docs.gitlab.com/ee/development/cicd/templates.html\n# This specific template is located at:\n# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml\n\n# Official language image. Look for the different tagged releases at:\n# https://hub.docker.com/r/library/ruby/tags/\nimage: ruby:latest\n\n# Pick zero or more services to be used on all builds.\n# Only needed when using a docker container to run your tests in.\n# Check out: https://docs.gitlab.com/ee/ci/services/index.html\nservices:\n - mysql:latest\n - redis:latest\n - postgres:latest\n\nvariables:\n POSTGRES_DB: database_name\n\n# Cache gems in between builds\ncache:\n paths:\n - vendor/ruby\n\n# This is a basic example for a gem or script which doesn't use\n# services such as redis or postgres\nbefore_script:\n - ruby -v # Print out ruby version for debugging\n # Uncomment next line if your rails app needs a JS runtime:\n # - apt-get update -q \u0026\u0026 apt-get install nodejs -yqq\n - bundle config set --local deployment true # Install dependencies into ./vendor/ruby\n - bundle install -j $(nproc)\n\n# Optional - Delete if not using `rubocop`\nrubocop:\n script:\n - rubocop\n\nrspec:\n script:\n - rspec spec\n\nrails:\n variables:\n DATABASE_URL: \"postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB\"\n script:\n - rails db:migrate\n - rails db:seed\n - rails test\n\n# This deploy job uses a simple deploy flow to Heroku, other providers, e.g. AWS Elastic Beanstalk\n# are supported too: https://github.com/travis-ci/dpl\ndeploy:\n stage: deploy\n environment: production\n script:\n - gem install dpl\n - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_PRODUCTION_KEY\n" } ``` diff --git a/doc/ci/pipelines/settings.md b/doc/ci/pipelines/settings.md index 379f002753e..16fbadee2d7 100644 --- a/doc/ci/pipelines/settings.md +++ b/doc/ci/pipelines/settings.md @@ -273,7 +273,7 @@ Use this regex for commonly used test tools. - Simplecov (Ruby). Example: `\(\d+.\d+\%\) covered`. -- pytest-cov (Python). Example: `^TOTAL.+?(\d+\%)$`. +- pytest-cov (Python). Example: `(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$`. - Scoverage (Scala). Example: `Statement coverage[A-Za-z\.*]\s*:\s*([^%]+)`. - `phpunit --coverage-text --colors=never` (PHP). Example: `^\s*Lines:\s*\d+.\d+\%`. - gcovr (C/C++). Example: `^TOTAL.*\s+(\d+\%)$`. diff --git a/doc/development/refactoring_guide/index.md b/doc/development/refactoring_guide/index.md index a6ed83258f3..9793db3bb85 100644 --- a/doc/development/refactoring_guide/index.md +++ b/doc/development/refactoring_guide/index.md @@ -71,7 +71,7 @@ expect(cleanForSnapshot(wrapper.element)).toMatchSnapshot(); ### Resources -[Unofficial wiki explanation](http://wiki.c2.com/?PinningTests) +[Unofficial wiki explanation](https://wiki.c2.com/?PinningTests) ### Examples diff --git a/doc/development/shell_commands.md b/doc/development/shell_commands.md index 6f56e60f619..fcb8c20bdd3 100644 --- a/doc/development/shell_commands.md +++ b/doc/development/shell_commands.md @@ -17,7 +17,7 @@ These guidelines are meant to make your code more reliable _and_ secure. ## Use File and FileUtils instead of shell commands -Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it. Use the Ruby API if it exists. +Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it. Use the Ruby API if it exists. ```ruby # Wrong diff --git a/doc/install/azure/index.md b/doc/install/azure/index.md index 780dfe17dac..c0a12d7aa15 100644 --- a/doc/install/azure/index.md +++ b/doc/install/azure/index.md @@ -155,7 +155,7 @@ to assign a descriptive DNS name to the VM: 1. Enter a descriptive DNS name for your instance in the **DNS name label** field, for example `gitlab-prod`. This makes the VM accessible at `gitlab-prod.eastus.cloudapp.azure.com`. -1. Select **Save** for the changes to take effect. +1. Select **Save**. Eventually, most users want to use their own domain name. For you to do this, you need to add a DNS `A` record with your domain registrar that points to the public IP address of your Azure VM. diff --git a/doc/integration/jira/issues.md b/doc/integration/jira/issues.md index aaff5de767b..2d9e928e654 100644 --- a/doc/integration/jira/issues.md +++ b/doc/integration/jira/issues.md @@ -54,10 +54,11 @@ You can [disable comments](#disable-comments-on-jira-issues) on issues. You can prevent merge requests from being merged if they do not refer to a Jira issue. To enforce this: -1. Navigate to your project's **Settings > General** page. -1. Expand the **Merge requests** section. +1. On the top bar, select **Menu > Projects** and find your project. +1. On the left sidebar, select **Settings > General**. +1. Expand **Merge requests**. 1. Under **Merge checks**, select the **Require an associated issue from Jira** checkbox. -1. Select **Save** for the changes to take effect. +1. Select **Save**. After you enable this feature, a merge request that doesn't reference an associated Jira issue can't be merged. The merge request displays the message diff --git a/doc/integration/saml.md b/doc/integration/saml.md index 39a10cfc31d..1a1eb17cf63 100644 --- a/doc/integration/saml.md +++ b/doc/integration/saml.md @@ -791,7 +791,6 @@ Examples: - [ADFS (Active Directory Federation Services)](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust) - [Auth0](https://auth0.com/docs/authenticate/protocols/saml/saml-sso-integrations/configure-auth0-saml-identity-provider) -- [PingOne by Ping Identity](http://docs.pingidentity.com/bundle/pingoneforenterprise/page/xsh1564020480660-1.html) GitLab provides the following setup notes for guidance only. If you have any questions on configuring the SAML app, please contact your provider's support. diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md index 49846eadd3d..c679cc16aca 100644 --- a/doc/raketasks/backup_restore.md +++ b/doc/raketasks/backup_restore.md @@ -561,7 +561,7 @@ For installations from source: backup: # snip upload: - # Fog storage connection settings, see http://fog.io/storage/ . + # Fog storage connection settings, see https://fog.io/storage/ . connection: provider: AWS region: eu-west-1 @@ -811,7 +811,7 @@ For installations from source: ```yaml backup: upload: - # Fog storage connection settings, see http://fog.io/storage/ . + # Fog storage connection settings, see https://fog.io/storage/ . connection: provider: Local local_root: '/mnt/backups' diff --git a/doc/user/application_security/terminology/index.md b/doc/user/application_security/terminology/index.md index 8277c30b81f..392bfa1dde2 100644 --- a/doc/user/application_security/terminology/index.md +++ b/doc/user/application_security/terminology/index.md @@ -96,6 +96,106 @@ A finding's location fingerprint is a text value that's unique for each location surface. Each Secure product defines this according to its type of attack surface. For example, SAST incorporates file path and line number. +### Package managers + +A Package manager is a system that manages your project dependencies. + +The package manager provides a method to install new dependencies (also referred to as "packages"), manage where packages are stored on your file system, and offer capabilities for you to publish your own packages. + +### Package types + +Each package manager, platform, type, or ecosystem has its own conventions and protocols to identify, locate, and provision software packages. + +The following table is a non-exhaustive list of some of the package managers and types referenced in GitLab documentation and software tools. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Package TypePackage Manager
gembundler
packagistcomposer
conanconan
gogo
mavengradle
maven
sbt
npmnpm
yarn
nugetnuget
pypisetuptools
pip
Pipenv
Poetry
+ ### Pipeline Security tab A page that displays findings discovered in the associated CI pipeline. diff --git a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md index 104fb5ca900..9182cf11566 100644 --- a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md +++ b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md @@ -56,10 +56,11 @@ As a result, [disabling GitLab CI/CD pipelines](../../../ci/enable_or_disable_ci does not disable this feature, as it is possible to use pipelines from external CI providers with this feature. To enable it, you must: -1. Navigate to your project's **Settings > General** page. -1. Expand the **Merge requests** section. -1. In the **Merge checks** subsection, select the **Pipelines must succeed** checkbox. -1. Press **Save** for the changes to take effect. +1. On the top bar, select **Menu > Projects** and find your project. +1. On the left sidebar, select **Settings > General**. +1. Expand **Merge requests**. +1. Under **Merge checks**, select the **Pipelines must succeed** checkbox. +1. Select **Save**. This setting also prevents merge requests from being merged if there is no pipeline. You should be careful to configure CI/CD so that pipelines run for every merge request. @@ -104,11 +105,13 @@ for details on avoiding two pipelines for a single merge request. When the **Pipelines must succeed** checkbox is checked, [skipped pipelines](../../../ci/pipelines/index.md#skip-a-pipeline) prevent merge requests from being merged. To change this behavior: -1. Navigate to your project's **Settings > General** page. -1. Expand the **Merge requests** section. -1. In the **Merge checks** subsection, ensure **Pipelines must succeed** is checked. -1. In the **Merge checks** subsection, select the **Skipped pipelines are considered successful** checkbox. -1. Press **Save** for the changes to take effect. +1. On the top bar, select **Menu > Projects** and find your project. +1. On the left sidebar, select **Settings > General**. +1. Expand **Merge requests**. +1. Under **Merge checks**: + - Ensure **Pipelines must succeed** is selected. + - Select the **Skipped pipelines are considered successful** checkbox. +1. Select **Save**. ## From the command line diff --git a/doc/user/project/merge_requests/test_coverage_visualization.md b/doc/user/project/merge_requests/test_coverage_visualization.md index 85b5bbea284..50ef9e86a02 100644 --- a/doc/user/project/merge_requests/test_coverage_visualization.md +++ b/doc/user/project/merge_requests/test_coverage_visualization.md @@ -255,7 +255,7 @@ run tests: - coverage run -m pytest - coverage report - coverage xml - coverage: '/TOTAL.*\s([.\d]+)%/' + coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/' artifacts: reports: coverage_report: diff --git a/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml index 856a097e6e0..8886929646d 100644 --- a/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml @@ -9,7 +9,7 @@ image: "crystallang/crystal:latest" # Pick zero or more services to be used on all builds. # Only needed when using a docker container to run your tests in. -# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service +# Check out: https://docs.gitlab.com/ee/ci/services/index.html # services: # - mysql:latest # - redis:latest diff --git a/lib/gitlab/ci/templates/Django.gitlab-ci.yml b/lib/gitlab/ci/templates/Django.gitlab-ci.yml index 426076c84a1..acc4a9d2917 100644 --- a/lib/gitlab/ci/templates/Django.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Django.gitlab-ci.yml @@ -41,7 +41,7 @@ default: # # Pick zero or more services to be used on all builds. # Only needed when using a docker container to run your tests in. - # Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service + # Check out: https://docs.gitlab.com/ee/ci/services/index.html services: - mysql:8.0 # diff --git a/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml index 1ceaf9fc86b..1eb920c7747 100644 --- a/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml @@ -7,7 +7,7 @@ image: elixir:latest # Pick zero or more services to be used on all builds. # Only needed when using a docker container to run your tests in. -# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service +# Check out: https://docs.gitlab.com/ee/ci/services/index.html services: - mysql:latest - redis:latest diff --git a/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml index ff7bac15017..0ec67526234 100644 --- a/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml @@ -9,7 +9,7 @@ image: php:latest # Pick zero or more services to be used on all builds. # Only needed when using a docker container to run your tests in. -# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service +# Check out: https://docs.gitlab.com/ee/ci/services/index.html services: - mysql:latest diff --git a/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml index 16bc0026aa8..44370f896a7 100644 --- a/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml @@ -9,7 +9,7 @@ image: node:latest # Pick zero or more services to be used on all builds. # Only needed when using a docker container to run your tests in. -# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service +# Check out: https://docs.gitlab.com/ee/ci/services/index.html services: - mysql:latest - redis:latest diff --git a/lib/gitlab/ci/templates/PHP.gitlab-ci.yml b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml index 281bf7e3dd9..4edc003a638 100644 --- a/lib/gitlab/ci/templates/PHP.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml @@ -23,7 +23,7 @@ before_script: - curl -sS https://getcomposer.org/installer | php - php composer.phar install -# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service +# Bring in any services we need https://docs.gitlab.com/ee/ci/services/index.html # See http://docs.gitlab.com/ee/ci/services/README.html for examples. services: - mysql:5.7 diff --git a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml index 44f959468a8..690a5a291e1 100644 --- a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml @@ -9,7 +9,7 @@ image: ruby:latest # Pick zero or more services to be used on all builds. # Only needed when using a docker container to run your tests in. -# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service +# Check out: https://docs.gitlab.com/ee/ci/services/index.html services: - mysql:latest - redis:latest diff --git a/lib/gitlab/ci/templates/Rust.gitlab-ci.yml b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml index 869c1782352..390f0bb8061 100644 --- a/lib/gitlab/ci/templates/Rust.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml @@ -9,7 +9,7 @@ image: "rust:latest" # Optional: Pick zero or more services to be used on all builds. # Only needed when using a docker container to run your tests in. -# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service +# Check out: https://docs.gitlab.com/ee/ci/services/index.html # services: # - mysql:latest # - redis:latest diff --git a/lib/sidebars/projects/menus/settings_menu.rb b/lib/sidebars/projects/menus/settings_menu.rb index 9dada3a3f73..d2d5b5881ca 100644 --- a/lib/sidebars/projects/menus/settings_menu.rb +++ b/lib/sidebars/projects/menus/settings_menu.rb @@ -112,7 +112,7 @@ module Sidebars ::Sidebars::MenuItem.new( title: _('Packages & Registries'), link: project_settings_packages_and_registries_path(context.project), - active_routes: { path: 'packages_and_registries#index' }, + active_routes: { path: 'packages_and_registries#show' }, item_id: :packages_and_registries ) end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 5e4ffeb8455..b1174d16adb 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -288,41 +288,35 @@ RSpec.describe Project, factory_default: :keep do end context 'updating a project' do - shared_examples 'project update' do - let_it_be(:project_namespace) { create(:project_namespace) } - let_it_be(:project) { project_namespace.project } + let_it_be(:project_namespace) { create(:project_namespace) } + let_it_be(:project) { project_namespace.project } - context 'when project namespace is not set' do - before do - project.update_column(:project_namespace_id, nil) - project.reload - end + context 'when project has an associated project namespace' do + # when FF is disabled creating a project does not create a project_namespace, so we create one + it 'project is INVALID when trying to remove project namespace' do + project.reload + # check that project actually has an associated project namespace + expect(project.project_namespace_id).to eq(project_namespace.id) - it 'updates the project successfully' do - # pre-check that project does not have a project namespace - expect(project.project_namespace).to be_nil - - project.update!(path: 'hopefully-valid-path2') - - expect(project).to be_persisted - expect(project).to be_valid - expect(project.path).to eq('hopefully-valid-path2') - expect(project.project_namespace).to be_nil - end + expect do + project.update!(project_namespace_id: nil, path: 'hopefully-valid-path1') + end.to raise_error(ActiveRecord::RecordInvalid) + expect(project).to be_invalid + expect(project.errors.full_messages).to include("Project namespace can't be blank") + expect(project.reload.project_namespace).to be_in_sync_with_project(project) end - context 'when project has an associated project namespace' do - # when FF is disabled creating a project does not create a project_namespace, so we create one - it 'project is INVALID when trying to remove project namespace' do - project.reload - # check that project actually has an associated project namespace - expect(project.project_namespace_id).to eq(project_namespace.id) + context 'when same project is being updated in 2 instances' do + it 'syncs only changed attributes' do + project1 = Project.last + project2 = Project.last + + project_name = project1.name + project_path = project1.path + + project1.update!(name: project_name + "-1") + project2.update!(path: project_path + "-1") - expect do - project.update!(project_namespace_id: nil, path: 'hopefully-valid-path1') - end.to raise_error(ActiveRecord::RecordInvalid) - expect(project).to be_invalid - expect(project.errors.full_messages).to include("Project namespace can't be blank") expect(project.reload.project_namespace).to be_in_sync_with_project(project) end end diff --git a/spec/models/protected_tag_spec.rb b/spec/models/protected_tag_spec.rb index e5cee6f18cd..b97954c055d 100644 --- a/spec/models/protected_tag_spec.rb +++ b/spec/models/protected_tag_spec.rb @@ -11,4 +11,56 @@ RSpec.describe ProtectedTag do it { is_expected.to validate_presence_of(:project) } it { is_expected.to validate_presence_of(:name) } end + + describe '#protected?' do + let(:project) { create(:project, :repository) } + + it 'returns true when the tag matches a protected tag via direct match' do + create(:protected_tag, project: project, name: 'foo') + + expect(described_class.protected?(project, 'foo')).to eq(true) + end + + it 'returns true when the tag matches a protected tag via wildcard match' do + create(:protected_tag, project: project, name: 'production/*') + + expect(described_class.protected?(project, 'production/some-tag')).to eq(true) + end + + it 'returns false when the tag does not match a protected tag via direct match' do + expect(described_class.protected?(project, 'foo')).to eq(false) + end + + it 'returns false when the tag does not match a protected tag via wildcard match' do + create(:protected_tag, project: project, name: 'production/*') + + expect(described_class.protected?(project, 'staging/some-tag')).to eq(false) + end + + it 'returns false when tag name is nil' do + expect(described_class.protected?(project, nil)).to eq(false) + end + + context 'with caching', :request_store do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:protected_tag) { create(:protected_tag, project: project, name: 'foo') } + + it 'correctly invalidates a cache' do + expect(described_class.protected?(project, 'foo')).to eq(true) + expect(described_class.protected?(project, 'bar')).to eq(false) + + create(:protected_tag, project: project, name: 'bar') + + expect(described_class.protected?(project, 'bar')).to eq(true) + end + + it 'correctly uses the cached version' do + expect(project).to receive(:protected_tags).once.and_call_original + + 2.times do + expect(described_class.protected?(project, protected_tag.name)).to eq(true) + end + end + end + end end diff --git a/spec/requests/projects/issue_links_controller_spec.rb b/spec/requests/projects/issue_links_controller_spec.rb index 3447ff83ed8..81fd1adb1fd 100644 --- a/spec/requests/projects/issue_links_controller_spec.rb +++ b/spec/requests/projects/issue_links_controller_spec.rb @@ -32,7 +32,10 @@ RSpec.describe Projects::IssueLinksController do get namespace_project_issue_links_path(issue_links_params) expect(json_response.count).to eq(1) - expect(json_response.first).to include('path' => project_work_items_path(issue_b.project, issue_b.id)) + expect(json_response.first).to include( + 'path' => project_work_items_path(issue_b.project, issue_b.id), + 'type' => 'TASK' + ) end end end diff --git a/spec/serializers/linked_project_issue_entity_spec.rb b/spec/serializers/linked_project_issue_entity_spec.rb index b28b00bd8e1..c4646754f16 100644 --- a/spec/serializers/linked_project_issue_entity_spec.rb +++ b/spec/serializers/linked_project_issue_entity_spec.rb @@ -25,6 +25,22 @@ RSpec.describe LinkedProjectIssueEntity do it { is_expected.to include(link_type: 'relates_to') } end + describe 'type' do + it 'returns the issue type' do + expect(serialized_entity).to include(type: 'ISSUE') + end + + context 'when related issue is a task' do + before do + related_issue.update!(issue_type: :task, work_item_type: WorkItems::Type.default_by_type(:task)) + end + + it 'returns a work item issue type' do + expect(serialized_entity).to include(type: 'TASK') + end + end + end + describe 'path' do it 'returns an issue path' do expect(serialized_entity).to include(path: project_issue_path(related_issue.project, related_issue.iid))