gitlab-org--gitlab-foss/lib/gitlab/changelog/committer.rb

70 lines
2.1 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
module Gitlab
module Changelog
# A class used for committing a release's changelog to a Git repository.
class Committer
def initialize(project, user)
@project = project
@user = user
end
# Commits a release's changelog to a file on a branch.
#
# The `release` argument is a `Gitlab::Changelog::Release` for which to
# update the changelog.
#
# The `file` argument specifies the path to commit the changes to.
#
# The `branch` argument specifies the branch to commit the changes on.
#
# The `message` argument specifies the commit message to use.
def commit(release:, file:, branch:, message:)
# When retrying, we need to reprocess the existing changelog from
# scratch, otherwise we may end up throwing away changes. As such, all
# the logic is contained within the retry block.
Retriable.retriable(on: Error) do
commit = Gitlab::Git::Commit.last_for_path(
@project.repository,
branch,
file,
literal_pathspec: true
)
content = blob_content(file, commit)
# If the release has already been added (e.g. concurrently by another
# API call), we don't want to add it again.
break if content&.match?(release.header_start_pattern)
service = Files::MultiService.new(
@project,
@user,
commit_message: message,
branch_name: branch,
start_branch: branch,
actions: [
{
action: content ? 'update' : 'create',
content: Generator.new(content.to_s).add(release),
file_path: file,
last_commit_id: commit&.sha
}
]
)
result = service.execute
raise Error, result[:message] if result[:status] != :success
end
end
def blob_content(file, commit = nil)
return unless commit
@project.repository.blob_at(commit.sha, file)&.data
end
end
end
end