summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-19 15:07:55 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-19 15:07:55 +0000
commitf92a53a216e6e7d5037ac701efbee5628f91aa9a (patch)
tree1eb957f0277b50002258681f61db869a2b683fec
parente3764d340e2849fccee8c06278d1f5f686edd35b (diff)
downloadgitlab-ce-f92a53a216e6e7d5037ac701efbee5628f91aa9a.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.eslintrc.yml1
-rw-r--r--app/models/ci/build.rb2
-rw-r--r--app/models/ci/resource.rb13
-rw-r--r--app/models/ci/resource_group.rb39
-rw-r--r--app/models/project.rb1
-rw-r--r--app/services/ci/retry_build_service.rb2
-rw-r--r--changelogs/unreleased/ci-resource-group-model.yml5
-rw-r--r--changelogs/unreleased/fix-container-scanning-remediation-bug.yml5
-rw-r--r--db/migrate/20191128145231_add_ci_resource_groups.rb22
-rw-r--r--db/migrate/20191128145232_add_fk_to_ci_resources_build_id.rb17
-rw-r--r--db/migrate/20191128145233_add_fk_to_ci_resource_groups_project_id.rb17
-rw-r--r--db/migrate/20191129144630_add_resource_group_id_to_ci_builds.rb25
-rw-r--r--db/migrate/20191129144631_add_index_to_resource_group_id.rb20
-rw-r--r--db/schema.rb24
-rw-r--r--doc/administration/incoming_email.md4
-rw-r--r--doc/administration/index.md2
-rw-r--r--doc/development/documentation/workflow.md3
-rw-r--r--doc/gitlab-basics/add-merge-request.md46
-rw-r--r--doc/user/packages/conan_repository/index.md188
-rw-r--r--doc/user/packages/index.md2
-rw-r--r--doc/user/project/merge_requests/creating_merge_requests.md205
-rw-r--r--doc/user/project/merge_requests/getting_started.md148
-rw-r--r--doc/user/project/merge_requests/img/create_merge_request_button_v12_6.pngbin0 -> 33280 bytes
-rw-r--r--doc/user/project/merge_requests/img/new_merge_request_page_v12_6.pngbin0 -> 289963 bytes
-rw-r--r--doc/user/project/merge_requests/index.md67
-rw-r--r--doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md48
-rw-r--r--doc/user/project/settings/index.md2
-rw-r--r--lib/gitlab/ci/config/entry/job.rb9
-rw-r--r--lib/gitlab/ci/pipeline/seed/build.rb2
-rw-r--r--lib/gitlab/ci/pipeline/seed/build/resource_group.rb40
-rw-r--r--lib/gitlab/ci/yaml_processor.rb1
-rw-r--r--spec/factories/ci/builds.rb8
-rw-r--r--spec/factories/ci/resource.rb11
-rw-r--r--spec/factories/ci/resource_group.rb8
-rw-r--r--spec/features/merge_request/user_suggests_changes_on_diff_spec.rb3
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/build/resource_group_spec.rb46
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/build_spec.rb9
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb15
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/models/ci/resource_group_spec.rb88
-rw-r--r--spec/models/ci/resource_spec.rb28
-rw-r--r--spec/models/concerns/safe_url_spec.rb4
-rw-r--r--spec/services/ci/create_pipeline_service_spec.rb38
-rw-r--r--spec/services/ci/retry_build_service_spec.rb6
-rw-r--r--spec/validators/qualified_domain_array_validator_spec.rb4
45 files changed, 978 insertions, 251 deletions
diff --git a/.eslintrc.yml b/.eslintrc.yml
index 15e02a41bee..94a8d017c28 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -42,7 +42,6 @@ rules:
lines-between-class-members: off
# Disabled for now, to make the plugin-vue 4.5 -> 5.0 update smoother
vue/no-confusing-v-for-v-if: error
- vue/no-unused-components: off
vue/no-use-v-if-with-v-for: off
vue/no-v-html: off
vue/use-v-on-exact: off
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index e3f0e07bb8f..fbf76f2c36a 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -23,6 +23,7 @@ module Ci
belongs_to :runner
belongs_to :trigger_request
belongs_to :erased_by, class_name: 'User'
+ belongs_to :resource_group, class_name: 'Ci::ResourceGroup', inverse_of: :builds
RUNNER_FEATURES = {
upload_multiple_artifacts: -> (build) { build.publishes_artifacts_reports? },
@@ -34,6 +35,7 @@ module Ci
}.freeze
has_one :deployment, as: :deployable, class_name: 'Deployment'
+ has_one :resource, class_name: 'Ci::Resource', inverse_of: :build
has_many :trace_sections, class_name: 'Ci::BuildTraceSection'
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id
diff --git a/app/models/ci/resource.rb b/app/models/ci/resource.rb
new file mode 100644
index 00000000000..ee5b6546165
--- /dev/null
+++ b/app/models/ci/resource.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Ci
+ class Resource < ApplicationRecord
+ extend Gitlab::Ci::Model
+
+ belongs_to :resource_group, class_name: 'Ci::ResourceGroup', inverse_of: :resources
+ belongs_to :build, class_name: 'Ci::Build', inverse_of: :resource
+
+ scope :free, -> { where(build: nil) }
+ scope :retained_by, -> (build) { where(build: build) }
+ end
+end
diff --git a/app/models/ci/resource_group.rb b/app/models/ci/resource_group.rb
new file mode 100644
index 00000000000..eb18f3da0bf
--- /dev/null
+++ b/app/models/ci/resource_group.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Ci
+ class ResourceGroup < ApplicationRecord
+ extend Gitlab::Ci::Model
+
+ belongs_to :project, inverse_of: :resource_groups
+
+ has_many :resources, class_name: 'Ci::Resource', inverse_of: :resource_group
+ has_many :builds, class_name: 'Ci::Build', inverse_of: :resource_group
+
+ validates :key,
+ length: { maximum: 255 },
+ format: { with: Gitlab::Regex.environment_name_regex,
+ message: Gitlab::Regex.environment_name_regex_message }
+
+ before_create :ensure_resource
+
+ ##
+ # NOTE: This is concurrency-safe method that the subquery in the `UPDATE`
+ # works as explicit locking.
+ def assign_resource_to(build)
+ resources.free.limit(1).update_all(build_id: build.id) > 0
+ end
+
+ def release_resource_from(build)
+ resources.retained_by(build).update_all(build_id: nil) > 0
+ end
+
+ private
+
+ def ensure_resource
+ # Currently we only support one resource per group, which means
+ # maximum one build can be set to the resource group, thus builds
+ # belong to the same resource group are executed once at time.
+ self.resources.build if self.resources.empty?
+ end
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index cfdcdbed502..1a84827b5ec 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -285,6 +285,7 @@ class Project < ApplicationRecord
has_many :pipeline_schedules, class_name: 'Ci::PipelineSchedule'
has_many :project_deploy_tokens
has_many :deploy_tokens, through: :project_deploy_tokens
+ has_many :resource_groups, class_name: 'Ci::ResourceGroup', inverse_of: :project
has_one :auto_devops, class_name: 'ProjectAutoDevops', inverse_of: :project, autosave: true
has_many :custom_attributes, class_name: 'ProjectCustomAttribute'
diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb
index 7a5e33c61ba..5abfbd26641 100644
--- a/app/services/ci/retry_build_service.rb
+++ b/app/services/ci/retry_build_service.rb
@@ -5,7 +5,7 @@ module Ci
CLONE_ACCESSORS = %i[pipeline project ref tag options name
allow_failure stage stage_id stage_idx trigger_request
yaml_variables when environment coverage_regex
- description tag_list protected needs].freeze
+ description tag_list protected needs resource_group].freeze
def execute(build)
reprocess!(build).tap do |new_build|
diff --git a/changelogs/unreleased/ci-resource-group-model.yml b/changelogs/unreleased/ci-resource-group-model.yml
new file mode 100644
index 00000000000..98bc0159626
--- /dev/null
+++ b/changelogs/unreleased/ci-resource-group-model.yml
@@ -0,0 +1,5 @@
+---
+title: Add Ci Resource Group models
+merge_request: 20950
+author:
+type: other
diff --git a/changelogs/unreleased/fix-container-scanning-remediation-bug.yml b/changelogs/unreleased/fix-container-scanning-remediation-bug.yml
new file mode 100644
index 00000000000..07b80716ff3
--- /dev/null
+++ b/changelogs/unreleased/fix-container-scanning-remediation-bug.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bug in Container Scanning report remediations
+merge_request: 21980
+author:
+type: fixed
diff --git a/db/migrate/20191128145231_add_ci_resource_groups.rb b/db/migrate/20191128145231_add_ci_resource_groups.rb
new file mode 100644
index 00000000000..8bde0254701
--- /dev/null
+++ b/db/migrate/20191128145231_add_ci_resource_groups.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddCiResourceGroups < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :ci_resource_groups do |t|
+ t.timestamps_with_timezone
+ t.bigint :project_id, null: false
+ t.string :key, null: false, limit: 255
+ t.index %i[project_id key], unique: true
+ end
+
+ create_table :ci_resources do |t|
+ t.timestamps_with_timezone
+ t.references :resource_group, null: false, index: false, foreign_key: { to_table: :ci_resource_groups, on_delete: :cascade }
+ t.bigint :build_id, null: true
+ t.index %i[build_id]
+ t.index %i[resource_group_id build_id], unique: true
+ end
+ end
+end
diff --git a/db/migrate/20191128145232_add_fk_to_ci_resources_build_id.rb b/db/migrate/20191128145232_add_fk_to_ci_resources_build_id.rb
new file mode 100644
index 00000000000..a13513de3b2
--- /dev/null
+++ b/db/migrate/20191128145232_add_fk_to_ci_resources_build_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddFkToCiResourcesBuildId < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :ci_resources, :ci_builds, column: :build_id, on_delete: :nullify
+ end
+
+ def down
+ remove_foreign_key_if_exists :ci_resources, column: :build_id
+ end
+end
diff --git a/db/migrate/20191128145233_add_fk_to_ci_resource_groups_project_id.rb b/db/migrate/20191128145233_add_fk_to_ci_resource_groups_project_id.rb
new file mode 100644
index 00000000000..bb23012ea9b
--- /dev/null
+++ b/db/migrate/20191128145233_add_fk_to_ci_resource_groups_project_id.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddFkToCiResourceGroupsProjectId < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :ci_resource_groups, :projects, column: :project_id, on_delete: :cascade
+ end
+
+ def down
+ remove_foreign_key_if_exists :ci_resource_groups, column: :project_id
+ end
+end
diff --git a/db/migrate/20191129144630_add_resource_group_id_to_ci_builds.rb b/db/migrate/20191129144630_add_resource_group_id_to_ci_builds.rb
new file mode 100644
index 00000000000..2e696c32e7e
--- /dev/null
+++ b/db/migrate/20191129144630_add_resource_group_id_to_ci_builds.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class AddResourceGroupIdToCiBuilds < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def up
+ unless column_exists?(:ci_builds, :resource_group_id)
+ add_column :ci_builds, :resource_group_id, :bigint
+ end
+
+ unless column_exists?(:ci_builds, :waiting_for_resource_at)
+ add_column :ci_builds, :waiting_for_resource_at, :datetime_with_timezone
+ end
+ end
+
+ def down
+ if column_exists?(:ci_builds, :resource_group_id)
+ remove_column :ci_builds, :resource_group_id, :bigint
+ end
+
+ if column_exists?(:ci_builds, :waiting_for_resource_at)
+ remove_column :ci_builds, :waiting_for_resource_at, :datetime_with_timezone
+ end
+ end
+end
diff --git a/db/migrate/20191129144631_add_index_to_resource_group_id.rb b/db/migrate/20191129144631_add_index_to_resource_group_id.rb
new file mode 100644
index 00000000000..0e5a84f094d
--- /dev/null
+++ b/db/migrate/20191129144631_add_index_to_resource_group_id.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class AddIndexToResourceGroupId < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_for_resource_group'.freeze
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :ci_builds, %i[resource_group_id id], where: 'resource_group_id IS NOT NULL', name: INDEX_NAME
+ add_concurrent_foreign_key :ci_builds, :ci_resource_groups, column: :resource_group_id, on_delete: :nullify
+ end
+
+ def down
+ remove_foreign_key_if_exists :ci_builds, column: :resource_group_id
+ remove_concurrent_index_by_name :ci_builds, INDEX_NAME
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index acf51164e0b..91fbcd42f30 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -684,6 +684,8 @@ ActiveRecord::Schema.define(version: 2019_12_16_183532) do
t.datetime_with_timezone "scheduled_at"
t.string "token_encrypted"
t.integer "upstream_pipeline_id"
+ t.bigint "resource_group_id"
+ t.datetime_with_timezone "waiting_for_resource_at"
t.index ["artifacts_expire_at"], name: "index_ci_builds_on_artifacts_expire_at", where: "(artifacts_file <> ''::text)"
t.index ["auto_canceled_by_id"], name: "index_ci_builds_on_auto_canceled_by_id"
t.index ["commit_id", "artifacts_expire_at", "id"], name: "index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial", where: "(((type)::text = 'Ci::Build'::text) AND ((retried = false) OR (retried IS NULL)) AND ((name)::text = ANY (ARRAY[('sast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('sast:container'::character varying)::text, ('container_scanning'::character varying)::text, ('dast'::character varying)::text])))"
@@ -698,6 +700,7 @@ ActiveRecord::Schema.define(version: 2019_12_16_183532) do
t.index ["project_id"], name: "index_ci_builds_on_project_id_for_successfull_pages_deploy", where: "(((type)::text = 'GenericCommitStatus'::text) AND ((stage)::text = 'deploy'::text) AND ((name)::text = 'pages:deploy'::text) AND ((status)::text = 'success'::text))"
t.index ["protected"], name: "index_ci_builds_on_protected"
t.index ["queued_at"], name: "index_ci_builds_on_queued_at"
+ t.index ["resource_group_id", "id"], name: "index_for_resource_group", where: "(resource_group_id IS NOT NULL)"
t.index ["runner_id"], name: "index_ci_builds_on_runner_id"
t.index ["scheduled_at"], name: "partial_index_ci_builds_on_scheduled_at_with_scheduled_jobs", where: "((scheduled_at IS NOT NULL) AND ((type)::text = 'Ci::Build'::text) AND ((status)::text = 'scheduled'::text))"
t.index ["stage_id", "stage_idx"], name: "tmp_build_stage_position_index", where: "(stage_idx IS NOT NULL)"
@@ -872,6 +875,23 @@ ActiveRecord::Schema.define(version: 2019_12_16_183532) do
t.index ["user_id"], name: "index_ci_pipelines_on_user_id"
end
+ create_table "ci_resource_groups", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "project_id", null: false
+ t.string "key", limit: 255, null: false
+ t.index ["project_id", "key"], name: "index_ci_resource_groups_on_project_id_and_key", unique: true
+ end
+
+ create_table "ci_resources", force: :cascade do |t|
+ t.datetime_with_timezone "created_at", null: false
+ t.datetime_with_timezone "updated_at", null: false
+ t.bigint "resource_group_id", null: false
+ t.bigint "build_id"
+ t.index ["build_id"], name: "index_ci_resources_on_build_id"
+ t.index ["resource_group_id", "build_id"], name: "index_ci_resources_on_resource_group_id_and_build_id", unique: true
+ end
+
create_table "ci_runner_namespaces", id: :serial, force: :cascade do |t|
t.integer "runner_id"
t.integer "namespace_id"
@@ -4395,6 +4415,7 @@ ActiveRecord::Schema.define(version: 2019_12_16_183532) do
add_foreign_key "ci_builds", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_a2141b1522", on_delete: :nullify
add_foreign_key "ci_builds", "ci_pipelines", column: "commit_id", name: "fk_d3130c9a7f", on_delete: :cascade
add_foreign_key "ci_builds", "ci_pipelines", column: "upstream_pipeline_id", name: "fk_87f4cefcda", on_delete: :cascade
+ add_foreign_key "ci_builds", "ci_resource_groups", column: "resource_group_id", name: "fk_6661f4f0e8", on_delete: :nullify
add_foreign_key "ci_builds", "ci_stages", column: "stage_id", name: "fk_3a9eaa254d", on_delete: :cascade
add_foreign_key "ci_builds", "projects", name: "fk_befce0568a", on_delete: :cascade
add_foreign_key "ci_builds_metadata", "ci_builds", column: "build_id", on_delete: :cascade
@@ -4415,6 +4436,9 @@ ActiveRecord::Schema.define(version: 2019_12_16_183532) do
add_foreign_key "ci_pipelines", "external_pull_requests", name: "fk_190998ef09", on_delete: :nullify
add_foreign_key "ci_pipelines", "merge_requests", name: "fk_a23be95014", on_delete: :cascade
add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade
+ add_foreign_key "ci_resource_groups", "projects", name: "fk_774722d144", on_delete: :cascade
+ add_foreign_key "ci_resources", "ci_builds", column: "build_id", name: "fk_e169a8e3d5", on_delete: :nullify
+ add_foreign_key "ci_resources", "ci_resource_groups", column: "resource_group_id", on_delete: :cascade
add_foreign_key "ci_runner_namespaces", "ci_runners", column: "runner_id", on_delete: :cascade
add_foreign_key "ci_runner_namespaces", "namespaces", on_delete: :cascade
add_foreign_key "ci_runner_projects", "projects", name: "fk_4478a6f1e4", on_delete: :cascade
diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md
index a0360f1d252..1550787d532 100644
--- a/doc/administration/incoming_email.md
+++ b/doc/administration/incoming_email.md
@@ -7,7 +7,7 @@ GitLab has several features based on receiving incoming emails:
- [New issue by email](../user/project/issues/managing_issues.md#new-issue-via-email):
allow GitLab users to create a new issue by sending an email to a
user-specific email address.
-- [New merge request by email](../user/project/merge_requests/creating_merge_requests.md#create-new-merge-requests-by-email):
+- [New merge request by email](../user/project/merge_requests/creating_merge_requests.md#new-merge-request-by-email-core-only):
allow GitLab users to create a new merge request by sending an email to a
user-specific email address.
- [Service Desk](../user/project/service_desk.md): provide e-mail support to
@@ -79,7 +79,7 @@ email address in order to sign up.
If you also host a public-facing GitLab instance at `hooli.com` and set your
incoming email domain to `hooli.com`, an attacker could abuse the "Create new
issue by email" or
-"[Create new merge request by email](../user/project/merge_requests/creating_merge_requests.md#create-new-merge-requests-by-email)"
+"[Create new merge request by email](../user/project/merge_requests/creating_merge_requests.md#new-merge-request-by-email-core-only)"
features by using a project's unique address as the email when signing up for
Slack, which would send a confirmation email, which would create a new issue or
merge request on the project owned by the attacker, allowing them to click the
diff --git a/doc/administration/index.md b/doc/administration/index.md
index 2a9980cddb3..4cafb4eb87c 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -119,7 +119,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Auditor users](auditor_users.md): Users with read-only access to all projects, groups, and other resources on the GitLab instance. **(PREMIUM ONLY)**
- [Incoming email](incoming_email.md): Configure incoming emails to allow
users to [reply by email](reply_by_email.md), create [issues by email](../user/project/issues/managing_issues.md#new-issue-via-email) and
- [merge requests by email](../user/project/merge_requests/creating_merge_requests.md#create-new-merge-requests-by-email), and to enable [Service Desk](../user/project/service_desk.md).
+ [merge requests by email](../user/project/merge_requests/creating_merge_requests.md#new-merge-request-by-email-core-only), and to enable [Service Desk](../user/project/service_desk.md).
- [Postfix for incoming email](reply_by_email_postfix_setup.md): Set up a
basic Postfix mail server with IMAP authentication on Ubuntu for incoming
emails.
diff --git a/doc/development/documentation/workflow.md b/doc/development/documentation/workflow.md
index e48c940dc21..ae13bc63583 100644
--- a/doc/development/documentation/workflow.md
+++ b/doc/development/documentation/workflow.md
@@ -297,8 +297,7 @@ To request help:
1. Locate the the Technical Writer for the relevant
[DevOps stage group](https://about.gitlab.com/handbook/product/technical-writing/index.html#assignments).
1. Either:
- - If urgent help is required, directly assign the Technical Writer in the issue or
- [in the merge request](../../user/project/merge_requests/creating_merge_requests.md#multiple-assignees-starter).
+ - If urgent help is required, directly assign the Technical Writer in the issue or in the merge request.
- If non-urgent help is required, ping the Technical Writer in the issue or merge request.
If you are a member of GitLab's Slack workspace, you can request help in `#docs`.
diff --git a/doc/gitlab-basics/add-merge-request.md b/doc/gitlab-basics/add-merge-request.md
index 28f32fefb95..1ee28183ac8 100644
--- a/doc/gitlab-basics/add-merge-request.md
+++ b/doc/gitlab-basics/add-merge-request.md
@@ -1,47 +1,5 @@
---
-type: howto
+redirect_to: '../user/project/merge_requests/creating_merge_requests.md'
---
-# How to create a merge request
-
-Merge requests are how you integrate separate changes that you've made in a
-[branch](create-branch.md) to a [project](create-project.md).
-
-This is a brief guide on how to create a merge request. For more detailed information,
-check the [merge requests documentation](../user/project/merge_requests/index.md), or
-you can watch our [GitLab Flow video](https://www.youtube.com/watch?v=InKNIvky2KE) for
-a quick overview of working with merge requests.
-
-1. Before you start, you should have already [created a branch](create-branch.md)
- and [pushed your changes](start-using-git.md#send-changes-to-gitlabcom) to GitLab.
-1. Go to the project where you'd like to merge your changes and click on the
- **Merge requests** tab.
-1. Click on **New merge request** on the right side of the screen.
-1. From there, you have the option to select the source branch and the target
- branch you'd like to compare to. The default target project is the upstream
- repository, but you can choose to compare across any of its forks.
-
- ![Select a branch](img/merge_request_select_branch.png)
-
-1. When ready, click on the **Compare branches and continue** button.
-1. At a minimum, add a title and a description to your merge request. Optionally,
- select a user to review your merge request. You may also select a milestone and
- labels.
-
- ![New merge request page](img/merge_request_page.png)
-
-1. When ready, click on the **Submit merge request** button.
-
-Your merge request will be ready to be reviewed, approved, and merged.
-
-<!-- ## Troubleshooting
-
-Include any troubleshooting steps that you can foresee. If you know beforehand what issues
-one might have when setting this up, or when something is changed, or on upgrading, it's
-important to describe those, too. Think of things that may go wrong and include them here.
-This is important to minimize requests for support, and to avoid doc comments with
-questions that you know someone might ask.
-
-Each scenario can be a third-level heading, e.g. `### Getting error message X`.
-If you have none to add when creating a doc, leave this section in place
-but commented out to help encourage others to add to it in the future. -->
+This document was moved to [another location](../user/project/merge_requests/creating_merge_requests.md).
diff --git a/doc/user/packages/conan_repository/index.md b/doc/user/packages/conan_repository/index.md
index 2366d1ccc0d..bf822169de4 100644
--- a/doc/user/packages/conan_repository/index.md
+++ b/doc/user/packages/conan_repository/index.md
@@ -22,46 +22,134 @@ by default. To enable it for existing projects, or if you want to disable it:
You should then be able to see the **Packages** section on the left sidebar.
-Before proceeding to authenticating with the GitLab Conan Repository, you should
-get familiar with the package naming convention.
+## Getting started
-## Authenticating to the GitLab Conan Repository
+This section will cover installing Conan and building a package for your C/C++ project. This is a quickstart if you are new
+to Conan. If you already are using Conan and understand how to build your own packages, move on to the [next section](#adding-the-gitlab-package-registry-as-a-conan-remote).
-You will need to generate a [personal access token](../../../user/profile/personal_access_tokens.md) with the scope set to `api` for repository authentication.
+### Installing Conan
+
+Follow the instructions at [conan.io](https://conan.io/downloads.html) to download the Conan package manager to your local development environment.
+
+Once installation is complete, verify you can use Conan in your terminal by running
+
+```sh
+conan --version
+```
+
+You should see the Conan version printed in the output:
+
+```
+Conan version 1.20.5
+```
-Now you can run conan commands using your token.
+### Installing CMake
-`CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan upload Hello/0.2@user/channel --remote=gitlab`
-`CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan search Hello* --all --remote=gitlab`
+When developing with C++ and Conan, you have a wide range of options for compilers. This tutorial walks through using the cmake
+compiler. In your terminal, run the command
-Alternatively, you can set the `CONAN_LOGIN_USERNAME` and `CONAN_PASSWORD` in your local conan config to be used when connecting to the `gitlab` remote. The examples here show the username and password inline.
+```sh
+cmake --version
+```
+
+You should see the cmake version printed in the output. If you see something else, you may have to install cmake.
+
+On a Mac, you can use [homebrew](https://brew.sh/) to install cmake by running `brew install cmake`. Otherwise, follow
+instructions at [cmake.org](https://cmake.org/install/) for your operating system.
+
+### Creating a project
+
+Understanding what is needed to create a valid and compilable C++ project is out of the scope of this guide, but if you are new to C++ and want to try out the GitLab
+package registry, Conan.io has a great [hello world starter project](https://github.com/conan-io/hello) that you can clone to get started.
-Next, you'll need to set your Conan remote to point to the GitLab Package Registry.
+Clone the repo and it can be used for the rest of the tutorial if you don't have your own C++ project.
-## Setting the Conan remote to the GitLab Package Registry
+### Building a package
-After you authenticate to the [GitLab Conan Repository](#authenticating-to-the-gitlab-conan-repository),
-you can set the Conan remote:
+In your terminal, navigate to the root folder of your project. Generate a new recipe by running `conan new` and providing it with a
+package name and version:
+
+```sh
+conan new Hello/0.1 -t
+```
+
+Next, you will create a package for that recipe by running `conan create` providing the Conan user and channel:
+
+```sh
+conan create . my-org+my-group+my-project/beta
+```
+
+NOTE: **Note**
+Current [naming restrictions](#package-recipe-naming-convention) require you to name the `user` value as the `+` separated path of your project on GitLab.
+
+The example above would create a package belonging to this project: `https://gitlab.com/my-org/my-group/my-project` with a channel of `beta`.
+
+These two example commands will generate a final package with the recipe `Hello/0.1@my-org+my-group+my-project/beta`.
+
+For more advanced details on creating and managing your packages, refer to the [Conan docs](https://docs.conan.io/en/latest/creating_packages.html).
+
+You are now ready to upload your package to the GitLab registry. To get started, first you will need to set GitLab as a remote, then you will need to add a Conan user for that remote to authenticate your requests.
+
+## Adding the GitLab Package Registry as a Conan remote
+
+Add a new remote to your Conan configuration:
```sh
conan remote add gitlab https://gitlab.example.com/api/v4/packages/conan
```
-Once the remote is set, you can use the remote when running Conan commands:
+Once the remote is set, you can use the remote when running Conan commands by adding `--remote=gitlab` to the end of your commands.
+
+For example:
```sh
conan search Hello* --all --remote=gitlab
```
-## Supported CLI commands
+## Authenticating to the GitLab Conan Repository
-The GitLab Conan repository supports the following Conan CLI commands:
+You will need to generate a [personal access token](../../../user/profile/personal_access_tokens.md) with the scope set to `api` for repository authentication.
-- `conan upload`: Upload your recipe and package files to the GitLab Package Registry.
-- `conan install`: Install a conan package from the GitLab Package Registry, this includes using the `conan.txt` file.
-- `conan search`: Search the GitLab Package Registry for public packages, and private packages you have permission to view.
-- `conan info`: View the info on a given package from the GitLab Package Registry.
-- `conan remove`: Delete the package from the GitLab Package Registry.
+### Adding a Conan user to the GitLab remote
+
+Once you have a personal access token and have [set your Conan remote](#adding-the-gitlab-package-registry-as-a-conan-remote), you can associate the token with the remote so you do not have to explicitly add them to each Conan command you run:
+
+```sh
+conan user <gitlab-username> -r gitlab -p <personal_access_token>
+```
+
+Note: **Note**
+If you named your remote something other than `gitlab`, your remote name should be used in this command instead of `gitlab`.
+
+From now on, when you run commands using `--remote=gitlab`, your username and password will automatically be included in the requests.
+
+Note: **Note**
+The personal access token is not stored locally at any moment. Conan uses JWT, so when you run this command, Conan will request an expirable token from GitLab using your token. The JWT does expire on a regular basis, so you will need to re-enter your personal access token when that happens.
+
+Alternatively, you could explicitly include your credentials in any given command.
+For example:
+
+```sh
+CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan upload Hello/0.1@my-group+my-project/beta --all --remote=gitlab
+```
+
+### Setting a default remote to your project (optional)
+
+If you'd like Conan to always use GitLab as the registry for your package, you can tell Conan to always reference the GitLab remote for a given package recipe:
+
+```sh
+conan remote add_ref Hello/0.1@my-group+my-project/beta gitlab
+```
+
+NOTE: **Note**
+The package recipe does include the version, so setting the default remote for `Hello/0.1@user/channel` will not work for `Hello/0.2@user/channel`.
+This functionality is best suited for when you want to consume or install packages from the GitLab registry without having to specify a remote.
+
+The rest of the example commands in this documentation assume that you have added a Conan user with your credentials to the `gitlab` remote and will not include the explicit credentials or remote option, but be aware that any of the commands could be run without having added a user or default remote:
+
+```sh
+`CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> <conan command> --remote=gitlab
+```
## Uploading a package
@@ -72,14 +160,14 @@ Ensure you have a project created on GitLab and that the personal access token y
You can upload your package to the GitLab Package Registry using the `conan upload` command:
```sh
-CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan upload Hello/0.1@my-group+my-project/beta --all --remote=gitlab
+conan upload Hello/0.1@my-group+my-project/beta --all
```
### Package recipe naming convention
-Standard Conan recipe convention looks like `package_name/version@username/channel`.
+Standard Conan recipe convention looks like `package_name/version@user/channel`.
-**Recipe usernames must be the `+` separated project path**. The package
+**The recipe user must be the `+` separated project path**. The package
name may be anything, but it is preferred that the project name be used unless
it is not possible due to a naming collision. For example:
@@ -95,7 +183,36 @@ A future iteration will extend support to [project and group level](https://gitl
## Installing a package
-Add the conan package to the `[requires]` section of your `conan.txt` file and they will be installed when you run `conan install` within your project.
+Conan packages are commonly installed as dependencies using the `conanfile.txt` file.
+
+In your project where you would like to install the Conan package as a dependency, open `conanfile.txt` or create
+an empty file named `conanfile.txt` in the root of your project.
+
+Add the Conan recipe to the `[requires]` section of the file:
+
+```ini
+ [requires]
+ Hello/0.1@my-group+my-project/beta
+
+ [generators]
+ cmake
+```
+
+Next, from the root of your project, create a build directory and navigate to it:
+
+```sh
+mkdir build && cd build
+```
+
+Now you can install the dependencies listed in `conanfile.txt`:
+
+```sh
+conan install ..
+```
+
+NOTE: **Note:**
+If you are trying to install the package you just created in this tutorial, not much will happen since that package
+already exists on your local machine.
## Removing a package
@@ -104,8 +221,11 @@ There are two ways to remove a Conan package from the GitLab Package Registry.
- **Using the Conan client in the command line:**
```sh
- CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan remove Hello/0.2@user/channel -r gitlab
+ conan remove Hello/0.2@user/channel --remote=gitlab
```
+
+ You need to explicitly include the remote in this command, otherwise the package will only be removed from your
+ local system cache.
NOTE: **Note:**
This command will remove all recipe and binary package files from the Package Registry.
@@ -119,9 +239,9 @@ The `conan search` command can be run searching by full or partial package name,
To search using a partial name, use the wildcard symbol `*`, which should be placed at the end of your search (e.g., `my-packa*`):
```sh
-CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan search Hello --all --remote=gitlab
-CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan search He* --all --remote=gitlab
-CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan search Hello/1.0.0@my-group+my-project/stable --all --remote=gitlab
+conan search Hello --all --remote=gitlab
+conan search He* --all --remote=gitlab
+conan search Hello/0.1@my-group+my-project/beta --all --remote=gitlab
```
The scope of your search will include all projects you have permission to access, this includes your private projects as well as all public projects.
@@ -131,5 +251,15 @@ The scope of your search will include all projects you have permission to access
The `conan info` command will return info about a given package:
```sh
-CONAN_LOGIN_USERNAME=<gitlab-username> CONAN_PASSWORD=<personal_access_token> conan info Hello/1.0.0@my-group+my-project/stable -r gitlab
+conan info Hello/0.1@my-group+my-project/beta
```
+
+## List of supported CLI commands
+
+The GitLab Conan repository supports the following Conan CLI commands:
+
+- `conan upload`: Upload your recipe and package files to the GitLab Package Registry.
+- `conan install`: Install a conan package from the GitLab Package Registry, this includes using the `conanfile.txt` file.
+- `conan search`: Search the GitLab Package Registry for public packages, and private packages you have permission to view.
+- `conan info`: View the info on a given package from the GitLab Package Registry.
+- `conan remove`: Delete the package from the GitLab Package Registry.
diff --git a/doc/user/packages/index.md b/doc/user/packages/index.md
index ecaad960340..613b4c975f4 100644
--- a/doc/user/packages/index.md
+++ b/doc/user/packages/index.md
@@ -10,7 +10,7 @@ The Packages feature allows GitLab to act as a repository for the following:
| ------------------- | ----------- | --------------------------- |
| [Container Registry](container_registry/index.md) | The GitLab Container Registry enables every project in GitLab to have its own space to store [Docker](https://www.docker.com/) images. | 8.8+ |
| [Dependency Proxy](dependency_proxy/index.md) **(PREMIUM)** | The GitLab Dependency Proxy sets up a local proxy for frequently used upstream images/packages. | 11.11+ |
-| [Conan Repository](conan_repository/index.md) **(PREMIUM)** | The GitLab Conan Repository enables every project in GitLab to have its own space to store [Conan](https://conan.io/) packages. | 12.4+ |
+| [Conan Repository](conan_repository/index.md) **(PREMIUM)** | The GitLab Conan Repository enables every project in GitLab to have its own space to store [Conan](https://conan.io/) packages. | 12.6+ |
| [Maven Repository](maven_repository/index.md) **(PREMIUM)** | The GitLab Maven Repository enables every project in GitLab to have its own space to store [Maven](https://maven.apache.org/) packages. | 11.3+ |
| [NPM Registry](npm_registry/index.md) **(PREMIUM)** | The GitLab NPM Registry enables every project in GitLab to have its own space to store [NPM](https://www.npmjs.com/) packages. | 11.7+ |
| [NuGet Repository](https://gitlab.com/gitlab-org/gitlab/issues/20050) **(PREMIUM)** | *COMING SOON* The GitLab NuGet Repository will enable every project in GitLab to have its own space to store [NuGet](https://www.nuget.org/) packages. | 12.7 (planned) |
diff --git a/doc/user/project/merge_requests/creating_merge_requests.md b/doc/user/project/merge_requests/creating_merge_requests.md
index 1dec58a8bb0..23b5ab9a79c 100644
--- a/doc/user/project/merge_requests/creating_merge_requests.md
+++ b/doc/user/project/merge_requests/creating_merge_requests.md
@@ -1,124 +1,165 @@
---
-type: index, reference
+type: howto
+description: "How to create Merge Requests in GitLab."
+disqus_identifier: 'https://docs.gitlab.com/ee/gitlab-basics/add-merge-request.html'
---
-# Creating merge requests
+# How to create a merge request
-Merge requests are the primary method of making changes to files in a GitLab project.
-Changes are proposed by creating and submitting a merge request, which is then
-[reviewed, and accepted (or rejected)](reviewing_and_managing_merge_requests.md),
-all within GitLab.
+Before creating a merge request, read through an
+[introduction to Merge Requests](getting_started.md)
+to familiarize yourself with the concept, the terminology,
+and to learn what you can do with them.
-## Creating new merge requests
+Every merge request starts by creating a branch. You can either
+do it locally through the command line, via a Git CLI application,
+or through the GitLab UI.
-You can start creating a new merge request by clicking the **New merge request** button
-on the **Merge Requests** page in a project. Then you must choose the source project and
-branch that contain your changes, and the target project and branch where you want to merge
-the changes into. Click on **Compare branches and continue** to go to the next step
-and start filling in the merge request details.
+This document describes the several ways to create a merge request.
-When viewing the commits on a branch other than master in **Repository > Commits**, you
-can click on the **Create merge request** button, and a new merge request will be started
-using the current branch as the source, and `master` in the current project as the target.
+When you start a new merge request, regarless of the method,
+you'll be taken to the [**New Merge Request** page](#new-merge-request-page)
+to fill it with information about the merge request.
-If you have recently pushed changes to GitLab, the **Create merge request** button will
-also appear in the top right of the:
+If you push a new branch to GitLab, also regardless of the method,
+you can click the [**Create Merge Request**](#create-merge-request-button)
+button and start a merge request from there.
+
+## New Merge Request page
+
+On the **New Merge Request** page, start by filling in the title
+and description for the merge request. If there are are already
+commits on the branch, the title will be pre-filled with the first
+line of the first commit message, and the description will be
+pre-filled with any additional lines in the commit message.
+The title is the only field that is mandatory in all cases.
+
+From there, you can fill it with information (title, description,
+assignee(s), milestone, labels, approvers) and click **Create Merge Request**.
+
+From that initial screen, you can also see all the commits,
+pipelines, and file changes pushed to your branch before submitting
+the merge request.
+
+![New Merge Request page](img/new_merge_request_page_v12_6.png)
+
+TIP: **Tip:**
+You can push one or more times to your branch in GitLab before
+creating the merge request.
+
+## Create Merge Request button
+
+Once you have pushed a new branch to GitLab, visit your repository
+in GitLab and to see a call-to-action at the top of your screen
+from which you can click the button **Create Merge Request**.
+
+![Create Merge Request button](img/create_merge_request_button_v12_6.png)
+
+You can also see the **Create merge request** button in the top-right of the:
- **Project** page.
- **Repository > Files** page.
- **Merge Requests** page.
-In this case, the merge request will use the most recent branch you pushed changes
-to as the source branch, and `master` in the current project as the target.
+In this case, GitLab will use the most recent branch you pushed
+changes to as the source branch, and the default branch in the current
+project as the target.
-You can also [create a new merge request directly from an issue](../repository/web_editor.md#create-a-new-branch-from-an-issue).
+## New merge request by adding, editing, and uploading a file
-## Workflow for new merge requests
+When you choose to edit, add, or upload a file through the GitLab UI,
+at the end of the file you'll see the option to add the **Commit message**,
+to select the **Target branch** of that commit, and the checkbox to
+**Start new a merge request with these changes**.
-On the **New Merge Request** page, you can start by filling in the title and description
-for the merge request. If there are are already commits on the branch, the title will
-be pre-filled with the first line of the first commit message, and the description will
-be pre-filled with any additional lines in the commit message. The title is the only
-field that is mandatory in all cases.
+Similarly, if you change files through the Web IDE, when you navigate to **Commit** on the left-hand sidebar, you'll see these same options.
-From here, you can also:
+Once you have added, edited, or uploaded the file:
-- Set the merge request as a [work in progress](work_in_progress_merge_requests.md).
-- Select the [assignee](#assignee), or [assignees](#multiple-assignees-starter). **(STARTER)**
-- Select a [milestone](../milestones/index.md).
-- Select [labels](../labels.md).
-- Add any [merge request dependencies](merge_request_dependencies.md). **(PREMIUM)**
-- Select [approval options](merge_request_approvals.md). **(STARTER)**
-- Verify the source and target branches are correct.
-- Enable the [delete source branch when merge request is accepted](#deleting-the-source-branch) option.
-- Enable the [squash commits when merge request is accepted](squash_and_merge.md) option.
-- If the merge request is from a fork, enable [Allow collaboration on merge requests across forks](allow_collaboration.md).
+1. Describe your changes in the commit message.
+1. Select an existing branch to add your commit into, or, if you'd like to create a new branch, type the new branch name (without spaces, capital letters, or special chars).
+1. Keep the checkbox checked to start a new merge request straightaway, or, uncheck it to add more changes to that branch before starting the merge request.
+1. Click **Commit changes**.
-Many of these can be set when pushing changes from the command line, with
-[Git push options](../push_options.md).
+If you chose to start a merge request, you'll be taken to the
+[**New Merge Request** page](#new-merge-request-page), from
+which you can fill it in with information and submit the merge request.
-### Merge requests to close issues
+The merge request will target the default branch of the repository.
+If you want to change it, you can do it later by editing the merge request.
-If the merge request is being created to resolve an issue, you can add a note in the
-description which will set it to [automatically close the issue](../issues/managing_issues.md#closing-issues-automatically)
-when merged.
+## New merge request from a new branch created through the UI
-If the issue is [confidential](../issues/confidential_issues.md), you may want to
-use a different workflow for [merge requests for confidential issues](../issues/confidential_issues.md#merge-requests-for-confidential-issues),
-to prevent confidential information from being exposed.
+To quickly start working on files through the GitLab UI,
+navigate to your project's **Repository > Branches** and click
+**New branch**. A new branch will be created and you can start
+editing files.
-## Assignee
+Once committed and pushed, you can click on the [**Create Merge Request**](#create-merge-request-button)
+button to open the [**New Merge Request** page](#new-merge-request-page).
+A new merge request will be started using the current branch as the source,
+and the default branch in the current project as the target.
-Choose an assignee to designate someone as the person responsible for the first
-[review of the merge request](reviewing_and_managing_merge_requests.md). Open the
-drop down box to search for the user you wish to assign, and the merge request will be
-added to their [assigned merge request list](../../search/index.md#issues-and-merge-requests).
+## New merge request from you local environment
-### Multiple assignees **(STARTER)**
+Assuming you have your repository cloned into your computer and you'd
+like to start working on changes to files, start by creating and
+checking out a new branch:
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2004) in [GitLab Starter 11.11](https://about.gitlab.com/pricing/).
+```bash
+git checkout -b my-new-branch
+```
-Multiple people often review merge requests at the same time. GitLab allows you to
-have multiple assignees for merge requests to indicate everyone that is reviewing or
-accountable for it.
+Work on your file changes, stage, and commit them:
-![multiple assignees for merge requests sidebar](img/multiple_assignees_for_merge_requests_sidebar.png)
+```bash
+git add .
+git commit -m "My commit message"
+```
-To assign multiple assignees to a merge request:
+Once you're done, [push your branch to GitLab](../../../gitlab-basics/start-using-git.md#send-changes-to-gitlabcom):
-1. From a merge request, expand the right sidebar and locate the **Assignees** section.
-1. Click on **Edit** and from the dropdown menu, select as many users as you want
- to assign the merge request to.
+```bash
+git push origin my-new-branch
+```
-Similarly, assignees are removed by deselecting them from the same dropdown menu.
+In the output, GitLab will prompt you with a direct link for creating
+a merge request:
-It's also possible to manage multiple assignees:
+```bash
+...
+remote: To create a merge request for docs-new-merge-request, visit:
+remote: https://gitlab-instance.com/my-group/my-project/merge_requests/new?merge_request%5Bsource_branch%5D=my-new-branch
+```
-- When creating a merge request.
-- Using [quick actions](../quick_actions.md#quick-actions-for-issues-merge-requests-and-epics).
+Copy that link and paste it in your browser, and the [**New Merge Request page**](#new-merge-request-page)
+will be displayed.
-## Deleting the source branch
+There is also a number of [flags you can add to commands when pushing through the command line](../push_options.md) to reduce the need for editing merge requests manually through the UI.
-When creating a merge request, select the "Delete source branch when merge
-request accepted" option and the source branch will be deleted when the merge
-request is merged. To make this option enabled by default for all new merge
-requests, enable it in the [project's settings](../settings/index.md#merge-request-settings).
+If you didn't push your branch to GitLab through the command line
+(for example, you used a Git CLI application to push your changes),
+you can create a merge request through the GitLab UI by clicking
+the [**Create Merge Request**](#create-merge-request-button) button.
-This option is also visible in an existing merge request next to the merge
-request button and can be selected/deselected before merging. It's only visible
-to users with [Maintainer permissions](../../permissions.md) in the source project.
+## New merge request from an issue
-If the user viewing the merge request does not have the correct permissions to
-delete the source branch and the source branch is set for deletion, the merge
-request widget will show the "Deletes source branch" text.
+You can also [create a new merge request directly from an issue](../repository/web_editor.md#create-a-new-branch-from-an-issue).
-![Delete source branch status](img/remove_source_branch_status.png)
+## New merge request from the Merge Requests page
-## Create new merge requests by email
+You can start creating a new merge request by clicking the
+**New merge request** button on the **Merge Requests** page in a project.
+Then choose the source project and branch that contain your changes,
+and the target project and branch where you want to merge the changes into.
+Click on **Compare branches and continue** to go to the
+[**New Merge Request** page](#new-merge-request-page) and fill in the details.
+
+## New merge request by email **(CORE ONLY)**
_This feature needs [incoming email](../../../administration/incoming_email.md)
-to be configured by a GitLab administrator to be available for CE/EE users, and
-it's available on GitLab.com._
+to be configured by a GitLab administrator to be available._ It isn't
+available in GitLab.com.
You can create a new merge request by sending an email to a user-specific email
address. The address can be obtained on the merge requests page by clicking on
@@ -156,3 +197,7 @@ created from the repository's HEAD or the specified target branch to
apply the patches. The target branch can be specified using the
[`/target_branch` quick action](../quick_actions.md). If the source
branch already exists, the patches will be applied on top of it.
+
+## Reviewing and managing Merge Requests
+
+Once you have submitted a merge request, it can be [reviewed and managed](reviewing_and_managing_merge_requests.md) through GitLab.
diff --git a/doc/user/project/merge_requests/getting_started.md b/doc/user/project/merge_requests/getting_started.md
new file mode 100644
index 00000000000..8992ea300dc
--- /dev/null
+++ b/doc/user/project/merge_requests/getting_started.md
@@ -0,0 +1,148 @@
+---
+type: index, reference
+description: "Getting started with Merge Requests."
+---
+
+# Getting started with Merge Requests
+
+A Merge Request (**MR**) is the basis of GitLab as a code
+collaboration and version control.
+
+When working in a Git-based platform, you can use branching
+strategies to collaborate on code.
+
+A repository is composed by its _default branch_, which contains
+the major version of the codebase, from which you create minor
+branches, also called _feature branches_, to propose changes to
+the codebase without introducing them directly into the major
+version of the codebase.
+
+Branching is specially important when collaborating with others,
+avoiding changes to be pushed directly to the default branch
+without prior reviews, tests, and approvals.
+
+When you create a new feature branch, change the files, and push
+it to GitLab, you have the option to create a **Merge Request**,
+which is essentially a _request_ to merge one branch into another.
+
+The branch you added your changes into is called _source branch_
+while the branch you'll request to merge your changes into is
+called _target branch_.
+
+The target branch can be the default or any other branch, depending
+on the branching strategies you choose.
+
+In a merge request, beyond visualizing the differences between the
+original content and your proposed changes, you can execute a
+[significant number of tasks](#what-you-can-do-with-merge-requests)
+before concluding your work and merging the merge request.
+
+You can watch our [GitLab Flow video](https://www.youtube.com/watch?v=InKNIvky2KE) for
+a quick overview of working with merge requests.
+
+## How to create a merge request
+
+Learn the various ways to [create a merge request](creating_merge_requests.md).
+
+## What you can do with merge requests
+
+When you start a new merge request, you'll have the following
+options to include straightaway (you can also add them later by
+clicking the **Edit** button on the merge request's page at the
+top-right side):
+
+- [Assign](#assignee) the merge request to a colleage for review.With GitLab Starter and higher tiers, you can [assign it to more than one person at a time](#multiple-assignees-starter).
+- Set a [milestone](../milestones/index.md) to track time-sensitive changes.
+- Add [labels](../labels.md) to help contextualize and filter your merge requests over time.
+- Require [approval](merge_request_approvals.md) from your team. **(STARTER)**
+- [Close issues automatically](#merge-requests-to-close-issues) when it's merged.
+- Enable the [delete source branch when merge request is accepted](#deleting-the-source-branch) option to keep your repository clean.
+- Enable the [squash commits when merge request is accepted](squash_and_merge.md) option to combine all the commits into one before merging, thus keep a clean commit history in your repository.
+- Set the merge request as a [Work In Progress (WIP)](work_in_progress_merge_requests.md) to avoid accidental merges before it's ready.
+
+Once you have created the merge request, you can also:
+
+- [Discuss](../../discussions/index.md) your implementation with your team in the merge request thread.
+- [Perform inline code reviews](reviewing_and_managing_merge_requests.md#perform-inline-code-reviews).
+- Add [merge request dependencies](merge_request_dependencies.md) to restrict it to be merged only when other merge requests have been merged. **(PREMIUM)**
+- Preview continuous integration [pipelines on the merge request widget](reviewing_and_managing_merge_requests.md#pipeline-status-in-merge-requests-widgets).
+- Preview how your changes look directly on your deployed application with [Review Apps](reviewing_and_managing_merge_requests.md#live-preview-with-review-apps).
+- [Allow collaboration on merge requests across forks](allow_collaboration.md).
+- Perform a [Review](../../discussions/index.md#merge-request-reviews-premium) in order to create multiple comments on a diff and publish them once you're ready. **(PREMIUM)**
+- Add [code suggestions](../../discussions/index.md#suggest-changes) to change the content of merge requests directly into merge request threads, and easily apply them to the codebase directly from the UI.
+- Add a time estimation and the time spent with that merge request with [Time Tracking](../time_tracking.md#time-tracking).
+
+Many of these can be set when pushing changes from the command line,
+with [Git push options](../push_options.md).
+
+See also other [features associated to merge requests](reviewing_and_managing_merge_requests.md#associated-features).
+
+### Assignee
+
+Choose an assignee to designate someone as the person responsible
+for the first [review of the merge request](reviewing_and_managing_merge_requests.md).
+Open the drop down box to search for the user you wish to assign,
+and the merge request will be added to their
+[assigned merge request list](../../search/index.md#issues-and-merge-requests).
+
+#### Multiple assignees **(STARTER)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/2004) in [GitLab Starter 11.11](https://about.gitlab.com/pricing/).
+
+Multiple people often review merge requests at the same time.
+GitLab allows you to have multiple assignees for merge requests
+to indicate everyone that is reviewing or accountable for it.
+
+![multiple assignees for merge requests sidebar](img/multiple_assignees_for_merge_requests_sidebar.png)
+
+To assign multiple assignees to a merge request:
+
+1. From a merge request, expand the right sidebar and locate the **Assignees** section.
+1. Click on **Edit** and from the dropdown menu, select as many users as you want to assign the merge request to.
+
+Similarly, assignees are removed by deselecting them from the same
+dropdown menu.
+
+It's also possible to manage multiple assignees:
+
+- When creating a merge request.
+- Using [quick actions](../quick_actions.md#quick-actions-for-issues-merge-requests-and-epics).
+
+### Merge requests to close issues
+
+If the merge request is being created to resolve an issue, you can
+add a note in the description which will set it to
+[automatically close the issue](../issues/managing_issues.md#closing-issues-automatically)
+when merged.
+
+If the issue is [confidential](../issues/confidential_issues.md),
+you may want to use a different workflow for
+[merge requests for confidential issues](../issues/confidential_issues.md#merge-requests-for-confidential-issues)
+to prevent confidential information from being exposed.
+
+### Deleting the source branch
+
+When creating a merge request, select the "Delete source branch
+when merge request accepted" option and the source branch will be
+deleted when the merge request is merged. To make this option
+enabled by default for all new merge requests, enable it in the
+[project's settings](../settings/index.md#merge-request-settings).
+
+This option is also visible in an existing merge request next to
+the merge request button and can be selected/deselected before merging.
+It's only visible to users with [Maintainer permissions](../../permissions.md)
+in the source project.
+
+If the user viewing the merge request does not have the correct
+permissions to delete the source branch and the source branch
+is set for deletion, the merge request widget will show the
+**Deletes source branch** text.
+
+![Delete source branch status](img/remove_source_branch_status.png)
+
+## Recommendations and best practices for Merge Requests
+
+- When working locally in your branch, add multiple commits and only push when you're done, so GitLab will run only one pipeline for all the commits pushed at once. By doing so, you save pipeline minutes.
+- Delete feature branches on merge or after merging them to keep your repository clean.
+- Take one thing at a time and ship the smallest changes possible. By doing so, you'll have faster reviews and your changes will be less prone to errors.
+- Don't use capital letters nor special chars in branch names.
diff --git a/doc/user/project/merge_requests/img/create_merge_request_button_v12_6.png b/doc/user/project/merge_requests/img/create_merge_request_button_v12_6.png
new file mode 100644
index 00000000000..e0a8af76be9
--- /dev/null
+++ b/doc/user/project/merge_requests/img/create_merge_request_button_v12_6.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/new_merge_request_page_v12_6.png b/doc/user/project/merge_requests/img/new_merge_request_page_v12_6.png
new file mode 100644
index 00000000000..9653d33cbff
--- /dev/null
+++ b/doc/user/project/merge_requests/img/new_merge_request_page_v12_6.png
Binary files differ
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index 203a2949243..60a868cc389 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -50,6 +50,8 @@ collaborating with that MR.
MRs also contain navigation tabs from which you can see the discussion happening on the thread,
the list of commits, the list of pipelines and jobs, the code changes and inline code reviews.
+To get started, read the [introduction to merge requests](getting_started.md).
+
## Merge request navigation tabs at the top
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33813) in GitLab 12.6. This positioning is experimental.
@@ -76,72 +78,11 @@ Feature.disable(:mr_tabs_position)
## Creating merge requests
-While making changes to files in the `master` branch of a repository is possible, it is not
-the common workflow. In most cases, a user will make changes in a [branch](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell#_git_branching),
-then [create a merge request](creating_merge_requests.md) to request that the changes
-be merged into another branch (often the `master` branch).
-
-It is then [reviewed](#reviewing-and-managing-merge-requests), possibly updated after
-discussions and suggestions, and finally approved and merged into the target branch.
-Creating and reviewing merge requests is one of the most fundamental parts of working
-with GitLab.
-
-When [creating merge requests](creating_merge_requests.md), there are a number of features
-to be aware of:
-
-| Feature | Description |
-|-----------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| [Adding patches when creating a merge request via e-mail](creating_merge_requests.md#adding-patches-when-creating-a-merge-request-via-e-mail) | Add commits to a merge request created by e-mail, by adding patches as e-mail attachments. |
-| [Allow collaboration on merge requests across forks](allow_collaboration.md) | Allows the maintainers of an upstream project to collaborate on a fork, to make fixes or rebase branches before merging, reducing the back and forth of accepting community contributions. |
-| [Assignee](creating_merge_requests.md#assignee) | Add an assignee to indicate who is reviewing or accountable for it. |
-| [Automatic issue closing](../../project/issues/managing_issues.md#closing-issues-automatically) | Set a merge request to close defined issues automatically as soon as it is merged. |
-| [Create new merge requests by email](creating_merge_requests.md#create-new-merge-requests-by-email) | Create new merge requests by sending an email to a user-specific email address. |
-| [Deleting the source branch](creating_merge_requests.md#deleting-the-source-branch) | Select the "Delete source branch when merge request accepted" option and the source branch will be deleted when the merge request is merged. |
-| [Git push options](../push_options.md) | Use Git push options to create or update merge requests when pushing changes to GitLab with Git, without needing to use the GitLab interface. |
-| [Labels](../../project/labels.md) | Organize your issues and merge requests consistently throughout the project. |
-| [Merge request approvals](merge_request_approvals.md) **(STARTER)** | Set the number of necessary approvals and predefine a list of approvers that will need to approve every merge request in a project. |
-| [Merge Request dependencies](merge_request_dependencies.md) **(PREMIUM)** | Specify that a merge request depends on other merge requests, enforcing a desired order of merging. |
-| [Merge Requests for Confidential Issues](../issues/confidential_issues.md#merge-requests-for-confidential-issues) | Create merge requests to resolve confidential issues for preventing leakage or early release of sensitive data through regular merge requests. |
-| [Milestones](../../project/milestones/index.md) | Track merge requests to achieve a broader goal in a certain period of time. |
-| [Multiple assignees](creating_merge_requests.md#multiple-assignees-starter) **(STARTER)** | Have multiple assignees for merge requests to indicate everyone that is reviewing or accountable for it. |
-| [Squash and merge](squash_and_merge.md) | Squash all changes present in a merge request into a single commit when merging, to allow for a neater commit history. |
-| [Work In Progress merge requests](work_in_progress_merge_requests.md) | Prevent the merge request from being merged before it's ready |
+Learn [how to create a merge request](creating_merge_requests.md).
## Reviewing and managing merge requests
-Once a merge request has been [created](#creating-merge-requests) and submitted, there
-are many powerful features that you can use during the review process to make sure only
-the changes you want are merged into the repository.
-
-For managers and administrators, it is also important to be able to view and manage
-all the merge requests in a group or project. When [reviewing or managing merge requests](reviewing_and_managing_merge_requests.md),
-there are a number of features to be aware of:
-
-| Feature | Description |
-|-------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
-| [Bulk editing merge requests](../../project/bulk_editing.md) | Update the attributes of multiple merge requests simultaneously. |
-| [Cherry-pick changes](cherry_pick_changes.md) | Cherry-pick any commit in the UI by simply clicking the **Cherry-pick** button in a merged merge requests or a commit. |
-| [Commenting on any file line in merge requests](reviewing_and_managing_merge_requests.md#commenting-on-any-file-line-in-merge-requests) | Make comments directly on the exact line of a file you want to talk about. |
-| [Discuss changes in threads in merge requests reviews](../../discussions/index.md) | Keep track of the progress during a code review by making and resolving comments. |
-| [Fast-forward merge requests](fast_forward_merge.md) | For a linear Git history and a way to accept merge requests without creating merge commits |
-| [Find the merge request that introduced a change](versions.md) | When viewing the commit details page, GitLab will link to the merge request(s) containing that commit. |
-| [Ignore whitespace changes in Merge Request diff view](reviewing_and_managing_merge_requests.md#ignore-whitespace-changes-in-Merge-Request-diff-view) | Hide whitespace changes from the diff view for a to focus on more important changes. |
-| [Incrementally expand merge request diffs](reviewing_and_managing_merge_requests.md#incrementally-expand-merge-request-diffs) | View the content directly above or below a change, to better understand the context of that change. |
-| [Live preview with Review Apps](reviewing_and_managing_merge_requests.md#live-preview-with-review-apps) | Live preview the changes when Review Apps are configured for your project |
-| [Merge request diff file navigation](reviewing_and_managing_merge_requests.md#merge-request-diff-file-navigation) | Quickly jump to any changed file within the diff view. |
-| [Merge requests versions](versions.md) | Select and compare the different versions of merge request diffs |
-| [Merge when pipeline succeeds](merge_when_pipeline_succeeds.md) | Set a merge request that looks ready to merge to merge automatically when CI pipeline succeeds. |
-| [Perform a Review](../../discussions/index.md#merge-request-reviews-premium) **(PREMIUM)** | Start a review in order to create multiple comments on a diff and publish them once you're ready. |
-| [Pipeline status in merge requests](reviewing_and_managing_merge_requests.md#pipeline-status-in-merge-requests) | If using [GitLab CI/CD](../../../ci/README.md), see pre and post-merge pipelines information, and which deployments are in progress. |
-| [Post-merge pipeline status](reviewing_and_managing_merge_requests.md#post-merge-pipeline-status) | When a merge request is merged, see the post-merge pipeline status of the branch the merge request was merged into. |
-| [Resolve conflicts](resolve_conflicts.md) | GitLab can provide the option to resolve certain merge request conflicts in the GitLab UI. |
-| [Revert changes](revert_changes.md) | Revert changes from any commit from within a merge request. |
-| [Semi-linear history merge requests](reviewing_and_managing_merge_requests.md#semi-linear-history-merge-requests) | Enable semi-linear history merge requests as another security layer to guarantee the pipeline is passing in the target branch |
-| [Suggest changes](../../discussions/index.md#suggest-changes) | Add suggestions to change the content of merge requests directly into merge request threads, and easily apply them to the codebase directly from the UI. |
-| [Time Tracking](../time_tracking.md#time-tracking) | Add a time estimation and the time spent with that merge request. |
-| [View changes between file versions](reviewing_and_managing_merge_requests.md#view-changes-between-file-versions) | View what will be changed when a merge request is merged. |
-| [View group merge requests](reviewing_and_managing_merge_requests.md#view-merge-requests-for-all-projects-in-a-group) | List and view the merge requests within a group. |
-| [View project merge requests](reviewing_and_managing_merge_requests.md#view-project-merge-requests) | List and view the merge requests within a project. |
+See the features at your displosal to [review and manage merge requests](reviewing_and_managing_merge_requests.md).
## Testing and reports in merge requests
diff --git a/doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md b/doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md
index 97c16a9794d..edc7b317c94 100644
--- a/doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md
+++ b/doc/user/project/merge_requests/reviewing_and_managing_merge_requests.md
@@ -85,7 +85,7 @@ specific commit page.
You can append `?w=1` while on the diffs page of a merge request to ignore any
whitespace changes.
-## Commenting on any file line in merge requests
+## Perform inline code reviews
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/13950) in GitLab 11.5.
@@ -94,20 +94,7 @@ in a Merge Request. To do so, click the **...** button in the gutter of the Merg
![Comment on any diff file line](img/comment-on-any-diff-line.png)
-## Live preview with Review Apps
-
-If you configured [Review Apps](https://about.gitlab.com/product/review-apps/) for your project,
-you can preview the changes submitted to a feature-branch through a merge request
-in a per-branch basis. No need to checkout the branch, install and preview locally;
-all your changes will be available to preview by anyone with the Review Apps link.
-
-With GitLab's [Route Maps](../../../ci/review_apps/index.md#route-maps) set, the
-merge request widget takes you directly to the pages changed, making it easier and
-faster to preview proposed modifications.
-
-[Read more about Review Apps](../../../ci/review_apps/index.md).
-
-## Pipeline status in merge requests
+## Pipeline status in merge requests widgets
If you've set up [GitLab CI/CD](../../../ci/README.md) in your project,
you will be able to see:
@@ -135,6 +122,37 @@ be disabled. If the pipeline fails to deploy, the deployment info will be hidden
For more information, [read about pipelines](../../../ci/pipelines.md).
+### Merge when pipeline succeeds (MWPS)
+
+Set a merge request that looks ready to merge to [merge automatically when CI pipeline succeeds](merge_when_pipeline_succeeds.md).
+
+### Live preview with Review Apps
+
+If you configured [Review Apps](https://about.gitlab.com/product/review-apps/) for your project,
+you can preview the changes submitted to a feature-branch through a merge request
+in a per-branch basis. No need to checkout the branch, install and preview locally;
+all your changes will be available to preview by anyone with the Review Apps link.
+
+With GitLab's [Route Maps](../../../ci/review_apps/index.md#route-maps) set, the
+merge request widget takes you directly to the pages changed, making it easier and
+faster to preview proposed modifications.
+
+[Read more about Review Apps](../../../ci/review_apps/index.md).
+
+## Associated features
+
+There is also a large number of features to associated to merge requests:
+
+| Feature | Description |
+|-------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
+| [Bulk editing merge requests](../../project/bulk_editing.md) | Update the attributes of multiple merge requests simultaneously. |
+| [Cherry-pick changes](cherry_pick_changes.md) | Cherry-pick any commit in the UI by simply clicking the **Cherry-pick** button in a merged merge requests or a commit. |
+| [Fast-forward merge requests](fast_forward_merge.md) | For a linear Git history and a way to accept merge requests without creating merge commits |
+| [Find the merge request that introduced a change](versions.md) | When viewing the commit details page, GitLab will link to the merge request(s) containing that commit. |
+| [Merge requests versions](versions.md) | Select and compare the different versions of merge request diffs |
+| [Resolve conflicts](resolve_conflicts.md) | GitLab can provide the option to resolve certain merge request conflicts in the GitLab UI. |
+| [Revert changes](revert_changes.md) | Revert changes from any commit from within a merge request. |
+
## Troubleshooting
Sometimes things don't go as expected in a merge request, here are some
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 2c7a24da8f9..1c0328ddcbb 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -57,7 +57,7 @@ Set up your project's merge request settings:
- Enable [merge request approvals](../merge_requests/merge_request_approvals.md). **(STARTER)**
- Enable [merge only if pipeline succeeds](../merge_requests/merge_when_pipeline_succeeds.md).
- Enable [merge only when all threads are resolved](../../discussions/index.md#only-allow-merge-requests-to-be-merged-if-all-threads-are-resolved).
-- Enable [`delete source branch after merge` option by default](../merge_requests/creating_merge_requests.md#deleting-the-source-branch)
+- Enable [`delete source branch after merge` option by default](../merge_requests/getting_started.md#deleting-the-source-branch)
![project's merge request settings](img/merge_requests_settings.png)
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index 6a55b8cda57..40918a6c85b 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -16,7 +16,8 @@ module Gitlab
ALLOWED_KEYS = %i[tags script only except rules type image services
allow_failure type stage when start_in artifacts cache
dependencies before_script needs after_script variables
- environment coverage retry parallel extends interruptible timeout].freeze
+ environment coverage retry parallel extends interruptible timeout
+ resource_group].freeze
REQUIRED_BY_NEEDS = %i[stage].freeze
@@ -48,6 +49,7 @@ module Gitlab
validates :dependencies, array_of_strings: true
validates :extends, array_of_strings_or_string: true
validates :rules, array_of_hashes: true
+ validates :resource_group, type: String
end
validates :start_in, duration: { limit: '1 week' }, if: :delayed?
@@ -156,7 +158,7 @@ module Gitlab
attributes :script, :tags, :allow_failure, :when, :dependencies,
:needs, :retry, :parallel, :extends, :start_in, :rules,
- :interruptible, :timeout
+ :interruptible, :timeout, :resource_group
def self.matching?(name, config)
!name.to_s.start_with?('.') &&
@@ -243,7 +245,8 @@ module Gitlab
artifacts: artifacts_value,
after_script: after_script_value,
ignore: ignored?,
- needs: needs_defined? ? needs_value : nil }
+ needs: needs_defined? ? needs_value : nil,
+ resource_group: resource_group }
end
end
end
diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb
index 590c7f4d1dd..98b4b4593e0 100644
--- a/lib/gitlab/ci/pipeline/seed/build.rb
+++ b/lib/gitlab/ci/pipeline/seed/build.rb
@@ -18,6 +18,7 @@ module Gitlab
@seed_attributes = attributes
@previous_stages = previous_stages
@needs_attributes = dig(:needs_attributes)
+ @resource_group_key = attributes.delete(:resource_group_key)
@using_rules = attributes.key?(:rules)
@using_only = attributes.key?(:only)
@@ -78,6 +79,7 @@ module Gitlab
else
::Ci::Build.new(attributes).tap do |job|
job.deployment = Seed::Deployment.new(job).to_resource
+ job.resource_group = Seed::Build::ResourceGroup.new(job, @resource_group_key).to_resource
end
end
end
diff --git a/lib/gitlab/ci/pipeline/seed/build/resource_group.rb b/lib/gitlab/ci/pipeline/seed/build/resource_group.rb
new file mode 100644
index 00000000000..100eb1d4084
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/seed/build/resource_group.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Pipeline
+ module Seed
+ class Build
+ class ResourceGroup < Seed::Base
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :build, :resource_group_key
+
+ def initialize(build, resource_group_key)
+ @build = build
+ @resource_group_key = resource_group_key
+ end
+
+ def to_resource
+ return unless Feature.enabled?(:ci_resource_group, build.project)
+ return unless resource_group_key.present?
+
+ resource_group = build.project.resource_groups
+ .safe_find_or_create_by(key: expanded_resource_group_key)
+
+ resource_group if resource_group.persisted?
+ end
+
+ private
+
+ def expanded_resource_group_key
+ strong_memoize(:expanded_resource_group_key) do
+ ExpandVariables.expand(resource_group_key, -> { build.simple_variables })
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index 27cd4f5fd6b..24e5f5fa9ab 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -64,6 +64,7 @@ module Gitlab
except: job[:except],
rules: job[:rules],
cache: job[:cache],
+ resource_group_key: job[:resource_group],
options: {
image: job[:image],
services: job[:services],
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index ecb1f1996d9..a38935c89ba 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -207,6 +207,14 @@ FactoryBot.define do
trigger_request factory: :ci_trigger_request
end
+ trait :resource_group do
+ waiting_for_resource_at { 5.minutes.ago }
+
+ after(:build) do |build, evaluator|
+ build.resource_group = create(:ci_resource_group, project: build.project)
+ end
+ end
+
after(:build) do |build, evaluator|
build.project ||= build.pipeline.project
end
diff --git a/spec/factories/ci/resource.rb b/spec/factories/ci/resource.rb
new file mode 100644
index 00000000000..d47b3ba4635
--- /dev/null
+++ b/spec/factories/ci/resource.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_resource, class: Ci::Resource do
+ resource_group factory: :ci_resource_group
+
+ trait(:retained) do
+ build factory: :ci_build
+ end
+ end
+end
diff --git a/spec/factories/ci/resource_group.rb b/spec/factories/ci/resource_group.rb
new file mode 100644
index 00000000000..bdfc0740a45
--- /dev/null
+++ b/spec/factories/ci/resource_group.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_resource_group, class: Ci::ResourceGroup do
+ project
+ sequence(:key) { |n| "IOS_#{n}" }
+ end
+end
diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
index 859638f1a52..085fe38b47a 100644
--- a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
+++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
@@ -97,7 +97,8 @@ describe 'User comments on a diff', :js do
end
context 'multiple suggestions in expanded lines' do
- it 'suggestions are appliable' do
+ # https://gitlab.com/gitlab-org/gitlab/issues/38277
+ it 'suggestions are appliable', :quarantine do
diff_file = merge_request.diffs(paths: ['files/ruby/popen.rb']).diff_files.first
hash = Digest::SHA1.hexdigest(diff_file.file_path)
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build/resource_group_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build/resource_group_spec.rb
new file mode 100644
index 00000000000..bf6985156d3
--- /dev/null
+++ b/spec/lib/gitlab/ci/pipeline/seed/build/resource_group_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Ci::Pipeline::Seed::Build::ResourceGroup do
+ let_it_be(:project) { create(:project) }
+ let(:job) { build(:ci_build, project: project) }
+ let(:seed) { described_class.new(job, resource_group_key) }
+
+ describe '#to_resource' do
+ subject { seed.to_resource }
+
+ context 'when resource group key is specified' do
+ let(:resource_group_key) { 'iOS' }
+
+ it 'returns a resource group object' do
+ is_expected.to be_a(Ci::ResourceGroup)
+ expect(subject.key).to eq('iOS')
+ end
+
+ context 'when environment has an invalid URL' do
+ let(:resource_group_key) { ':::' }
+
+ it 'returns nothing' do
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when there is a resource group already' do
+ let!(:resource_group) { create(:ci_resource_group, project: project, key: 'iOS') }
+
+ it 'does not create a new resource group' do
+ expect { subject }.not_to change { Ci::ResourceGroup.count }
+ end
+ end
+ end
+
+ context 'when resource group key is nil' do
+ let(:resource_group_key) { nil }
+
+ it 'returns nothing' do
+ is_expected.to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
index 2ae513aea1b..5526ec9e16f 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
@@ -231,6 +231,15 @@ describe Gitlab::Ci::Pipeline::Seed::Build do
end
end
end
+
+ context 'when job belongs to a resource group' do
+ let(:attributes) { { name: 'rspec', ref: 'master', resource_group_key: 'iOS' } }
+
+ it 'returns a job with resource group' do
+ expect(subject.resource_group).not_to be_nil
+ expect(subject.resource_group.key).to eq('iOS')
+ end
+ end
end
context 'when job is a bridge' do
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 8f9c5c74260..f61b28b06c8 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -241,6 +241,21 @@ module Gitlab
end
end
end
+
+ describe 'resource group' do
+ context 'when resource group is defined' do
+ let(:config) do
+ YAML.dump(rspec: {
+ script: 'test',
+ resource_group: 'iOS'
+ })
+ end
+
+ it 'has the attributes' do
+ expect(subject[:resource_group_key]).to eq 'iOS'
+ end
+ end
+ end
end
describe '#stages_attributes' do
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 2ea563c50b6..8f0f09bc0be 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -444,6 +444,7 @@ project:
- service_desk_setting
- import_failures
- container_expiration_policy
+- resource_groups
award_emoji:
- awardable
- user
diff --git a/spec/models/ci/resource_group_spec.rb b/spec/models/ci/resource_group_spec.rb
new file mode 100644
index 00000000000..ce8b03282bc
--- /dev/null
+++ b/spec/models/ci/resource_group_spec.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::ResourceGroup do
+ describe 'validation' do
+ it 'valids when key includes allowed character' do
+ resource_group = build(:ci_resource_group, key: 'test')
+
+ expect(resource_group).to be_valid
+ end
+
+ it 'invalids when key includes invalid character' do
+ resource_group = build(:ci_resource_group, key: ':::')
+
+ expect(resource_group).not_to be_valid
+ end
+ end
+
+ describe '#ensure_resource' do
+ it 'creates one resource when resource group is created' do
+ resource_group = create(:ci_resource_group)
+
+ expect(resource_group.resources.count).to eq(1)
+ expect(resource_group.resources.all?(&:persisted?)).to eq(true)
+ end
+ end
+
+ describe '#assign_resource_to' do
+ subject { resource_group.assign_resource_to(build) }
+
+ let(:build) { create(:ci_build) }
+ let(:resource_group) { create(:ci_resource_group) }
+
+ it 'retains resource for the build' do
+ expect(resource_group.resources.first.build).to be_nil
+
+ is_expected.to eq(true)
+
+ expect(resource_group.resources.first.build).to eq(build)
+ end
+
+ context 'when there are no free resources' do
+ before do
+ resource_group.assign_resource_to(create(:ci_build))
+ end
+
+ it 'fails to retain resource' do
+ is_expected.to eq(false)
+ end
+ end
+
+ context 'when the build has already retained a resource' do
+ let!(:another_resource) { create(:ci_resource, resource_group: resource_group, build: build) }
+
+ it 'fails to retain resource' do
+ expect { subject }.to raise_error(ActiveRecord::RecordNotUnique)
+ end
+ end
+ end
+
+ describe '#release_resource_from' do
+ subject { resource_group.release_resource_from(build) }
+
+ let(:build) { create(:ci_build) }
+ let(:resource_group) { create(:ci_resource_group) }
+
+ context 'when the build has already retained a resource' do
+ before do
+ resource_group.assign_resource_to(build)
+ end
+
+ it 'releases resource from the build' do
+ expect(resource_group.resources.first.build).to eq(build)
+
+ is_expected.to eq(true)
+
+ expect(resource_group.resources.first.build).to be_nil
+ end
+ end
+
+ context 'when the build has already released a resource' do
+ it 'fails to release resource' do
+ is_expected.to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/models/ci/resource_spec.rb b/spec/models/ci/resource_spec.rb
new file mode 100644
index 00000000000..27e512e2c45
--- /dev/null
+++ b/spec/models/ci/resource_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::Resource do
+ describe '.free' do
+ subject { described_class.free }
+
+ let(:resource_group) { create(:ci_resource_group) }
+ let!(:free_resource) { resource_group.resources.take }
+ let!(:retained_resource) { create(:ci_resource, :retained, resource_group: resource_group) }
+
+ it 'returns free resources' do
+ is_expected.to eq([free_resource])
+ end
+ end
+
+ describe '.retained_by' do
+ subject { described_class.retained_by(build) }
+
+ let(:build) { create(:ci_build) }
+ let!(:resource) { create(:ci_resource, build: build) }
+
+ it 'returns retained resources' do
+ is_expected.to eq([resource])
+ end
+ end
+end
diff --git a/spec/models/concerns/safe_url_spec.rb b/spec/models/concerns/safe_url_spec.rb
index 3244410181e..0ad26660a60 100644
--- a/spec/models/concerns/safe_url_spec.rb
+++ b/spec/models/concerns/safe_url_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe SafeUrl do
describe '#safe_url' do
- class TestClass
+ class SafeUrlTestClass
include SafeUrl
attr_reader :url
@@ -14,7 +14,7 @@ describe SafeUrl do
end
end
- let(:test_class) { TestClass.new(url) }
+ let(:test_class) { SafeUrlTestClass.new(url) }
let(:url) { 'http://example.com' }
subject { test_class.safe_url }
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb
index 5f760844046..a4432cbcf5b 100644
--- a/spec/services/ci/create_pipeline_service_spec.rb
+++ b/spec/services/ci/create_pipeline_service_spec.rb
@@ -915,6 +915,44 @@ describe Ci::CreatePipelineService do
end
end
+ context 'with resource group' do
+ context 'when resource group is defined' do
+ before do
+ config = YAML.dump(
+ test: { stage: 'test', script: 'ls', resource_group: resource_group_key }
+ )
+
+ stub_ci_pipeline_yaml_file(config)
+ end
+
+ let(:resource_group_key) { 'iOS' }
+
+ it 'persists the association correctly' do
+ result = execute_service
+ deploy_job = result.builds.find_by_name!(:test)
+ resource_group = project.resource_groups.find_by_key!(resource_group_key)
+
+ expect(result).to be_persisted
+ expect(deploy_job.resource_group.key).to eq(resource_group_key)
+ expect(project.resource_groups.count).to eq(1)
+ expect(resource_group.builds.count).to eq(1)
+ expect(resource_group.resources.count).to eq(1)
+ expect(resource_group.resources.first.build).to eq(nil)
+ end
+
+ context 'when resourc group key includes predefined variables' do
+ let(:resource_group_key) { '$CI_COMMIT_REF_NAME-$CI_JOB_NAME' }
+
+ it 'interpolates the variables into the key correctly' do
+ result = execute_service
+
+ expect(result).to be_persisted
+ expect(project.resource_groups.exists?(key: 'master-test')).to eq(true)
+ end
+ end
+ end
+ end
+
context 'with timeout' do
context 'when builds with custom timeouts are configured' do
before do
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index b1368f7776b..76fe6f53a11 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -31,7 +31,7 @@ describe Ci::RetryBuildService do
job_artifacts_container_scanning job_artifacts_dast
job_artifacts_license_management job_artifacts_performance
job_artifacts_codequality job_artifacts_metrics scheduled_at
- job_variables].freeze
+ job_variables waiting_for_resource_at].freeze
IGNORE_ACCESSORS =
%i[type lock_version target_url base_tags trace_sections
@@ -40,14 +40,14 @@ describe Ci::RetryBuildService do
user_id auto_canceled_by_id retried failure_reason
sourced_pipelines artifacts_file_store artifacts_metadata_store
metadata runner_session trace_chunks upstream_pipeline_id
- artifacts_file artifacts_metadata artifacts_size commands].freeze
+ artifacts_file artifacts_metadata artifacts_size commands resource resource_group_id].freeze
shared_examples 'build duplication' do
let(:another_pipeline) { create(:ci_empty_pipeline, project: project) }
let(:build) do
create(:ci_build, :failed, :expired, :erased, :queued, :coverage, :tags,
- :allowed_to_fail, :on_tag, :triggered, :teardown_environment,
+ :allowed_to_fail, :on_tag, :triggered, :teardown_environment, :resource_group,
description: 'my-job', stage: 'test', stage_id: stage.id,
pipeline: pipeline, auto_canceled_by: another_pipeline,
scheduled_at: 10.seconds.since)
diff --git a/spec/validators/qualified_domain_array_validator_spec.rb b/spec/validators/qualified_domain_array_validator_spec.rb
index 6beb4c67f6f..ab6cca4b671 100644
--- a/spec/validators/qualified_domain_array_validator_spec.rb
+++ b/spec/validators/qualified_domain_array_validator_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe QualifiedDomainArrayValidator do
- class TestClass
+ class QualifiedDomainArrayValidatorTestClass
include ActiveModel::Validations
attr_accessor :domain_array
@@ -14,7 +14,7 @@ describe QualifiedDomainArrayValidator do
end
let!(:record) do
- TestClass.new(['gitlab.com'])
+ QualifiedDomainArrayValidatorTestClass.new(['gitlab.com'])
end
subject { validator.validate(record) }