Skip to content
Snippets Groups Projects
Unverified Commit c2d78268 authored by Sashi's avatar Sashi Committed by Sashi Kumar
Browse files

Execute project hooks and services when deployment starts

This commit changes the deployment hook feature to additionally
trigger an event when a deployment starts.
parent c260eed3
No related branches found
No related tags found
No related merge requests found
Showing
with 152 additions and 29 deletions
Loading
Loading
@@ -24,7 +24,7 @@ def service_event_description(event)
when "commit", "commit_events"
s_("ProjectService|Event will be triggered when a commit is created/updated")
when "deployment"
s_("ProjectService|Event will be triggered when a deployment finishes")
s_("ProjectService|Event will be triggered when a deployment starts or finishes")
when "alert"
s_("ProjectService|Event will be triggered when a new, unique alert is recorded")
end
Loading
Loading
Loading
Loading
@@ -46,6 +46,8 @@ class Deployment < ApplicationRecord
scope :older_than, -> (deployment) { where('id < ?', deployment.id) }
scope :with_deployable, -> { includes(:deployable).where('deployable_id IS NOT NULL') }
 
FINISHED_STATUSES = %i[success failed canceled].freeze
state_machine :status, initial: :created do
event :run do
transition created: :running
Loading
Loading
@@ -63,27 +65,41 @@ class Deployment < ApplicationRecord
transition any - [:canceled] => :canceled
end
 
before_transition any => [:success, :failed, :canceled] do |deployment|
before_transition any => FINISHED_STATUSES do |deployment|
deployment.finished_at = Time.current
end
 
after_transition any => :success do |deployment|
after_transition any => :running do |deployment|
next unless deployment.project.forward_deployment_enabled?
deployment.run_after_commit do
Deployments::SuccessWorker.perform_async(id)
Deployments::ForwardDeploymentWorker.perform_async(id)
end
end
 
after_transition any => [:success, :failed, :canceled] do |deployment|
after_transition any => :running do |deployment|
deployment.run_after_commit do
Deployments::FinishedWorker.perform_async(id)
next unless Feature.enabled?(:ci_send_deployment_hook_when_start, deployment.project)
Deployments::ExecuteHooksWorker.perform_async(id)
end
end
 
after_transition any => :running do |deployment|
next unless deployment.project.forward_deployment_enabled?
after_transition any => :success do |deployment|
deployment.run_after_commit do
Deployments::UpdateEnvironmentWorker.perform_async(id)
end
end
 
after_transition any => FINISHED_STATUSES do |deployment|
deployment.run_after_commit do
Deployments::ForwardDeploymentWorker.perform_async(id)
Deployments::LinkMergeRequestWorker.perform_async(id)
end
end
after_transition any => FINISHED_STATUSES do |deployment|
deployment.run_after_commit do
Deployments::ExecuteHooksWorker.perform_async(id)
end
end
end
Loading
Loading
@@ -273,7 +289,7 @@ def link_merge_requests(relation)
SQL
end
 
# Changes the status of a deployment and triggers the correspinding state
# Changes the status of a deployment and triggers the corresponding state
# machine events.
def update_status(status)
case status
Loading
Loading
Loading
Loading
@@ -38,7 +38,11 @@ def activity
private
 
def message
"Deploy to #{environment} #{humanized_status}"
if running?
"Starting deploy to #{environment}"
else
"Deploy to #{environment} #{humanized_status}"
end
end
 
def color
Loading
Loading
@@ -73,5 +77,9 @@ def commit_link
def humanized_status
status == 'success' ? 'succeeded' : status
end
def running?
status == 'running'
end
end
end
# frozen_string_literal: true
 
module Deployments
class AfterCreateService
class UpdateEnvironmentService
attr_reader :deployment
attr_reader :deployable
 
Loading
Loading
@@ -64,4 +64,4 @@ def renew_auto_stop_in
end
end
 
