diff --git a/app/libs/triggers/pre_release/almost_trunk.rb b/app/libs/triggers/pre_release/almost_trunk.rb index a8c746a6b..ecbe5d621 100644 --- a/app/libs/triggers/pre_release/almost_trunk.rb +++ b/app/libs/triggers/pre_release/almost_trunk.rb @@ -42,7 +42,7 @@ def hotfix_branch? def source_ref if hotfix_branch? { - ref: release.hotfixed_from.tag_name, + ref: release.hotfixed_from.end_ref, type: :tag } else diff --git a/app/models/release.rb b/app/models/release.rb index dea41beee..54a220728 100644 --- a/app/models/release.rb +++ b/app/models/release.rb @@ -231,21 +231,31 @@ def end_time end def fetch_commit_log + # release branch for a new release may not exist on vcs provider since pre release job runs in parallel to fetch commit log job + target_branch = train.working_branch if upcoming? ongoing_head = train.ongoing_release.first_commit source_commitish, from_ref = ongoing_head.commit_hash, ongoing_head.short_sha + elsif hotfix? + return if new_hotfix_branch? # there is no diff between the hotfixed from tag and the new hotfix release branch + source_commitish = from_ref = hotfixed_from.end_ref + target_branch = hotfixed_from.release_branch else - source_commitish = from_ref = previous_release&.tag_name || previous_release&.last_commit&.short_sha + source_commitish = from_ref = previous_release&.end_ref end return if source_commitish.blank? create_release_changelog( - commits: vcs_provider.commit_log(source_commitish, train.working_branch), + commits: vcs_provider.commit_log(source_commitish, target_branch), from_ref: ) end + def end_ref + tag_name || last_commit.short_sha + end + def release_version release_platform_runs.pluck(:release_version).map(&:to_semverish).max.to_s end @@ -418,7 +428,7 @@ def set_version end def previous_release - train.releases.where(status: "finished").order(completed_at: :desc).first + train.releases.where(status: "finished").reorder(completed_at: :desc).first end def on_start! diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb index 2fb772eeb..116e4ce1d 100644 --- a/spec/models/release_spec.rb +++ b/spec/models/release_spec.rb @@ -329,4 +329,73 @@ expect(run.retrigger_for_hotfix?).to be(false) end end + + describe "#fetch_commit_log" do + let(:train) { create(:train) } + let(:release) { create(:release, :on_track, train:) } + let(:vcs_mock_provider) { instance_double(GithubIntegration) } + let(:diff) { + [{url: "https://sample.com", + message: "commit message", + timestamp: "2024-01-10T18:38:06.000Z", + author_url: "https://github.com/jondoe", + author_name: "Jon Doe", + commit_hash: SecureRandom.uuid.split("-").join, + author_email: "jon@doe.com", + author_login: "jon-doe"}.with_indifferent_access] + } + + before do + allow_any_instance_of(described_class).to receive(:vcs_provider).and_return(vcs_mock_provider) + allow(vcs_mock_provider).to receive(:commit_log).and_return(diff) + end + + it "fetches the commits between last finished release and release branch" do + finished_release = create(:release, :finished, train:, completed_at: 2.days.ago, tag_name: "foo") + _older_finished_release = create(:release, :finished, train:, completed_at: 4.days.ago, tag_name: "bar") + + release.fetch_commit_log + expect(vcs_mock_provider).to have_received(:commit_log).with(finished_release.tag_name, train.working_branch).once + expect(release.release_changelog.reload.commits.map(&:with_indifferent_access)).to eq(diff) + expect(release.release_changelog.reload.from_ref).to eq(finished_release.tag_name) + end + + it "fetches the commits between ongoing release and release branch for upcoming release" do + ongoing_release = create(:release, :on_track, train:, scheduled_at: 1.day.ago) + commits = create_list(:commit, 5, :without_trigger, release: ongoing_release) + ongoing_head = commits.first + + release.fetch_commit_log + expect(vcs_mock_provider).to have_received(:commit_log).with(ongoing_head.commit_hash, train.working_branch).once + expect(release.release_changelog.reload.commits.map(&:with_indifferent_access)).to eq(diff) + expect(release.release_changelog.reload.from_ref).to eq(ongoing_head.short_sha) + end + + it "does not fetch commit log if no finished release exists for the train" do + release.fetch_commit_log + expect(vcs_mock_provider).not_to have_received(:commit_log) + expect(release.release_changelog).to be_nil + end + + context "when hotfix release" do + it "fetches the commits between hotfixed from release and release branch" do + finished_release = create(:release, :finished, train:, completed_at: 2.days.ago, tag_name: "foo") + hotfix_release = create(:release, :on_track, :hotfix, train:, hotfixed_from: finished_release) + + hotfix_release.fetch_commit_log + expect(vcs_mock_provider).to have_received(:commit_log).with(finished_release.tag_name, release.release_branch).once + expect(hotfix_release.release_changelog.reload.commits.map(&:with_indifferent_access)).to eq(diff) + expect(hotfix_release.release_changelog.reload.from_ref).to eq(finished_release.tag_name) + end + + it "does not fetch commit log when new hotfix branch" do + finished_release = create(:release, :finished, train:, completed_at: 2.days.ago, tag_name: "foo") + hotfix_release = create(:release, :on_track, :hotfix, train:, hotfixed_from: finished_release, new_hotfix_branch: true) + + hotfix_release.fetch_commit_log + expect(vcs_mock_provider).not_to have_received(:commit_log) + expect(hotfix_release.release_changelog).to be_nil + end + end + end end