Commit 13bd5ac8 authored by Zeger-Jan van de Weg's avatar Zeger-Jan van de Weg Committed by Kerri Miller

Don't create duplicate deployments

When the API parameters for a deployment are the same as the last
deployment no new deployment will be created. This prevents duplicate
deployments if nothing changed. As such no hooks will be executed
either, which prevents for example Slack notifications which don't add
value.
parent fe7b31dd
...@@ -353,6 +353,13 @@ class Deployment < ApplicationRecord ...@@ -353,6 +353,13 @@ class Deployment < ApplicationRecord
File.join(environment.ref_path, 'deployments', iid.to_s) File.join(environment.ref_path, 'deployments', iid.to_s)
end end
def equal_to?(params)
ref == params[:ref] &&
tag == params[:tag] &&
sha == params[:sha] &&
status == params[:status]
end
private private
def legacy_finished_at def legacy_finished_at
......
...@@ -11,6 +11,8 @@ module Deployments ...@@ -11,6 +11,8 @@ module Deployments
end end
def execute def execute
return last_deployment if last_deployment&.equal_to?(params)
environment.deployments.build(deployment_attributes).tap do |deployment| environment.deployments.build(deployment_attributes).tap do |deployment|
# Deployment#change_status already saves the model, so we only need to # Deployment#change_status already saves the model, so we only need to
# call #save ourselves if no status is provided. # call #save ourselves if no status is provided.
...@@ -36,5 +38,11 @@ module Deployments ...@@ -36,5 +38,11 @@ module Deployments
on_stop: params[:on_stop] on_stop: params[:on_stop]
} }
end end
private
def last_deployment
@environment.last_deployment
end
end end
end end
---
title: Deployments::CreateService executions are idempotent for duplicate params
merge_request: 47610
author:
type: added
...@@ -41,6 +41,27 @@ RSpec.describe Deployments::CreateService do ...@@ -41,6 +41,27 @@ RSpec.describe Deployments::CreateService do
expect(service.execute).to be_persisted expect(service.execute).to be_persisted
end end
context 'when the last deployment has the same parameters' do
let(:params) do
{
sha: 'b83d6e391c22777fca1ed3012fce84f633d7fed0',
ref: 'master',
tag: false,
status: 'success'
}
end
it 'does not create a new deployment' do
described_class.new(environment, user, params).execute
expect(Deployments::UpdateEnvironmentWorker).not_to receive(:perform_async)
expect(Deployments::LinkMergeRequestWorker).not_to receive(:perform_async)
expect(Deployments::ExecuteHooksWorker).not_to receive(:perform_async)
described_class.new(environment.reload, user, params).execute
end
end
end end
describe '#deployment_attributes' do describe '#deployment_attributes' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment