releases.rb 5.11 KB
Newer Older
Alessio Caiazza's avatar
Alessio Caiazza committed
1 2 3 4 5 6
# frozen_string_literal: true

module API
  class Releases < Grape::API
    include PaginationParams

Sean Carroll's avatar
Sean Carroll committed
7
    RELEASE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS
Shinya Maeda's avatar
Shinya Maeda committed
8
      .merge(tag_name: API::NO_SLASH_URL_PART_REGEX)
Alessio Caiazza's avatar
Alessio Caiazza committed
9

Shinya Maeda's avatar
Shinya Maeda committed
10
    before { authorize_read_releases! }
Alessio Caiazza's avatar
Alessio Caiazza committed
11 12 13 14 15 16 17 18 19 20 21 22 23

    params do
      requires :id, type: String, desc: 'The ID of a project'
    end
    resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
      desc 'Get a project releases' do
        detail 'This feature was introduced in GitLab 11.7.'
        success Entities::Release
      end
      params do
        use :pagination
      end
      get ':id/releases' do
24
        releases = ::ReleasesFinder.new(user_project, current_user).execute
Alessio Caiazza's avatar
Alessio Caiazza committed
25

26
        present paginate(releases), with: Entities::Release, current_user: current_user
Alessio Caiazza's avatar
Alessio Caiazza committed
27 28 29 30 31 32 33
      end

      desc 'Get a single project release' do
        detail 'This feature was introduced in GitLab 11.7.'
        success Entities::Release
      end
      params do
Shinya Maeda's avatar
Shinya Maeda committed
34
        requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
Alessio Caiazza's avatar
Alessio Caiazza committed
35
      end
Sean Carroll's avatar
Sean Carroll committed
36
      get ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
37
        authorize_download_code!
Alessio Caiazza's avatar
Alessio Caiazza committed
38

39
        present release, with: Entities::Release, current_user: current_user
Alessio Caiazza's avatar
Alessio Caiazza committed
40 41 42 43 44 45 46
      end

      desc 'Create a new release' do
        detail 'This feature was introduced in GitLab 11.7.'
        success Entities::Release
      end
      params do
Shinya Maeda's avatar
Shinya Maeda committed
47
        requires :tag_name,    type: String, desc: 'The name of the tag', as: :tag
48
        optional :name,        type: String, desc: 'The name of the release'
Shinya Maeda's avatar
Shinya Maeda committed
49 50
        requires :description, type: String, desc: 'The release notes'
        optional :ref,         type: String, desc: 'The commit sha or branch name'
51 52 53 54 55
        optional :assets, type: Hash do
          optional :links, type: Array do
            requires :name, type: String
            requires :url, type: String
          end
56
        end
57
        optional :milestones, type: Array, desc: 'The titles of the related milestones', default: []
58
        optional :released_at, type: DateTime, desc: 'The date when the release will be/was ready. Defaults to the current time.'
Alessio Caiazza's avatar
Alessio Caiazza committed
59
      end
60
      route_setting :authentication, job_token_allowed: true
Alessio Caiazza's avatar
Alessio Caiazza committed
61 62 63
      post ':id/releases' do
        authorize_create_release!

Shinya Maeda's avatar
Shinya Maeda committed
64 65 66
        result = ::Releases::CreateService
          .new(user_project, current_user, declared_params(include_missing: false))
          .execute
Alessio Caiazza's avatar
Alessio Caiazza committed
67 68

        if result[:status] == :success
69
          present result[:release], with: Entities::Release, current_user: current_user
Alessio Caiazza's avatar
Alessio Caiazza committed
70
        else
Shinya Maeda's avatar
Shinya Maeda committed
71
          render_api_error!(result[:message], result[:http_status])
Alessio Caiazza's avatar
Alessio Caiazza committed
72 73 74 75 76 77 78 79
        end
      end

      desc 'Update a release' do
        detail 'This feature was introduced in GitLab 11.7.'
        success Entities::Release
      end
      params do
80
        requires :tag_name,    type: String, desc: 'The name of the tag', as: :tag
Shinya Maeda's avatar
Shinya Maeda committed
81 82
        optional :name,        type: String, desc: 'The name of the release'
        optional :description, type: String, desc: 'Release notes with markdown support'
Jason Goodman's avatar
Jason Goodman committed
83
        optional :released_at, type: DateTime, desc: 'The date when the release will be/was ready.'
84
        optional :milestones,  type: Array, desc: 'The titles of the related milestones'
Alessio Caiazza's avatar
Alessio Caiazza committed
85
      end
Sean Carroll's avatar
Sean Carroll committed
86
      put ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
Alessio Caiazza's avatar
Alessio Caiazza committed
87 88
        authorize_update_release!

Shinya Maeda's avatar
Shinya Maeda committed
89 90 91
        result = ::Releases::UpdateService
          .new(user_project, current_user, declared_params(include_missing: false))
          .execute
Alessio Caiazza's avatar
Alessio Caiazza committed
92 93

        if result[:status] == :success
94
          present result[:release], with: Entities::Release, current_user: current_user
Alessio Caiazza's avatar
Alessio Caiazza committed
95 96 97 98
        else
          render_api_error!(result[:message], result[:http_status])
        end
      end
99 100 101 102 103 104

      desc 'Delete a release' do
        detail 'This feature was introduced in GitLab 11.7.'
        success Entities::Release
      end
      params do
105
        requires :tag_name, type: String, desc: 'The name of the tag', as: :tag
106
      end
Sean Carroll's avatar
Sean Carroll committed
107
      delete ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
Shinya Maeda's avatar
Shinya Maeda committed
108
        authorize_destroy_release!
109

Shinya Maeda's avatar
Shinya Maeda committed
110 111 112
        result = ::Releases::DestroyService
          .new(user_project, current_user, declared_params(include_missing: false))
          .execute
113 114

        if result[:status] == :success
115
          present result[:release], with: Entities::Release, current_user: current_user
116 117 118 119
        else
          render_api_error!(result[:message], result[:http_status])
        end
      end
Alessio Caiazza's avatar
Alessio Caiazza committed
120
    end
Shinya Maeda's avatar
Shinya Maeda committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

    helpers do
      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

143 144 145 146
      def authorize_download_code!
        authorize! :download_code, release
      end

Shinya Maeda's avatar
Shinya Maeda committed
147 148 149 150
      def release
        @release ||= user_project.releases.find_by_tag(params[:tag])
      end
    end
Alessio Caiazza's avatar
Alessio Caiazza committed
151 152
  end
end