Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/reports/components/issues_list.vue85
-rw-r--r--app/assets/javascripts/reports/components/report_item.vue (renamed from app/assets/javascripts/reports/components/report_issues.vue)44
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/smart_virtual_list.vue42
-rw-r--r--app/helpers/user_callouts_helper.rb5
-rw-r--r--app/models/ci/build.rb39
-rw-r--r--app/models/ci/pipeline.rb19
-rw-r--r--app/models/concerns/deployable.rb29
-rw-r--r--app/models/deployment.rb76
-rw-r--r--app/models/environment.rb4
-rw-r--r--app/models/environment_status.rb6
-rw-r--r--app/models/project.rb2
-rw-r--r--app/services/create_deployment_service.rb74
-rw-r--r--app/services/update_deployment_service.rb53
-rw-r--r--app/views/clusters/clusters/_banner.html.haml6
-rw-r--r--app/views/clusters/clusters/gcp/_form.html.haml2
-rw-r--r--app/views/clusters/clusters/gcp/_show.html.haml2
-rw-r--r--app/views/clusters/clusters/user/_form.html.haml2
-rw-r--r--app/views/clusters/clusters/user/_show.html.haml2
-rw-r--r--app/workers/all_queues.yml2
-rw-r--r--app/workers/build_success_worker.rb16
-rw-r--r--app/workers/deployments/success_worker.rb17
22 files changed, 332 insertions, 196 deletions
diff --git a/app/assets/javascripts/reports/components/issues_list.vue b/app/assets/javascripts/reports/components/issues_list.vue
index 3b425ee2fed..f4243522ef8 100644
--- a/app/assets/javascripts/reports/components/issues_list.vue
+++ b/app/assets/javascripts/reports/components/issues_list.vue
@@ -1,18 +1,31 @@
<script>
-import IssuesBlock from '~/reports/components/report_issues.vue';
-import { STATUS_SUCCESS, STATUS_FAILED, STATUS_NEUTRAL } from '~/reports/constants';
+import ReportItem from '~/reports/components/report_item.vue';
+import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS } from '~/reports/constants';
+import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue';
+
+const wrapIssueWithState = (status, isNew = false) => issue => ({
+ status: issue.status || status,
+ isNew,
+ issue,
+});
/**
* Renders block of issues
*/
-
export default {
components: {
- IssuesBlock,
+ SmartVirtualList,
+ ReportItem,
},
- success: STATUS_SUCCESS,
- failed: STATUS_FAILED,
- neutral: STATUS_NEUTRAL,
+ // Typical height of a report item in px
+ typicalReportItemHeight: 32,
+ /*
+ The maximum amount of shown issues. This is calculated by
+ ( max-height of report-block-list / typicalReportItemHeight ) + some safety margin
+ We will use VirtualList if we have more items than this number.
+ For entries lower than this number, the virtual scroll list calculates the total height of the element wrongly.
+ */
+ maxShownReportItems: 20,
props: {
newIssues: {
type: Array,
@@ -40,42 +53,34 @@ export default {
default: '',
},
},
+ computed: {
+ issuesWithState() {
+ return [
+ ...this.newIssues.map(wrapIssueWithState(STATUS_FAILED, true)),
+ ...this.unresolvedIssues.map(wrapIssueWithState(STATUS_FAILED)),
+ ...this.neutralIssues.map(wrapIssueWithState(STATUS_NEUTRAL)),
+ ...this.resolvedIssues.map(wrapIssueWithState(STATUS_SUCCESS)),
+ ];
+ },
+ },
};
</script>
<template>
- <div class="report-block-container">
-
- <issues-block
- v-if="newIssues.length"
- :component="component"
- :issues="newIssues"
- class="js-mr-code-new-issues"
- status="failed"
- is-new
- />
-
- <issues-block
- v-if="unresolvedIssues.length"
- :component="component"
- :issues="unresolvedIssues"
- :status="$options.failed"
- class="js-mr-code-new-issues"
- />
-
- <issues-block
- v-if="neutralIssues.length"
- :component="component"
- :issues="neutralIssues"
- :status="$options.neutral"
- class="js-mr-code-non-issues"
- />
-
- <issues-block
- v-if="resolvedIssues.length"
+ <smart-virtual-list
+ :length="issuesWithState.length"
+ :remain="$options.maxShownReportItems"
+ :size="$options.typicalReportItemHeight"
+ class="report-block-container"
+ wtag="ul"
+ wclass="report-block-list"
+ >
+ <report-item
+ v-for="(wrapped, index) in issuesWithState"
+ :key="index"
+ :issue="wrapped.issue"
+ :status="wrapped.status"
:component="component"
- :issues="resolvedIssues"
- :status="$options.success"
- class="js-mr-code-resolved-issues"
+ :is-new="wrapped.isNew"
/>
- </div>
+ </smart-virtual-list>
</template>
diff --git a/app/assets/javascripts/reports/components/report_issues.vue b/app/assets/javascripts/reports/components/report_item.vue
index a2a03945ae3..01e6d357a21 100644
--- a/app/assets/javascripts/reports/components/report_issues.vue
+++ b/app/assets/javascripts/reports/components/report_item.vue
@@ -3,14 +3,14 @@ import IssueStatusIcon from '~/reports/components/issue_status_icon.vue';
import { components, componentNames } from '~/reports/components/issue_body';
export default {
- name: 'ReportIssues',
+ name: 'ReportItem',
components: {
IssueStatusIcon,
...components,
},
props: {
- issues: {
- type: Array,
+ issue: {
+ type: Object,
required: true,
},
component: {
@@ -33,27 +33,21 @@ export default {
};
</script>
<template>
- <div>
- <ul class="report-block-list">
- <li
- v-for="(issue, index) in issues"
- :key="index"
- :class="{ 'is-dismissed': issue.isDismissed }"
- class="report-block-list-issue"
- >
- <issue-status-icon
- :status="issue.status || status"
- class="append-right-5"
- />
+ <li
+ :class="{ 'is-dismissed': issue.isDismissed }"
+ class="report-block-list-issue"
+ >
+ <issue-status-icon
+ :status="status"
+ class="append-right-5"
+ />
- <component
- :is="component"
- v-if="component"
- :issue="issue"
- :status="issue.status || status"
- :is-new="isNew"
- />
- </li>
- </ul>
- </div>
+ <component
+ :is="component"
+ v-if="component"
+ :issue="issue"
+ :status="status"
+ :is-new="isNew"
+ />
+ </li>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
index 8bcabc10225..53608838f2f 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
@@ -71,6 +71,7 @@ export default {
linkStart: `<a href="${this.troubleshootingDocsPath}">`,
linkEnd: '</a>',
},
+ false,
);
},
},
diff --git a/app/assets/javascripts/vue_shared/components/smart_virtual_list.vue b/app/assets/javascripts/vue_shared/components/smart_virtual_list.vue
new file mode 100644
index 00000000000..63034a45f77
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/smart_virtual_list.vue
@@ -0,0 +1,42 @@
+<script>
+import VirtualList from 'vue-virtual-scroll-list';
+
+export default {
+ name: 'SmartVirtualList',
+ components: { VirtualList },
+ props: {
+ size: { type: Number, required: true },
+ length: { type: Number, required: true },
+ remain: { type: Number, required: true },
+ rtag: { type: String, default: 'div' },
+ wtag: { type: String, default: 'div' },
+ wclass: { type: String, default: null },
+ },
+};
+</script>
+<template>
+ <virtual-list
+ v-if="length > remain"
+ v-bind="$attrs"
+ :size="remain"
+ :remain="remain"
+ :rtag="rtag"
+ :wtag="wtag"
+ :wclass="wclass"
+ class="js-virtual-list"
+ >
+ <slot></slot>
+ </virtual-list>
+ <component
+ :is="rtag"
+ v-else
+ class="js-plain-element"
+ >
+ <component
+ :is="wtag"
+ :class="wclass"
+ >
+ <slot></slot>
+ </component>
+ </component>
+</template>
diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb
index bae01d476df..4aba48061ba 100644
--- a/app/helpers/user_callouts_helper.rb
+++ b/app/helpers/user_callouts_helper.rb
@@ -3,7 +3,6 @@
module UserCalloutsHelper
GKE_CLUSTER_INTEGRATION = 'gke_cluster_integration'.freeze
GCP_SIGNUP_OFFER = 'gcp_signup_offer'.freeze
- CLUSTER_SECURITY_WARNING = 'cluster_security_warning'.freeze
def show_gke_cluster_integration_callout?(project)
can?(current_user, :create_cluster, project) &&
@@ -14,10 +13,6 @@ module UserCalloutsHelper
!user_dismissed?(GCP_SIGNUP_OFFER)
end
- def show_cluster_security_warning?
- !user_dismissed?(CLUSTER_SECURITY_WARNING)
- end
-
private
def user_dismissed?(feature_name)
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index d7eab57763e..360c9924a7d 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -9,19 +9,18 @@ module Ci
include Presentable
include Importable
include Gitlab::Utils::StrongMemoize
+ include Deployable
belongs_to :project, inverse_of: :builds
belongs_to :runner
belongs_to :trigger_request
belongs_to :erased_by, class_name: 'User'
- has_many :deployments, as: :deployable
-
RUNNER_FEATURES = {
upload_multiple_artifacts: -> (build) { build.publishes_artifacts_reports? }
}.freeze
- has_one :last_deployment, -> { order('deployments.id DESC') }, as: :deployable, class_name: 'Deployment'
+ has_one :deployment, as: :deployable, class_name: 'Deployment'
has_many :trace_sections, class_name: 'Ci::BuildTraceSection'
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id
@@ -195,6 +194,8 @@ module Ci
end
after_transition pending: :running do |build|
+ build.deployment&.run
+
build.run_after_commit do
BuildHooksWorker.perform_async(id)
end
@@ -207,14 +208,18 @@ module Ci
end
after_transition any => [:success] do |build|
+ build.deployment&.succeed
+
build.run_after_commit do
- BuildSuccessWorker.perform_async(id)
PagesWorker.perform_async(:deploy, id) if build.pages_generator?
end
end
before_transition any => [:failed] do |build|
next unless build.project
+
+ build.deployment&.drop
+
next if build.retries_max.zero?
if build.retries_count < build.retries_max
@@ -233,6 +238,10 @@ module Ci
after_transition running: any do |build|
Ci::BuildRunnerSession.where(build: build).delete_all
end
+
+ after_transition any => [:skipped, :canceled] do |build|
+ build.deployment&.cancel
+ end
end
def ensure_metadata
@@ -342,8 +351,12 @@ module Ci
self.options.fetch(:environment, {}).fetch(:action, 'start') if self.options
end
+ def has_deployment?
+ !!self.deployment
+ end
+
def outdated_deployment?
- success? && !last_deployment.try(:last?)
+ success? && !deployment.try(:last?)
end
def depends_on_builds
@@ -358,6 +371,10 @@ module Ci
user == current_user
end
+ def on_stop
+ options&.dig(:environment, :on_stop)
+ end
+
# A slugified version of the build ref, suitable for inclusion in URLs and
# domain names. Rules:
#
@@ -725,7 +742,7 @@ module Ci
if success?
return successful_deployment_status
- elsif complete? && !success?
+ elsif failed?
return :failed
end
@@ -742,13 +759,11 @@ module Ci
end
def successful_deployment_status
- if success? && last_deployment&.last?
- return :last
- elsif success? && last_deployment.present?
- return :out_of_date
+ if deployment&.last?
+ :last
+ else
+ :out_of_date
end
-
- :creating
end
def each_report(report_types)
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 0daf2419b67..56010e899a4 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -181,22 +181,31 @@ module Ci
#
# ref - The name (or names) of the branch(es)/tag(s) to limit the list of
# pipelines to.
- def self.newest_first(ref = nil)
+ # limit - This limits a backlog search, default to 100.
+ def self.newest_first(ref: nil, limit: 100)
relation = order(id: :desc)
+ relation = relation.where(ref: ref) if ref
+
+ if limit
+ ids = relation.limit(limit).select(:id)
+ # MySQL does not support limit in subquery
+ ids = ids.pluck(:id) if Gitlab::Database.mysql?
+ relation = relation.where(id: ids)
+ end
- ref ? relation.where(ref: ref) : relation
+ relation
end
def self.latest_status(ref = nil)
- newest_first(ref).pluck(:status).first
+ newest_first(ref: ref).pluck(:status).first
end
def self.latest_successful_for(ref)
- newest_first(ref).success.take
+ newest_first(ref: ref).success.take
end
def self.latest_successful_for_refs(refs)
- relation = newest_first(refs).success
+ relation = newest_first(ref: refs).success
relation.each_with_object({}) do |pipeline, hash|
hash[pipeline.ref] ||= pipeline
diff --git a/app/models/concerns/deployable.rb b/app/models/concerns/deployable.rb
new file mode 100644
index 00000000000..f4f1989f0a9
--- /dev/null
+++ b/app/models/concerns/deployable.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Deployable
+ extend ActiveSupport::Concern
+
+ included do
+ after_create :create_deployment
+
+ def create_deployment
+ return unless starts_environment? && !has_deployment?
+
+ environment = project.environments.find_or_create_by(
+ name: expanded_environment_name
+ )
+
+ environment.deployments.create!(
+ project_id: environment.project_id,
+ environment: environment,
+ ref: ref,
+ tag: tag,
+ sha: sha,
+ user: user,
+ deployable: self,
+ on_stop: on_stop).tap do |_|
+ self.reload # Reload relationships
+ end
+ end
+ end
+end
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 37efbb04fce..54a900a3b85 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -3,6 +3,7 @@
class Deployment < ActiveRecord::Base
include AtomicInternalId
include IidRoutes
+ include AfterCommitQueue
belongs_to :project, required: true
belongs_to :environment, required: true
@@ -16,11 +17,44 @@ class Deployment < ActiveRecord::Base
delegate :name, to: :environment, prefix: true
- after_create :create_ref
- after_create :invalidate_cache
-
scope :for_environment, -> (environment) { where(environment_id: environment) }
+ state_machine :status, initial: :created do
+ event :run do
+ transition created: :running
+ end
+
+ event :succeed do
+ transition any - [:success] => :success
+ end
+
+ event :drop do
+ transition any - [:failed] => :failed
+ end
+
+ event :cancel do
+ transition any - [:canceled] => :canceled
+ end
+
+ before_transition any => [:success, :failed, :canceled] do |deployment|
+ deployment.finished_at = Time.now
+ end
+
+ after_transition any => :success do |deployment|
+ deployment.run_after_commit do
+ Deployments::SuccessWorker.perform_async(id)
+ end
+ end
+ end
+
+ enum status: {
+ created: 0,
+ running: 1,
+ success: 2,
+ failed: 3,
+ canceled: 4
+ }
+
def self.last_for_environment(environment)
ids = self
.for_environment(environment)
@@ -69,15 +103,15 @@ class Deployment < ActiveRecord::Base
end
def update_merge_request_metrics!
- return unless environment.update_merge_request_metrics?
+ return unless environment.update_merge_request_metrics? && success?
merge_requests = project.merge_requests
.joins(:metrics)
.where(target_branch: self.ref, merge_request_metrics: { first_deployed_to_production_at: nil })
- .where("merge_request_metrics.merged_at <= ?", self.created_at)
+ .where("merge_request_metrics.merged_at <= ?", finished_at)
if previous_deployment
- merge_requests = merge_requests.where("merge_request_metrics.merged_at >= ?", previous_deployment.created_at)
+ merge_requests = merge_requests.where("merge_request_metrics.merged_at >= ?", previous_deployment.finished_at)
end
# Need to use `map` instead of `select` because MySQL doesn't allow `SELECT`ing from the same table
@@ -91,7 +125,7 @@ class Deployment < ActiveRecord::Base
MergeRequest::Metrics
.where(merge_request_id: merge_request_ids, first_deployed_to_production_at: nil)
- .update_all(first_deployed_to_production_at: self.created_at)
+ .update_all(first_deployed_to_production_at: finished_at)
end
def previous_deployment
@@ -109,8 +143,18 @@ class Deployment < ActiveRecord::Base
@stop_action ||= manual_actions.find_by(name: on_stop)
end
+ def finished_at
+ read_attribute(:finished_at) || legacy_finished_at
+ end
+
+ def deployed_at
+ return unless success?
+
+ finished_at
+ end
+
def formatted_deployment_time
- created_at.to_time.in_time_zone.to_s(:medium)
+ deployed_at&.to_time&.in_time_zone&.to_s(:medium)
end
def has_metrics?
@@ -118,21 +162,17 @@ class Deployment < ActiveRecord::Base
end
def metrics
- return {} unless has_metrics?
+ return {} unless has_metrics? && success?
metrics = prometheus_adapter.query(:deployment, self)
- metrics&.merge(deployment_time: created_at.to_i) || {}
+ metrics&.merge(deployment_time: finished_at.to_i) || {}
end
def additional_metrics
- return {} unless has_metrics?
+ return {} unless has_metrics? && success?
metrics = prometheus_adapter.query(:additional_metrics_deployment, self)
- metrics&.merge(deployment_time: created_at.to_i) || {}
- end
-
- def status
- 'success'
+ metrics&.merge(deployment_time: finished_at.to_i) || {}
end
private
@@ -144,4 +184,8 @@ class Deployment < ActiveRecord::Base
def ref_path
File.join(environment.ref_path, 'deployments', iid.to_s)
end
+
+ def legacy_finished_at
+ self.created_at if success? && !read_attribute(:finished_at)
+ end
end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 1c31c01eb9f..7d104bb0c25 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -8,9 +8,9 @@ class Environment < ActiveRecord::Base
belongs_to :project, required: true
- has_many :deployments, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
+ has_many :deployments, -> { success }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
- has_one :last_deployment, -> { order('deployments.id DESC') }, class_name: 'Deployment'
+ has_one :last_deployment, -> { success.order('deployments.id DESC') }, class_name: 'Deployment'
before_validation :nullify_external_url
before_validation :generate_slug, if: ->(env) { env.slug.blank? }
diff --git a/app/models/environment_status.rb b/app/models/environment_status.rb
index a84871f7253..7efc8da09ad 100644
--- a/app/models/environment_status.rb
+++ b/app/models/environment_status.rb
@@ -8,8 +8,8 @@ class EnvironmentStatus
delegate :id, to: :environment
delegate :name, to: :environment
delegate :project, to: :environment
+ delegate :status, to: :deployment, allow_nil: true
delegate :deployed_at, to: :deployment, allow_nil: true
- delegate :status, to: :deployment
def self.for_merge_request(mr, user)
build_environments_status(mr, user, mr.head_pipeline)
@@ -33,10 +33,6 @@ class EnvironmentStatus
end
end
- def deployed_at
- deployment&.created_at
- end
-
def changes
return [] if project.route_map_for(sha).nil?
diff --git a/app/models/project.rb b/app/models/project.rb
index d3b148d0ac0..d5a4ae79c47 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -254,7 +254,7 @@ class Project < ActiveRecord::Base
has_many :variables, class_name: 'Ci::Variable'
has_many :triggers, class_name: 'Ci::Trigger'
has_many :environments
- has_many :deployments
+ has_many :deployments, -> { success }
has_many :pipeline_schedules, class_name: 'Ci::PipelineSchedule'
has_many :project_deploy_tokens
has_many :deploy_tokens, through: :project_deploy_tokens
diff --git a/app/services/create_deployment_service.rb b/app/services/create_deployment_service.rb
deleted file mode 100644
index bb3f605da28..00000000000
--- a/app/services/create_deployment_service.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-class CreateDeploymentService
- attr_reader :job
-
- delegate :expanded_environment_name,
- :variables,
- :project,
- to: :job
-
- def initialize(job)
- @job = job
- end
-
- def execute
- return unless executable?
-
- ActiveRecord::Base.transaction do
- environment.external_url = expanded_environment_url if
- expanded_environment_url
-
- environment.fire_state_event(action)
-
- break unless environment.save
- break if environment.stopped?
-
- deploy.tap(&:update_merge_request_metrics!)
- end
- end
-
- private
-
- def executable?
- project && job.environment.present? && environment
- end
-
- def deploy
- project.deployments.create(
- environment: environment,
- ref: job.ref,
- tag: job.tag,
- sha: job.sha,
- user: job.user,
- deployable: job,
- on_stop: on_stop)
- end
-
- def environment
- @environment ||= job.persisted_environment
- end
-
- def environment_options
- @environment_options ||= job.options&.dig(:environment) || {}
- end
-
- def expanded_environment_url
- return @expanded_environment_url if defined?(@expanded_environment_url)
-
- @expanded_environment_url =
- ExpandVariables.expand(environment_url, variables) if environment_url
- end
-
- def environment_url
- environment_options[:url]
- end
-
- def on_stop
- environment_options[:on_stop]
- end
-
- def action
- environment_options[:action] || 'start'
- end
-end
diff --git a/app/services/update_deployment_service.rb b/app/services/update_deployment_service.rb
new file mode 100644
index 00000000000..aa7fcca1e2a
--- /dev/null
+++ b/app/services/update_deployment_service.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+class UpdateDeploymentService
+ attr_reader :deployment
+ attr_reader :deployable
+
+ delegate :environment, to: :deployment
+ delegate :variables, to: :deployable
+
+ def initialize(deployment)
+ @deployment = deployment
+ @deployable = deployment.deployable
+ end
+
+ def execute
+ deployment.create_ref
+ deployment.invalidate_cache
+
+ ActiveRecord::Base.transaction do
+ environment.external_url = expanded_environment_url if
+ expanded_environment_url
+
+ environment.fire_state_event(action)
+
+ break unless environment.save
+ break if environment.stopped?
+
+ deployment.tap(&:update_merge_request_metrics!)
+ end
+ end
+
+ private
+
+ def environment_options
+ @environment_options ||= deployable.options&.dig(:environment) || {}
+ end
+
+ def expanded_environment_url
+ return @expanded_environment_url if defined?(@expanded_environment_url)
+ return unless environment_url
+
+ @expanded_environment_url =
+ ExpandVariables.expand(environment_url, variables)
+ end
+
+ def environment_url
+ environment_options[:url]
+ end
+
+ def action
+ environment_options[:action] || 'start'
+ end
+end
diff --git a/app/views/clusters/clusters/_banner.html.haml b/app/views/clusters/clusters/_banner.html.haml
index 73cfea0ef92..160c5f009a7 100644
--- a/app/views/clusters/clusters/_banner.html.haml
+++ b/app/views/clusters/clusters/_banner.html.haml
@@ -7,9 +7,3 @@
.hidden.js-cluster-success.bs-callout.bs-callout-success{ role: 'alert' }
= s_("ClusterIntegration|Kubernetes cluster was successfully created on Google Kubernetes Engine. Refresh the page to see Kubernetes cluster's details")
-
-- if show_cluster_security_warning?
- .js-cluster-security-warning.alert.alert-block.alert-dismissable.bs-callout.bs-callout-warning
- %button.close{ type: "button", data: { feature_id: UserCalloutsHelper::CLUSTER_SECURITY_WARNING, dismiss_endpoint: user_callouts_path } } &times;
- = s_("ClusterIntegration|The default cluster configuration grants access to many functionalities needed to successfully build and deploy a containerised application.")
- = link_to s_("More information"), help_page_path('user/project/clusters/index.md', anchor: 'security-implications')
diff --git a/app/views/clusters/clusters/gcp/_form.html.haml b/app/views/clusters/clusters/gcp/_form.html.haml
index ad842036a62..8ed4666e79a 100644
--- a/app/views/clusters/clusters/gcp/_form.html.haml
+++ b/app/views/clusters/clusters/gcp/_form.html.haml
@@ -64,7 +64,7 @@
.form-group
.form-check
= provider_gcp_field.check_box :legacy_abac, { class: 'form-check-input' }, false, true
- = provider_gcp_field.label :legacy_abac, s_('ClusterIntegration|RBAC-enabled cluster (experimental)'), class: 'form-check-label label-bold'
+ = provider_gcp_field.label :legacy_abac, s_('ClusterIntegration|RBAC-enabled cluster'), class: 'form-check-label label-bold'
.form-text.text-muted
= s_('ClusterIntegration|Enable this setting if using role-based access control (RBAC).')
= s_('ClusterIntegration|This option will allow you to install applications on RBAC clusters.')
diff --git a/app/views/clusters/clusters/gcp/_show.html.haml b/app/views/clusters/clusters/gcp/_show.html.haml
index 6021b220285..ca55ccb8fdf 100644
--- a/app/views/clusters/clusters/gcp/_show.html.haml
+++ b/app/views/clusters/clusters/gcp/_show.html.haml
@@ -40,7 +40,7 @@
.form-group
.form-check
= platform_kubernetes_field.check_box :authorization_type, { class: 'form-check-input', disabled: true }, 'rbac', 'abac'
- = platform_kubernetes_field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster (experimental)'), class: 'form-check-label label-bold'
+ = platform_kubernetes_field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster'), class: 'form-check-label label-bold'
.form-text.text-muted
= s_('ClusterIntegration|Enable this setting if using role-based access control (RBAC).')
= s_('ClusterIntegration|This option will allow you to install applications on RBAC clusters.')
diff --git a/app/views/clusters/clusters/user/_form.html.haml b/app/views/clusters/clusters/user/_form.html.haml
index 4e6232b69de..e4758938059 100644
--- a/app/views/clusters/clusters/user/_form.html.haml
+++ b/app/views/clusters/clusters/user/_form.html.haml
@@ -28,7 +28,7 @@
.form-group
.form-check
= platform_kubernetes_field.check_box :authorization_type, { class: 'form-check-input qa-rbac-checkbox' }, 'rbac', 'abac'
- = platform_kubernetes_field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster (experimental)'), class: 'form-check-label label-bold'
+ = platform_kubernetes_field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster'), class: 'form-check-label label-bold'
.form-text.text-muted
= s_('ClusterIntegration|Enable this setting if using role-based access control (RBAC).')
= s_('ClusterIntegration|This option will allow you to install applications on RBAC clusters.')
diff --git a/app/views/clusters/clusters/user/_show.html.haml b/app/views/clusters/clusters/user/_show.html.haml
index a871fef0240..ad8c35e32e3 100644
--- a/app/views/clusters/clusters/user/_show.html.haml
+++ b/app/views/clusters/clusters/user/_show.html.haml
@@ -29,7 +29,7 @@
.form-group
.form-check
= platform_kubernetes_field.check_box :authorization_type, { class: 'form-check-input', disabled: true }, 'rbac', 'abac'
- = platform_kubernetes_field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster (experimental)'), class: 'form-check-label label-bold'
+ = platform_kubernetes_field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster'), class: 'form-check-label label-bold'
.form-text.text-muted
= s_('ClusterIntegration|Enable this setting if using role-based access control (RBAC).')
= s_('ClusterIntegration|This option will allow you to install applications on RBAC clusters.')
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index a66a6f4c777..953ab95735b 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -73,6 +73,8 @@
- pipeline_processing:update_head_pipeline_for_merge_request
- pipeline_processing:ci_build_schedule
+- deployment:deployments_success
+
- repository_check:repository_check_clear
- repository_check:repository_check_batch
- repository_check:repository_check_single_repository
diff --git a/app/workers/build_success_worker.rb b/app/workers/build_success_worker.rb
index c17608f7378..9a865fea621 100644
--- a/app/workers/build_success_worker.rb
+++ b/app/workers/build_success_worker.rb
@@ -10,13 +10,27 @@ class BuildSuccessWorker
def perform(build_id)
Ci::Build.find_by(id: build_id).try do |build|
create_deployment(build) if build.has_environment?
+ stop_environment(build) if build.stops_environment?
end
end
# rubocop: enable CodeReuse/ActiveRecord
private
+ ##
+ # Deprecated:
+ # As of 11.5, we started creating a deployment record when ci_builds record is created.
+ # Therefore we no longer need to create a deployment, after a build succeeded.
+ # We're leaving this code for the transition period, but we can remove this code in 11.6.
def create_deployment(build)
- CreateDeploymentService.new(build).execute
+ build.create_deployment.try do |deployment|
+ deployment.succeed
+ end
+ end
+
+ ##
+ # TODO: This should be processed in DeploymentSuccessWorker once we started storing `action` value in `deployments` records
+ def stop_environment(build)
+ build.persisted_environment.fire_state_event(:stop)
end
end
diff --git a/app/workers/deployments/success_worker.rb b/app/workers/deployments/success_worker.rb
new file mode 100644
index 00000000000..da517f3fb26
--- /dev/null
+++ b/app/workers/deployments/success_worker.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Deployments
+ class SuccessWorker
+ include ApplicationWorker
+
+ queue_namespace :deployment
+
+ def perform(deployment_id)
+ Deployment.find_by_id(deployment_id).try do |deployment|
+ break unless deployment.success?
+
+ UpdateDeploymentService.new(deployment).execute
+ end
+ end
+ end
+end