debian-mirror-gitlab/lib/api/releases.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

286 lines
10 KiB
Ruby
Raw Normal View History

2019-02-15 15:39:39 +05:30
# frozen_string_literal: true
module API
2021-01-03 14:25:43 +05:30
class Releases < ::API::Base
2019-02-15 15:39:39 +05:30
include PaginationParams
2019-12-04 20:38:33 +05:30
RELEASE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS
2019-02-15 15:39:39 +05:30
.merge(tag_name: API::NO_SLASH_URL_PART_REGEX)
2021-06-08 01:23:25 +05:30
RELEASE_CLI_USER_AGENT = 'GitLab-release-cli'
2019-02-15 15:39:39 +05:30
2022-06-21 17:19:12 +05:30
feature_category :release_orchestration
2022-07-16 23:28:13 +05:30
urgency :low
2019-02-15 15:39:39 +05:30
2022-06-21 17:19:12 +05:30
params do
requires :id, type: String, desc: 'The ID of a group'
end
resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before { authorize_read_group_releases! }
2021-06-08 01:23:25 +05:30
2022-06-21 17:19:12 +05:30
desc 'Get a list of releases for projects in this group.' do
success Entities::Release
end
params do
requires :id, type: Integer, desc: 'The ID of the group to get releases for'
optional :sort, type: String, values: %w[asc desc], default: 'desc',
2022-08-27 11:52:29 +05:30
desc: 'Return projects sorted in ascending and descending order by released_at'
2022-06-21 17:19:12 +05:30
optional :simple, type: Boolean, default: false,
2022-08-27 11:52:29 +05:30
desc: 'Return only the ID, URL, name, and path of each project'
2022-06-21 17:19:12 +05:30
use :pagination
end
get ":id/releases" do
finder_options = {
sort: params[:sort]
}
strict_params = declared_params(include_missing: false)
releases = find_group_releases(finder_options)
present_group_releases(strict_params, releases)
end
end
2021-01-29 00:20:46 +05:30
2019-02-15 15:39:39 +05:30
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
2022-06-21 17:19:12 +05:30
before { authorize_read_releases! }
after { track_release_event }
2019-02-15 15:39:39 +05:30
desc 'Get a project releases' do
detail 'This feature was introduced in GitLab 11.7.'
2021-06-08 01:23:25 +05:30
named 'get_releases'
2019-02-15 15:39:39 +05:30
success Entities::Release
end
params do
use :pagination
2021-01-03 14:25:43 +05:30
optional :order_by, type: String, values: %w[released_at created_at], default: 'released_at',
desc: 'Return releases ordered by `released_at` or `created_at`.'
optional :sort, type: String, values: %w[asc desc], default: 'desc',
desc: 'Return releases sorted in `asc` or `desc` order.'
2021-06-08 01:23:25 +05:30
optional :include_html_description, type: Boolean,
2022-08-27 11:52:29 +05:30
desc: 'If `true`, a response includes HTML rendered markdown of the release description.'
2019-02-15 15:39:39 +05:30
end
2021-12-11 22:18:48 +05:30
route_setting :authentication, job_token_allowed: true
2019-02-15 15:39:39 +05:30
get ':id/releases' do
2021-01-03 14:25:43 +05:30
releases = ::ReleasesFinder.new(user_project, current_user, declared_params.slice(:order_by, :sort)).execute
2019-02-15 15:39:39 +05:30
2021-06-08 01:23:25 +05:30
# We cache the serialized payload per user in order to avoid repeated renderings.
# Since the cached result could contain sensitive information,
# it will expire in a short interval.
present_cached paginate(releases),
with: Entities::Release,
# `current_user` could be absent if the releases are publicly accesible.
# We should not use `cache_key` for the user because the version/updated_at
# context is unnecessary here.
cache_context: -> (_) { "user:{#{current_user&.id}}" },
expires_in: 5.minutes,
current_user: current_user,
include_html_description: params[:include_html_description]
2019-02-15 15:39:39 +05:30
end
desc 'Get a single project release' do
detail 'This feature was introduced in GitLab 11.7.'
2021-06-08 01:23:25 +05:30
named 'get_release'
2019-02-15 15:39:39 +05:30
success Entities::Release
end
params do
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
2021-06-08 01:23:25 +05:30
optional :include_html_description, type: Boolean,
2022-08-27 11:52:29 +05:30
desc: 'If `true`, a response includes HTML rendered markdown of the release description.'
2019-02-15 15:39:39 +05:30
end
2021-12-11 22:18:48 +05:30
route_setting :authentication, job_token_allowed: true
2019-12-04 20:38:33 +05:30
get ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
2019-07-31 22:56:46 +05:30
authorize_download_code!
2019-02-15 15:39:39 +05:30
2021-09-30 23:02:18 +05:30
not_found! unless release
2021-06-08 01:23:25 +05:30
present release, with: Entities::Release, current_user: current_user, include_html_description: params[:include_html_description]
2019-02-15 15:39:39 +05:30
end
desc 'Create a new release' do
detail 'This feature was introduced in GitLab 11.7.'
2021-06-08 01:23:25 +05:30
named 'create_release'
2019-02-15 15:39:39 +05:30
success Entities::Release
end
params do
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
2022-07-23 23:45:48 +05:30
optional :tag_message, type: String, desc: 'Message to use if creating a new annotated tag'
2019-12-26 22:10:19 +05:30
optional :name, type: String, desc: 'The name of the release'
2020-04-08 14:13:33 +05:30
optional :description, type: String, desc: 'The release notes'
2022-07-23 23:45:48 +05:30
optional :ref, type: String, desc: 'Commit SHA or branch name to use if creating a new tag'
2019-02-15 15:39:39 +05:30
optional :assets, type: Hash do
optional :links, type: Array do
2020-10-24 23:57:45 +05:30
requires :name, type: String, desc: 'The name of the link'
requires :url, type: String, desc: 'The URL of the link'
optional :filepath, type: String, desc: 'The filepath of the link'
optional :link_type, type: String, desc: 'The link type, one of: "runbook", "image", "package" or "other"'
2019-02-15 15:39:39 +05:30
end
end
2020-07-28 23:09:34 +05:30
optional :milestones, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The titles of the related milestones', default: []
2019-09-30 21:07:59 +05:30
optional :released_at, type: DateTime, desc: 'The date when the release will be/was ready. Defaults to the current time.'
2019-02-15 15:39:39 +05:30
end
2020-01-01 13:55:28 +05:30
route_setting :authentication, job_token_allowed: true
2019-02-15 15:39:39 +05:30
post ':id/releases' do
authorize_create_release!
result = ::Releases::CreateService
.new(user_project, current_user, declared_params(include_missing: false))
.execute
if result[:status] == :success
2020-03-13 15:44:24 +05:30
log_release_created_audit_event(result[:release])
2019-07-31 22:56:46 +05:30
present result[:release], with: Entities::Release, current_user: current_user
2019-02-15 15:39:39 +05:30
else
render_api_error!(result[:message], result[:http_status])
end
end
desc 'Update a release' do
detail 'This feature was introduced in GitLab 11.7.'
2021-06-08 01:23:25 +05:30
named 'update_release'
2019-02-15 15:39:39 +05:30
success Entities::Release
end
params do
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
optional :name, type: String, desc: 'The name of the release'
optional :description, type: String, desc: 'Release notes with markdown support'
2019-09-30 21:07:59 +05:30
optional :released_at, type: DateTime, desc: 'The date when the release will be/was ready.'
2021-01-29 00:20:46 +05:30
optional :milestones, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The titles of the related milestones'
2019-02-15 15:39:39 +05:30
end
2021-12-11 22:18:48 +05:30
route_setting :authentication, job_token_allowed: true
2019-12-04 20:38:33 +05:30
put ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
2019-02-15 15:39:39 +05:30
authorize_update_release!
result = ::Releases::UpdateService
.new(user_project, current_user, declared_params(include_missing: false))
.execute
if result[:status] == :success
2020-03-13 15:44:24 +05:30
log_release_updated_audit_event
log_release_milestones_updated_audit_event if result[:milestones_updated]
2019-07-31 22:56:46 +05:30
present result[:release], with: Entities::Release, current_user: current_user
2019-02-15 15:39:39 +05:30
else
render_api_error!(result[:message], result[:http_status])
end
end
desc 'Delete a release' do
detail 'This feature was introduced in GitLab 11.7.'
2021-06-08 01:23:25 +05:30
named 'delete_release'
2019-02-15 15:39:39 +05:30
success Entities::Release
end
params do
2019-03-02 22:35:43 +05:30
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
2019-02-15 15:39:39 +05:30
end
2021-12-11 22:18:48 +05:30
route_setting :authentication, job_token_allowed: true
2019-12-04 20:38:33 +05:30
delete ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
2019-02-15 15:39:39 +05:30
authorize_destroy_release!
result = ::Releases::DestroyService
.new(user_project, current_user, declared_params(include_missing: false))
.execute
if result[:status] == :success
2022-08-27 11:52:29 +05:30
log_release_deleted_audit_event
2019-07-31 22:56:46 +05:30
present result[:release], with: Entities::Release, current_user: current_user
2019-02-15 15:39:39 +05:30
else
render_api_error!(result[:message], result[:http_status])
end
end
end
helpers do
2022-06-21 17:19:12 +05:30
def authorize_read_group_releases!
authorize! :read_release, user_group
end
2019-02-15 15:39:39 +05:30
def authorize_create_release!
authorize! :create_release, user_project
end
def authorize_read_releases!
authorize! :read_release, user_project
end
def authorize_read_release!
authorize! :read_release, release
end
def authorize_update_release!
authorize! :update_release, release
end
def authorize_destroy_release!
authorize! :destroy_release, release
end
2019-07-31 22:56:46 +05:30
def authorize_download_code!
2021-09-30 23:02:18 +05:30
authorize! :download_code, user_project
2019-07-31 22:56:46 +05:30
end
2020-04-22 19:07:51 +05:30
def authorize_create_evidence!
2021-01-03 14:25:43 +05:30
# extended in EE
2020-04-22 19:07:51 +05:30
end
2019-02-15 15:39:39 +05:30
def release
@release ||= user_project.releases.find_by_tag(params[:tag])
end
2020-03-13 15:44:24 +05:30
def log_release_created_audit_event(release)
2021-01-03 14:25:43 +05:30
# extended in EE
2020-03-13 15:44:24 +05:30
end
def log_release_updated_audit_event
2021-01-03 14:25:43 +05:30
# extended in EE
2020-03-13 15:44:24 +05:30
end
2022-08-27 11:52:29 +05:30
def log_release_deleted_audit_event
# extended in EE
end
2020-03-13 15:44:24 +05:30
def log_release_milestones_updated_audit_event
2021-01-03 14:25:43 +05:30
# extended in EE
2020-03-13 15:44:24 +05:30
end
2021-06-08 01:23:25 +05:30
def release_cli?
request.env['HTTP_USER_AGENT']&.include?(RELEASE_CLI_USER_AGENT) == true
end
def event_context
{
release_cli: release_cli?
}
end
def track_release_event
Gitlab::Tracking.event(options[:for].name, options[:route_options][:named],
project: user_project, user: current_user, **event_context)
end
2022-06-21 17:19:12 +05:30
def find_group_releases(finder_options)
::Releases::GroupReleasesFinder
.new(user_group, current_user, finder_options)
.execute(preload: true)
end
def present_group_releases(params, releases)
options = {
with: params[:simple] ? Entities::BasicReleaseDetails : Entities::Release,
current_user: current_user
}
# GroupReleasesFinder has already ordered the data for us
present paginate(releases, skip_default_order: true), options
end
2019-02-15 15:39:39 +05:30
end
end
end
2020-03-13 15:44:24 +05:30
2021-06-08 01:23:25 +05:30
API::Releases.prepend_mod_with('API::Releases')