summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-04 00:07:52 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-04 00:07:52 +0000
commit4fe93274dec62ff7361a67be88e320131d66b788 (patch)
tree98ae79e3101ffd6569fc48bb4c7ad8808540ceb8
parentbbaf2bb0438b1c71020d9d216feb528add225a7f (diff)
downloadgitlab-ce-4fe93274dec62ff7361a67be88e320131d66b788.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/graphql/types/base_field.rb2
-rw-r--r--app/helpers/system_note_helper.rb2
-rw-r--r--app/models/ci/build.rb19
-rw-r--r--app/models/concerns/ci/metadatable.rb2
-rw-r--r--app/services/ci/retry_build_service.rb2
-rw-r--r--changelogs/unreleased/208798-replace-instances-of-the-issue-duplicate-icon-with-the-duplicate-i.yml5
-rw-r--r--changelogs/unreleased/persist-expanded-environment-name-in-build-metadata.yml5
-rw-r--r--db/migrate/20200102140148_add_expanded_environment_name_to_ci_build_metadata.rb13
-rw-r--r--db/migrate/20200225111018_add_index_for_group_and_iid_search_to_epics.rb22
-rw-r--r--db/schema.rb2
-rw-r--r--doc/administration/geo/replication/datatypes.md7
-rw-r--r--doc/administration/geo/replication/troubleshooting.md8
-rw-r--r--doc/administration/geo/replication/updating_the_geo_nodes.md2
-rw-r--r--doc/administration/geo/replication/version_specific_updates.md14
-rw-r--r--doc/api/epics.md2
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql21
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json30
-rw-r--r--doc/api/graphql/reference/index.md6
-rw-r--r--doc/api/group_clusters.md30
-rw-r--r--doc/api/issues.md20
-rw-r--r--doc/api/issues_statistics.md6
-rw-r--r--doc/api/merge_requests.md8
-rw-r--r--doc/api/project_clusters.md4
-rw-r--r--doc/security/user_email_confirmation.md8
-rw-r--r--doc/user/admin_area/settings/sign_up_restrictions.md7
-rw-r--r--lib/gitlab/ci/pipeline/seed/build.rb33
-rw-r--r--lib/gitlab/ci/pipeline/seed/deployment.rb6
-rw-r--r--lib/gitlab/ci/pipeline/seed/environment.rb14
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/factories/ci/builds.rb3
-rw-r--r--spec/graphql/types/base_field_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/build_spec.rb88
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb11
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/environment_spec.rb59
-rw-r--r--spec/models/ci/build_spec.rb30
-rw-r--r--spec/models/concerns/issuable_spec.rb2
-rw-r--r--spec/services/ci/retry_build_service_spec.rb4
37 files changed, 404 insertions, 98 deletions
diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb
index 8ff2b5ad532..1b296f8d52b 100644
--- a/app/graphql/types/base_field.rb
+++ b/app/graphql/types/base_field.rb
@@ -41,7 +41,7 @@ module Types
attr_reader :feature_flag
def feature_documentation_message(key, description)
- "#{description}. Available only when feature flag #{key} is enabled."
+ "#{description}. Available only when feature flag `#{key}` is enabled."
end
def check_feature_flag(args)
diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb
index c982b48a94e..6702a805cb7 100644
--- a/app/helpers/system_note_helper.rb
+++ b/app/helpers/system_note_helper.rb
@@ -23,7 +23,7 @@ module SystemNoteHelper
'moved' => 'arrow-right',
'outdated' => 'pencil-square',
'pinned_embed' => 'thumbtack',
- 'duplicate' => 'issue-duplicate',
+ 'duplicate' => 'duplicate',
'locked' => 'lock',
'unlocked' => 'lock-open',
'due_date' => 'calendar'
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index f79a5682963..fd099107fe7 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -59,15 +59,11 @@ module Ci
##
# Since Gitlab 11.5, deployments records started being created right after
# `ci_builds` creation. We can look up a relevant `environment` through
- # `deployment` relation today. This is much more efficient than expanding
- # environment name with variables.
+ # `deployment` relation today.
# (See more https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/22380)
#
- # However, we have to still expand environment name if it's a stop action,
- # because `deployment` persists information for start action only.
- #
- # We will follow up this by persisting expanded name in build metadata or
- # persisting stop action in database.
+ # Since Gitlab 12.9, we started persisting the expanded environment name to
+ # avoid repeated variables expansion in `action: stop` builds as well.
def persisted_environment
return unless has_environment?
@@ -465,7 +461,14 @@ module Ci
return unless has_environment?
strong_memoize(:expanded_environment_name) do
- ExpandVariables.expand(environment, -> { simple_variables })
+ # We're using a persisted expanded environment name in order to avoid
+ # variable expansion per request.
+ if Feature.enabled?(:ci_persisted_expanded_environment_name, project, default_enabled: true) &&
+ metadata&.expanded_environment_name.present?
+ metadata.expanded_environment_name
+ else
+ ExpandVariables.expand(environment, -> { simple_variables })
+ end
end
end
diff --git a/app/models/concerns/ci/metadatable.rb b/app/models/concerns/ci/metadatable.rb
index 9bfe76728e4..bd40af28bc9 100644
--- a/app/models/concerns/ci/metadatable.rb
+++ b/app/models/concerns/ci/metadatable.rb
@@ -14,6 +14,8 @@ module Ci
inverse_of: :build,
autosave: true
+ accepts_nested_attributes_for :metadata
+
delegate :timeout, to: :metadata, prefix: true, allow_nil: true
delegate :interruptible, to: :metadata, prefix: false, allow_nil: true
delegate :has_exposed_artifacts?, to: :metadata, prefix: false, allow_nil: true
diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb
index 87f818ad497..a65fe2ecb3a 100644
--- a/app/services/ci/retry_build_service.rb
+++ b/app/services/ci/retry_build_service.rb
@@ -52,7 +52,7 @@ module Ci
def create_build!(attributes)
build = project.builds.new(attributes)
- build.deployment = ::Gitlab::Ci::Pipeline::Seed::Deployment.new(build).to_resource
+ build.assign_attributes(::Gitlab::Ci::Pipeline::Seed::Build.environment_attributes_for(build))
build.retried = false
build.save!
build
diff --git a/changelogs/unreleased/208798-replace-instances-of-the-issue-duplicate-icon-with-the-duplicate-i.yml b/changelogs/unreleased/208798-replace-instances-of-the-issue-duplicate-icon-with-the-duplicate-i.yml
new file mode 100644
index 00000000000..9cbee38da7d
--- /dev/null
+++ b/changelogs/unreleased/208798-replace-instances-of-the-issue-duplicate-icon-with-the-duplicate-i.yml
@@ -0,0 +1,5 @@
+---
+title: Replace issue-duplicate icon with duplicate icon
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/persist-expanded-environment-name-in-build-metadata.yml b/changelogs/unreleased/persist-expanded-environment-name-in-build-metadata.yml
new file mode 100644
index 00000000000..a6de3aa78c5
--- /dev/null
+++ b/changelogs/unreleased/persist-expanded-environment-name-in-build-metadata.yml
@@ -0,0 +1,5 @@
+---
+title: Persist expanded environment name in ci build metadata
+merge_request: 22374
+author:
+type: performance
diff --git a/db/migrate/20200102140148_add_expanded_environment_name_to_ci_build_metadata.rb b/db/migrate/20200102140148_add_expanded_environment_name_to_ci_build_metadata.rb
new file mode 100644
index 00000000000..e76806c5d3f
--- /dev/null
+++ b/db/migrate/20200102140148_add_expanded_environment_name_to_ci_build_metadata.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddExpandedEnvironmentNameToCiBuildMetadata < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def up
+ add_column :ci_builds_metadata, :expanded_environment_name, :string, limit: 255
+ end
+
+ def down
+ remove_column :ci_builds_metadata, :expanded_environment_name
+ end
+end
diff --git a/db/migrate/20200225111018_add_index_for_group_and_iid_search_to_epics.rb b/db/migrate/20200225111018_add_index_for_group_and_iid_search_to_epics.rb
new file mode 100644
index 00000000000..98f35d9f1ae
--- /dev/null
+++ b/db/migrate/20200225111018_add_index_for_group_and_iid_search_to_epics.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddIndexForGroupAndIidSearchToEpics < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_epics_on_group_id_and_iid_varchar_pattern'
+
+ disable_ddl_transaction!
+
+ def up
+ disable_statement_timeout do
+ execute "CREATE INDEX CONCURRENTLY \"#{INDEX_NAME}\" ON epics (group_id, CAST(iid AS VARCHAR) varchar_pattern_ops);"
+ end
+ end
+
+ def down
+ disable_statement_timeout do
+ remove_concurrent_index_by_name :epics, INDEX_NAME
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 355b36e1483..188062b8897 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -722,6 +722,7 @@ ActiveRecord::Schema.define(version: 2020_02_27_165129) do
t.jsonb "config_variables"
t.boolean "has_exposed_artifacts"
t.string "environment_auto_stop_in", limit: 255
+ t.string "expanded_environment_name", limit: 255
t.index ["build_id"], name: "index_ci_builds_metadata_on_build_id", unique: true
t.index ["build_id"], name: "index_ci_builds_metadata_on_build_id_and_has_exposed_artifacts", where: "(has_exposed_artifacts IS TRUE)"
t.index ["build_id"], name: "index_ci_builds_metadata_on_build_id_and_interruptible", where: "(interruptible = true)"
@@ -1581,6 +1582,7 @@ ActiveRecord::Schema.define(version: 2020_02_27_165129) do
t.integer "start_date_sourcing_epic_id"
t.integer "due_date_sourcing_epic_id"
t.integer "health_status", limit: 2
+ t.index "group_id, ((iid)::character varying) varchar_pattern_ops", name: "index_epics_on_group_id_and_iid_varchar_pattern"
t.index ["assignee_id"], name: "index_epics_on_assignee_id"
t.index ["author_id"], name: "index_epics_on_author_id"
t.index ["closed_by_id"], name: "index_epics_on_closed_by_id"
diff --git a/doc/administration/geo/replication/datatypes.md b/doc/administration/geo/replication/datatypes.md
index 9ee215c60c5..feb0c2f2f4d 100644
--- a/doc/administration/geo/replication/datatypes.md
+++ b/doc/administration/geo/replication/datatypes.md
@@ -131,7 +131,7 @@ successfully, you must replicate their data using some other means.
| Project wiki repository | **Yes** | **Yes** | |
| Project designs repository | **Yes** | [No][design-verification] | |
| Uploads | **Yes** | [No][upload-verification] | Verified only on transfer, or manually (*1*)|
-| LFS objects | **Yes** | [No][lfs-verification] | Verified only on transfer, or manually (*1*)|
+| LFS objects | **Yes** | [No][lfs-verification] | Verified only on transfer, or manually (*1*). Unavailable for new LFS objects in 11.11.x and 12.0.x (*2*). |
| CI job artifacts (other than traces) | **Yes** | [No][artifact-verification] | Verified only manually (*1*) |
| Archived traces | **Yes** | [No][artifact-verification] | Verified only on transfer, or manually (*1*)|
| Personal snippets | **Yes** | **Yes** | |
@@ -148,7 +148,10 @@ successfully, you must replicate their data using some other means.
| Content in object storage | **Yes** | No | |
- (*1*): The integrity can be verified manually using
- [Integrity Check Rake Task](../../raketasks/check.md) on both nodes and comparing the output between them.
+ [Integrity Check Rake Task](../../raketasks/check.md) on both nodes and comparing
+ the output between them.
+- (*2*): GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new
+ LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/issues/32696).
[design-replication]: https://gitlab.com/groups/gitlab-org/-/epics/1633
[design-verification]: https://gitlab.com/gitlab-org/gitlab/issues/32467
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index b5be29f7dff..c3e1da3311f 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -377,6 +377,14 @@ sudo gitlab-ctl reconfigure
This will increase the timeout to three hours (10800 seconds). Choose a time
long enough to accommodate a full clone of your largest repositories.
+### New LFS objects are never replicated
+
+If new LFS objects are never replicated to secondary Geo nodes, check the version of
+GitLab you are running. GitLab versions 11.11.x or 12.0.x are affected by
+[a bug that results in new LFS objects not being replicated to Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/issues/32696).
+
+To resolve the issue, upgrade to GitLab 12.1 or newer.
+
### Resetting Geo **secondary** node replication
If you get a **secondary** node in a broken state and want to reset the replication state,
diff --git a/doc/administration/geo/replication/updating_the_geo_nodes.md b/doc/administration/geo/replication/updating_the_geo_nodes.md
index d094ccf3e54..df66b1b36ec 100644
--- a/doc/administration/geo/replication/updating_the_geo_nodes.md
+++ b/doc/administration/geo/replication/updating_the_geo_nodes.md
@@ -14,6 +14,8 @@ different steps.
- [Updating to GitLab 12.7](version_specific_updates.md#updating-to-gitlab-127)
- [Updating to GitLab 12.2](version_specific_updates.md#updating-to-gitlab-122)
- [Updating to GitLab 12.1](version_specific_updates.md#updating-to-gitlab-121)
+- [Updating to GitLab 12.0](version_specific_updates.md#updating-to-gitlab-120)
+- [Updating to GitLab 11.11](version_specific_updates.md#updating-to-gitlab-1111)
- [Updating to GitLab 10.8](version_specific_updates.md#updating-to-gitlab-108)
- [Updating to GitLab 10.6](version_specific_updates.md#updating-to-gitlab-106)
- [Updating to GitLab 10.5](version_specific_updates.md#updating-to-gitlab-105)
diff --git a/doc/administration/geo/replication/version_specific_updates.md b/doc/administration/geo/replication/version_specific_updates.md
index 77fcaaba764..a697d07ded4 100644
--- a/doc/administration/geo/replication/version_specific_updates.md
+++ b/doc/administration/geo/replication/version_specific_updates.md
@@ -45,6 +45,20 @@ This can be temporarily disabled by running the following before updating:
sudo touch /etc/gitlab/disable-postgresql-upgrade
```
+## Updating to GitLab 12.0
+
+WARNING: **Warning:**
+This version is affected by [a bug that results in new LFS objects not being replicated to
+Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/issues/32696). The issue is fixed
+in GitLab 12.1. Please upgrade to GitLab 12.1 or newer.
+
+## Updating to GitLab 11.11
+
+WARNING: **Warning:**
+This version is affected by [a bug that results in new LFS objects not being replicated to
+Geo secondary nodes](https://gitlab.com/gitlab-org/gitlab/issues/32696). The issue is fixed
+in GitLab 12.1. Please upgrade to GitLab 12.1 or newer.
+
## Updating to GitLab 10.8
Before 10.8, broadcast messages would not propagate without flushing
diff --git a/doc/api/epics.md b/doc/api/epics.md
index 54dc3754de0..fddf7e22d0d 100644
--- a/doc/api/epics.md
+++ b/doc/api/epics.md
@@ -53,7 +53,7 @@ GET /groups/:id/epics?state=opened
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `author_id` | integer | no | Return epics created by the given user `id` |
| `labels` | string | no | Return epics matching a comma separated list of labels names. Label names from the epic group or a parent group can be used |
-| `with_labels_details` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413)|
+| `with_labels_details` | boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413)|
| `order_by` | string | no | Return epics ordered by `created_at` or `updated_at` fields. Default is `created_at` |
| `sort` | string | no | Return epics sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search epics against their `title` and `description` |
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index d6a0cc97e25..eae3626515e 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -1891,6 +1891,11 @@ type Epic implements Noteable {
iid: ID
"""
+ Filter epics by iid for autocomplete
+ """
+ iidStartsWith: String
+
+ """
List of IIDs of epics, e.g., [1, 2]
"""
iids: [ID!]
@@ -1944,7 +1949,7 @@ type Epic implements Noteable {
"""
Total weight of open and closed descendant epic's issues. Available only when
- feature flag unfiltered_epic_aggregates is enabled.
+ feature flag `unfiltered_epic_aggregates` is enabled.
"""
descendantWeightSum: EpicDescendantWeights
@@ -2409,7 +2414,7 @@ type EpicIssue implements Noteable {
epicIssueId: ID!
"""
- Current health status. Available only when feature flag save_issuable_health_status is enabled.
+ Current health status. Available only when feature flag `save_issuable_health_status` is enabled.
"""
healthStatus: HealthStatus
@@ -2942,6 +2947,11 @@ type Group {
iid: ID
"""
+ Filter epics by iid for autocomplete
+ """
+ iidStartsWith: String
+
+ """
List of IIDs of epics, e.g., [1, 2]
"""
iids: [ID!]
@@ -3009,6 +3019,11 @@ type Group {
iid: ID
"""
+ Filter epics by iid for autocomplete
+ """
+ iidStartsWith: String
+
+ """
List of IIDs of epics, e.g., [1, 2]
"""
iids: [ID!]
@@ -3390,7 +3405,7 @@ type Issue implements Noteable {
epic: Epic
"""
- Current health status. Available only when feature flag save_issuable_health_status is enabled.
+ Current health status. Available only when feature flag `save_issuable_health_status` is enabled.
"""
healthStatus: HealthStatus
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 4429bc6621d..bf59c94f6cc 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -3513,6 +3513,16 @@
}
},
"defaultValue": null
+ },
+ {
+ "name": "iidStartsWith",
+ "description": "Filter epics by iid for autocomplete",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
}
],
"type": {
@@ -3634,6 +3644,16 @@
"defaultValue": null
},
{
+ "name": "iidStartsWith",
+ "description": "Filter epics by iid for autocomplete",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
@@ -4867,6 +4887,16 @@
"defaultValue": null
},
{
+ "name": "iidStartsWith",
+ "description": "Filter epics by iid for autocomplete",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 54333464603..79be0c0d626 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -317,7 +317,7 @@ Represents an epic.
| `closedAt` | Time | Timestamp of the epic's closure |
| `createdAt` | Time | Timestamp of the epic's creation |
| `descendantCounts` | EpicDescendantCount | Number of open and closed descendant epics and issues |
-| `descendantWeightSum` | EpicDescendantWeights | Total weight of open and closed descendant epic's issues. Available only when feature flag unfiltered_epic_aggregates is enabled. |
+| `descendantWeightSum` | EpicDescendantWeights | Total weight of open and closed descendant epic's issues. Available only when feature flag `unfiltered_epic_aggregates` is enabled. |
| `description` | String | Description of the epic |
| `downvotes` | Int! | Number of downvotes the epic has received |
| `dueDate` | Time | Due date of the epic |
@@ -385,7 +385,7 @@ Relationship between an epic and an issue
| `dueDate` | Time | Due date of the issue |
| `epic` | Epic | Epic to which this issue belongs |
| `epicIssueId` | ID! | ID of the epic-issue relation |
-| `healthStatus` | HealthStatus | Current health status. Available only when feature flag save_issuable_health_status is enabled. |
+| `healthStatus` | HealthStatus | Current health status. Available only when feature flag `save_issuable_health_status` is enabled. |
| `id` | ID | Global ID of the epic-issue relation |
| `iid` | ID! | Internal ID of the issue |
| `milestone` | Milestone | Milestone of the issue |
@@ -506,7 +506,7 @@ Autogenerated return type of EpicTreeReorder
| `downvotes` | Int! | Number of downvotes the issue has received |
| `dueDate` | Time | Due date of the issue |
| `epic` | Epic | Epic to which this issue belongs |
-| `healthStatus` | HealthStatus | Current health status. Available only when feature flag save_issuable_health_status is enabled. |
+| `healthStatus` | HealthStatus | Current health status. Available only when feature flag `save_issuable_health_status` is enabled. |
| `iid` | ID! | Internal ID of the issue |
| `milestone` | Milestone | Milestone of the issue |
| `reference` | String! | Internal reference of the issue. Returned in shortened format by default |
diff --git a/doc/api/group_clusters.md b/doc/api/group_clusters.md
index afe1561b129..0b783c2fc72 100644
--- a/doc/api/group_clusters.md
+++ b/doc/api/group_clusters.md
@@ -153,16 +153,16 @@ Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
-| `name` | String | yes | The name of the cluster |
-| `domain` | String | no | The [base domain](../user/group/clusters/index.md#base-domain) of the cluster |
+| `name` | string | yes | The name of the cluster |
+| `domain` | string | no | The [base domain](../user/group/clusters/index.md#base-domain) of the cluster |
| `management_project_id` | integer | no | The ID of the [management project](../user/clusters/management_project.md) for the cluster |
-| `enabled` | Boolean | no | Determines if cluster is active or not, defaults to true |
-| `managed` | Boolean | no | Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true |
-| `platform_kubernetes_attributes[api_url]` | String | yes | The URL to access the Kubernetes API |
-| `platform_kubernetes_attributes[token]` | String | yes | The token to authenticate against Kubernetes |
-| `platform_kubernetes_attributes[ca_cert]` | String | no | TLS certificate (needed if API is using a self-signed TLS certificate |
-| `platform_kubernetes_attributes[authorization_type]` | String | no | The cluster authorization type: `rbac`, `abac` or `unknown_authorization`. Defaults to `rbac`. |
-| `environment_scope` | String | no | The associated environment to the cluster. Defaults to `*` **(PREMIUM)** |
+| `enabled` | boolean | no | Determines if cluster is active or not, defaults to true |
+| `managed` | boolean | no | Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true |
+| `platform_kubernetes_attributes[api_url]` | string | yes | The URL to access the Kubernetes API |
+| `platform_kubernetes_attributes[token]` | string | yes | The token to authenticate against Kubernetes |
+| `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate (needed if API is using a self-signed TLS certificate |
+| `platform_kubernetes_attributes[authorization_type]` | string | no | The cluster authorization type: `rbac`, `abac` or `unknown_authorization`. Defaults to `rbac`. |
+| `environment_scope` | string | no | The associated environment to the cluster. Defaults to `*` **(PREMIUM)** |
Example request:
@@ -223,12 +223,12 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `cluster_id` | integer | yes | The ID of the cluster |
-| `name` | String | no | The name of the cluster |
-| `domain` | String | no | The [base domain](../user/group/clusters/index.md#base-domain) of the cluster |
-| `platform_kubernetes_attributes[api_url]` | String | no | The URL to access the Kubernetes API |
-| `platform_kubernetes_attributes[token]` | String | no | The token to authenticate against Kubernetes |
-| `platform_kubernetes_attributes[ca_cert]` | String | no | TLS certificate (needed if API is using a self-signed TLS certificate |
-| `environment_scope` | String | no | The associated environment to the cluster **(PREMIUM)** |
+| `name` | string | no | The name of the cluster |
+| `domain` | string | no | The [base domain](../user/group/clusters/index.md#base-domain) of the cluster |
+| `platform_kubernetes_attributes[api_url]` | string | no | The URL to access the Kubernetes API |
+| `platform_kubernetes_attributes[token]` | string | no | The token to authenticate against Kubernetes |
+| `platform_kubernetes_attributes[ca_cert]` | string | no | TLS certificate (needed if API is using a self-signed TLS certificate |
+| `environment_scope` | string | no | The associated environment to the cluster **(PREMIUM)** |
NOTE: **Note:**
`name`, `api_url`, `ca_cert` and `token` can only be updated if the cluster was added
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 612971d8f5e..d1404efd265 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -47,7 +47,7 @@ GET /issues?confidential=true
| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `state` | string | no | Return `all` issues or just those that are `opened` or `closed` |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. The `description_html` attribute was introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413)|
+| `with_labels_details` | boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. The `description_html` attribute was introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413)|
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ |
@@ -65,7 +65,7 @@ GET /issues?confidential=true
| `created_before` | datetime | no | Return issues created on or before the given time |
| `updated_after` | datetime | no | Return issues updated on or after the given time |
| `updated_before` | datetime | no | Return issues updated on or before the given time |
-| `confidential` | Boolean | no | Filter confidential or public issues. |
+| `confidential` | boolean | no | Filter confidential or public issues. |
| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `my_reaction_emoji`, `search`, `in` |
```shell
@@ -203,7 +203,7 @@ GET /groups/:id/issues?confidential=true
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. The `description_html` attribute was introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
+| `with_labels_details` | boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. The `description_html` attribute was introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
@@ -220,9 +220,9 @@ GET /groups/:id/issues?confidential=true
| `created_before` | datetime | no | Return issues created on or before the given time |
| `updated_after` | datetime | no | Return issues updated on or after the given time |
| `updated_before` | datetime | no | Return issues updated on or before the given time |
-| `confidential` | Boolean | no | Filter confidential or public issues. |
+| `confidential` | boolean | no | Filter confidential or public issues. |
| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `my_reaction_emoji`, `search`, `in` |
-| `non_archived` | Boolean | no | Return issues from non archived projects. Default is true. _(Introduced in [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23785))_ |
+| `non_archived` | boolean | no | Return issues from non archived projects. Default is true. _(Introduced in [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23785))_ |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4/issues
@@ -359,7 +359,7 @@ GET /projects/:id/issues?confidential=true
| `iids[]` | integer array | no | Return only the milestone having the given `iid` |
| `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. `description_html` Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
+| `with_labels_details` | boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. `description_html` Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ |
@@ -375,7 +375,7 @@ GET /projects/:id/issues?confidential=true
| `created_before` | datetime | no | Return issues created on or before the given time |
| `updated_after` | datetime | no | Return issues updated on or after the given time |
| `updated_before` | datetime | no | Return issues updated on or before the given time |
-| `confidential` | Boolean | no | Filter confidential or public issues. |
+| `confidential` | boolean | no | Filter confidential or public issues. |
| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `my_reaction_emoji`, `search`, `in` |
```shell
@@ -647,7 +647,7 @@ POST /projects/:id/issues
| `iid` | integer/string | no | The internal ID of the project's issue (requires admin or project owner rights) |
| `title` | string | yes | The title of an issue |
| `description` | string | no | The description of an issue. Limited to 1,048,576 characters. |
-| `confidential` | Boolean | no | Set an issue to be confidential. Default is `false`. |
+| `confidential` | boolean | no | Set an issue to be confidential. Default is `false`. |
| `assignee_ids` | integer array | no | The ID of a user to assign issue |
| `milestone_id` | integer | no | The global ID of a milestone to assign issue |
| `labels` | string | no | Comma-separated label names for an issue |
@@ -755,7 +755,7 @@ PUT /projects/:id/issues/:issue_iid
| `issue_iid` | integer | yes | The internal ID of a project's issue |
| `title` | string | no | The title of an issue |
| `description` | string | no | The description of an issue. Limited to 1,048,576 characters. |
-| `confidential` | Boolean | no | Updates an issue to be confidential |
+| `confidential` | boolean | no | Updates an issue to be confidential |
| `assignee_ids` | integer array | no | The ID of the user(s) to assign the issue to. Set to `0` or provide an empty value to unassign all assignees. |
| `milestone_id` | integer | no | The global ID of a milestone to assign the issue to. Set to `0` or provide an empty value to unassign a milestone.|
| `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. |
@@ -763,7 +763,7 @@ PUT /projects/:id/issues/:issue_iid
| `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights). Empty string or null values are not accepted.|
| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` |
| `weight` **(STARTER)** | integer | no | The weight of the issue. Valid values are greater than or equal to 0. 0 |
-| `discussion_locked` | Boolean | no | Flag indicating if the issue's discussion is locked. If the discussion is locked only project members can add or edit comments. |
+| `discussion_locked` | boolean | no | Flag indicating if the issue's discussion is locked. If the discussion is locked only project members can add or edit comments. |
| `epic_id` **(ULTIMATE)** | integer | no | ID of the epic to add the issue to. Valid values are greater than or equal to 0. |
| `epic_iid` **(ULTIMATE)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [will be removed in 13.0](https://gitlab.com/gitlab-org/gitlab/issues/35157)) |
diff --git a/doc/api/issues_statistics.md b/doc/api/issues_statistics.md
index cb8379aba64..511078f3028 100644
--- a/doc/api/issues_statistics.md
+++ b/doc/api/issues_statistics.md
@@ -43,7 +43,7 @@ GET /issues_statistics?confidential=true
| `created_before` | datetime | no | Return issues created on or before the given time |
| `updated_after` | datetime | no | Return issues updated on or after the given time |
| `updated_before` | datetime | no | Return issues updated on or before the given time |
-| `confidential` | Boolean | no | Filter confidential or public issues. |
+| `confidential` | boolean | no | Filter confidential or public issues. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/issues_statistics
@@ -99,7 +99,7 @@ GET /groups/:id/issues_statistics?confidential=true
| `created_before` | datetime | no | Return issues created on or before the given time |
| `updated_after` | datetime | no | Return issues updated on or after the given time |
| `updated_before` | datetime | no | Return issues updated on or before the given time |
-| `confidential` | Boolean | no | Filter confidential or public issues. |
+| `confidential` | boolean | no | Filter confidential or public issues. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/4/issues_statistics
@@ -155,7 +155,7 @@ GET /projects/:id/issues_statistics?confidential=true
| `created_before` | datetime | no | Return issues created on or before the given time |
| `updated_after` | datetime | no | Return issues updated on or after the given time |
| `updated_before` | datetime | no | Return issues updated on or before the given time |
-| `confidential` | Boolean | no | Filter confidential or public issues. |
+| `confidential` | boolean | no | Filter confidential or public issues. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues_statistics
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index a0f9a120480..75cb0e7f49b 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -45,7 +45,7 @@ Parameters:
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request |
| `labels` | string | no | Return merge requests matching a comma separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
+| `with_labels_details` | boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
| `created_after` | datetime | no | Return merge requests created on or after the given time |
| `created_before` | datetime | no | Return merge requests created on or before the given time |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time |
@@ -221,7 +221,7 @@ Parameters:
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request |
| `labels` | string | no | Return merge requests matching a comma separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
+| `with_labels_details` | boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) |
| `created_after` | datetime | no | Return merge requests created on or after the given time |
| `created_before` | datetime | no | Return merge requests created on or before the given time |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time |
@@ -383,7 +383,7 @@ Parameters:
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request |
| `labels` | string | no | Return merge requests matching a comma separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. |
-| `with_labels_details` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413)|
+| `with_labels_details` | boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. Introduced in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413)|
| `created_after` | datetime | no | Return merge requests created on or after the given time |
| `created_before` | datetime | no | Return merge requests created on or before the given time |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time |
@@ -397,7 +397,7 @@ Parameters:
| `source_branch` | string | no | Return merge requests with the given source branch |
| `target_branch` | string | no | Return merge requests with the given target branch |
| `search` | string | no | Search merge requests against their `title` and `description` |
-| `non_archived` | Boolean | no | Return merge requests from non archived projects only. Default is true. _(Introduced in [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23809))_ |
+| `non_archived` | boolean | no | Return merge requests from non archived projects only. Default is true. _(Introduced in [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23809))_ |
```json
[
diff --git a/doc/api/project_clusters.md b/doc/api/project_clusters.md
index 448d5966135..6586cfc9f7f 100644
--- a/doc/api/project_clusters.md
+++ b/doc/api/project_clusters.md
@@ -179,8 +179,8 @@ Parameters:
| `id` | integer | yes | The ID of the project owned by the authenticated user |
| `name` | String | yes | The name of the cluster |
| `domain` | String | no | The [base domain](../user/project/clusters/index.md#base-domain) of the cluster |
-| `enabled` | Boolean | no | Determines if cluster is active or not, defaults to true |
-| `managed` | Boolean | no | Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true |
+| `enabled` | boolean | no | Determines if cluster is active or not, defaults to true |
+| `managed` | boolean | no | Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true |
| `platform_kubernetes_attributes[api_url]` | String | yes | The URL to access the Kubernetes API |
| `platform_kubernetes_attributes[token]` | String | yes | The token to authenticate against Kubernetes |
| `platform_kubernetes_attributes[ca_cert]` | String | no | TLS certificate (needed if API is using a self-signed TLS certificate |
diff --git a/doc/security/user_email_confirmation.md b/doc/security/user_email_confirmation.md
index a493b374d66..d435d928c51 100644
--- a/doc/security/user_email_confirmation.md
+++ b/doc/security/user_email_confirmation.md
@@ -5,8 +5,12 @@ type: howto
# User email confirmation at sign-up
GitLab can be configured to require confirmation of a user's email address when
-the user signs up. When this setting is enabled, the user is unable to sign in until
-they confirm their email address.
+the user signs up. When this setting is enabled:
+
+- For GitLab 12.1 and earlier, the user is unable to sign in until they confirm their
+ email address.
+- For GitLab 12.2 and later, the user [has 30 days to confirm their email address](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31245).
+ After 30 days, they will be unable to log in and access GitLab features.
In **Admin Area > Settings** (`/admin/application_settings/general`), go to the section
**Sign-up Restrictions** and look for the **Send confirmation email on sign-up** option.
diff --git a/doc/user/admin_area/settings/sign_up_restrictions.md b/doc/user/admin_area/settings/sign_up_restrictions.md
index a7a6b0ecefd..6dbdf24d477 100644
--- a/doc/user/admin_area/settings/sign_up_restrictions.md
+++ b/doc/user/admin_area/settings/sign_up_restrictions.md
@@ -37,7 +37,12 @@ email domains to prevent malicious users from creating accounts.
## Require email confirmation
You can send confirmation emails during sign-up and require that users confirm
-their email address before they are allowed to sign in.
+their email address. If this setting is selected:
+
+- For GitLab 12.1 and earlier, the user is unable to sign in until they confirm their
+ email address.
+- For GitLab 12.2 and later, the user [has 30 days to confirm their email address](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31245).
+ After 30 days, they will be unable to log in and access GitLab features.
![Email confirmation](img/email_confirmation_v12_7.png)
diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb
index 98b4b4593e0..114a46ca9f6 100644
--- a/lib/gitlab/ci/pipeline/seed/build.rb
+++ b/lib/gitlab/ci/pipeline/seed/build.rb
@@ -7,6 +7,8 @@ module Gitlab
class Build < Seed::Base
include Gitlab::Utils::StrongMemoize
+ EnvironmentCreationFailure = Class.new(StandardError)
+
delegate :dig, to: :@seed_attributes
# When the `ci_dag_limit_needs` is enabled it uses the lower limit
@@ -77,14 +79,39 @@ module Gitlab
if bridge?
::Ci::Bridge.new(attributes)
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
+ ::Ci::Build.new(attributes).tap do |build|
+ build.assign_attributes(self.class.environment_attributes_for(build))
+ build.resource_group = Seed::Build::ResourceGroup.new(build, @resource_group_key).to_resource
end
end
end
end
+ def self.environment_attributes_for(build)
+ return {} unless build.has_environment?
+
+ environment = Seed::Environment.new(build).to_resource
+
+ # If there is a validation error on environment creation, such as
+ # the name contains invalid character, the build falls back to a
+ # non-environment job.
+ unless environment.persisted?
+ Gitlab::ErrorTracking.track_exception(
+ EnvironmentCreationFailure.new,
+ project_id: build.project_id,
+ reason: environment.errors.full_messages.to_sentence)
+
+ return { environment: nil }
+ end
+
+ {
+ deployment: Seed::Deployment.new(build, environment).to_resource,
+ metadata_attributes: {
+ expanded_environment_name: environment.name
+ }
+ }
+ end
+
private
def all_of_only?
diff --git a/lib/gitlab/ci/pipeline/seed/deployment.rb b/lib/gitlab/ci/pipeline/seed/deployment.rb
index cc63fb4c609..624189acc8a 100644
--- a/lib/gitlab/ci/pipeline/seed/deployment.rb
+++ b/lib/gitlab/ci/pipeline/seed/deployment.rb
@@ -7,9 +7,9 @@ module Gitlab
class Deployment < Seed::Base
attr_reader :job, :environment
- def initialize(job)
+ def initialize(job, environment)
@job = job
- @environment = Seed::Environment.new(@job)
+ @environment = environment
end
def to_resource
@@ -17,7 +17,6 @@ module Gitlab
return unless job.starts_environment?
deployment = ::Deployment.new(attributes)
- deployment.environment = environment.to_resource
# If there is a validation error on environment creation, such as
# the name contains invalid character, the job will fall back to a
@@ -45,6 +44,7 @@ module Gitlab
def attributes
{
project: job.project,
+ environment: environment,
user: job.user,
ref: job.ref,
tag: job.tag,
diff --git a/lib/gitlab/ci/pipeline/seed/environment.rb b/lib/gitlab/ci/pipeline/seed/environment.rb
index 2d3a1e702f9..42e8c365824 100644
--- a/lib/gitlab/ci/pipeline/seed/environment.rb
+++ b/lib/gitlab/ci/pipeline/seed/environment.rb
@@ -12,25 +12,15 @@ module Gitlab
end
def to_resource
- find_environment || ::Environment.create(attributes)
+ job.project.environments
+ .safe_find_or_create_by(name: expanded_environment_name)
end
private
- def find_environment
- job.project.environments.find_by_name(expanded_environment_name)
- end
-
def expanded_environment_name
job.expanded_environment_name
end
-
- def attributes
- {
- project: job.project,
- name: expanded_environment_name
- }
- end
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index a6eef56feb2..08b7ec47129 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -19907,6 +19907,9 @@ msgstr ""
msgid "This group"
msgstr ""
+msgid "This group cannot be invited to a project inside a group with enforced SSO"
+msgstr ""
+
msgid "This group does not provide any group Runners yet."
msgstr ""
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index 5127d55645c..b6f18240b9e 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -230,8 +230,9 @@ FactoryBot.define do
# Build deployment/environment relations if environment name is set
# to the job. If `build.deployment` has already been set, it doesn't
# build a new instance.
+ environment = Gitlab::Ci::Pipeline::Seed::Environment.new(build).to_resource
build.deployment =
- Gitlab::Ci::Pipeline::Seed::Deployment.new(build).to_resource
+ Gitlab::Ci::Pipeline::Seed::Deployment.new(build, environment).to_resource
end
end
diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb
index 9e5f6dd2037..2547d39bcb2 100644
--- a/spec/graphql/types/base_field_spec.rb
+++ b/spec/graphql/types/base_field_spec.rb
@@ -174,7 +174,7 @@ describe Types::BaseField do
let(:flag) { :test_flag }
it 'prepends the description' do
- expect(field.description). to eq 'Test description. Available only when feature flag test_flag is enabled.'
+ expect(field.description). to eq 'Test description. Available only when feature flag `test_flag` is enabled.'
end
context 'falsey feature_flag values' do
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
index 1f5fc000832..01f65939da7 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
@@ -214,24 +214,98 @@ describe Gitlab::Ci::Pipeline::Seed::Build do
it { is_expected.to be_a(::Ci::Build) }
it { is_expected.to be_valid }
- context 'when job has environment name' do
- let(:attributes) { { name: 'rspec', ref: 'master', environment: 'production' } }
-
+ shared_examples_for 'deployment job' do
it 'returns a job with deployment' do
expect(subject.deployment).not_to be_nil
expect(subject.deployment.deployable).to eq(subject)
- expect(subject.deployment.environment.name).to eq('production')
+ expect(subject.deployment.environment.name).to eq(expected_environment_name)
end
+ end
+
+ shared_examples_for 'non-deployment job' do
+ it 'returns a job without deployment' do
+ expect(subject.deployment).to be_nil
+ end
+ end
+
+ shared_examples_for 'ensures environment existence' do
+ it 'has environment' do
+ expect(subject).to be_has_environment
+ expect(subject.environment).to eq(environment_name)
+ expect(subject.metadata.expanded_environment_name).to eq(expected_environment_name)
+ expect(Environment.exists?(name: expected_environment_name)).to eq(true)
+ end
+ end
+
+ shared_examples_for 'ensures environment inexistence' do
+ it 'does not have environment' do
+ expect(subject).not_to be_has_environment
+ expect(subject.environment).to be_nil
+ expect(subject.metadata.expanded_environment_name).to be_nil
+ expect(Environment.exists?(name: expected_environment_name)).to eq(false)
+ end
+ end
+
+ context 'when job deploys to production' do
+ let(:environment_name) { 'production' }
+ let(:expected_environment_name) { 'production' }
+ let(:attributes) { { name: 'deploy', ref: 'master', environment: 'production' } }
+
+ it_behaves_like 'deployment job'
+ it_behaves_like 'ensures environment existence'
context 'when the environment name is invalid' do
- let(:attributes) { { name: 'rspec', ref: 'master', environment: '!!!' } }
+ let(:attributes) { { name: 'deploy', ref: 'master', environment: '!!!' } }
- it 'returns a job without deployment' do
- expect(subject.deployment).to be_nil
+ it_behaves_like 'non-deployment job'
+ it_behaves_like 'ensures environment inexistence'
+
+ it 'tracks an exception' do
+ expect(Gitlab::ErrorTracking).to receive(:track_exception)
+ .with(an_instance_of(described_class::EnvironmentCreationFailure),
+ project_id: project.id,
+ reason: %q{Name can contain only letters, digits, '-', '_', '/', '$', '{', '}', '.', and spaces, but it cannot start or end with '/'})
+ .once
+
+ subject
end
end
end
+ context 'when job starts a review app' do
+ let(:environment_name) { 'review/$CI_COMMIT_REF_NAME' }
+ let(:expected_environment_name) { "review/#{pipeline.ref}" }
+
+ let(:attributes) do
+ {
+ name: 'deploy', ref: 'master', environment: environment_name,
+ options: { environment: { name: environment_name } }
+ }
+ end
+
+ it_behaves_like 'deployment job'
+ it_behaves_like 'ensures environment existence'
+ end
+
+ context 'when job stops a review app' do
+ let(:environment_name) { 'review/$CI_COMMIT_REF_NAME' }
+ let(:expected_environment_name) { "review/#{pipeline.ref}" }
+
+ let(:attributes) do
+ {
+ name: 'deploy', ref: 'master', environment: environment_name,
+ options: { environment: { name: environment_name, action: 'stop' } }
+ }
+ end
+
+ it 'returns a job without deployment' do
+ expect(subject.deployment).to be_nil
+ end
+
+ it_behaves_like 'non-deployment job'
+ it_behaves_like 'ensures environment existence'
+ end
+
context 'when job belongs to a resource group' do
let(:attributes) { { name: 'rspec', ref: 'master', resource_group_key: 'iOS' } }
diff --git a/spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb
index c5c91135f60..8d097bdd740 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/deployment_spec.rb
@@ -10,7 +10,8 @@ describe Gitlab::Ci::Pipeline::Seed::Deployment do
end
let(:job) { build(:ci_build, project: project, pipeline: pipeline) }
- let(:seed) { described_class.new(job) }
+ let(:environment) { Gitlab::Ci::Pipeline::Seed::Environment.new(job).to_resource }
+ let(:seed) { described_class.new(job, environment) }
let(:attributes) { {} }
before do
@@ -82,5 +83,13 @@ describe Gitlab::Ci::Pipeline::Seed::Deployment do
is_expected.to be_nil
end
end
+
+ context 'when job does not have environment attribute' do
+ let(:attributes) { { name: 'test' } }
+
+ it 'returns nothing' do
+ is_expected.to be_nil
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/seed/environment_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/environment_spec.rb
index 71389999c6e..4c0464e5e7c 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/environment_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/environment_spec.rb
@@ -15,29 +15,68 @@ describe Gitlab::Ci::Pipeline::Seed::Environment do
describe '#to_resource' do
subject { seed.to_resource }
- context 'when job has environment attribute' do
- let(:attributes) do
- {
- environment: 'production',
- options: { environment: { name: 'production' } }
- }
- end
-
+ shared_examples_for 'returning a correct environment' do
it 'returns a persisted environment object' do
+ expect { subject }.to change { Environment.count }.by(1)
+
expect(subject).to be_a(Environment)
expect(subject).to be_persisted
expect(subject.project).to eq(project)
- expect(subject.name).to eq('production')
+ expect(subject.name).to eq(expected_environment_name)
end
context 'when environment has already existed' do
- let!(:environment) { create(:environment, project: project, name: 'production') }
+ let!(:environment) { create(:environment, project: project, name: expected_environment_name) }
it 'returns the existing environment object' do
+ expect { subject }.not_to change { Environment.count }
+
expect(subject).to be_persisted
expect(subject).to eq(environment)
end
end
end
+
+ context 'when job has environment attribute' do
+ let(:environment_name) { 'production' }
+ let(:expected_environment_name) { 'production' }
+
+ let(:attributes) do
+ {
+ environment: environment_name,
+ options: { environment: { name: environment_name } }
+ }
+ end
+
+ it_behaves_like 'returning a correct environment'
+ end
+
+ context 'when job starts a review app' do
+ let(:environment_name) { 'review/$CI_COMMIT_REF_NAME' }
+ let(:expected_environment_name) { "review/#{job.ref}" }
+
+ let(:attributes) do
+ {
+ environment: environment_name,
+ options: { environment: { name: environment_name } }
+ }
+ end
+
+ it_behaves_like 'returning a correct environment'
+ end
+
+ context 'when job stops a review app' do
+ let(:environment_name) { 'review/$CI_COMMIT_REF_NAME' }
+ let(:expected_environment_name) { "review/#{job.ref}" }
+
+ let(:attributes) do
+ {
+ environment: environment_name,
+ options: { environment: { name: environment_name, action: 'stop' } }
+ }
+ end
+
+ it_behaves_like 'returning a correct environment'
+ end
end
end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 37219365ecf..757c158e16a 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -1293,7 +1293,35 @@ describe Ci::Build do
environment: 'review/$APP_HOST')
end
- it { is_expected.to eq('review/host') }
+ it 'returns an expanded environment name with a list of variables' do
+ expect(build).to receive(:simple_variables).once.and_call_original
+
+ is_expected.to eq('review/host')
+ end
+
+ context 'when build metadata has already persisted the expanded environment name' do
+ before do
+ build.metadata.expanded_environment_name = 'review/host'
+ end
+
+ it 'returns a persisted expanded environment name without a list of variables' do
+ expect(build).not_to receive(:simple_variables)
+
+ is_expected.to eq('review/host')
+ end
+
+ context 'when ci_persisted_expanded_environment_name feature flag is disabled' do
+ before do
+ stub_feature_flags(ci_persisted_expanded_environment_name: false)
+ end
+
+ it 'returns an expanded environment name with a list of variables' do
+ expect(build).to receive(:simple_variables).once.and_call_original
+
+ is_expected.to eq('review/host')
+ end
+ end
+ end
end
context 'when using persisted variables' do
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 3e5c16c2491..4ecbc671c72 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -56,8 +56,6 @@ describe Issuable do
end
describe "Scope" do
- subject { build(:issue) }
-
it { expect(issuable_class).to respond_to(:opened) }
it { expect(issuable_class).to respond_to(:closed) }
it { expect(issuable_class).to respond_to(:assigned) }
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index 188271f4a75..8a22b2c8da3 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -238,6 +238,10 @@ describe Ci::RetryBuildService do
it 'creates a new deployment' do
expect { new_build }.to change { Deployment.count }.by(1)
end
+
+ it 'persists expanded environment name' do
+ expect(new_build.metadata.expanded_environment_name).to eq('production')
+ end
end
context 'when scheduling_type of build is nil' do