Deployments::AfterCreateService.prepend_if_ee('EE::Deployments::AfterCreateService')
Deployments::UpdateEnvironmentService.prepend_if_ee('EE::Deployments::UpdateEnvironmentService')
Loading
Loading
@@ -77,7 +77,7 @@
= form.label :deployment_events, class: 'list-label form-check-label ml-1' do
%strong= s_('Webhooks|Deployment events')
%p.text-muted.ml-1
= s_('Webhooks|This URL will be triggered when a deployment is finished/failed/canceled')
= s_('Webhooks|This URL is triggered when a deployment starts, finishes, fails, or is canceled')
.form-group
= form.label :enable_ssl_verification, s_('Webhooks|SSL verification'), class: 'label-bold checkbox'
.form-check
Loading
Loading
Loading
Loading
@@ -427,6 +427,14 @@
:weight: 1
:idempotent: true
:tags: []
- :name: deployment:deployments_execute_hooks
:feature_category: :continuous_delivery
:has_external_dependencies:
:urgency: :low
:resource_boundary: :cpu
:weight: 3
:idempotent:
:tags: []
- :name: deployment:deployments_finished
:feature_category: :continuous_delivery
:has_external_dependencies:
Loading
Loading
@@ -443,6 +451,14 @@
:weight: 3
:idempotent:
:tags: []
- :name: deployment:deployments_link_merge_request
:feature_category: :continuous_delivery
:has_external_dependencies:
:urgency: :low
:resource_boundary: :cpu
:weight: 3
:idempotent: true
:tags: []
- :name: deployment:deployments_success
:feature_category: :continuous_delivery
:has_external_dependencies:
Loading
Loading
@@ -451,6 +467,14 @@
:weight: 3
:idempotent:
:tags: []
- :name: deployment:deployments_update_environment
:feature_category: :continuous_delivery
:has_external_dependencies:
:urgency: :low
:resource_boundary: :cpu
:weight: 3
:idempotent: true
:tags: []
- :name: gcp_cluster:cluster_configure_istio
:feature_category: :kubernetes_management
:has_external_dependencies: true
Loading
Loading
# frozen_string_literal: true
module Deployments
class ExecuteHooksWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
queue_namespace :deployment
feature_category :continuous_delivery
worker_resource_boundary :cpu
def perform(deployment_id)
if (deploy = Deployment.find_by_id(deployment_id))
deploy.execute_hooks
end
end
end
end
# frozen_string_literal: true
module Deployments
class LinkMergeRequestWorker
include ApplicationWorker
queue_namespace :deployment
idempotent!
feature_category :continuous_delivery
worker_resource_boundary :cpu
def perform(deployment_id)
if (deploy = Deployment.find_by_id(deployment_id))
LinkMergeRequestsService.new(deploy).execute
end
end
end
end
Loading
Loading
@@ -12,7 +12,7 @@ def perform(deployment_id)
Deployment.find_by_id(deployment_id).try do |deployment|
break unless deployment.success?
 
Deployments::AfterCreateService.new(deployment).execute
Deployments::UpdateEnvironmentService.new(deployment).execute
end
end
end
Loading
Loading
# frozen_string_literal: true
module Deployments
class UpdateEnvironmentWorker
include ApplicationWorker
queue_namespace :deployment
idempotent!
feature_category :continuous_delivery
worker_resource_boundary :cpu
def perform(deployment_id)
Deployment.find_by_id(deployment_id).try do |deployment|
break unless deployment.success?
Deployments::UpdateEnvironmentService.new(deployment).execute
end
end
end
end
---
title: Send chat notification when deployment starts
merge_request: 41214
author: Sashi Kumar
type: added
---
name: ci_send_deployment_hook_when_start
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41214
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/247137
group: group::progressive delivery
type: development
default_enabled: false
Loading
Loading
@@ -1303,7 +1303,12 @@ Note that `commit.id` is the ID of the pipeline, not the ID of the commit.
 
### Deployment events
 
Triggered when deployment is finished/failed/canceled.
Triggered when a deployment:
- Starts ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41214) in GitLab 13.5.)
- Succeeds
- Fails
- Is cancelled
 
**Request Header**:
 
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@
 
module EE
module Deployments
module AfterCreateService
module UpdateEnvironmentService
extend ::Gitlab::Utils::Override
 
override :execute
Loading
Loading
Loading
Loading
@@ -35,7 +35,8 @@
 
