diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-17 14:33:21 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-17 14:33:21 +0300 |
commit | 7021455bd1ed7b125c55eb1b33c5a01f2bc55ee0 (patch) | |
tree | 5bdc2229f5198d516781f8d24eace62fc7e589e9 /lib/api/entities | |
parent | 185b095e93520f96e9cfc31d9c3e69b498cdab7c (diff) |
Add latest changes from gitlab-org/gitlab@15-6-stable-eev15.6.0-rc42
Diffstat (limited to 'lib/api/entities')
116 files changed, 991 insertions, 536 deletions
diff --git a/lib/api/entities/application.rb b/lib/api/entities/application.rb index 33514200424..c3d8f9667c3 100644 --- a/lib/api/entities/application.rb +++ b/lib/api/entities/application.rb @@ -4,10 +4,12 @@ module API module Entities class Application < Grape::Entity expose :id - expose :uid, as: :application_id - expose :name, as: :application_name - expose :redirect_uri, as: :callback_url - expose :confidential + expose :uid, as: :application_id, + documentation: { type: 'string', + example: '5832fc6e14300a0d962240a8144466eef4ee93ef0d218477e55f11cf12fc3737' } + expose :name, as: :application_name, documentation: { type: 'string', example: 'MyApplication' } + expose :redirect_uri, as: :callback_url, documentation: { type: 'string', example: 'https://redirect.uri' } + expose :confidential, documentation: { type: 'boolean', example: true } end end end diff --git a/lib/api/entities/application_statistics.rb b/lib/api/entities/application_statistics.rb index 4bcba1da464..7e75ef23675 100644 --- a/lib/api/entities/application_statistics.rb +++ b/lib/api/entities/application_statistics.rb @@ -6,47 +6,57 @@ module API include ActionView::Helpers::NumberHelper include CountHelper - expose :forks do |counts| + expose :forks, + documentation: { type: 'integer', example: 6, desc: 'Approximate number of repo forks' } do |counts| approximate_fork_count_with_delimiters(counts) end - expose :issues do |counts| + expose :issues, + documentation: { type: 'integer', example: 121, desc: 'Approximate number of issues' } do |counts| approximate_count_with_delimiters(counts, ::Issue) end - expose :merge_requests do |counts| + expose :merge_requests, + documentation: { type: 'integer', example: 49, desc: 'Approximate number of merge requests' } do |counts| approximate_count_with_delimiters(counts, ::MergeRequest) end - expose :notes do |counts| + expose :notes, + documentation: { type: 'integer', example: 6, desc: 'Approximate number of notes' } do |counts| approximate_count_with_delimiters(counts, ::Note) end - expose :snippets do |counts| + expose :snippets, + documentation: { type: 'integer', example: 4, desc: 'Approximate number of snippets' } do |counts| approximate_count_with_delimiters(counts, ::Snippet) end - expose :ssh_keys do |counts| + expose :ssh_keys, + documentation: { type: 'integer', example: 11, desc: 'Approximate number of SSH keys' } do |counts| approximate_count_with_delimiters(counts, ::Key) end - expose :milestones do |counts| + expose :milestones, + documentation: { type: 'integer', example: 3, desc: 'Approximate number of milestones' } do |counts| approximate_count_with_delimiters(counts, ::Milestone) end - expose :users do |counts| + expose :users, documentation: { type: 'integer', example: 22, desc: 'Approximate number of users' } do |counts| approximate_count_with_delimiters(counts, ::User) end - expose :projects do |counts| + expose :projects, + documentation: { type: 'integer', example: 4, desc: 'Approximate number of projects' } do |counts| approximate_count_with_delimiters(counts, ::Project) end - expose :groups do |counts| + expose :groups, + documentation: { type: 'integer', example: 1, desc: 'Approximate number of projects' } do |counts| approximate_count_with_delimiters(counts, ::Group) end - expose :active_users do |_| + expose :active_users, + documentation: { type: 'integer', example: 21, desc: 'Number of active users' } do |_| number_with_delimiter(::User.active.count) end end diff --git a/lib/api/entities/application_with_secret.rb b/lib/api/entities/application_with_secret.rb index 3e540381d89..1d0acee8624 100644 --- a/lib/api/entities/application_with_secret.rb +++ b/lib/api/entities/application_with_secret.rb @@ -4,7 +4,8 @@ module API module Entities # Use with care, this exposes the secret class ApplicationWithSecret < Entities::Application - expose :secret + expose :secret, documentation: { type: 'string', + example: 'ee1dd64b6adc89cf7e2c23099301ccc2c61b441064e9324d963c46902a85ec34' } end end end diff --git a/lib/api/entities/basic_project_details.rb b/lib/api/entities/basic_project_details.rb index e96504db53e..2585b2d0b6d 100644 --- a/lib/api/entities/basic_project_details.rb +++ b/lib/api/entities/basic_project_details.rb @@ -6,15 +6,18 @@ module API include ::API::ProjectsRelationBuilder include Gitlab::Utils::StrongMemoize - expose :default_branch_or_main, as: :default_branch, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) } + expose :default_branch_or_main, documentation: { type: 'string', example: 'main' }, as: :default_branch, if: -> (project, options) { Ability.allowed?(options[:current_user], :read_code, project) } # Avoids an N+1 query: https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-168273770 - expose :topic_names, as: :tag_list - expose :topic_names, as: :topics + expose :topic_names, as: :tag_list, documentation: { type: 'string', is_array: true, example: 'tag' } + expose :topic_names, as: :topics, documentation: { type: 'string', is_array: true, example: 'topic' } - expose :ssh_url_to_repo, :http_url_to_repo, :web_url, :readme_url + expose :ssh_url_to_repo, documentation: { type: 'string', example: 'git@gitlab.example.com:gitlab/gitlab.git' } + expose :http_url_to_repo, documentation: { type: 'string', example: 'https://gitlab.example.com/gitlab/gitlab.git' } + expose :web_url, documentation: { type: 'string', example: 'https://gitlab.example.com/gitlab/gitlab' } + expose :readme_url, documentation: { type: 'string', example: 'https://gitlab.example.com/gitlab/gitlab/blob/master/README.md' } - expose :license_url, if: :license do |project| + expose :license_url, if: :license, documentation: { type: 'string', example: 'https://gitlab.example.com/gitlab/gitlab/blob/master/LICENCE' } do |project| license = project.repository.license_blob if license @@ -26,13 +29,13 @@ module API project.repository.license end - expose :avatar_url do |project, options| + expose :avatar_url, documentation: { type: 'string', example: 'http://example.com/uploads/project/avatar/3/uploads/avatar.png' } do |project, options| project.avatar_url(only_path: false) end - expose :forks_count - expose :star_count - expose :last_activity_at + expose :forks_count, documentation: { type: 'integer', example: 1 } + expose :star_count, documentation: { type: 'integer', example: 1 } + expose :last_activity_at, documentation: { type: 'dateTime', example: '2013-09-30T13:46:02Z' } expose :namespace, using: 'API::Entities::NamespaceBasic' expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes @@ -57,6 +60,8 @@ module API super end + def self.postload_relation(projects_relation, options = {}) end + private alias_method :project, :object diff --git a/lib/api/entities/basic_ref.rb b/lib/api/entities/basic_ref.rb index 79c15075d99..1b821a5b0ec 100644 --- a/lib/api/entities/basic_ref.rb +++ b/lib/api/entities/basic_ref.rb @@ -3,7 +3,8 @@ module API module Entities class BasicRef < Grape::Entity - expose :type, :name + expose :type, documentation: { type: 'string', example: 'tag' } + expose :name, documentation: { type: 'string', example: 'v1.1.0' } end end end diff --git a/lib/api/entities/basic_release_details.rb b/lib/api/entities/basic_release_details.rb index d13080f32f4..dba19b3abd7 100644 --- a/lib/api/entities/basic_release_details.rb +++ b/lib/api/entities/basic_release_details.rb @@ -5,12 +5,12 @@ module API class BasicReleaseDetails < Grape::Entity include ::API::Helpers::Presentable - expose :name - expose :tag, as: :tag_name - expose :description - expose :created_at - expose :released_at - expose :upcoming_release?, as: :upcoming_release + expose :name, documentation: { type: 'string', example: 'Release v1.0' } + expose :tag, documentation: { type: 'string', example: 'v1.0' }, as: :tag_name + expose :description, documentation: { type: 'string', example: 'Finally released v1.0' } + expose :created_at, documentation: { type: 'dateTime', example: '2019-01-03T01:56:19.539Z' } + expose :released_at, documentation: { type: 'dateTime', example: '2019-01-03T01:56:19.539Z' } + expose :upcoming_release?, documentation: { type: 'boolean' }, as: :upcoming_release end end end diff --git a/lib/api/entities/basic_repository_storage_move.rb b/lib/api/entities/basic_repository_storage_move.rb index 3ee112fb9a2..83b4f428a56 100644 --- a/lib/api/entities/basic_repository_storage_move.rb +++ b/lib/api/entities/basic_repository_storage_move.rb @@ -3,11 +3,11 @@ module API module Entities class BasicRepositoryStorageMove < Grape::Entity - expose :id - expose :created_at - expose :human_state_name, as: :state - expose :source_storage_name - expose :destination_storage_name + expose :id, documentation: { type: 'integer', example: 1 } + expose :created_at, documentation: { type: 'dateTime', example: '2020-05-07T04:27:17.234Z' } + expose :human_state_name, as: :state, documentation: { type: 'string', example: 'scheduled' } + expose :source_storage_name, documentation: { type: 'string', example: 'default' } + expose :destination_storage_name, documentation: { type: 'string', example: 'storage1' } end end end diff --git a/lib/api/entities/basic_snippet.rb b/lib/api/entities/basic_snippet.rb index 26297514798..0e9977fd81b 100644 --- a/lib/api/entities/basic_snippet.rb +++ b/lib/api/entities/basic_snippet.rb @@ -3,16 +3,30 @@ module API module Entities class BasicSnippet < Grape::Entity - expose :id, :title, :description, :visibility - expose :updated_at, :created_at - expose :project_id - expose :web_url do |snippet| + expose :id, documentation: { type: 'integer', example: 1 } + expose :title, documentation: { type: 'string', example: 'test' } + expose :description, documentation: { type: 'string', example: 'Ruby test snippet' } + expose :visibility, documentation: { type: 'string', example: 'public' } + expose :author, using: Entities::UserBasic, documentation: { type: 'Entities::UserBasic' } + expose :created_at, documentation: { type: 'dateTime', example: '2012-06-28T10:52:04Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2012-06-28T10:52:04Z' } + expose :project_id, documentation: { type: 'integer', example: 1 } + expose :web_url, documentation: { + type: 'string', example: 'http://example.com/example/example/snippets/1' + } do |snippet| Gitlab::UrlBuilder.build(snippet) end - expose :raw_url do |snippet| + expose :raw_url, documentation: { + type: 'string', example: 'http://example.com/example/example/snippets/1/raw' + } do |snippet| Gitlab::UrlBuilder.build(snippet, raw: true) end - expose :ssh_url_to_repo, :http_url_to_repo, if: ->(snippet) { snippet.repository_exists? } + expose :ssh_url_to_repo, documentation: { + type: 'string', example: 'ssh://user@gitlab.example.com/snippets/65.git' + }, if: ->(snippet) { snippet.repository_exists? } + expose :http_url_to_repo, documentation: { + type: 'string', example: 'https://gitlab.example.com/snippets/65.git' + }, if: ->(snippet) { snippet.repository_exists? } end end end diff --git a/lib/api/entities/branch.rb b/lib/api/entities/branch.rb index 6a75dcddeda..01eaf5c8d31 100644 --- a/lib/api/entities/branch.rb +++ b/lib/api/entities/branch.rb @@ -5,13 +5,17 @@ module API class Branch < Grape::Entity include Gitlab::Routing - expose :name + expose :name, documentation: { type: 'string', example: 'master' } expose :commit, using: Entities::Commit do |repo_branch, options| options[:project].repository.commit(repo_branch.dereferenced_target) end - expose :merged do |repo_branch, options| + expose :merged, + documentation: { + type: 'boolean', + example: true + } do |repo_branch, options| if options[:merged_branch_names] options[:merged_branch_names].include?(repo_branch.name) else @@ -19,27 +23,51 @@ module API end end - expose :protected do |repo_branch, options| + expose :protected, + documentation: { + type: 'boolean', + example: true + } do |repo_branch, options| ::ProtectedBranch.protected?(options[:project], repo_branch.name) end - expose :developers_can_push do |repo_branch, options| + expose :developers_can_push, + documentation: { + type: 'boolean', + example: true + } do |repo_branch, options| ::ProtectedBranch.developers_can?(:push, repo_branch.name, protected_refs: options[:project].protected_branches) end - expose :developers_can_merge do |repo_branch, options| + expose :developers_can_merge, + documentation: { + type: 'boolean', + example: true + } do |repo_branch, options| ::ProtectedBranch.developers_can?(:merge, repo_branch.name, protected_refs: options[:project].protected_branches) end - expose :can_push do |repo_branch, options| + expose :can_push, + documentation: { + type: 'boolean', + example: true + } do |repo_branch, options| Gitlab::UserAccess.new(options[:current_user], container: options[:project]).can_push_to_branch?(repo_branch.name) end - expose :default do |repo_branch, options| + expose :default, + documentation: { + type: 'boolean', + example: true + } do |repo_branch, options| options[:project].default_branch == repo_branch.name end - expose :web_url do |repo_branch| + expose :web_url, + documentation: { + type: 'string', + example: 'https://gitlab.example.com/Commit921/the-dude/-/tree/master' + } do |repo_branch| project_tree_url(options[:project], repo_branch.name) end end diff --git a/lib/api/entities/bulk_import.rb b/lib/api/entities/bulk_import.rb index 373ae486dcf..75989cb4180 100644 --- a/lib/api/entities/bulk_import.rb +++ b/lib/api/entities/bulk_import.rb @@ -3,11 +3,13 @@ module API module Entities class BulkImport < Grape::Entity - expose :id - expose :status_name, as: :status - expose :source_type - expose :created_at - expose :updated_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :status_name, as: :status, documentation: { + type: 'string', example: 'finished', values: %w[created started finished timeout failed] + } + expose :source_type, documentation: { type: 'string', example: 'gitlab' } + expose :created_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :updated_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } end end end diff --git a/lib/api/entities/bulk_imports/entity.rb b/lib/api/entities/bulk_imports/entity.rb index 142bfaf2149..8f9fbe57935 100644 --- a/lib/api/entities/bulk_imports/entity.rb +++ b/lib/api/entities/bulk_imports/entity.rb @@ -4,19 +4,21 @@ module API module Entities module BulkImports class Entity < Grape::Entity - expose :id - expose :bulk_import_id - expose :status_name, as: :status - expose :source_full_path - expose :destination_name # deprecated - expose :destination_slug - expose :destination_namespace - expose :parent_id - expose :namespace_id - expose :project_id - expose :created_at - expose :updated_at - expose :failures, using: EntityFailure + expose :id, documentation: { type: 'integer', example: 1 } + expose :bulk_import_id, documentation: { type: 'integer', example: 1 } + expose :status_name, as: :status, documentation: { + type: 'string', example: 'created', values: %w[created started finished timeout failed] + } + expose :source_full_path, documentation: { type: 'string', example: 'source_group' } + expose :destination_name, documentation: { type: 'string', example: 'destination_slug' } # deprecated + expose :destination_slug, documentation: { type: 'string', example: 'destination_slug' } + expose :destination_namespace, documentation: { type: 'string', example: 'destination_path' } + expose :parent_id, documentation: { type: 'integer', example: 1 } + expose :namespace_id, documentation: { type: 'integer', example: 1 } + expose :project_id, documentation: { type: 'integer', example: 1 } + expose :created_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :updated_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :failures, using: EntityFailure, documentation: { is_array: true } end end end diff --git a/lib/api/entities/bulk_imports/entity_failure.rb b/lib/api/entities/bulk_imports/entity_failure.rb index 56312745868..3e69e7fa2aa 100644 --- a/lib/api/entities/bulk_imports/entity_failure.rb +++ b/lib/api/entities/bulk_imports/entity_failure.rb @@ -4,16 +4,18 @@ module API module Entities module BulkImports class EntityFailure < Grape::Entity - expose :relation - expose :pipeline_step, as: :step - expose :exception_message do |failure| + expose :relation, documentation: { type: 'string', example: 'group' } + expose :pipeline_step, as: :step, documentation: { type: 'string', example: 'extractor' } + expose :exception_message, documentation: { type: 'string', example: 'error message' } do |failure| ::Projects::ImportErrorFilter.filter_message(failure.exception_message.truncate(72)) end - expose :exception_class - expose :correlation_id_value - expose :created_at - expose :pipeline_class - expose :pipeline_step + expose :exception_class, documentation: { type: 'string', example: 'Exception' } + expose :correlation_id_value, documentation: { type: 'string', example: 'dfcf583058ed4508e4c7c617bd7f0edd' } + expose :created_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :pipeline_class, documentation: { + type: 'string', example: 'BulkImports::Groups::Pipelines::GroupPipeline' + } + expose :pipeline_step, documentation: { type: 'string', example: 'extractor' } end end end diff --git a/lib/api/entities/bulk_imports/export_status.rb b/lib/api/entities/bulk_imports/export_status.rb index c9c7f34a16a..fee983c6fd8 100644 --- a/lib/api/entities/bulk_imports/export_status.rb +++ b/lib/api/entities/bulk_imports/export_status.rb @@ -4,10 +4,10 @@ module API module Entities module BulkImports class ExportStatus < Grape::Entity - expose :relation - expose :status - expose :error - expose :updated_at + expose :relation, documentation: { type: 'string', example: 'issues' } + expose :status, documentation: { type: 'string', example: 'started', values: %w[started finished failed] } + expose :error, documentation: { type: 'string', example: 'Error message' } + expose :updated_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } end end end diff --git a/lib/api/entities/ci/job.rb b/lib/api/entities/ci/job.rb index cf87684ce55..d9e6b7eed75 100644 --- a/lib/api/entities/ci/job.rb +++ b/lib/api/entities/ci/job.rb @@ -6,10 +6,17 @@ module API class Job < JobBasic # artifacts_file is included in job_artifacts, but kept for backward compatibility (remove in api/v5) expose :artifacts_file, using: ::API::Entities::Ci::JobArtifactFile, if: -> (job, opts) { job.artifacts? } - expose :job_artifacts, as: :artifacts, using: ::API::Entities::Ci::JobArtifact + expose :job_artifacts, as: :artifacts, + using: ::API::Entities::Ci::JobArtifact, + documentation: { is_array: true } expose :runner, with: ::API::Entities::Ci::Runner - expose :artifacts_expire_at - expose :tag_list do |job| + expose :artifacts_expire_at, + documentation: { type: 'dateTime', example: '2016-01-19T09:05:50.355Z' } + + expose( + :tag_list, + documentation: { type: 'string', is_array: true, example: ['ubuntu18', 'docker runner'] } + ) do |job| job.tags.map(&:name).sort end end diff --git a/lib/api/entities/ci/job_artifact.rb b/lib/api/entities/ci/job_artifact.rb index 9e504aee383..8276c0f4073 100644 --- a/lib/api/entities/ci/job_artifact.rb +++ b/lib/api/entities/ci/job_artifact.rb @@ -4,7 +4,12 @@ module API module Entities module Ci class JobArtifact < Grape::Entity - expose :file_type, :size, :filename, :file_format + expose :file_type, + documentation: { type: 'string', values: ::Ci::JobArtifact.file_types.keys, example: 'archive' } + expose :size, documentation: { type: 'integer', example: 1000 } + expose :filename, documentation: { type: 'string', example: 'artifacts.zip' } + expose :file_format, + documentation: { type: 'string', values: ::Ci::JobArtifact.file_formats.keys, example: 'zip' } end end end diff --git a/lib/api/entities/ci/job_artifact_file.rb b/lib/api/entities/ci/job_artifact_file.rb index 418eb408ab6..0266f99cd6d 100644 --- a/lib/api/entities/ci/job_artifact_file.rb +++ b/lib/api/entities/ci/job_artifact_file.rb @@ -4,8 +4,8 @@ module API module Entities module Ci class JobArtifactFile < Grape::Entity - expose :filename - expose :cached_size, as: :size + expose :filename, documentation: { type: 'string', example: 'artifacts.zip' } + expose :cached_size, as: :size, documentation: { type: 'integer', example: 1000 } end end end diff --git a/lib/api/entities/ci/job_basic.rb b/lib/api/entities/ci/job_basic.rb index fb975475cf5..3cbb8aad313 100644 --- a/lib/api/entities/ci/job_basic.rb +++ b/lib/api/entities/ci/job_basic.rb @@ -4,23 +4,36 @@ module API module Entities module Ci class JobBasic < Grape::Entity - expose :id, :status, :stage, :name, :ref, :tag, :coverage, :allow_failure - expose :created_at, :started_at, :finished_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :status, documentation: { type: 'string', example: 'waiting_for_resource' } + expose :stage, documentation: { type: 'string', example: 'deploy' } + expose :name, documentation: { type: 'string', example: 'deploy_to_production' } + expose :ref, documentation: { type: 'string', example: 'main' } + expose :tag, documentation: { type: 'boolean' } + expose :coverage, documentation: { type: 'number', format: 'float', example: 98.29 } + expose :allow_failure, documentation: { type: 'boolean' } + expose :created_at, documentation: { type: 'dateTime', example: '2015-12-24T15:51:21.880Z' } + expose :started_at, documentation: { type: 'dateTime', example: '2015-12-24T17:54:30.733Z' } + expose :finished_at, documentation: { type: 'dateTime', example: '2015-12-24T17:54:31.198Z' } expose :duration, - documentation: { type: 'Floating', desc: 'Time spent running' } + documentation: { type: 'number', format: 'float', desc: 'Time spent running', example: 0.465 } expose :queued_duration, - documentation: { type: 'Floating', desc: 'Time spent enqueued' } + documentation: { type: 'number', format: 'float', desc: 'Time spent enqueued', example: 0.123 } expose :user, with: ::API::Entities::User expose :commit, with: ::API::Entities::Commit expose :pipeline, with: ::API::Entities::Ci::PipelineBasic - expose :failure_reason, if: -> (job) { job.failed? } + expose :failure_reason, + documentation: { type: 'string', example: 'script_failure' }, if: -> (job) { job.failed? } - expose :web_url do |job, _options| + expose( + :web_url, + documentation: { type: 'string', example: 'https://example.com/foo/bar/-/jobs/1' } + ) do |job, _options| Gitlab::Routing.url_helpers.project_job_url(job.project, job) end expose :project do - expose :ci_job_token_scope_enabled do |job| + expose :ci_job_token_scope_enabled, documentation: { type: 'string', example: false } do |job| job.project.ci_outbound_job_token_scope_enabled? end end diff --git a/lib/api/entities/ci/lint/result.rb b/lib/api/entities/ci/lint/result.rb index b44a6e13463..698b02d3b4a 100644 --- a/lib/api/entities/ci/lint/result.rb +++ b/lib/api/entities/ci/lint/result.rb @@ -5,12 +5,17 @@ module API module Ci module Lint class Result < Grape::Entity - expose :valid?, as: :valid - expose :errors - expose :warnings - expose :merged_yaml - expose :includes - expose :jobs, if: -> (result, options) { options[:include_jobs] } + expose :valid?, as: :valid, documentation: { type: 'boolean' } + expose :errors, documentation: { is_array: true, type: 'string', + example: 'variables config should be a hash of key value pairs' } + expose :warnings, documentation: { is_array: true, type: 'string', + example: 'jobs:job may allow multiple pipelines ...' } + expose :merged_yaml, documentation: { type: 'string', example: '---\n:another_test:\n :stage: test\n + :script: echo 2\n:test:\n :stage: test\n :script: echo 1\n' } + expose :includes, documentation: { is_array: true, type: 'object', + example: '{ "blob": "https://gitlab.com/root/example-project/-/blob/...' } + expose :jobs, if: -> (result, options) { options[:include_jobs] }, + documentation: { is_array: true, type: 'object', example: '{ "name": "test: .... }' } end end end diff --git a/lib/api/entities/ci/pipeline.rb b/lib/api/entities/ci/pipeline.rb index a8033a21044..7631cf60dbd 100644 --- a/lib/api/entities/ci/pipeline.rb +++ b/lib/api/entities/ci/pipeline.rb @@ -4,13 +4,21 @@ module API module Entities module Ci class Pipeline < PipelineBasic - expose :before_sha, :tag, :yaml_errors + expose :before_sha, documentation: { type: 'string', example: 'a91957a858320c0e17f3a0eca7cfacbff50ea29a' } + expose :tag, documentation: { type: 'boolean', example: false } + expose :yaml_errors, documentation: { type: 'string', example: "widgets:build: needs 'widgets:test'" } expose :user, with: Entities::UserBasic - expose :created_at, :updated_at, :started_at, :finished_at, :committed_at - expose :duration - expose :queued_duration - expose :coverage do |pipeline| + expose :created_at, documentation: { type: 'dateTime', example: '2015-12-24T15:51:21.880Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2015-12-24T17:54:31.198Z' } + expose :started_at, documentation: { type: 'dateTime', example: '2015-12-24T17:54:30.733Z' } + expose :finished_at, documentation: { type: 'dateTime', example: '2015-12-24T17:54:31.198Z' } + expose :committed_at, documentation: { type: 'dateTime', example: '2015-12-24T15:51:21.880Z' } + expose :duration, + documentation: { type: 'integer', desc: 'Time spent running in seconds', example: 127 } + expose :queued_duration, + documentation: { type: 'integer', desc: 'Time spent enqueued in seconds', example: 63 } + expose :coverage, documentation: { type: 'number', format: 'float', example: 98.29 } do |pipeline| pipeline.present.coverage end expose :detailed_status, using: DetailedStatusEntity do |pipeline, options| diff --git a/lib/api/entities/ci/pipeline_basic.rb b/lib/api/entities/ci/pipeline_basic.rb index a2a5a98920a..6d82cca1bf1 100644 --- a/lib/api/entities/ci/pipeline_basic.rb +++ b/lib/api/entities/ci/pipeline_basic.rb @@ -4,10 +4,21 @@ module API module Entities module Ci class PipelineBasic < Grape::Entity - expose :id, :iid, :project_id, :sha, :ref, :status, :source - expose :created_at, :updated_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :iid, documentation: { type: 'integer', example: 2 } + expose :project_id, documentation: { type: 'integer', example: 3 } + expose :sha, documentation: { type: 'string', example: '0ec9e58fdfca6cdd6652c083c9edb53abc0bad52' } + expose :ref, documentation: { type: 'string', example: 'feature-branch' } + expose :status, documentation: { type: 'string', example: 'success' } + expose :source, documentation: { type: 'string', example: 'push' } + expose :created_at, documentation: { type: 'dateTime', example: '2022-10-21T16:49:48.000+02:00' } + expose :updated_at, documentation: { type: 'dateTime', example: '2022-10-21T16:49:48.000+02:00' } - expose :web_url do |pipeline, _options| + expose :web_url, + documentation: { + type: 'string', + example: 'https://gitlab.example.com/gitlab-org/gitlab-foss/-/pipelines/61' + } do |pipeline, _options| Gitlab::Routing.url_helpers.project_pipeline_url(pipeline.project, pipeline) end end diff --git a/lib/api/entities/ci/pipeline_schedule.rb b/lib/api/entities/ci/pipeline_schedule.rb index f1596b7d285..58496bded03 100644 --- a/lib/api/entities/ci/pipeline_schedule.rb +++ b/lib/api/entities/ci/pipeline_schedule.rb @@ -4,9 +4,15 @@ module API module Entities module Ci class PipelineSchedule < Grape::Entity - expose :id - expose :description, :ref, :cron, :cron_timezone, :next_run_at, :active - expose :created_at, :updated_at + expose :id, documentation: { type: 'integer', example: 13 } + expose :description, documentation: { type: 'string', example: 'Test schedule pipeline' } + expose :ref, documentation: { type: 'string', example: 'develop' } + expose :cron, documentation: { type: 'string', example: '* * * * *' } + expose :cron_timezone, documentation: { type: 'string', example: 'Asia/Tokyo' } + expose :next_run_at, documentation: { type: 'dateTime', example: '2017-05-19T13:41:00.000Z' } + expose :active, documentation: { type: 'boolean', example: true } + expose :created_at, documentation: { type: 'dateTime', example: '2017-05-19T13:31:08.849Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2017-05-19T13:40:17.727Z' } expose :owner, using: ::API::Entities::UserBasic end end diff --git a/lib/api/entities/ci/resource_group.rb b/lib/api/entities/ci/resource_group.rb index 0afadfa9e2a..c14e32d32b1 100644 --- a/lib/api/entities/ci/resource_group.rb +++ b/lib/api/entities/ci/resource_group.rb @@ -4,7 +4,11 @@ module API module Entities module Ci class ResourceGroup < Grape::Entity - expose :id, :key, :process_mode, :created_at, :updated_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :key, documentation: { type: 'string', example: 'production' } + expose :process_mode, documentation: { type: 'string', example: 'unordered' } + expose :created_at, documentation: { type: 'dateTime', example: '2021-09-01T08:04:59.650Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2021-09-01T08:04:59.650Z' } end end end diff --git a/lib/api/entities/ci/runner.rb b/lib/api/entities/ci/runner.rb index f034eb5c94c..9361709b6ed 100644 --- a/lib/api/entities/ci/runner.rb +++ b/lib/api/entities/ci/runner.rb @@ -4,20 +4,22 @@ module API module Entities module Ci class Runner < Grape::Entity - expose :id - expose :description - expose :ip_address - expose :active # TODO Remove in v5 in favor of `paused` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/375709 - expose :paused do |runner| + expose :id, documentation: { type: 'integer', example: 8 } + expose :description, documentation: { type: 'string', example: 'test-1-20150125' } + expose :ip_address, documentation: { type: 'string', example: '127.0.0.1' } + # TODO Remove in v5 in favor of `paused` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/375709 + expose :active, documentation: { type: 'boolean', example: true } + expose :paused, documentation: { type: 'boolean', example: false } do |runner| !runner.active end - expose :instance_type?, as: :is_shared - expose :runner_type - expose :name - expose :online?, as: :online + expose :instance_type?, as: :is_shared, documentation: { type: 'boolean', example: true } + expose :runner_type, + documentation: { type: 'string', values: ::Ci::Runner.runner_types.keys, example: 'instance_type' } + expose :name, documentation: { type: 'string', example: 'test' } + expose :online?, as: :online, documentation: { type: 'boolean', example: true } # DEPRECATED # TODO Remove in v5 in favor of `status` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/375709 - expose :deprecated_rest_status, as: :status + expose :deprecated_rest_status, as: :status, documentation: { type: 'string', example: 'online' } end end end diff --git a/lib/api/entities/ci/secure_file.rb b/lib/api/entities/ci/secure_file.rb index 639615e5779..d957e4488fd 100644 --- a/lib/api/entities/ci/secure_file.rb +++ b/lib/api/entities/ci/secure_file.rb @@ -9,6 +9,8 @@ module API expose :checksum expose :checksum_algorithm expose :created_at + expose :expires_at + expose :metadata end end end diff --git a/lib/api/entities/ci/variable.rb b/lib/api/entities/ci/variable.rb index f4d5248245a..47597cb77be 100644 --- a/lib/api/entities/ci/variable.rb +++ b/lib/api/entities/ci/variable.rb @@ -4,10 +4,16 @@ module API module Entities module Ci class Variable < Grape::Entity - expose :variable_type, :key, :value - expose :protected?, as: :protected, if: -> (entity, _) { entity.respond_to?(:protected?) } - expose :masked?, as: :masked, if: -> (entity, _) { entity.respond_to?(:masked?) } - expose :environment_scope, if: -> (entity, _) { entity.respond_to?(:environment_scope) } + expose :variable_type, documentation: { type: 'string', example: 'env_var' } + expose :key, documentation: { type: 'string', example: 'TEST_VARIABLE_1' } + expose :value, documentation: { type: 'string', example: 'TEST_1' } + expose :protected?, as: :protected, if: -> (entity, _) { entity.respond_to?(:protected?) }, + documentation: { type: 'boolean' } + expose :masked?, as: :masked, if: -> (entity, _) { entity.respond_to?(:masked?) }, + documentation: { type: 'boolean' } + expose :raw?, as: :raw, if: -> (entity, _) { entity.respond_to?(:raw?) }, documentation: { type: 'boolean' } + expose :environment_scope, if: -> (entity, _) { entity.respond_to?(:environment_scope) }, + documentation: { type: 'string', example: '*' } end end end diff --git a/lib/api/entities/commit.rb b/lib/api/entities/commit.rb index 6cd180cd584..ab1f51289d7 100644 --- a/lib/api/entities/commit.rb +++ b/lib/api/entities/commit.rb @@ -3,15 +3,26 @@ module API module Entities class Commit < Grape::Entity - expose :id, :short_id, :created_at - expose :parent_ids - expose :full_title, as: :title - expose :safe_message, as: :message - expose :author_name, :author_email, :authored_date - expose :committer_name, :committer_email, :committed_date - expose :trailers + expose :id, documentation: { type: 'string', example: '2695effb5807a22ff3d138d593fd856244e155e7' } + expose :short_id, documentation: { type: 'string', example: '2695effb' } + expose :created_at, documentation: { type: 'dateTime', example: '2017-07-26T11:08:53.000+02:00' } + expose :parent_ids, + documentation: { type: 'string', is_array: true, example: '2a4b78934375d7f53875269ffd4f45fd83a84ebe' } + expose :full_title, as: :title, documentation: { type: 'string', example: 'Initial commit' } + expose :safe_message, as: :message, documentation: { type: 'string', example: 'Initial commit' } + expose :author_name, documentation: { type: 'string', example: 'John Smith' } + expose :author_email, documentation: { type: 'string', example: 'john@example.com' } + expose :authored_date, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :committer_name, documentation: { type: 'string', example: 'Jack Smith' } + expose :committer_email, documentation: { type: 'string', example: 'jack@example.com' } + expose :committed_date, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :trailers, documentation: { type: 'object', example: '{ "Merged-By": "Jane Doe janedoe@gitlab.com" }' } - expose :web_url do |commit, _options| + expose :web_url, + documentation: { + type: 'string', + example: 'https://gitlab.example.com/janedoe/gitlab-foss/-/commit/ed899a2f4b50b4370feeea94676502b42383c746' + } do |commit, _options| c = commit c = c.__subject__ if c.is_a?(Gitlab::View::Presenter::Base) Gitlab::UrlBuilder.build(c) diff --git a/lib/api/entities/commit_detail.rb b/lib/api/entities/commit_detail.rb index cc529639359..428c53f7fe3 100644 --- a/lib/api/entities/commit_detail.rb +++ b/lib/api/entities/commit_detail.rb @@ -6,10 +6,10 @@ module API include ::API::Helpers::Presentable expose :stats, using: Entities::CommitStats, if: :include_stats - expose :status_for, as: :status - expose :project_id + expose :status_for, as: :status, documentation: { type: 'string', example: 'success' } + expose :project_id, documentation: { type: 'integer', example: 1 } - expose :last_pipeline do |commit, options| + expose :last_pipeline, documentation: { type: ::API::Entities::Ci::PipelineBasic.to_s } do |commit, options| pipeline = commit.last_pipeline if can_read_pipeline? ::API::Entities::Ci::PipelineBasic.represent(pipeline, options) end diff --git a/lib/api/entities/commit_note.rb b/lib/api/entities/commit_note.rb index fe91712b48d..0632dc467b8 100644 --- a/lib/api/entities/commit_note.rb +++ b/lib/api/entities/commit_note.rb @@ -3,12 +3,22 @@ module API module Entities class CommitNote < Grape::Entity - expose :note - expose(:path) { |note| note.diff_file.try(:file_path) if note.diff_note? } - expose(:line) { |note| note.diff_line.try(:line) if note.diff_note? } - expose(:line_type) { |note| note.diff_line.try(:type) if note.diff_note? } + expose :note, documentation: { type: 'string', example: 'this doc is really nice' } + + expose :path, documentation: { type: 'string', example: 'README.md' } do |note| + note.diff_file.try(:file_path) if note.diff_note? + end + + expose :line, documentation: { type: 'integer', example: 11 } do |note| + note.diff_line.try(:line) if note.diff_note? + end + + expose :line_type, documentation: { type: 'string', example: 'new' } do |note| + note.diff_line.try(:type) if note.diff_note? + end + expose :author, using: Entities::UserBasic - expose :created_at + expose :created_at, documentation: { type: 'dateTime', example: '2016-01-19T09:44:55.600Z' } end end end diff --git a/lib/api/entities/commit_signature.rb b/lib/api/entities/commit_signature.rb index 0d8e977a9f5..9430dd5e2a2 100644 --- a/lib/api/entities/commit_signature.rb +++ b/lib/api/entities/commit_signature.rb @@ -3,7 +3,7 @@ module API module Entities class CommitSignature < Grape::Entity - expose :signature_type + expose :signature_type, documentation: { type: 'string', example: 'PGP' } expose :signature, merge: true do |commit, options| if commit.signature.is_a?(::CommitSignatures::GpgSignature) || commit.raw_commit_from_rugged? @@ -13,7 +13,7 @@ module API end end - expose :commit_source do |commit, _| + expose :commit_source, documentation: { type: 'string', example: 'gitaly' } do |commit, _| commit.raw_commit_from_rugged? ? "rugged" : "gitaly" end diff --git a/lib/api/entities/commit_stats.rb b/lib/api/entities/commit_stats.rb index d9ba99c8eb0..e07483e5d97 100644 --- a/lib/api/entities/commit_stats.rb +++ b/lib/api/entities/commit_stats.rb @@ -3,7 +3,9 @@ module API module Entities class CommitStats < Grape::Entity - expose :additions, :deletions, :total + expose :additions, documentation: { type: 'integer', example: 1 } + expose :deletions, documentation: { type: 'integer', example: 0 } + expose :total, documentation: { type: 'integer', example: 1 } end end end diff --git a/lib/api/entities/commit_status.rb b/lib/api/entities/commit_status.rb index 61b8bf89cfe..df6a41895ff 100644 --- a/lib/api/entities/commit_status.rb +++ b/lib/api/entities/commit_status.rb @@ -3,8 +3,22 @@ module API module Entities class CommitStatus < Grape::Entity - expose :id, :sha, :ref, :status, :name, :target_url, :description, - :created_at, :started_at, :finished_at, :allow_failure, :coverage + expose :id, documentation: { type: 'integer', example: 93 } + expose :sha, documentation: { type: 'string', example: '18f3e63d05582537db6d183d9d557be09e1f90c8' } + expose :ref, documentation: { type: 'string', example: 'develop' } + expose :status, documentation: { type: 'string', example: 'success' } + expose :name, documentation: { type: 'string', example: 'default' } + expose :target_url, documentation: { + type: 'string', + example: 'https://gitlab.example.com/janedoe/gitlab-foss/builds/91' + } + expose :description, documentation: { type: 'string' } + expose :created_at, documentation: { type: 'dateTime', example: '2016-01-19T09:05:50.355Z' } + expose :started_at, documentation: { type: 'dateTime', example: '2016-01-20T08:40:25.832Z' } + expose :finished_at, documentation: { type: 'dateTime', example: '2016-01-21T08:40:25.832Z' } + expose :allow_failure, documentation: { type: 'boolean', example: false } + expose :coverage, documentation: { type: 'number', format: 'float', example: 98.29 } + expose :author, using: Entities::UserBasic end end diff --git a/lib/api/entities/compare.rb b/lib/api/entities/compare.rb index 75a36d9bb01..92066868d3c 100644 --- a/lib/api/entities/compare.rb +++ b/lib/api/entities/compare.rb @@ -7,21 +7,24 @@ module API compare.commits.last end - expose :commits, using: Entities::Commit do |compare, _| + expose :commits, documentation: { is_array: true }, using: Entities::Commit do |compare, _| compare.commits end - expose :diffs, using: Entities::Diff do |compare, _| + expose :diffs, documentation: { is_array: true }, using: Entities::Diff do |compare, _| compare.diffs.diffs.to_a end - expose :compare_timeout do |compare, _| + expose :compare_timeout, documentation: { type: 'boolean' } do |compare, _| compare.diffs.diffs.overflow? end - expose :same, as: :compare_same_ref + expose :same, as: :compare_same_ref, documentation: { type: 'boolean' } - expose :web_url do |compare, _| + expose :web_url, + documentation: { + example: "https://gitlab.example.com/gitlab/gitlab-foss/-/compare/main...feature" + } do |compare, _| Gitlab::UrlBuilder.build(compare) end end diff --git a/lib/api/entities/container_registry.rb b/lib/api/entities/container_registry.rb index 2fdfac40c32..d12c8142e69 100644 --- a/lib/api/entities/container_registry.rb +++ b/lib/api/entities/container_registry.rb @@ -12,13 +12,13 @@ module API class Repository < Grape::Entity include ::API::Helpers::RelatedResourcesHelpers - expose :id - expose :name - expose :path - expose :project_id - expose :location - expose :created_at - expose :expiration_policy_started_at, as: :cleanup_policy_started_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :name, documentation: { type: 'string', example: 'releases' } + expose :path, documentation: { type: 'string', example: 'group/project/releases' } + expose :project_id, documentation: { type: 'integer', example: 9 } + expose :location, documentation: { type: 'string', example: 'gitlab.example.com/group/project/releases' } + expose :created_at, documentation: { type: 'dateTime', example: '2019-01-10T13:39:08.229Z' } + expose :expiration_policy_started_at, as: :cleanup_policy_started_at, documentation: { type: 'dateTime', example: '2020-08-17T03:12:35.489Z' } expose :tags_count, if: -> (_, options) { options[:tags_count] } expose :tags, using: Tag, if: -> (_, options) { options[:tags] } expose :delete_api_path, if: ->(object, options) { Ability.allowed?(options[:user], :admin_container_image, object) } diff --git a/lib/api/entities/contributor.rb b/lib/api/entities/contributor.rb index 8763822b674..4fab953f0f6 100644 --- a/lib/api/entities/contributor.rb +++ b/lib/api/entities/contributor.rb @@ -3,7 +3,11 @@ module API module Entities class Contributor < Grape::Entity - expose :name, :email, :commits, :additions, :deletions + expose :name, documentation: { example: 'John Doe' } + expose :email, documentation: { example: 'johndoe@example.com' } + expose :commits, documentation: { type: 'integer', example: 117 } + expose :additions, documentation: { type: 'integer', example: 3 } + expose :deletions, documentation: { type: 'integer', example: 5 } end end end diff --git a/lib/api/entities/custom_attribute.rb b/lib/api/entities/custom_attribute.rb index f949b709517..883b572ac75 100644 --- a/lib/api/entities/custom_attribute.rb +++ b/lib/api/entities/custom_attribute.rb @@ -3,8 +3,8 @@ module API module Entities class CustomAttribute < Grape::Entity - expose :key - expose :value + expose :key, documentation: { type: 'string', example: 'foo' } + expose :value, documentation: { type: 'string', example: 'bar' } end end end diff --git a/lib/api/entities/deploy_key.rb b/lib/api/entities/deploy_key.rb index 2c9c33549a1..1bcd06f2c88 100644 --- a/lib/api/entities/deploy_key.rb +++ b/lib/api/entities/deploy_key.rb @@ -3,9 +3,15 @@ module API module Entities class DeployKey < Entities::SSHKey - expose :key - expose :fingerprint, if: ->(key, _) { key.fingerprint.present? } - expose :fingerprint_sha256 + expose :key, + documentation: { type: 'string', example: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDNJAkI3Wdf0r13c8a5pEExB2YowPWCSVzfZV22pNBc1CuEbyYLHpUyaD0GwpGvFdx2aP7lMEk35k6Rz3ccBF6jRaVJyhsn5VNnW92PMpBJ/P1UebhXwsFHdQf5rTt082cSxWuk61kGWRQtk4ozt/J2DF/dIUVaLvc+z4HomT41fQ==' } + + expose :fingerprint, + documentation: { type: 'string', example: '4a:9d:64:15:ed:3a:e6:07:6e:89:36:b3:3b:03:05:d9' }, + if: ->(key, _) { key.fingerprint.present? } + + expose :fingerprint_sha256, + documentation: { type: 'string', example: 'SHA256:Jrs3LD1Ji30xNLtTVf9NDCj7kkBgPBb2pjvTZ3HfIgU' } expose :projects_with_write_access, using: Entities::ProjectIdentity, if: -> (_, options) { options[:include_projects_with_write_access] } end diff --git a/lib/api/entities/deploy_keys_project.rb b/lib/api/entities/deploy_keys_project.rb index 12a86fbdf8e..4501af88067 100644 --- a/lib/api/entities/deploy_keys_project.rb +++ b/lib/api/entities/deploy_keys_project.rb @@ -4,7 +4,7 @@ module API module Entities class DeployKeysProject < Grape::Entity expose :deploy_key, merge: true, using: Entities::DeployKey - expose :can_push + expose :can_push, documentation: { type: 'boolean' } end end end diff --git a/lib/api/entities/deploy_token.rb b/lib/api/entities/deploy_token.rb index daee104ba6b..9861467e35d 100644 --- a/lib/api/entities/deploy_token.rb +++ b/lib/api/entities/deploy_token.rb @@ -4,8 +4,13 @@ module API module Entities class DeployToken < Grape::Entity # exposing :token is a security risk and should be avoided - expose :id, :name, :username, :expires_at, :scopes, :revoked - expose :expired?, as: :expired + expose :id, documentation: { type: 'integer', example: 1 } + expose :name, documentation: { type: 'string', example: 'MyToken' } + expose :username, documentation: { type: 'string', example: 'gitlab+deploy-token-1' } + expose :expires_at, documentation: { type: 'dateTime', example: '2020-02-14T00:00:00.000Z' } + expose :scopes, documentation: { type: 'array', example: ['read_repository'] } + expose :revoked, documentation: { type: 'boolean' } + expose :expired?, documentation: { type: 'boolean' }, as: :expired end end end diff --git a/lib/api/entities/deploy_token_with_token.rb b/lib/api/entities/deploy_token_with_token.rb index 11efe3720fa..a96051e1403 100644 --- a/lib/api/entities/deploy_token_with_token.rb +++ b/lib/api/entities/deploy_token_with_token.rb @@ -3,7 +3,7 @@ module API module Entities class DeployTokenWithToken < Entities::DeployToken - expose :token + expose :token, documentation: { type: 'string', example: 'jMRvtPNxrn3crTAGukpZ' } end end end diff --git a/lib/api/entities/deployment.rb b/lib/api/entities/deployment.rb index 4e3a4c289d9..426e92e7723 100644 --- a/lib/api/entities/deployment.rb +++ b/lib/api/entities/deployment.rb @@ -3,11 +3,16 @@ module API module Entities class Deployment < Grape::Entity - expose :id, :iid, :ref, :sha, :created_at, :updated_at + expose :id, documentation: { type: 'integer', example: 41 } + expose :iid, documentation: { type: 'integer', example: 1 } + expose :ref, documentation: { type: 'string', example: 'main' } + expose :sha, documentation: { type: 'string', example: '99d03678b90d914dbb1b109132516d71a4a03ea8' } + expose :created_at, documentation: { type: 'dateTime', example: '2016-08-11T11:32:35.444Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2016-08-11T11:32:35.444Z' } expose :user, using: Entities::UserBasic expose :environment, using: Entities::EnvironmentBasic expose :deployable, using: Entities::Ci::Job - expose :status + expose :status, documentation: { type: 'string', example: 'created' } end end end diff --git a/lib/api/entities/diff.rb b/lib/api/entities/diff.rb index e92bc5d6b68..e9650f07f00 100644 --- a/lib/api/entities/diff.rb +++ b/lib/api/entities/diff.rb @@ -3,11 +3,17 @@ module API module Entities class Diff < Grape::Entity - expose :old_path, :new_path, :a_mode, :b_mode - expose :new_file?, as: :new_file - expose :renamed_file?, as: :renamed_file - expose :deleted_file?, as: :deleted_file - expose :json_safe_diff, as: :diff + expose :json_safe_diff, as: :diff, documentation: { + type: 'string', + example: '--- a/doc/update/5.4-to-6.0.md\n+++ b/doc/update/5.4-to-6.0.md\n@@ -71,6 +71,8 @@\n...' + } + expose :new_path, documentation: { type: 'string', example: 'doc/update/5.4-to-6.0.md' } + expose :old_path, documentation: { type: 'string', example: 'doc/update/5.4-to-6.0.md' } + expose :a_mode, documentation: { type: 'string', example: '100755' } + expose :b_mode, documentation: { type: 'string', example: '100644' } + expose :new_file?, as: :new_file, documentation: { type: 'boolean' } + expose :renamed_file?, as: :renamed_file, documentation: { type: 'boolean' } + expose :deleted_file?, as: :deleted_file, documentation: { type: 'boolean' } end end end diff --git a/lib/api/entities/entity_helpers.rb b/lib/api/entities/entity_helpers.rb index 3a68044ad35..6fb04bb8ad6 100644 --- a/lib/api/entities/entity_helpers.rb +++ b/lib/api/entities/entity_helpers.rb @@ -11,8 +11,8 @@ module API ->(obj, opts) { Ability.allowed?(opts[:user], "destroy_#{attr}".to_sym, yield(obj)) } end - def expose_restricted(attr, &block) - expose attr, if: can_read(attr, &block) + def expose_restricted(attr, documentation: {}, &block) + expose attr, documentation: documentation, if: can_read(attr, &block) end end end diff --git a/lib/api/entities/environment.rb b/lib/api/entities/environment.rb index 3b6ed94c3f1..dc9911d5acb 100644 --- a/lib/api/entities/environment.rb +++ b/lib/api/entities/environment.rb @@ -5,10 +5,10 @@ module API class Environment < Entities::EnvironmentBasic include RequestAwareEntity - expose :tier + expose :tier, documentation: { type: 'string', example: 'development' } expose :project, using: Entities::BasicProjectDetails expose :last_deployment, using: Entities::Deployment, if: { last_deployment: true } - expose :state + expose :state, documentation: { type: 'string', example: 'available' } end end end diff --git a/lib/api/entities/environment_basic.rb b/lib/api/entities/environment_basic.rb index d9894eac147..1b4a9371820 100644 --- a/lib/api/entities/environment_basic.rb +++ b/lib/api/entities/environment_basic.rb @@ -3,7 +3,12 @@ module API module Entities class EnvironmentBasic < Grape::Entity - expose :id, :name, :slug, :external_url, :created_at, :updated_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :name, documentation: { type: 'string', example: 'deploy' } + expose :slug, documentation: { type: 'string', example: 'deploy' } + expose :external_url, documentation: { type: 'string', example: 'https://deploy.gitlab.example.com' } + expose :created_at, documentation: { type: 'dateTime', example: '2019-05-25T18:55:13.252Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2019-05-25T18:55:13.252Z' } end end end diff --git a/lib/api/entities/error_tracking.rb b/lib/api/entities/error_tracking.rb index 163bda92680..5e3b983c58c 100644 --- a/lib/api/entities/error_tracking.rb +++ b/lib/api/entities/error_tracking.rb @@ -4,11 +4,11 @@ module API module Entities module ErrorTracking class ProjectSetting < Grape::Entity - expose :enabled, as: :active - expose :project_name - expose :sentry_external_url - expose :api_url - expose :integrated + expose :enabled, as: :active, documentation: { type: 'boolean' } + expose :project_name, documentation: { type: 'string', example: 'sample sentry project' } + expose :sentry_external_url, documentation: { type: 'string', example: 'https://sentry.io/myawesomeproject/project' } + expose :api_url, documentation: { type: 'string', example: 'https://sentry.io/api/0/projects/myawesomeproject/project' } + expose :integrated, documentation: { type: 'boolean' } def integrated return false unless ::Feature.enabled?(:integrated_error_tracking, object.project) @@ -18,10 +18,10 @@ module API end class ClientKey < Grape::Entity - expose :id - expose :active - expose :public_key - expose :sentry_dsn + expose :id, documentation: { type: 'integer', example: 1 } + expose :active, documentation: { type: 'boolean' } + expose :public_key, documentation: { type: 'string', example: 'glet_aa77551d849c083f76d0bc545ed053a3' } + expose :sentry_dsn, documentation: { type: 'string', example: 'https://glet_aa77551d849c083f76d0bc545ed053a3@gitlab.example.com/api/v4/error_tracking/collector/5' } end end end diff --git a/lib/api/entities/feature.rb b/lib/api/entities/feature.rb index d1151849cd7..48dd5a22a7e 100644 --- a/lib/api/entities/feature.rb +++ b/lib/api/entities/feature.rb @@ -3,8 +3,8 @@ module API module Entities class Feature < Grape::Entity - expose :name - expose :state + expose :name, documentation: { type: 'string', example: 'experimental_feature' } + expose :state, documentation: { type: 'string', example: 'off' } expose :gates, using: Entities::FeatureGate do |model| model.gates.map do |gate| value = model.gate_values[gate.key] diff --git a/lib/api/entities/feature_flag.rb b/lib/api/entities/feature_flag.rb index 9dec3873504..273307357a2 100644 --- a/lib/api/entities/feature_flag.rb +++ b/lib/api/entities/feature_flag.rb @@ -3,12 +3,12 @@ module API module Entities class FeatureFlag < Grape::Entity - expose :name - expose :description - expose :active - expose :version - expose :created_at - expose :updated_at + expose :name, documentation: { type: 'string', example: 'merge_train' } + expose :description, documentation: { type: 'string', example: 'merge train feature flag' } + expose :active, documentation: { type: 'boolean' } + expose :version, documentation: { type: 'string', example: 'new_version_flag' } + expose :created_at, documentation: { type: 'dateTime', example: '2019-11-04T08:13:51.423Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2019-11-04T08:13:51.423Z' } expose :scopes do |_ff| [] end diff --git a/lib/api/entities/feature_flag/scope.rb b/lib/api/entities/feature_flag/scope.rb index 906fe718257..e29793c250a 100644 --- a/lib/api/entities/feature_flag/scope.rb +++ b/lib/api/entities/feature_flag/scope.rb @@ -4,8 +4,8 @@ module API module Entities class FeatureFlag < Grape::Entity class Scope < Grape::Entity - expose :id - expose :environment_scope + expose :id, documentation: { type: 'integer', example: 1 } + expose :environment_scope, documentation: { type: 'string', example: 'production' } end end end diff --git a/lib/api/entities/feature_flag/strategy.rb b/lib/api/entities/feature_flag/strategy.rb index 32699be0ee3..62178420370 100644 --- a/lib/api/entities/feature_flag/strategy.rb +++ b/lib/api/entities/feature_flag/strategy.rb @@ -4,9 +4,9 @@ module API module Entities class FeatureFlag < Grape::Entity class Strategy < Grape::Entity - expose :id - expose :name - expose :parameters + expose :id, documentation: { type: 'integer', example: 1 } + expose :name, documentation: { type: 'string', example: 'userWithId' } + expose :parameters, documentation: { type: 'string', example: '{"userIds": "user1"}' } expose :scopes, using: FeatureFlag::Scope end end diff --git a/lib/api/entities/feature_flag/user_list.rb b/lib/api/entities/feature_flag/user_list.rb index bc8b12ea22e..efb3261658a 100644 --- a/lib/api/entities/feature_flag/user_list.rb +++ b/lib/api/entities/feature_flag/user_list.rb @@ -6,13 +6,13 @@ module API class UserList < Grape::Entity include RequestAwareEntity - expose :id - expose :iid - expose :project_id - expose :created_at - expose :updated_at - expose :name - expose :user_xids + expose :id, documentation: { type: 'integer', example: 1 } + expose :iid, documentation: { type: 'integer', example: 1 } + expose :project_id, documentation: { type: 'integer', example: 2 } + expose :created_at, documentation: { type: 'dateTime', example: '2020-02-04T08:13:10.507Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2020-02-04T08:13:10.507Z' } + expose :name, documentation: { type: 'string', example: 'user_list' } + expose :user_xids, documentation: { type: 'string', example: 'user1,user2' } expose :path do |list| project_feature_flags_user_list_path(list.project, list) diff --git a/lib/api/entities/feature_gate.rb b/lib/api/entities/feature_gate.rb index bea9c9474b3..ad4702bf210 100644 --- a/lib/api/entities/feature_gate.rb +++ b/lib/api/entities/feature_gate.rb @@ -3,8 +3,8 @@ module API module Entities class FeatureGate < Grape::Entity - expose :key - expose :value + expose :key, documentation: { type: 'string', example: 'percentage_of_actors' } + expose :value, documentation: { type: 'integer', example: 34 } end end end diff --git a/lib/api/entities/freeze_period.rb b/lib/api/entities/freeze_period.rb index 9b5f08925db..d6853c544a5 100644 --- a/lib/api/entities/freeze_period.rb +++ b/lib/api/entities/freeze_period.rb @@ -3,9 +3,11 @@ module API module Entities class FreezePeriod < Grape::Entity - expose :id - expose :freeze_start, :freeze_end, :cron_timezone - expose :created_at, :updated_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :freeze_start, documentation: { type: 'string', example: '0 23 * * 5' } + expose :freeze_end, documentation: { type: 'string', example: '0 8 * * 1' } + expose :cron_timezone, documentation: { type: 'string', example: 'UTC' } + expose :created_at, :updated_at, documentation: { type: 'dateTime', example: '2020-05-15T17:03:35.702Z' } end end end diff --git a/lib/api/entities/go_module_version.rb b/lib/api/entities/go_module_version.rb index 643e25df9e0..b9dd88982dd 100644 --- a/lib/api/entities/go_module_version.rb +++ b/lib/api/entities/go_module_version.rb @@ -3,8 +3,8 @@ module API module Entities class GoModuleVersion < Grape::Entity - expose :name, as: 'Version' - expose :time, as: 'Time' + expose :name, as: 'Version', documentation: { type: 'string', example: 'v1.0.0' } + expose :time, as: 'Time', documentation: { type: 'string', example: '1617822312 -0600' } end end end diff --git a/lib/api/entities/hook.rb b/lib/api/entities/hook.rb index 95924321221..e24e201ac57 100644 --- a/lib/api/entities/hook.rb +++ b/lib/api/entities/hook.rb @@ -3,12 +3,18 @@ module API module Entities class Hook < Grape::Entity - expose :id, :url, :created_at, :push_events, :tag_push_events, :merge_requests_events, :repository_update_events - expose :enable_ssl_verification + expose :id, documentation: { type: 'string', example: 1 } + expose :url, documentation: { type: 'string', example: 'https://webhook.site' } + expose :created_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :push_events, documentation: { type: 'boolean' } + expose :tag_push_events, documentation: { type: 'boolean' } + expose :merge_requests_events, documentation: { type: 'boolean' } + expose :repository_update_events, documentation: { type: 'boolean' } + expose :enable_ssl_verification, documentation: { type: 'boolean' } - expose :alert_status - expose :disabled_until - expose :url_variables + expose :alert_status, documentation: { type: 'symbol', example: :executable } + expose :disabled_until, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :url_variables, documentation: { type: 'Hash', example: { "token" => "secr3t" }, is_array: true } def url_variables object.url_variables.keys.map { { key: _1 } } diff --git a/lib/api/entities/issuable_entity.rb b/lib/api/entities/issuable_entity.rb index e2c674c0b8b..4e70f945a48 100644 --- a/lib/api/entities/issuable_entity.rb +++ b/lib/api/entities/issuable_entity.rb @@ -3,10 +3,16 @@ module API module Entities class IssuableEntity < Grape::Entity - expose :id, :iid - expose(:project_id) { |entity| entity&.project.try(:id) } - expose :title, :description - expose :state, :created_at, :updated_at + expose :id, documentation: { type: 'integer', example: 84 } + expose :iid, documentation: { type: 'integer', example: 14 } + expose :project_id, documentation: { type: 'integer', example: 4 } do |entity| + entity&.project.try(:id) + end + expose :title, documentation: { type: 'string', example: 'Impedit et ut et dolores vero provident ullam est' } + expose :description, documentation: { type: 'string', example: 'Repellendus impedit et vel velit dignissimos.' } + expose :state, documentation: { type: 'string', example: 'closed' } + expose :created_at, documentation: { type: 'dateTime', example: '2022-08-17T12:46:35.053Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2022-11-14T17:22:01.470Z' } def presented lazy_issuable_metadata diff --git a/lib/api/entities/issue_basic.rb b/lib/api/entities/issue_basic.rb index 20f66c026e6..89fb8bbe1c0 100644 --- a/lib/api/entities/issue_basic.rb +++ b/lib/api/entities/issue_basic.rb @@ -7,10 +7,10 @@ module API item.upcase if item.respond_to?(:upcase) end - expose :closed_at + expose :closed_at, documentation: { type: 'dateTime', example: '2022-11-15T08:30:55.232Z' } expose :closed_by, using: Entities::UserBasic - expose :labels do |issue, options| + expose :labels, documentation: { type: 'string', is_array: true, example: 'bug' } do |issue, options| if options[:with_labels_details] ::API::Entities::LabelBasic.represent(issue.labels.sort_by(&:title)) else @@ -23,7 +23,7 @@ module API expose :issue_type, as: :type, format_with: :upcase, - documentation: { type: "String", desc: "One of #{::WorkItems::Type.allowed_types_for_issues.map(&:upcase)}" } + documentation: { type: 'String', example: 'ISSUE', desc: "One of #{::WorkItems::Type.allowed_types_for_issues.map(&:upcase)}" } expose :assignee, using: ::API::Entities::UserBasic do |issue| issue.assignees.first @@ -33,12 +33,12 @@ module API expose(:merge_requests_count) { |issue, options| issuable_metadata.merge_requests_count } expose(:upvotes) { |issue, options| issuable_metadata.upvotes } expose(:downvotes) { |issue, options| issuable_metadata.downvotes } - expose :due_date - expose :confidential - expose :discussion_locked - expose :issue_type + expose :due_date, documentation: { type: 'date', example: '2022-11-20' } + expose :confidential, documentation: { type: 'boolean' } + expose :discussion_locked, documentation: { type: 'boolean' } + expose :issue_type, documentation: { type: 'string', example: 'issue' } - expose :web_url do |issue| + expose :web_url, documentation: { type: 'string', example: 'http://example.com/example/example/issues/14' } do |issue| Gitlab::UrlBuilder.build(issue) end diff --git a/lib/api/entities/license.rb b/lib/api/entities/license.rb index 8ecf8a430fe..6318fec6774 100644 --- a/lib/api/entities/license.rb +++ b/lib/api/entities/license.rb @@ -4,12 +4,25 @@ module API module Entities # Serializes a Licensee::License class License < Entities::LicenseBasic - expose :popular?, as: :popular - expose(:description) { |license| license.meta['description'] } - expose(:conditions) { |license| license.meta['conditions'] } - expose(:permissions) { |license| license.meta['permissions'] } - expose(:limitations) { |license| license.meta['limitations'] } - expose :content + expose :popular?, as: :popular, documentation: { type: 'boolean' } + + expose :description, documentation: { type: 'string', example: 'A simple license' } do |license| + license.meta['description'] + end + + expose :conditions, documentation: { type: 'string', is_array: true, example: 'include-copyright' } do |license| + license.meta['conditions'] + end + + expose :permissions, documentation: { type: 'string', is_array: true, example: 'commercial-use' } do |license| + license.meta['permissions'] + end + + expose :limitations, documentation: { type: 'string', is_array: true, example: 'liability' } do |license| + license.meta['limitations'] + end + + expose :content, documentation: { type: 'string', example: 'GNU GENERAL PUBLIC LICENSE' } end end end diff --git a/lib/api/entities/license_basic.rb b/lib/api/entities/license_basic.rb index 0916738d21d..e3bb55d4104 100644 --- a/lib/api/entities/license_basic.rb +++ b/lib/api/entities/license_basic.rb @@ -4,8 +4,10 @@ module API module Entities # Serializes a Gitlab::Git::DeclaredLicense class LicenseBasic < Grape::Entity - expose :key, :name, :nickname - expose :url, as: :html_url + expose :key, documentation: { type: 'string', example: 'gpl-3.0' } + expose :name, documentation: { type: 'string', example: 'GNU General Public License v3.0' } + expose :nickname, documentation: { type: 'string', example: 'GNU GPLv3' } + expose :url, as: :html_url, documentation: { example: 'http://choosealicense.com/licenses/gpl-3.0' } # This was dropped: # https://github.com/github/choosealicense.com/commit/325806b42aa3d5b78e84120327ec877bc936dbdd#diff-66df8f1997786f7052d29010f2cbb4c66391d60d24ca624c356acc0ab986f139 diff --git a/lib/api/entities/markdown.rb b/lib/api/entities/markdown.rb new file mode 100644 index 00000000000..0fbaec4375e --- /dev/null +++ b/lib/api/entities/markdown.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module API + module Entities + class Markdown < Grape::Entity + expose :html, documentation: { type: 'string', example: '<p dir=\"auto\">Hello world!</p>"' } + end + end +end diff --git a/lib/api/entities/merge_request_approvals.rb b/lib/api/entities/merge_request_approvals.rb index 6810952b2fc..54f196e0d74 100644 --- a/lib/api/entities/merge_request_approvals.rb +++ b/lib/api/entities/merge_request_approvals.rb @@ -3,15 +3,15 @@ module API module Entities class MergeRequestApprovals < Grape::Entity - expose :user_has_approved do |merge_request, options| + expose :user_has_approved, documentation: { type: 'boolean' } do |merge_request, options| merge_request.approved_by?(options[:current_user]) end - expose :user_can_approve do |merge_request, options| + expose :user_can_approve, documentation: { type: 'boolean' } do |merge_request, options| merge_request.eligible_for_approval_by?(options[:current_user]) end - expose :approved do |merge_request| + expose :approved, documentation: { type: 'boolean' } do |merge_request| merge_request.approvals.present? end diff --git a/lib/api/entities/merge_request_basic.rb b/lib/api/entities/merge_request_basic.rb index 55d58166590..27f6e6ade06 100644 --- a/lib/api/entities/merge_request_basic.rb +++ b/lib/api/entities/merge_request_basic.rb @@ -58,6 +58,7 @@ module API merge_request.check_mergeability(async: true) unless options[:skip_merge_status_recheck] merge_request.public_merge_status end + expose :detailed_merge_status expose :diff_head_sha, as: :sha expose :merge_commit_sha expose :squash_commit_sha @@ -93,6 +94,12 @@ module API expose :task_completion_status expose :cannot_be_merged?, as: :has_conflicts expose :mergeable_discussions_state?, as: :blocking_discussions_resolved + + private + + def detailed_merge_status + ::MergeRequests::Mergeability::DetailedMergeStatusService.new(merge_request: object).execute + end end end end diff --git a/lib/api/entities/merge_request_simple.rb b/lib/api/entities/merge_request_simple.rb index f3ff4cc18a8..d5c511ad9a4 100644 --- a/lib/api/entities/merge_request_simple.rb +++ b/lib/api/entities/merge_request_simple.rb @@ -3,8 +3,11 @@ module API module Entities class MergeRequestSimple < IssuableEntity - expose :title - expose :web_url do |merge_request, options| + expose :title, documentation: { type: 'string', example: 'Test MR 1580978354' } + expose :web_url, + documentation: { + type: 'string', example: 'http://local.gitlab.test:8181/root/merge-train-race-condition/-/merge_requests/59' + } do |merge_request, options| Gitlab::UrlBuilder.build(merge_request) end end diff --git a/lib/api/entities/metadata.rb b/lib/api/entities/metadata.rb index daa491ec42a..7dfcad2ccab 100644 --- a/lib/api/entities/metadata.rb +++ b/lib/api/entities/metadata.rb @@ -3,13 +3,14 @@ module API module Entities class Metadata < Grape::Entity - expose :version - expose :revision + expose :version, documentation: { type: 'string', example: '15.2-pre' } + expose :revision, documentation: { type: 'string', example: 'c401a659d0c' } expose :kas do expose :enabled, documentation: { type: 'boolean' } - expose :externalUrl - expose :version + expose :externalUrl, documentation: { type: 'string', example: 'grpc://gitlab.example.com:8150' } + expose :version, documentation: { type: 'string', example: '15.0.0' } end + expose :enterprise, documentation: { type: 'boolean' } end end end diff --git a/lib/api/entities/metrics/dashboard/annotation.rb b/lib/api/entities/metrics/dashboard/annotation.rb index 66bd09d84f9..08d1a333259 100644 --- a/lib/api/entities/metrics/dashboard/annotation.rb +++ b/lib/api/entities/metrics/dashboard/annotation.rb @@ -5,13 +5,13 @@ module API module Metrics module Dashboard class Annotation < Grape::Entity - expose :id - expose :starting_at - expose :ending_at - expose :dashboard_path - expose :description - expose :environment_id - expose :cluster_id + expose :id, documentation: { type: 'integer', example: 4 } + expose :starting_at, documentation: { type: 'dateTime', example: '2016-04-08T03:45:40.000Z' } + expose :ending_at, documentation: { type: 'dateTime', example: '2016-08-08T09:00:00.000Z' } + expose :dashboard_path, documentation: { type: 'string', example: '.gitlab/dashboards/custom_metrics.yml' } + expose :description, documentation: { type: 'string', example: 'annotation description' } + expose :environment_id, documentation: { type: 'integer', example: 1 } + expose :cluster_id, documentation: { type: 'integer', example: 2 } end end end diff --git a/lib/api/entities/metrics/user_starred_dashboard.rb b/lib/api/entities/metrics/user_starred_dashboard.rb index d774160e3ea..1d2a8a39547 100644 --- a/lib/api/entities/metrics/user_starred_dashboard.rb +++ b/lib/api/entities/metrics/user_starred_dashboard.rb @@ -4,7 +4,10 @@ module API module Entities module Metrics class UserStarredDashboard < Grape::Entity - expose :id, :dashboard_path, :user_id, :project_id + expose :id, documentation: { type: 'integer', example: 5 } + expose :dashboard_path, documentation: { type: 'string', example: 'config/prometheus/common_metrics.yml' } + expose :user_id, documentation: { type: 'integer', example: 1 } + expose :project_id, documentation: { type: 'integer', example: 20 } end end end diff --git a/lib/api/entities/ml/mlflow/run.rb b/lib/api/entities/ml/mlflow/run.rb index a8e1cfe08dd..8b16c67611f 100644 --- a/lib/api/entities/ml/mlflow/run.rb +++ b/lib/api/entities/ml/mlflow/run.rb @@ -6,7 +6,7 @@ module API module Mlflow class Run < Grape::Entity expose :run do - expose(:info) { |candidate| RunInfo.represent(candidate) } + expose :itself, using: RunInfo, as: :info expose :data do expose :metrics, using: Metric expose :params, using: RunParam diff --git a/lib/api/entities/ml/mlflow/run_info.rb b/lib/api/entities/ml/mlflow/run_info.rb index 096950e349d..d3934545ba4 100644 --- a/lib/api/entities/ml/mlflow/run_info.rb +++ b/lib/api/entities/ml/mlflow/run_info.rb @@ -11,7 +11,7 @@ module API expose(:start_time) { |candidate| candidate.start_time || 0 } expose :end_time, expose_nil: false expose(:status) { |candidate| candidate.status.to_s.upcase } - expose(:artifact_uri) { |candidate| 'not_implemented' } + expose(:artifact_uri) { |candidate, options| "#{options[:packages_url]}#{candidate.artifact_root}" } expose(:lifecycle_stage) { |candidate| 'active' } expose(:user_id) { |candidate| candidate.user_id.to_s } diff --git a/lib/api/entities/ml/mlflow/update_run.rb b/lib/api/entities/ml/mlflow/update_run.rb index 090d69b8895..55def810ef5 100644 --- a/lib/api/entities/ml/mlflow/update_run.rb +++ b/lib/api/entities/ml/mlflow/update_run.rb @@ -5,13 +5,7 @@ module API module Ml module Mlflow class UpdateRun < Grape::Entity - expose :run_info - - private - - def run_info - RunInfo.represent object - end + expose :itself, using: RunInfo, as: :run_info end end end diff --git a/lib/api/entities/package.rb b/lib/api/entities/package.rb index 18fc0576dd4..c92a4677220 100644 --- a/lib/api/entities/package.rb +++ b/lib/api/entities/package.rb @@ -4,11 +4,12 @@ module API module Entities class Package < Grape::Entity include ::API::Helpers::RelatedResourcesHelpers + include ::Routing::PackagesHelper extend ::API::Entities::EntityHelpers - expose :id + expose :id, documentation: { type: 'integer', example: 1 } - expose :name do |package| + expose :name, documentation: { type: 'string', example: '@foo/bar' } do |package| if package.conan? package.conan_recipe else @@ -20,17 +21,13 @@ module API package.name end - expose :version - expose :package_type - expose :status + expose :version, documentation: { type: 'string', example: '1.0.3' } + expose :package_type, documentation: { type: 'string', example: 'npm' } + expose :status, documentation: { type: 'string', example: 'default' } expose :_links do - expose :web_path do |package, opts| - if package.infrastructure_package? - ::Gitlab::Routing.url_helpers.namespace_project_infrastructure_registry_path(opts[:namespace], package.project, package) - else - ::Gitlab::Routing.url_helpers.project_package_path(package.project, package) - end + expose :web_path do |package| + package_path(package) end expose :delete_api_path, if: can_destroy(:package, &:project) do |package| @@ -38,10 +35,12 @@ module API end end - expose :created_at - expose :last_downloaded_at - expose :project_id, if: ->(_, opts) { opts[:group] } - expose :project_path, if: ->(obj, opts) { opts[:group] && Ability.allowed?(opts[:user], :read_project, obj.project) } + expose :created_at, documentation: { type: 'dateTime', example: '2022-09-16T12:47:31.949Z' } + expose :last_downloaded_at, documentation: { type: 'dateTime', example: '2022-09-19T11:32:35.169Z' } + expose :project_id, documentation: { type: 'integer', example: 2 }, if: ->(_, opts) { opts[:group] } + expose :project_path, documentation: { type: 'string', example: 'gitlab/foo/bar' }, if: ->(obj, opts) do + opts[:group] && Ability.allowed?(opts[:user], :read_project, obj.project) + end expose :tags expose :pipeline, if: ->(package) { package.original_build_info }, using: Package::Pipeline diff --git a/lib/api/entities/package_file.rb b/lib/api/entities/package_file.rb index e34a6a7aa1d..19372b75012 100644 --- a/lib/api/entities/package_file.rb +++ b/lib/api/entities/package_file.rb @@ -3,9 +3,14 @@ module API module Entities class PackageFile < Grape::Entity - expose :id, :package_id, :created_at - expose :file_name, :size - expose :file_md5, :file_sha1, :file_sha256 + expose :id, documentation: { type: 'integer', example: 225 } + expose :package_id, documentation: { type: 'integer', example: 4 } + expose :created_at, documentation: { type: 'dateTime', example: '2018-11-07T15:25:52.199Z' } + expose :file_name, documentation: { type: 'string', example: 'my-app-1.5-20181107.152550-1.jar' } + expose :size, documentation: { type: 'integer', example: '2421' } + expose :file_md5, documentation: { type: 'string', example: '58e6a45a629910c6ff99145a688971ac' } + expose :file_sha1, documentation: { type: 'string', example: 'ebd193463d3915d7e22219f52740056dfd26cbfe' } + expose :file_sha256, documentation: { type: 'string', example: 'a903393463d3915d7e22219f52740056dfd26cbfeff321b' } expose :pipelines, if: ->(package_file) { package_file.pipelines.present? }, using: Package::Pipeline end end diff --git a/lib/api/entities/personal_access_token.rb b/lib/api/entities/personal_access_token.rb index 55764daef9d..3ec91ca5fc9 100644 --- a/lib/api/entities/personal_access_token.rb +++ b/lib/api/entities/personal_access_token.rb @@ -3,9 +3,16 @@ module API module Entities class PersonalAccessToken < Grape::Entity - expose :id, :name, :revoked, :created_at, :scopes, :user_id, :last_used_at - expose :active?, as: :active - expose :expires_at do |personal_access_token| + expose :id, documentation: { type: 'integer', example: 2 } + expose :name, documentation: { type: 'string', example: 'John Doe' } + expose :revoked, documentation: { type: 'boolean' } + expose :created_at, documentation: { type: 'dateTime' } + expose :scopes, documentation: { type: 'array', example: ['api'] } + expose :user_id, documentation: { type: 'integer', example: 3 } + expose :last_used_at, documentation: { type: 'dateTime', example: '2020-08-31T15:53:00.073Z' } + expose :active?, as: :active, documentation: { type: 'boolean' } + expose :expires_at, documentation: + { type: 'dateTime', example: '2020-08-31T15:53:00.073Z' } do |personal_access_token| personal_access_token.expires_at ? personal_access_token.expires_at.strftime("%Y-%m-%d") : nil end end diff --git a/lib/api/entities/plan_limit.rb b/lib/api/entities/plan_limit.rb index 94e50f19b35..34018f03eb1 100644 --- a/lib/api/entities/plan_limit.rb +++ b/lib/api/entities/plan_limit.rb @@ -3,23 +3,23 @@ module API module Entities class PlanLimit < Grape::Entity - expose :ci_pipeline_size - expose :ci_active_jobs - expose :ci_active_pipelines - expose :ci_project_subscriptions - expose :ci_pipeline_schedules - expose :ci_needs_size_limit - expose :ci_registered_group_runners - expose :ci_registered_project_runners - expose :conan_max_file_size - expose :generic_packages_max_file_size - expose :helm_max_file_size - expose :maven_max_file_size - expose :npm_max_file_size - expose :nuget_max_file_size - expose :pypi_max_file_size - expose :terraform_module_max_file_size - expose :storage_size_limit + expose :ci_pipeline_size, documentation: { type: 'integer', example: 0 } + expose :ci_active_jobs, documentation: { type: 'integer', example: 0 } + expose :ci_active_pipelines, documentation: { type: 'integer', example: 0 } + expose :ci_project_subscriptions, documentation: { type: 'integer', example: 2 } + expose :ci_pipeline_schedules, documentation: { type: 'integer', example: 10 } + expose :ci_needs_size_limit, documentation: { type: 'integer', example: 50 } + expose :ci_registered_group_runners, documentation: { type: 'integer', example: 1000 } + expose :ci_registered_project_runners, documentation: { type: 'integer', example: 1000 } + expose :conan_max_file_size, documentation: { type: 'integer', example: 3221225472 } + expose :generic_packages_max_file_size, documentation: { type: 'integer', example: 5368709120 } + expose :helm_max_file_size, documentation: { type: 'integer', example: 5242880 } + expose :maven_max_file_size, documentation: { type: 'integer', example: 3221225472 } + expose :npm_max_file_size, documentation: { type: 'integer', example: 524288000 } + expose :nuget_max_file_size, documentation: { type: 'integer', example: 524288000 } + expose :pypi_max_file_size, documentation: { type: 'integer', example: 3221225472 } + expose :terraform_module_max_file_size, documentation: { type: 'integer', example: 1073741824 } + expose :storage_size_limit, documentation: { type: 'integer', example: 15000 } end end end diff --git a/lib/api/entities/project.rb b/lib/api/entities/project.rb index f158695f605..1c1bafbf161 100644 --- a/lib/api/entities/project.rb +++ b/lib/api/entities/project.rb @@ -5,147 +5,148 @@ module API class Project < BasicProjectDetails include ::API::Helpers::RelatedResourcesHelpers - expose :container_registry_url, as: :container_registry_image_prefix, if: -> (_, _) { Gitlab.config.registry.enabled } + expose :container_registry_url, as: :container_registry_image_prefix, documentation: { type: 'string', example: 'registry.gitlab.example.com/gitlab/gitlab-client' }, if: -> (_, _) { Gitlab.config.registry.enabled } expose :_links do - expose :self do |project| + expose :self, documentation: { type: 'string', example: 'https://gitlab.example.com/api/v4/projects/4' } do |project| expose_url(api_v4_projects_path(id: project.id)) end - expose :issues, if: -> (project, options) { issues_available?(project, options) } do |project| + expose :issues, documentation: { type: 'string', example: 'https://gitlab.example.com/api/v4/projects/4/issues' }, if: -> (project, options) { issues_available?(project, options) } do |project| expose_url(api_v4_projects_issues_path(id: project.id)) end - expose :merge_requests, if: -> (project, options) { mrs_available?(project, options) } do |project| + expose :merge_requests, documentation: { type: 'string', example: 'https://gitlab.example.com/api/v4/projects/4/merge_requests' }, if: -> (project, options) { mrs_available?(project, options) } do |project| expose_url(api_v4_projects_merge_requests_path(id: project.id)) end - expose :repo_branches do |project| + expose :repo_branches, documentation: { type: 'string', example: 'https://gitlab.example.com/api/v4/projects/4/repository/branches' } do |project| expose_url(api_v4_projects_repository_branches_path(id: project.id)) end - expose :labels do |project| + expose :labels, documentation: { type: 'string', example: 'https://gitlab.example.com/api/v4/projects/4/labels' } do |project| expose_url(api_v4_projects_labels_path(id: project.id)) end - expose :events do |project| + expose :events, documentation: { type: 'string', example: 'https://gitlab.example.com/api/v4/projects/4/events' } do |project| expose_url(api_v4_projects_events_path(id: project.id)) end - expose :members do |project| + expose :members, documentation: { type: 'string', example: 'https://gitlab.example.com/api/v4/projects/4/members' } do |project| expose_url(api_v4_projects_members_path(id: project.id)) end - expose :cluster_agents do |project| + expose :cluster_agents, documentation: { type: 'string', example: 'https://gitlab.example.com/api/v4/projects/4/cluster_agents' } do |project| expose_url(api_v4_projects_cluster_agents_path(id: project.id)) end end - expose :packages_enabled - expose :empty_repo?, as: :empty_repo - expose :archived?, as: :archived - expose :visibility + expose :packages_enabled, documentation: { type: 'boolean' } + expose :empty_repo?, as: :empty_repo, documentation: { type: 'boolean' } + expose :archived?, as: :archived, documentation: { type: 'boolean' } + expose :visibility, documentation: { type: 'string', example: 'public' } expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } - expose :resolve_outdated_diff_discussions + expose :resolve_outdated_diff_discussions, documentation: { type: 'boolean' } expose :container_expiration_policy, using: Entities::ContainerExpirationPolicy, if: -> (project, _) { project.container_expiration_policy } # Expose old field names with the new permissions methods to keep API compatible # TODO: remove in API v5, replaced by *_access_level - expose(:issues_enabled) { |project, options| project.feature_available?(:issues, options[:current_user]) } - expose(:merge_requests_enabled) { |project, options| project.feature_available?(:merge_requests, options[:current_user]) } - expose(:wiki_enabled) { |project, options| project.feature_available?(:wiki, options[:current_user]) } - expose(:jobs_enabled) { |project, options| project.feature_available?(:builds, options[:current_user]) } - expose(:snippets_enabled) { |project, options| project.feature_available?(:snippets, options[:current_user]) } - expose(:container_registry_enabled) { |project, options| project.feature_available?(:container_registry, options[:current_user]) } - expose :service_desk_enabled - expose :service_desk_address, if: -> (project, options) do + expose(:issues_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:issues, options[:current_user]) } + expose(:merge_requests_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:merge_requests, options[:current_user]) } + expose(:wiki_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:wiki, options[:current_user]) } + expose(:jobs_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:builds, options[:current_user]) } + expose(:snippets_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:snippets, options[:current_user]) } + expose(:container_registry_enabled, documentation: { type: 'boolean' }) { |project, options| project.feature_available?(:container_registry, options[:current_user]) } + expose :service_desk_enabled, documentation: { type: 'boolean' } + expose :service_desk_address, documentation: { type: 'string', example: 'address@example.com' }, if: -> (project, options) do Ability.allowed?(options[:current_user], :admin_issue, project) end - expose(:can_create_merge_request_in) do |project, options| + expose(:can_create_merge_request_in, documentation: { type: 'boolean' }) do |project, options| Ability.allowed?(options[:current_user], :create_merge_request_in, project) end - expose(:issues_access_level) { |project, options| project_feature_string_access_level(project, :issues) } - expose(:repository_access_level) { |project, options| project_feature_string_access_level(project, :repository) } - expose(:merge_requests_access_level) { |project, options| project_feature_string_access_level(project, :merge_requests) } - expose(:forking_access_level) { |project, options| project_feature_string_access_level(project, :forking) } - expose(:wiki_access_level) { |project, options| project_feature_string_access_level(project, :wiki) } - expose(:builds_access_level) { |project, options| project_feature_string_access_level(project, :builds) } - expose(:snippets_access_level) { |project, options| project_feature_string_access_level(project, :snippets) } - expose(:pages_access_level) { |project, options| project_feature_string_access_level(project, :pages) } - expose(:operations_access_level) { |project, options| project_feature_string_access_level(project, :operations) } - expose(:analytics_access_level) { |project, options| project_feature_string_access_level(project, :analytics) } - expose(:container_registry_access_level) { |project, options| project_feature_string_access_level(project, :container_registry) } - expose(:security_and_compliance_access_level) { |project, options| project_feature_string_access_level(project, :security_and_compliance) } - expose(:releases_access_level) { |project, options| project_feature_string_access_level(project, :releases) } - - expose :emails_disabled - expose :shared_runners_enabled - expose :lfs_enabled?, as: :lfs_enabled - expose :creator_id + expose(:issues_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :issues) } + expose(:repository_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :repository) } + expose(:merge_requests_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :merge_requests) } + expose(:forking_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :forking) } + expose(:wiki_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :wiki) } + expose(:builds_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :builds) } + expose(:snippets_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :snippets) } + expose(:pages_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :pages) } + expose(:operations_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :operations) } + expose(:analytics_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :analytics) } + expose(:container_registry_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :container_registry) } + expose(:security_and_compliance_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :security_and_compliance) } + expose(:releases_access_level, documentation: { type: 'string', example: 'enabled' }) { |project, options| project_feature_string_access_level(project, :releases) } + + expose :emails_disabled, documentation: { type: 'boolean' } + expose :shared_runners_enabled, documentation: { type: 'boolean' } + expose :lfs_enabled?, as: :lfs_enabled, documentation: { type: 'boolean' } + expose :creator_id, documentation: { type: 'integer', example: 1 } expose :forked_from_project, using: Entities::BasicProjectDetails, if: ->(project, options) do project.forked? && Ability.allowed?(options[:current_user], :read_project, project.forked_from_project) end - expose :mr_default_target_self, if: -> (project) { project.forked? } + expose :mr_default_target_self, if: -> (project) { project.forked? }, documentation: { type: 'boolean' } - expose :import_url, if: -> (project, options) { Ability.allowed?(options[:current_user], :admin_project, project) } do |project| + expose :import_url, documentation: { type: 'string', example: 'https://gitlab.com/gitlab/gitlab.git' }, if: -> (project, options) { Ability.allowed?(options[:current_user], :admin_project, project) } do |project| project[:import_url] end - expose :import_type, if: -> (project, options) { Ability.allowed?(options[:current_user], :admin_project, project) } - expose :import_status - expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] } do |project| + expose :import_type, documentation: { type: 'string', example: 'git' }, if: -> (project, options) { Ability.allowed?(options[:current_user], :admin_project, project) } + expose :import_status, documentation: { type: 'string', example: 'none' } + expose :import_error, documentation: { type: 'string', example: 'Import error' }, if: lambda { |_project, options| options[:user_can_admin_project] } do |project| project.import_state&.last_error end - expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) } - expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] } - expose :ci_default_git_depth - expose :ci_forward_deployment_enabled - expose(:ci_job_token_scope_enabled) { |p, _| p.ci_outbound_job_token_scope_enabled? } - expose :ci_separated_caches - expose :ci_opt_in_jwt - expose :ci_allow_fork_pipelines_to_run_in_parent_project - expose :public_builds, as: :public_jobs - expose :build_git_strategy, if: lambda { |project, options| options[:user_can_admin_project] } do |project, options| + expose :open_issues_count, documentation: { type: 'integer', example: 1 }, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) } + expose :runners_token, documentation: { type: 'string', example: 'b8547b1dc37721d05889db52fa2f02' }, if: lambda { |_project, options| options[:user_can_admin_project] } + expose :ci_default_git_depth, documentation: { type: 'integer', example: 20 } + expose :ci_forward_deployment_enabled, documentation: { type: 'boolean' } + expose(:ci_job_token_scope_enabled, documentation: { type: 'boolean' }) { |p, _| p.ci_outbound_job_token_scope_enabled? } + expose :ci_separated_caches, documentation: { type: 'boolean' } + expose :ci_opt_in_jwt, documentation: { type: 'boolean' } + expose :ci_allow_fork_pipelines_to_run_in_parent_project, documentation: { type: 'boolean' } + expose :public_builds, as: :public_jobs, documentation: { type: 'boolean' } + expose :build_git_strategy, documentation: { type: 'string', example: 'fetch' }, if: lambda { |project, options| options[:user_can_admin_project] } do |project, options| project.build_allow_git_fetch ? 'fetch' : 'clone' end - expose :build_timeout - expose :auto_cancel_pending_pipelines - expose :ci_config_path, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) } - expose :shared_with_groups do |project, options| + expose :build_timeout, documentation: { type: 'integer', example: 3600 } + expose :auto_cancel_pending_pipelines, documentation: { type: 'string', example: 'enabled' } + expose :ci_config_path, documentation: { type: 'string', example: '' }, if: -> (project, options) { Ability.allowed?(options[:current_user], :read_code, project) } + expose :shared_with_groups, documentation: { is_array: true } do |project, options| user = options[:current_user] SharedGroupWithProject.represent(project.visible_group_links(for_user: user), options) end - expose :only_allow_merge_if_pipeline_succeeds - expose :allow_merge_on_skipped_pipeline - expose :restrict_user_defined_variables - expose :request_access_enabled - expose :only_allow_merge_if_all_discussions_are_resolved - expose :remove_source_branch_after_merge - expose :printing_merge_request_link_enabled - expose :merge_method - expose :squash_option - expose :enforce_auth_checks_on_uploads - expose :suggestion_commit_message - expose :merge_commit_template - expose :squash_commit_template + expose :only_allow_merge_if_pipeline_succeeds, documentation: { type: 'boolean' } + expose :allow_merge_on_skipped_pipeline, documentation: { type: 'boolean' } + expose :restrict_user_defined_variables, documentation: { type: 'boolean' } + expose :request_access_enabled, documentation: { type: 'boolean' } + expose :only_allow_merge_if_all_discussions_are_resolved, documentation: { type: 'boolean' } + expose :remove_source_branch_after_merge, documentation: { type: 'boolean' } + expose :printing_merge_request_link_enabled, documentation: { type: 'boolean' } + expose :merge_method, documentation: { type: 'string', example: 'merge' } + expose :squash_option, documentation: { type: 'string', example: 'default_off' } + expose :enforce_auth_checks_on_uploads, documentation: { type: 'boolean' } + expose :suggestion_commit_message, documentation: { type: 'string', example: 'Suggestion message' } + expose :merge_commit_template, documentation: { type: 'string', example: '%(title)' } + expose :squash_commit_template, documentation: { type: 'string', example: '%(source_branch)' } + expose :issue_branch_template, documentation: { type: 'string', example: '%(title)' } expose :statistics, using: 'API::Entities::ProjectStatistics', if: -> (project, options) { options[:statistics] && Ability.allowed?(options[:current_user], :read_statistics, project) } - expose :auto_devops_enabled?, as: :auto_devops_enabled - expose :auto_devops_deploy_strategy do |project, options| + expose :auto_devops_enabled?, as: :auto_devops_enabled, documentation: { type: 'boolean' } + expose :auto_devops_deploy_strategy, documentation: { type: 'string', example: 'continuous' } do |project, options| project.auto_devops.nil? ? 'continuous' : project.auto_devops.deploy_strategy end - expose :autoclose_referenced_issues - expose :repository_storage, if: ->(project, options) { + expose :autoclose_referenced_issues, documentation: { type: 'boolean' } + expose :repository_storage, documentation: { type: 'string', example: 'default' }, if: ->(project, options) { Ability.allowed?(options[:current_user], :change_repository_storage, project) } - expose :keep_latest_artifacts_available?, as: :keep_latest_artifact - expose :runner_token_expiration_interval + expose :keep_latest_artifacts_available?, as: :keep_latest_artifact, documentation: { type: 'boolean' } + expose :runner_token_expiration_interval, documentation: { type: 'integer', example: 3600 } # rubocop: disable CodeReuse/ActiveRecord def self.preload_resource(project) diff --git a/lib/api/entities/project_daily_fetches.rb b/lib/api/entities/project_daily_fetches.rb index 036b5dc99b8..8797aeb9521 100644 --- a/lib/api/entities/project_daily_fetches.rb +++ b/lib/api/entities/project_daily_fetches.rb @@ -3,8 +3,8 @@ module API module Entities class ProjectDailyFetches < Grape::Entity - expose :fetch_count, as: :count - expose :date + expose :fetch_count, as: :count, documentation: { type: 'integer', example: 3 } + expose :date, documentation: { type: 'date', example: '2022-01-01' } end end end diff --git a/lib/api/entities/project_daily_statistics.rb b/lib/api/entities/project_daily_statistics.rb index 803ee445851..555ecc6be39 100644 --- a/lib/api/entities/project_daily_statistics.rb +++ b/lib/api/entities/project_daily_statistics.rb @@ -4,8 +4,8 @@ module API module Entities class ProjectDailyStatistics < Grape::Entity expose :fetches do - expose :total_fetch_count, as: :total - expose :fetches, as: :days, using: ProjectDailyFetches + expose :total_fetch_count, as: :total, documentation: { type: 'integer', example: 3 } + expose :fetches, as: :days, using: ProjectDailyFetches, documentation: { is_array: true } end end end diff --git a/lib/api/entities/project_export_status.rb b/lib/api/entities/project_export_status.rb index ad84a45996a..9a2aeb7a6bb 100644 --- a/lib/api/entities/project_export_status.rb +++ b/lib/api/entities/project_export_status.rb @@ -5,13 +5,21 @@ module API class ProjectExportStatus < ProjectIdentity include ::API::Helpers::RelatedResourcesHelpers - expose :export_status + expose :export_status, documentation: { + type: 'string', example: 'finished', values: %w[queued started finished failed] + } expose :_links, if: lambda { |project, _options| project.export_status == :finished } do - expose :api_url do |project| + expose :api_url, documentation: { + type: 'string', + example: 'https://gitlab.example.com/api/v4/projects/1/export/download' + } do |project| expose_url(api_v4_projects_export_download_path(id: project.id)) end - expose :web_url do |project| + expose :web_url, documentation: { + type: 'string', + example: 'https://gitlab.example.com/gitlab-org/gitlab-test/download_export' + } do |project| Gitlab::Routing.url_helpers.download_export_project_url(project) end end diff --git a/lib/api/entities/project_group_link.rb b/lib/api/entities/project_group_link.rb index 89138854e67..b5d5991ec7f 100644 --- a/lib/api/entities/project_group_link.rb +++ b/lib/api/entities/project_group_link.rb @@ -3,7 +3,11 @@ module API module Entities class ProjectGroupLink < Grape::Entity - expose :id, :project_id, :group_id, :group_access, :expires_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :project_id, documentation: { type: 'integer', example: 1 } + expose :group_id, documentation: { type: 'integer', example: 1 } + expose :group_access, documentation: { type: 'integer', example: 10 } + expose :expires_at, documentation: { type: 'date', example: '2016-09-26' } end end end diff --git a/lib/api/entities/project_hook.rb b/lib/api/entities/project_hook.rb index 6c71e5d317c..bffb057abed 100644 --- a/lib/api/entities/project_hook.rb +++ b/lib/api/entities/project_hook.rb @@ -3,10 +3,17 @@ module API module Entities class ProjectHook < Hook - expose :project_id, :issues_events, :confidential_issues_events - expose :note_events, :confidential_note_events, :pipeline_events, :wiki_page_events, :deployment_events - expose :job_events, :releases_events - expose :push_events_branch_filter + expose :project_id, documentation: { type: 'string', example: 1 } + expose :issues_events, documentation: { type: 'boolean' } + expose :confidential_issues_events, documentation: { type: 'boolean' } + expose :note_events, documentation: { type: 'boolean' } + expose :confidential_note_events, documentation: { type: 'boolean' } + expose :pipeline_events, documentation: { type: 'boolean' } + expose :wiki_page_events, documentation: { type: 'boolean' } + expose :deployment_events, documentation: { type: 'boolean' } + expose :job_events, documentation: { type: 'boolean' } + expose :releases_events, documentation: { type: 'boolean' } + expose :push_events_branch_filter, documentation: { type: 'string', example: 'my-branch-*' } end end end diff --git a/lib/api/entities/project_identity.rb b/lib/api/entities/project_identity.rb index 2055195eea0..14aef05b95e 100644 --- a/lib/api/entities/project_identity.rb +++ b/lib/api/entities/project_identity.rb @@ -3,10 +3,13 @@ module API module Entities class ProjectIdentity < Grape::Entity - expose :id, :description - expose :name, :name_with_namespace - expose :path, :path_with_namespace - expose :created_at + expose :id, documentation: { type: 'integer', example: 1 } + expose :description, documentation: { type: 'string', example: 'desc' } + expose :name, documentation: { type: 'string', example: 'project1' } + expose :name_with_namespace, documentation: { type: 'string', example: 'John Doe / project1' } + expose :path, documentation: { type: 'string', example: 'project1' } + expose :path_with_namespace, documentation: { type: 'string', example: 'namespace1/project1' } + expose :created_at, documentation: { type: 'dateTime', example: '2020-05-07T04:27:17.016Z' } end end end diff --git a/lib/api/entities/project_import_failed_relation.rb b/lib/api/entities/project_import_failed_relation.rb index 26cfae7260c..543cc62f364 100644 --- a/lib/api/entities/project_import_failed_relation.rb +++ b/lib/api/entities/project_import_failed_relation.rb @@ -3,14 +3,17 @@ module API module Entities class ProjectImportFailedRelation < Grape::Entity - expose :id, :created_at, :exception_class, :source + expose :id, documentation: { type: 'string', example: 1 } + expose :created_at, documentation: { type: 'dateTime', example: '2012-05-28T04:42:42-07:00' } + expose :exception_class, documentation: { type: 'string', example: 'StandardError' } + expose :source, documentation: { type: 'string', example: 'ImportRepositoryWorker' } - expose :exception_message do |_| + expose :exception_message, documentation: { type: 'string' } do |_| nil end - expose :relation_key, as: :relation_name - expose :relation_index, as: :line_number + expose :relation_key, as: :relation_name, documentation: { type: 'string', example: 'issues' } + expose :relation_index, as: :line_number, documentation: { type: 'integer', example: 1 } end end end diff --git a/lib/api/entities/project_import_status.rb b/lib/api/entities/project_import_status.rb index 5daae4a70f2..59388aacafd 100644 --- a/lib/api/entities/project_import_status.rb +++ b/lib/api/entities/project_import_status.rb @@ -3,21 +3,25 @@ module API module Entities class ProjectImportStatus < ProjectIdentity - expose :import_status - expose :import_type - expose :correlation_id do |project, _options| + expose :import_status, documentation: { type: 'string', example: 'scheduled' } + expose :import_type, documentation: { type: 'string', example: 'gitlab_project' } + expose :correlation_id, documentation: { + type: 'string', example: 'dfcf583058ed4508e4c7c617bd7f0edd' + } do |project, _options| project.import_state&.correlation_id end - expose :failed_relations, using: Entities::ProjectImportFailedRelation do |project, _options| + expose :failed_relations, using: Entities::ProjectImportFailedRelation, documentation: { + is_array: true + } do |project, _options| project.import_state&.relation_hard_failures(limit: 100) || [] end - expose :import_error do |project, _options| + expose :import_error, documentation: { type: 'string', example: 'Error message' } do |project, _options| project.import_state&.last_error end - expose :stats do |project, _options| + expose :stats, documentation: { type: 'object' } do |project, _options| if project.github_import? ::Gitlab::GithubImport::ObjectCounter.summary(project) end diff --git a/lib/api/entities/project_integration.rb b/lib/api/entities/project_integration.rb index 155136d2f80..29bb60a19e5 100644 --- a/lib/api/entities/project_integration.rb +++ b/lib/api/entities/project_integration.rb @@ -4,7 +4,7 @@ module API module Entities class ProjectIntegration < Entities::ProjectIntegrationBasic # Expose serialized properties - expose :properties do |integration, options| + expose :properties, documentation: { type: 'Hash', example: { "token" => "secr3t" } } do |integration, options| integration.api_field_names.to_h do |name| [name, integration.public_send(name)] # rubocop:disable GitlabSecurity/PublicSend end diff --git a/lib/api/entities/project_integration_basic.rb b/lib/api/entities/project_integration_basic.rb index 2870123b83d..aa0ad158b83 100644 --- a/lib/api/entities/project_integration_basic.rb +++ b/lib/api/entities/project_integration_basic.rb @@ -3,15 +3,26 @@ module API module Entities class ProjectIntegrationBasic < Grape::Entity - expose :id, :title - expose :slug do |integration| + expose :id, documentation: { type: 'integer', example: 75 } + expose :title, documentation: { type: 'string', example: 'Jenkins CI' } + expose :slug, documentation: { type: 'integer', example: 'jenkins' } do |integration| integration.to_param.dasherize end - expose :created_at, :updated_at, :active - expose :commit_events, :push_events, :issues_events, :confidential_issues_events - expose :merge_requests_events, :tag_push_events, :note_events - expose :confidential_note_events, :pipeline_events, :wiki_page_events - expose :job_events, :comment_on_event_enabled + expose :created_at, documentation: { type: 'dateTime', example: '2019-11-20T11:20:25.297Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2019-11-20T12:24:37.498Z' } + expose :active, documentation: { type: 'boolean' } + expose :commit_events, documentation: { type: 'boolean' } + expose :push_events, documentation: { type: 'boolean' } + expose :issues_events, documentation: { type: 'boolean' } + expose :confidential_issues_events, documentation: { type: 'boolean' } + expose :merge_requests_events, documentation: { type: 'boolean' } + expose :tag_push_events, documentation: { type: 'boolean' } + expose :note_events, documentation: { type: 'boolean' } + expose :confidential_note_events, documentation: { type: 'boolean' } + expose :pipeline_events, documentation: { type: 'boolean' } + expose :wiki_page_events, documentation: { type: 'boolean' } + expose :job_events, documentation: { type: 'boolean' } + expose :comment_on_event_enabled, documentation: { type: 'boolean' } end end end diff --git a/lib/api/entities/project_repository_storage.rb b/lib/api/entities/project_repository_storage.rb index 0816bebde2c..ae5039601d7 100644 --- a/lib/api/entities/project_repository_storage.rb +++ b/lib/api/entities/project_repository_storage.rb @@ -5,12 +5,16 @@ module API class ProjectRepositoryStorage < Grape::Entity include Gitlab::Routing - expose :disk_path do |project| + expose :disk_path, documentation: { + type: 'string', + example: '@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' + } do |project| project.repository.disk_path end - expose :id, as: :project_id - expose :repository_storage, :created_at + expose :id, as: :project_id, documentation: { type: 'integer', example: 1 } + expose :repository_storage, documentation: { type: 'string', example: 'default' } + expose :created_at, documentation: { type: 'dateTime', example: '2012-10-12T17:04:47Z' } end end end diff --git a/lib/api/entities/project_with_access.rb b/lib/api/entities/project_with_access.rb index b541ccbadcf..9722b8806d4 100644 --- a/lib/api/entities/project_with_access.rb +++ b/lib/api/entities/project_with_access.rb @@ -25,23 +25,41 @@ module API # rubocop: disable CodeReuse/ActiveRecord def self.preload_relation(projects_relation, options = {}) - relation = super(projects_relation, options) - # use reselect to override the existing select and - # prevent an error `subquery has too many columns` - project_ids = relation.reselect('projects.id') - namespace_ids = relation.reselect(:namespace_id) + if ::Feature.enabled?(:projects_preloader_fix) + super(projects_relation, options) + else + relation = super(projects_relation, options) + # use reselect to override the existing select and + # prevent an error `subquery has too many columns` + project_ids = relation.reselect('projects.id') + namespace_ids = relation.reselect(:namespace_id) + + options[:project_members] = options[:current_user] + .project_members + .where(source_id: project_ids) + .preload(:source, user: [notification_settings: :source]) + + options[:group_members] = options[:current_user] + .group_members + .where(source_id: namespace_ids) + .preload(:source, user: [notification_settings: :source]) + + relation + end + end + + def self.postload_relation(projects_relation, options = {}) + return unless ::Feature.enabled?(:projects_preloader_fix) options[:project_members] = options[:current_user] .project_members - .where(source_id: project_ids) + .where(source_id: projects_relation.subquery(:id)) .preload(:source, user: [notification_settings: :source]) options[:group_members] = options[:current_user] .group_members - .where(source_id: namespace_ids) + .where(source_id: projects_relation.subquery(:namespace_id)) .preload(:source, user: [notification_settings: :source]) - - relation end # rubocop: enable CodeReuse/ActiveRecord end diff --git a/lib/api/entities/protected_branch.rb b/lib/api/entities/protected_branch.rb index ac44d06e69c..42f721b40a6 100644 --- a/lib/api/entities/protected_branch.rb +++ b/lib/api/entities/protected_branch.rb @@ -3,11 +3,11 @@ module API module Entities class ProtectedBranch < Grape::Entity - expose :id - expose :name - expose :push_access_levels, using: Entities::ProtectedRefAccess - expose :merge_access_levels, using: Entities::ProtectedRefAccess - expose :allow_force_push + expose :id, documentation: { type: 'integer', example: 1 } + expose :name, documentation: { type: 'string', example: 'main' } + expose :push_access_levels, using: Entities::ProtectedRefAccess, documentation: { is_array: true } + expose :merge_access_levels, using: Entities::ProtectedRefAccess, documentation: { is_array: true } + expose :allow_force_push, documentation: { type: 'boolean' } end end end diff --git a/lib/api/entities/protected_ref_access.rb b/lib/api/entities/protected_ref_access.rb index 443277e23cf..ba28c724448 100644 --- a/lib/api/entities/protected_ref_access.rb +++ b/lib/api/entities/protected_ref_access.rb @@ -3,10 +3,12 @@ module API module Entities class ProtectedRefAccess < Grape::Entity - expose :access_level - expose :access_level_description do |protected_ref_access| - protected_ref_access.humanize - end + expose :id, documentation: { type: 'integer', example: 1 } + expose :access_level, documentation: { type: 'integer', example: 40 } + expose :access_level_description, + documentation: { type: 'string', example: 'Maintainers' } do |protected_ref_access| + protected_ref_access.humanize + end end end end diff --git a/lib/api/entities/protected_tag.rb b/lib/api/entities/protected_tag.rb index dc397f01af6..ba984ae79b8 100644 --- a/lib/api/entities/protected_tag.rb +++ b/lib/api/entities/protected_tag.rb @@ -3,7 +3,7 @@ module API module Entities class ProtectedTag < Grape::Entity - expose :name + expose :name, documentation: { type: 'string', example: 'release-1-0' } expose :create_access_levels, using: Entities::ProtectedRefAccess end end diff --git a/lib/api/entities/pull_mirror.rb b/lib/api/entities/pull_mirror.rb new file mode 100644 index 00000000000..72a5220987e --- /dev/null +++ b/lib/api/entities/pull_mirror.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module API + module Entities + class PullMirror < Grape::Entity + expose :id, documentation: { type: 'integer', example: 101486 } + expose :status, as: :update_status, documentation: { type: 'string', example: 'finished' } + expose :url, +documentation: { type: 'string', + example: 'https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git' } do |import_state| + import_state.project.safe_import_url + end + expose :last_error, documentation: { type: 'string', example: nil } + expose :last_update_at, documentation: { type: 'dateTime', example: '2020-01-06T17:32:02.823Z' } + expose :last_update_started_at, documentation: { type: 'dateTime', example: '2020-01-06T17:32:02.823Z' } + expose :last_successful_update_at, documentation: { type: 'dateTime', example: '2020-01-06T17:32:02.823Z' } + end + end +end diff --git a/lib/api/entities/release.rb b/lib/api/entities/release.rb index 2403c907f7f..c1a48a46d64 100644 --- a/lib/api/entities/release.rb +++ b/lib/api/entities/release.rb @@ -9,22 +9,24 @@ module API MarkupHelper.markdown_field(entity, :description, current_user: options[:current_user]) end expose :author, using: Entities::UserBasic, if: -> (release, _) { release.author.present? } - expose :commit, using: Entities::Commit, if: ->(_, _) { can_download_code? } + expose :commit, using: Entities::Commit, if: ->(_, _) { can_read_code? } expose :milestones, using: Entities::MilestoneWithStats, if: -> (release, _) { release.milestones.present? && can_read_milestone? } do |release, _| release.milestones.order_by_dates_and_title end - expose :commit_path, expose_nil: false - expose :tag_path, expose_nil: false + expose :commit_path, + documentation: { type: 'string', example: '/root/app/commit/588440f66559714280628a4f9799f0c4eb880a4a' }, + expose_nil: false + expose :tag_path, documentation: { type: 'string', example: '/root/app/-/tags/v1.0' }, expose_nil: false expose :assets do - expose :assets_count, as: :count - expose :sources, using: Entities::Releases::Source, if: ->(_, _) { can_download_code? } + expose :assets_count, documentation: { type: 'integer', example: 2 }, as: :count + expose :sources, using: Entities::Releases::Source, if: ->(_, _) { can_read_code? } expose :sorted_links, as: :links, using: Entities::Releases::Link end - expose :evidences, using: Entities::Releases::Evidence, expose_nil: false, if: ->(_, _) { can_download_code? } + expose :evidences, using: Entities::Releases::Evidence, expose_nil: false, if: ->(_, _) { can_read_code? } expose :_links do expose :self_url, as: :self, expose_nil: false expose :edit_url, expose_nil: false @@ -32,8 +34,8 @@ module API private - def can_download_code? - Ability.allowed?(options[:current_user], :download_code, object.project) + def can_read_code? + Ability.allowed?(options[:current_user], :read_code, object.project) end def can_read_milestone? diff --git a/lib/api/entities/releases/evidence.rb b/lib/api/entities/releases/evidence.rb index 01603a71dbf..9d324309213 100644 --- a/lib/api/entities/releases/evidence.rb +++ b/lib/api/entities/releases/evidence.rb @@ -6,9 +6,9 @@ module API class Evidence < Grape::Entity include ::API::Helpers::Presentable - expose :sha - expose :filepath - expose :collected_at + expose :sha, documentation: { type: 'string', example: '760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d' } + expose :filepath, documentation: { type: 'string', example: 'https://gitlab.example.com/root/app/-/releases/v1.0/evidence.json' } + expose :collected_at, documentation: { type: 'dateTime', example: '2019-01-03T01:56:19.539Z' } end end end diff --git a/lib/api/entities/releases/link.rb b/lib/api/entities/releases/link.rb index 5157645af69..abf380e11d5 100644 --- a/lib/api/entities/releases/link.rb +++ b/lib/api/entities/releases/link.rb @@ -4,14 +4,22 @@ module API module Entities module Releases class Link < Grape::Entity - expose :id - expose :name - expose :url - expose :direct_asset_url do |link| + expose :id, documentation: { type: 'integer', example: 1 } + expose :name, documentation: { type: 'string', example: 'app-v1.0.dmg' } + expose :url, documentation: + { + type: 'string', + example: 'https://gitlab.example.com/root/app/-/jobs/688/artifacts/raw/bin/app-v1.0.dmg' + } + expose :direct_asset_url, documentation: + { + type: 'string', + example: 'https://gitlab.example.com/root/app/-/releases/v1.0/downloads/app-v1.0.dmg' + } do |link| ::Releases::LinkPresenter.new(link).direct_asset_url end - expose :external?, as: :external - expose :link_type + expose :external?, documentation: { type: 'boolean' }, as: :external + expose :link_type, documentation: { type: 'string', example: 'other' } end end end diff --git a/lib/api/entities/releases/source.rb b/lib/api/entities/releases/source.rb index 2b0c8038ddf..8c6750d6142 100644 --- a/lib/api/entities/releases/source.rb +++ b/lib/api/entities/releases/source.rb @@ -4,8 +4,8 @@ module API module Entities module Releases class Source < Grape::Entity - expose :format - expose :url + expose :format, documentation: { type: 'string', example: 'zip' } + expose :url, documentation: { type: 'string', example: 'https://gitlab.example.com/root/app/-/archive/v1.0/app-v1.0.zip' } end end end diff --git a/lib/api/entities/remote_mirror.rb b/lib/api/entities/remote_mirror.rb index 87daef9a05c..9fb5b2697bc 100644 --- a/lib/api/entities/remote_mirror.rb +++ b/lib/api/entities/remote_mirror.rb @@ -3,16 +3,16 @@ module API module Entities class RemoteMirror < Grape::Entity - expose :id - expose :enabled - expose :safe_url, as: :url - expose :update_status - expose :last_update_at - expose :last_update_started_at - expose :last_successful_update_at - expose :last_error - expose :only_protected_branches - expose :keep_divergent_refs + expose :id, documentation: { type: 'integer', example: 101486 } + expose :enabled, documentation: { type: 'boolean', example: true } + expose :safe_url, as: :url, documentation: { type: 'string', example: 'https://*****:*****@example.com/gitlab/example.git' } + expose :update_status, documentation: { type: 'string', example: 'finished' } + expose :last_update_at, documentation: { type: 'dateTime', example: '2020-01-06T17:32:02.823Z' } + expose :last_update_started_at, documentation: { type: 'dateTime', example: '2020-01-06T17:32:02.823Z' } + expose :last_successful_update_at, documentation: { type: 'dateTime', example: '2020-01-06T17:31:55.864Z' } + expose :last_error, documentation: { type: 'integer', example: 'The remote mirror URL is invalid.' } + expose :only_protected_branches, documentation: { type: 'boolean' } + expose :keep_divergent_refs, documentation: { type: 'boolean' } end end end diff --git a/lib/api/entities/resource_access_token.rb b/lib/api/entities/resource_access_token.rb index 569fd16f488..e4f140d3fc0 100644 --- a/lib/api/entities/resource_access_token.rb +++ b/lib/api/entities/resource_access_token.rb @@ -3,7 +3,12 @@ module API module Entities class ResourceAccessToken < Entities::PersonalAccessToken - expose :access_level do |token, options| + expose :access_level, + documentation: { type: 'integer', + example: 40, + description: 'Access level. Valid values are 10 (Guest), 20 (Reporter), 30 (Developer) \ + , 40 (Maintainer), and 50 (Owner). Defaults to 40.', + values: [10, 20, 30, 40, 50] } do |token, options| options[:resource].member(token.user).access_level end end diff --git a/lib/api/entities/resource_milestone_event.rb b/lib/api/entities/resource_milestone_event.rb index 26dc6620cbe..b301f5b7d0a 100644 --- a/lib/api/entities/resource_milestone_event.rb +++ b/lib/api/entities/resource_milestone_event.rb @@ -3,18 +3,18 @@ module API module Entities class ResourceMilestoneEvent < Grape::Entity - expose :id + expose :id, documentation: { type: 'integer', example: 142 } expose :user, using: Entities::UserBasic - expose :created_at - expose :resource_type do |event, _options| + expose :created_at, documentation: { type: 'dateTime', example: '2018-08-20T13:38:20.077Z' } + expose :resource_type, documentation: { type: 'string', example: 'Issue' } do |event, _options| event.issuable.class.name end - expose :resource_id do |event, _options| + expose :resource_id, documentation: { type: 'integer', example: 253 } do |event, _options| event.issuable.id end expose :milestone, using: Entities::Milestone - expose :action - expose :state + expose :action, documentation: { type: 'string', example: 'add' } + expose :state, documentation: { type: 'string', example: 'active' } end end end diff --git a/lib/api/entities/snippet.rb b/lib/api/entities/snippet.rb index af885aaf0eb..709566944ed 100644 --- a/lib/api/entities/snippet.rb +++ b/lib/api/entities/snippet.rb @@ -3,11 +3,13 @@ module API module Entities class Snippet < BasicSnippet - expose :author, using: Entities::UserBasic - expose :file_name do |snippet| + expose :author, using: Entities::UserBasic, documentation: { type: 'Entities::UserBasic' } + expose :file_name, documentation: { type: 'string', example: 'add.rb' } do |snippet| snippet_files.first || snippet.file_name end - expose :files do |snippet, options| + expose :files, documentation: { + is_array: true, example: 'e0d123e5f316bef78bfdf5a008837577' + } do |snippet, options| snippet_files.map do |file| { path: file, diff --git a/lib/api/entities/snippets/repository_storage_move.rb b/lib/api/entities/snippets/repository_storage_move.rb index 4e14d1dfba2..711d07545fb 100644 --- a/lib/api/entities/snippets/repository_storage_move.rb +++ b/lib/api/entities/snippets/repository_storage_move.rb @@ -4,7 +4,7 @@ module API module Entities module Snippets class RepositoryStorageMove < BasicRepositoryStorageMove - expose :snippet, using: Entities::BasicSnippet + expose :snippet, using: Entities::BasicSnippet, documentation: { type: 'Entities::BasicSnippet' } end end end diff --git a/lib/api/entities/ssh_key.rb b/lib/api/entities/ssh_key.rb index e1554730cb6..3db10bb8ec2 100644 --- a/lib/api/entities/ssh_key.rb +++ b/lib/api/entities/ssh_key.rb @@ -3,8 +3,15 @@ module API module Entities class SSHKey < Grape::Entity - expose :id, :title, :created_at, :expires_at - expose :publishable_key, as: :key + expose :id, documentation: { type: 'integer', example: 1 } + expose :title, documentation: { type: 'string', example: 'Sample key 25' } + expose :created_at, documentation: { type: 'dateTime', example: '2015-09-03T07:24:44.627Z' } + expose :expires_at, documentation: { type: 'dateTime', example: '2020-09-03T07:24:44.627Z' } + expose :publishable_key, as: :key, documentation: + { type: 'string', + example: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1256k6Yjz\ + GGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCdd\ + NaP0L+hM7zhFNzjFvpaMgJw0=' } end end end diff --git a/lib/api/entities/tag.rb b/lib/api/entities/tag.rb index 2d3569bb9bb..713bae64d5c 100644 --- a/lib/api/entities/tag.rb +++ b/lib/api/entities/tag.rb @@ -3,7 +3,9 @@ module API module Entities class Tag < Grape::Entity - expose :name, :message, :target + expose :name, documentation: { type: 'string', example: 'v1.0.0' } + expose :message, documentation: { type: 'string', example: 'Release v1.0.0' } + expose :target, documentation: { type: 'string', example: '2695effb5807a22ff3d138d593fd856244e155e7' } expose :commit, using: Entities::Commit do |repo_tag, options| options[:project].repository.commit(repo_tag.dereferenced_target) @@ -15,7 +17,7 @@ module API end # rubocop: enable CodeReuse/ActiveRecord - expose :protected do |repo_tag, options| + expose :protected, documentation: { type: 'boolean', example: true } do |repo_tag, options| ::ProtectedTag.protected?(options[:project], repo_tag.name) end end diff --git a/lib/api/entities/tag_release.rb b/lib/api/entities/tag_release.rb index d5f73d60332..66d1eeeab4a 100644 --- a/lib/api/entities/tag_release.rb +++ b/lib/api/entities/tag_release.rb @@ -4,8 +4,8 @@ module API module Entities # deprecated old Release representation class TagRelease < Grape::Entity - expose :tag, as: :tag_name - expose :description + expose :tag, as: :tag_name, documentation: { type: 'string', example: '1.0.0' } + expose :description, documentation: { type: 'string', example: 'Amazing release. Wow' } end end end diff --git a/lib/api/entities/templates_list.rb b/lib/api/entities/templates_list.rb index 8e8aa1bd285..eba80bd04d3 100644 --- a/lib/api/entities/templates_list.rb +++ b/lib/api/entities/templates_list.rb @@ -3,8 +3,8 @@ module API module Entities class TemplatesList < Grape::Entity - expose :key - expose :name + expose :key, documentation: { type: 'string', example: 'mit' } + expose :name, documentation: { type: 'string', example: 'MIT License' } end end end diff --git a/lib/api/entities/tree_object.rb b/lib/api/entities/tree_object.rb index e4e840ebe43..1f542885169 100644 --- a/lib/api/entities/tree_object.rb +++ b/lib/api/entities/tree_object.rb @@ -3,9 +3,12 @@ module API module Entities class TreeObject < Grape::Entity - expose :id, :name, :type, :path + expose :id, documentation: { example: 'a1e8f8d745cc87e3a9248358d9352bb7f9a0aeba' } + expose :name, documentation: { example: 'html' } + expose :type, documentation: { example: 'tree' } + expose :path, documentation: { example: 'files/html' } - expose :mode do |obj, options| + expose :mode, documentation: { example: '040000' } do |obj, options| filemode = obj.mode filemode = "0" + filemode if filemode.length < 6 filemode diff --git a/lib/api/entities/trigger.rb b/lib/api/entities/trigger.rb index 6a9f772fc6b..ccdaeb6a07a 100644 --- a/lib/api/entities/trigger.rb +++ b/lib/api/entities/trigger.rb @@ -5,10 +5,12 @@ module API class Trigger < Grape::Entity include ::API::Helpers::Presentable - expose :id - expose :token - expose :description - expose :created_at, :updated_at, :last_used + expose :id, documentation: { type: 'integer', example: 10 } + expose :token, documentation: { type: 'string', example: '6d056f63e50fe6f8c5f8f4aa10edb7' } + expose :description, documentation: { type: 'string', example: 'test' } + expose :created_at, documentation: { type: 'dateTime', example: '2015-12-24T15:51:21.880Z' } + expose :updated_at, documentation: { type: 'dateTime', example: '2015-12-24T17:54:31.198Z' } + expose :last_used, documentation: { type: 'dateTime', example: '2015-12-24T17:54:31.198Z' } expose :owner, using: Entities::UserBasic end end diff --git a/lib/api/entities/user_agent_detail.rb b/lib/api/entities/user_agent_detail.rb index a2d02c16589..eb6d909794e 100644 --- a/lib/api/entities/user_agent_detail.rb +++ b/lib/api/entities/user_agent_detail.rb @@ -3,9 +3,9 @@ module API module Entities class UserAgentDetail < Grape::Entity - expose :user_agent - expose :ip_address - expose :submitted, as: :akismet_submitted + expose :user_agent, documentation: { type: 'string', example: 'AppleWebKit/537.36' } + expose :ip_address, documentation: { type: 'string', example: '127.0.0.1' } + expose :submitted, as: :akismet_submitted, documentation: { type: 'boolean', example: false } end end end diff --git a/lib/api/entities/user_associations_count.rb b/lib/api/entities/user_associations_count.rb new file mode 100644 index 00000000000..af744d2d49a --- /dev/null +++ b/lib/api/entities/user_associations_count.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module API + module Entities + class UserAssociationsCount < Grape::Entity + expose :groups_count do |user| + user.groups.size + end + + expose :projects_count do |user| + user.projects.size + end + + expose :issues_count do |user| + user.issues.size + end + + expose :merge_requests_count do |user| + user.merge_requests.size + end + end + end +end diff --git a/lib/api/entities/user_basic.rb b/lib/api/entities/user_basic.rb index b8ee4e5a6e0..32e066b9f7e 100644 --- a/lib/api/entities/user_basic.rb +++ b/lib/api/entities/user_basic.rb @@ -3,16 +3,25 @@ module API module Entities class UserBasic < UserSafe - expose :state + expose :state, documentation: { type: 'string', example: 'active' } - expose :avatar_url do |user, options| + expose :avatar_url, documentation: { type: 'string', example: 'https://gravatar.com/avatar/1' } do |user, options| user.avatar_url(only_path: false) end - expose :avatar_path, if: ->(user, options) { options.fetch(:only_path, false) && user.avatar_path } - expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes + expose( + :avatar_path, + documentation: { + type: 'string', + example: '/user/avatar/28/The-Big-Lebowski-400-400.png' + }, + if: ->(user, options) { options.fetch(:only_path, false) && user.avatar_path } + ) - expose :web_url do |user, options| + expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes, + documentation: { is_array: true } + + expose :web_url, documentation: { type: 'string', example: 'https://gitlab.example.com/root' } do |user, options| Gitlab::Routing.url_helpers.user_url(user) end end diff --git a/lib/api/entities/user_counts.rb b/lib/api/entities/user_counts.rb new file mode 100644 index 00000000000..e86454c249b --- /dev/null +++ b/lib/api/entities/user_counts.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module API + module Entities + class UserCounts < Grape::Entity + expose( + :assigned_open_merge_requests_count, # @deprecated + as: :merge_requests, + documentation: { type: 'integer', example: 10 } + ) + expose :assigned_open_issues_count, as: :assigned_issues, documentation: { type: 'integer', example: 10 } + expose( + :assigned_open_merge_requests_count, + as: :assigned_merge_requests, + documentation: { type: 'integer', example: 10 } + ) + expose( + :review_requested_open_merge_requests_count, + as: :review_requested_merge_requests, + documentation: { type: 'integer', example: 10 } + ) + expose :todos_pending_count, as: :todos, documentation: { type: 'integer', example: 10 } + end + end +end diff --git a/lib/api/entities/user_public.rb b/lib/api/entities/user_public.rb index 5d0e464abe1..eda72d2cfc6 100644 --- a/lib/api/entities/user_public.rb +++ b/lib/api/entities/user_public.rb @@ -3,17 +3,23 @@ module API module Entities class UserPublic < Entities::User - expose :last_sign_in_at - expose :confirmed_at - expose :last_activity_on - expose :email - expose :theme_id, :color_scheme_id, :projects_limit, :current_sign_in_at + expose :last_sign_in_at, documentation: { type: 'dateTime', example: '2015-09-03T07:24:01.670Z' } + expose :confirmed_at, documentation: { type: 'dateTime', example: '2015-09-03T07:24:01.670Z' } + expose :last_activity_on, documentation: { type: 'dateTime', example: '2015-09-03T07:24:01.670Z' } + expose :email, documentation: { type: 'string', example: 'john@example.com' } + expose :theme_id, documentation: { type: 'integer', example: 2 } + expose :color_scheme_id, documentation: { type: 'integer', example: 1 } + expose :projects_limit, documentation: { type: 'integer', example: 10 } + expose :current_sign_in_at, documentation: { type: 'dateTime', example: '2015-09-03T07:24:01.670Z' } expose :identities, using: Entities::Identity - expose :can_create_group?, as: :can_create_group - expose :can_create_project?, as: :can_create_project - expose :two_factor_enabled?, as: :two_factor_enabled + expose :can_create_group?, as: :can_create_group, documentation: { type: 'boolean', example: true } + expose :can_create_project?, as: :can_create_project, documentation: { type: 'boolean', example: true } + + expose :two_factor_enabled?, as: :two_factor_enabled, documentation: { type: 'boolean', example: true } + expose :external - expose :private_profile + + expose :private_profile, documentation: { type: 'boolean', example: :null } expose :commit_email_or_default, as: :commit_email end end diff --git a/lib/api/entities/user_safe.rb b/lib/api/entities/user_safe.rb index 127a8ef2160..0fbb10307cf 100644 --- a/lib/api/entities/user_safe.rb +++ b/lib/api/entities/user_safe.rb @@ -5,8 +5,9 @@ module API class UserSafe < Grape::Entity include RequestAwareEntity - expose :id, :username - expose :name do |user| + expose :id, documentation: { type: 'integer', example: 1 } + expose :username, documentation: { type: 'string', example: 'admin' } + expose :name, documentation: { type: 'string', example: 'Administrator' } do |user| current_user = request.respond_to?(:current_user) ? request.current_user : options.fetch(:current_user, nil) user.redacted_name(current_user) diff --git a/lib/api/entities/wiki_attachment.rb b/lib/api/entities/wiki_attachment.rb index 03a6cc8d644..8629261cfc6 100644 --- a/lib/api/entities/wiki_attachment.rb +++ b/lib/api/entities/wiki_attachment.rb @@ -5,12 +5,16 @@ module API class WikiAttachment < Grape::Entity include Gitlab::FileMarkdownLinkBuilder - expose :file_name - expose :file_path - expose :branch + expose :file_name, documentation: { type: 'string', example: 'dk.png' } + expose :file_path, documentation: { type: 'string', example: 'uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png' } + expose :branch, documentation: { type: 'string', example: 'main' } expose :link do - expose :file_path, as: :url - expose :markdown do |_entity| + expose :file_path, as: :url, documentation: { + type: 'string', example: 'uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png' + } + expose :markdown, documentation: { + type: 'string', example: '![dk](uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png)' + } do |_entity| self.markdown_link end end diff --git a/lib/api/entities/wiki_page.rb b/lib/api/entities/wiki_page.rb index 5bba4271396..07ef4a4a156 100644 --- a/lib/api/entities/wiki_page.rb +++ b/lib/api/entities/wiki_page.rb @@ -5,7 +5,9 @@ module API class WikiPage < WikiPageBasic include ::MarkupHelper - expose :content do |wiki_page, options| + expose :content, documentation: { + type: 'string', example: 'Here is an instruction how to deploy this project.' + } do |wiki_page, options| if options[:render_html] render_wiki_content( wiki_page, @@ -17,7 +19,7 @@ module API end end - expose :encoding do |wiki_page| + expose :encoding, documentation: { type: 'string', example: 'UTF-8' } do |wiki_page| wiki_page.content.encoding.name end end diff --git a/lib/api/entities/wiki_page_basic.rb b/lib/api/entities/wiki_page_basic.rb index e10c0e6d553..088a0d1bf55 100644 --- a/lib/api/entities/wiki_page_basic.rb +++ b/lib/api/entities/wiki_page_basic.rb @@ -3,9 +3,9 @@ module API module Entities class WikiPageBasic < Grape::Entity - expose :format - expose :slug - expose :title + expose :format, documentation: { type: 'string', example: 'markdown' } + expose :slug, documentation: { type: 'string', example: 'deploy' } + expose :title, documentation: { type: 'string', example: 'deploy' } end end end diff --git a/lib/api/entities/x509_certificate.rb b/lib/api/entities/x509_certificate.rb index aad11339148..95d4948906e 100644 --- a/lib/api/entities/x509_certificate.rb +++ b/lib/api/entities/x509_certificate.rb @@ -3,13 +3,16 @@ module API module Entities class X509Certificate < Grape::Entity - expose :id - expose :subject - expose :subject_key_identifier - expose :email - expose :serial_number - expose :certificate_status - expose :x509_issuer, using: 'API::Entities::X509Issuer' + expose :id, documentation: { type: 'integer', example: 1 } + expose :subject, documentation: { type: 'string', example: 'CN=gitlab@example.org,OU=Example,O=World' } + expose :subject_key_identifier, documentation: { + type: 'string', + example: 'BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC:BC' + } + expose :email, documentation: { type: 'string', example: 'gitlab@example.org' } + expose :serial_number, documentation: { type: 'integer', example: 278969561018901340486471282831158785578 } + expose :certificate_status, documentation: { type: 'string', example: 'good' } + expose :x509_issuer, using: 'API::Entities::X509Issuer', documentation: { type: 'string', example: '100755' } end end end diff --git a/lib/api/entities/x509_issuer.rb b/lib/api/entities/x509_issuer.rb index b480bc107bc..22429560c72 100644 --- a/lib/api/entities/x509_issuer.rb +++ b/lib/api/entities/x509_issuer.rb @@ -3,10 +3,13 @@ module API module Entities class X509Issuer < Grape::Entity - expose :id - expose :subject - expose :subject_key_identifier - expose :crl_url + expose :id, documentation: { type: 'integer', example: 1 } + expose :subject, documentation: { type: 'string', example: 'CN=PKI,OU=Example,O=World' } + expose :subject_key_identifier, documentation: { + type: 'string', + example: 'AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB:AB' + } + expose :crl_url, documentation: { type: 'string', example: 'http://example.com/pki.crl' } end end end diff --git a/lib/api/entities/x509_signature.rb b/lib/api/entities/x509_signature.rb index 909b630288c..c3f0cb3659d 100644 --- a/lib/api/entities/x509_signature.rb +++ b/lib/api/entities/x509_signature.rb @@ -3,7 +3,7 @@ module API module Entities class X509Signature < Grape::Entity - expose :verification_status + expose :verification_status, documentation: { type: 'string', example: 'unverified' } expose :x509_certificate, using: 'API::Entities::X509Certificate' end end |