diff --git a/app/models/release.rb b/app/models/release.rb index ecfae554fe00fe6f30b9ac0692e768d098fc935f..2543717895fde87e760732904ce88a91d0b1007d 100644 --- a/app/models/release.rb +++ b/app/models/release.rb @@ -34,7 +34,6 @@ class Release < ApplicationRecord delegate :repository, to: :project - after_commit :create_evidence!, on: :create, unless: :importing? after_commit :notify_new_release, on: :create, unless: :importing? MAX_NUMBER_TO_DISPLAY = 3 @@ -70,6 +69,10 @@ def upcoming_release? released_at.present? && released_at > Time.zone.now end + def historical_release? + released_at.present? && released_at < created_at + end + def name self.read_attribute(:name) || tag end @@ -98,10 +101,6 @@ def actual_tag end end - def create_evidence! - CreateEvidenceWorker.perform_async(self.id) - end - def notify_new_release NewReleaseWorker.perform_async(id) end diff --git a/changelogs/unreleased/38103-collect-release-evidence-at-moment-of-release-end-date.yml b/changelogs/unreleased/38103-collect-release-evidence-at-moment-of-release-end-date.yml new file mode 100644 index 0000000000000000000000000000000000000000..97a5807ab17dc74f497157278ff5546a8c4e9b41 --- /dev/null +++ b/changelogs/unreleased/38103-collect-release-evidence-at-moment-of-release-end-date.yml @@ -0,0 +1,5 @@ +--- +title: Collect release evidence at release timestamp +merge_request: 23697 +author: +type: added diff --git a/lib/api/releases.rb b/lib/api/releases.rb index 506d2b0f9859dff638fa2e737b2800f13acd46b2..b1f23d9837f0564fc5c9d5f60be178dee2feb5ba 100644 --- a/lib/api/releases.rb +++ b/lib/api/releases.rb @@ -67,6 +67,7 @@ class Releases < Grape::API if result[:status] == :success log_release_created_audit_event(result[:release]) + create_evidence! present result[:release], with: Entities::Release, current_user: current_user else @@ -164,6 +165,16 @@ def log_release_updated_audit_event def log_release_milestones_updated_audit_event # This is a separate method so that EE can extend its behaviour end + + def create_evidence! + return if release.historical_release? + + if release.upcoming_release? + CreateEvidenceWorker.perform_at(release.released_at, release.id) + else + CreateEvidenceWorker.perform_async(release.id) + end + end end end end diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb index 2f84b92b806b63f9c20facb7f161bf3b0ef81c22..85e398c7d5ff80177d28ae94b5013234efcf91c4 100644 --- a/spec/models/release_spec.rb +++ b/spec/models/release_spec.rb @@ -53,12 +53,6 @@ end end - describe 'callbacks' do - it 'creates a new Evidence object on after_commit', :sidekiq_inline do - expect { release }.to change(Evidence, :count).by(1) - end - end - describe '#assets_count' do subject { release.assets_count } diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb index ae95b54a5902cd36e328cc36fcff31d428864c23..e0f88caeab663e51868866e3b5eab38a62c55558 100644 --- a/spec/requests/api/releases_spec.rb +++ b/spec/requests/api/releases_spec.rb @@ -9,6 +9,7 @@ let(:guest) { create(:user) } let(:non_project_member) { create(:user) } let(:commit) { create(:commit, project: project) } + let(:last_release) { project.releases.last } before do project.add_maintainer(maintainer) @@ -709,6 +710,109 @@ expect(response).to have_gitlab_http_status(:conflict) end end + + context 'Evidence collection' do + let(:params) do + { + name: 'New release', + tag_name: 'v0.1', + description: 'Super nice release', + released_at: released_at + }.compact + end + + around do |example| + Timecop.freeze { example.run } + end + + subject do + post api("/projects/#{project.id}/releases", maintainer), params: params + end + + context 'historical release' do + let(:released_at) { 3.weeks.ago } + + it 'does not execute CreateEvidenceWorker' do + expect { subject }.not_to change(CreateEvidenceWorker.jobs, :size) + end + + it 'does not create an Evidence object', :sidekiq_inline do + expect { subject }.not_to change(Evidence, :count) + end + + it 'is a historical release' do + subject + + expect(last_release.historical_release?).to be_truthy + end + + it 'is not an upcoming release' do + subject + + expect(last_release.upcoming_release?).to be_falsy + end + end + + context 'immediate release' do + let(:released_at) { nil } + + it 'sets `released_at` to the current dttm' do + subject + + expect(last_release.updated_at).to be_like_time(Time.now) + end + + it 'queues CreateEvidenceWorker' do + expect { subject }.to change(CreateEvidenceWorker.jobs, :size).by(1) + end + + it 'creates Evidence', :sidekiq_inline do + expect { subject }.to change(Evidence, :count).by(1) + end + + it 'is not a historical release' do + subject + + expect(last_release.historical_release?).to be_falsy + end + + it 'is not an upcoming release' do + subject + + expect(last_release.upcoming_release?).to be_falsy + end + end + + context 'upcoming release' do + let(:released_at) { 1.day.from_now } + + it 'queues CreateEvidenceWorker' do + expect { subject }.to change(CreateEvidenceWorker.jobs, :size).by(1) + end + + it 'queues CreateEvidenceWorker at the released_at timestamp' do + subject + + expect(CreateEvidenceWorker.jobs.last['at']).to eq(released_at.to_i) + end + + it 'creates Evidence', :sidekiq_inline do + expect { subject }.to change(Evidence, :count).by(1) + end + + it 'is not a historical release' do + subject + + expect(last_release.historical_release?).to be_falsy + end + + it 'is an upcoming release' do + subject + + expect(last_release.upcoming_release?).to be_truthy + end + end + end end describe 'PUT /projects/:id/releases/:tag_name' do