context 'when user does not have access to the environment' do
it 'fails the build' do
allow(Deployments::FinishedWorker).to receive(:perform_async)
allow(Deployments::LinkMergeRequestWorker).to receive(:perform_async)
allow(Deployments::ExecuteHooksWorker).to receive(:perform_async)
subject
 
expect(ci_build.failed?).to be_truthy
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@
 
require 'spec_helper'
 
RSpec.describe Deployments::AfterCreateService do
RSpec.describe Deployments::UpdateEnvironmentService do
include ::EE::GeoHelpers
 
let(:primary) { create(:geo_node, :primary) }
Loading
Loading
Loading
Loading
@@ -20,8 +20,8 @@ def build(deployment)
environment: deployment.environment.name,
project: deployment.project.hook_attrs,
short_sha: deployment.short_sha,
user: deployment.user.hook_attrs,
user_url: Gitlab::UrlBuilder.build(deployment.user),
user: deployment.deployed_by.hook_attrs,
user_url: Gitlab::UrlBuilder.build(deployment.deployed_by),
commit_url: Gitlab::UrlBuilder.build(deployment.commit),
commit_title: deployment.commit.title
}
Loading
Loading
Loading
Loading
@@ -20015,7 +20015,7 @@ msgstr ""
msgid "ProjectService|Event will be triggered when a confidential issue is created/updated/closed"
msgstr ""
 
msgid "ProjectService|Event will be triggered when a deployment finishes"
msgid "ProjectService|Event will be triggered when a deployment starts or finishes"
msgstr ""
 
msgid "ProjectService|Event will be triggered when a merge request is created/updated/merged"
Loading
Loading
@@ -28851,13 +28851,13 @@ msgstr ""
msgid "Webhooks|Tag push events"
msgstr ""
 
msgid "Webhooks|This URL will be triggered by a push to the repository"
msgid "Webhooks|This URL is triggered when a deployment starts, finishes, fails, or is canceled"
msgstr ""
 
msgid "Webhooks|This URL will be triggered when a confidential issue is created/updated/merged"
msgid "Webhooks|This URL will be triggered by a push to the repository"
msgstr ""
 
msgid "Webhooks|This URL will be triggered when a deployment is finished/failed/canceled"
msgid "Webhooks|This URL will be triggered when a confidential issue is created/updated/merged"
msgstr ""
 
msgid "Webhooks|This URL will be triggered when a merge request is created/updated/merged"
Loading
Loading
Loading
Loading
@@ -19,7 +19,7 @@
deployment = create(:deployment, status: :failed, environment: environment, sha: commit.sha, project: project)
deployable = deployment.deployable
expected_deployable_url = Gitlab::Routing.url_helpers.project_job_url(deployable.project, deployable)
expected_user_url = Gitlab::Routing.url_helpers.user_url(deployment.user)
expected_user_url = Gitlab::Routing.url_helpers.user_url(deployment.deployed_by)
expected_commit_url = Gitlab::UrlBuilder.build(commit)
 
data = described_class.build(deployment)
Loading
Loading
@@ -30,7 +30,7 @@
expect(data[:environment]).to eq("somewhere")
expect(data[:project]).to eq(project.hook_attrs)
expect(data[:short_sha]).to eq(deployment.short_sha)
expect(data[:user]).to eq(deployment.user.hook_attrs)
expect(data[:user]).to eq(deployment.deployed_by.hook_attrs)
expect(data[:user_url]).to eq(expected_user_url)
expect(data[:commit_url]).to eq(expected_commit_url)
expect(data[:commit_title]).to eq(commit.title)
Loading
Loading
Loading
Loading
@@ -1109,7 +1109,8 @@
let(:environment) { deployment.environment }
 
before do
allow(Deployments::FinishedWorker).to receive(:perform_async)
allow(Deployments::LinkMergeRequestWorker).to receive(:perform_async)
allow(Deployments::ExecuteHooksWorker).to receive(:perform_async)
end
 
it 'has deployments record with created status' do
Loading
Loading
@@ -1129,7 +1130,8 @@
 
context 'when transits to success' do
before do
allow(Deployments::SuccessWorker).to receive(:perform_async)
allow(Deployments::UpdateEnvironmentWorker).to receive(:perform_async)
allow(Deployments::ExecuteHooksWorker).to receive(:perform_async)
build.success!
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment