70 lines
2.1 KiB
Ruby
70 lines
2.1 KiB
Ruby
|
# 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.new(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
|