Skip to content
Snippets Groups Projects
Unverified Commit 4d3f7ae1 authored by Francisco Javier López's avatar Francisco Javier López
Browse files

Removed API endpoint and specs

parent 439adb96
No related branches found
No related tags found
No related merge requests found
Showing
with 25 additions and 1018 deletions
Loading
Loading
@@ -8,8 +8,6 @@ engines:
languages:
- ruby
- javascript
exclude_paths:
- "lib/api/v3/*"
ratings:
paths:
- Gemfile.lock
Loading
Loading
Loading
Loading
@@ -173,7 +173,6 @@ Lint/UriEscapeUnescape:
- 'spec/requests/api/files_spec.rb'
- 'spec/requests/api/internal_spec.rb'
- 'spec/requests/api/issues_spec.rb'
- 'spec/requests/api/v3/issues_spec.rb'
 
# Offense count: 1
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
Loading
Loading
@@ -333,8 +332,6 @@ RSpec/ScatteredSetup:
- 'spec/lib/gitlab/bitbucket_import/importer_spec.rb'
- 'spec/lib/gitlab/git/env_spec.rb'
- 'spec/requests/api/jobs_spec.rb'
- 'spec/requests/api/v3/builds_spec.rb'
- 'spec/requests/api/v3/projects_spec.rb'
- 'spec/services/projects/create_service_spec.rb'
 
# Offense count: 1
Loading
Loading
@@ -618,7 +615,6 @@ Style/OrAssignment:
Exclude:
- 'app/models/concerns/token_authenticatable.rb'
- 'lib/api/commit_statuses.rb'
- 'lib/api/v3/members.rb'
- 'lib/gitlab/project_transfer.rb'
 
# Offense count: 50
Loading
Loading
@@ -781,7 +777,6 @@ Style/TernaryParentheses:
- 'app/finders/projects_finder.rb'
- 'app/helpers/namespaces_helper.rb'
- 'features/support/capybara.rb'
- 'lib/api/v3/projects.rb'
- 'lib/gitlab/ci/build/artifacts/metadata/entry.rb'
- 'spec/requests/api/pipeline_schedules_spec.rb'
- 'spec/support/capybara.rb'
Loading
Loading
Loading
Loading
@@ -360,17 +360,6 @@ def repository_storages
Array(read_attribute(:repository_storages))
end
 
# DEPRECATED
# repository_storage is still required in the API. Remove in 9.0
# Still used in API v3
def repository_storage
repository_storages.first
end
def repository_storage=(value)
self.repository_storages = [value]
end
def default_project_visibility=(level)
super(Gitlab::VisibilityLevel.level_value(level))
end
Loading
Loading
# Makes api V3 compatible with old project features permissions methods
# Makes api V4 compatible with old project features permissions methods
#
# After migrating issues_enabled merge_requests_enabled builds_enabled snippets_enabled and wiki_enabled
# fields to a new table "project_features", support for the old fields is still needed in the API.
Loading
Loading
---
title: Removed API v3 from the codebase
merge_request: 18970
author:
type: removed
Loading
Loading
@@ -90,24 +90,23 @@ specification.
## Compatibility Guidelines
 
The HTTP API is versioned using a single number, the current one being 4. This
number symbolises the same as the major version number as described by
number symbolises the same as the major version number as described by
[SemVer](https://semver.org/). This mean that backward incompatible changes
will require this version number to change. However, the minor version is
not explicit. This allows for a stable API endpoint, but also means new
not explicit. This allows for a stable API endpoint, but also means new
features can be added to the API in the same version number.
 
New features and bug fixes are released in tandem with a new GitLab, and apart
from incidental patch and security releases, are released on the 22nd each
month. Backward incompatible changes (e.g. endpoints removal, parameters
removal etc.), as well as removal of entire API versions are done in tandem
with a major point release of GitLab itself. All deprecations and changes
between two versions should be listed in the documentation. For the changes
month. Backward incompatible changes (e.g. endpoints removal, parameters
removal etc.), as well as removal of entire API versions are done in tandem
with a major point release of GitLab itself. All deprecations and changes
between two versions should be listed in the documentation. For the changes
between v3 and v4; please read the [v3 to v4 documentation](v3_to_v4.md)
 
#### Current status
 
Currently two API versions are available, v3 and v4. v3 is deprecated and
will soon be removed. Deletion is scheduled for
Currently only API version v4 is available. Version v3 was removed in
[GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-ce/issues/36819).
 
## Basic usage
Loading
Loading
Loading
Loading
@@ -23,7 +23,7 @@ POST /applications
| `scopes` | string | yes | The scopes of the application |
 
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --data "name=MyApplication&redirect_uri=http://redirect.uri&scopes=" https://gitlab.example.com/api/v3/applications
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --data "name=MyApplication&redirect_uri=http://redirect.uri&scopes=" https://gitlab.example.com/api/v4/applications
```
 
Example response:
Loading
Loading
Loading
Loading
@@ -123,7 +123,7 @@ POST /projects/:id/environments/:environment_id/stop
| `environment_id` | integer | yes | The ID of the environment |
 
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/environments/1/stop"
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/environments/1/stop"
```
 
Example response:
Loading
Loading
Loading
Loading
@@ -1169,7 +1169,7 @@ The `file=` parameter must point to a file on your filesystem and be preceded
by `@`. For example:
 
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "file=@dk.png" https://gitlab.example.com/api/v3/projects/5/uploads
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "file=@dk.png" https://gitlab.example.com/api/v4/projects/5/uploads
```
 
Returned object:
Loading
Loading
Loading
Loading
@@ -2,10 +2,9 @@
 
Since GitLab 9.0, API V4 is the preferred version to be used.
 
API V3 will be unsupported from GitLab 9.5, to be released on August
22, 2017. It will be removed in GitLab 9.5 or later. In the meantime, we advise
you to make any necessary changes to applications that use V3. The V3 API
documentation is still
API V3 was unsupported from GitLab 9.5, released on August
22, 2017. API v3 was removed in [GitLab 11.0](https://gitlab.com/gitlab-org/gitlab-ce/issues/36819).
The V3 API documentation is still
[available](https://gitlab.com/gitlab-org/gitlab-ce/blob/8-16-stable/doc/api/README.md).
 
Below are the changes made between V3 and V4.
Loading
Loading
Loading
Loading
@@ -107,7 +107,7 @@ you will not get a shibboleth session!
RewriteEngine on
 
#Don't escape encoded characters in api requests
RewriteCond %{REQUEST_URI} ^/api/v3/.*
RewriteCond %{REQUEST_URI} ^/api/v4/.*
RewriteCond %{REQUEST_URI} !/Shibboleth.sso
RewriteCond %{REQUEST_URI} !/shibboleth-sp
RewriteRule .* http://127.0.0.1:8181%{REQUEST_URI} [P,QSA,NE]
Loading
Loading
Loading
Loading
@@ -22,48 +22,14 @@ class API < Grape::API
allow_access_with_scope :api
prefix :api
 
version %w(v3 v4), using: :path
version 'v3', using: :path do
helpers ::API::V3::Helpers
helpers ::API::Helpers::CommonHelpers
mount ::API::V3::AwardEmoji
mount ::API::V3::Boards
mount ::API::V3::Branches
mount ::API::V3::BroadcastMessages
mount ::API::V3::Builds
mount ::API::V3::Commits
mount ::API::V3::DeployKeys
mount ::API::V3::Environments
mount ::API::V3::Files
mount ::API::V3::Groups
mount ::API::V3::Issues
mount ::API::V3::Labels
mount ::API::V3::Members
mount ::API::V3::MergeRequestDiffs
mount ::API::V3::MergeRequests
mount ::API::V3::Notes
mount ::API::V3::Pipelines
mount ::API::V3::ProjectHooks
mount ::API::V3::Milestones
mount ::API::V3::Projects
mount ::API::V3::ProjectSnippets
mount ::API::V3::Repositories
mount ::API::V3::Runners
mount ::API::V3::Services
mount ::API::V3::Settings
mount ::API::V3::Snippets
mount ::API::V3::Subscriptions
mount ::API::V3::SystemHooks
mount ::API::V3::Tags
mount ::API::V3::Templates
mount ::API::V3::Todos
mount ::API::V3::Triggers
mount ::API::V3::Users
mount ::API::V3::Variables
route :any, '*path' do
error!('API V3 is no longer supported. Use API V4 instead.', 410)
end
end
 
version 'v4', using: :path
before do
header['X-Frame-Options'] = 'SAMEORIGIN'
header['X-Content-Type-Options'] = 'nosniff'
Loading
Loading
module API
module V3
class AwardEmoji < Grape::API
include PaginationParams
before { authenticate! }
AWARDABLES = %w[issue merge_request snippet].freeze
resource :projects, requirements: { id: %r{[^/]+} } do
AWARDABLES.each do |awardable_type|
awardable_string = awardable_type.pluralize
awardable_id_string = "#{awardable_type}_id"
params do
requires :id, type: String, desc: 'The ID of a project'
requires :"#{awardable_id_string}", type: Integer, desc: "The ID of an Issue, Merge Request or Snippet"
end
[
":id/#{awardable_string}/:#{awardable_id_string}/award_emoji",
":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji"
].each do |endpoint|
desc 'Get a list of project +awardable+ award emoji' do
detail 'This feature was introduced in 8.9'
success Entities::AwardEmoji
end
params do
use :pagination
end
get endpoint do
if can_read_awardable?
awards = awardable.award_emoji
present paginate(awards), with: Entities::AwardEmoji
else
not_found!("Award Emoji")
end
end
desc 'Get a specific award emoji' do
detail 'This feature was introduced in 8.9'
success Entities::AwardEmoji
end
params do
requires :award_id, type: Integer, desc: 'The ID of the award'
end
get "#{endpoint}/:award_id" do
if can_read_awardable?
present awardable.award_emoji.find(params[:award_id]), with: Entities::AwardEmoji
else
not_found!("Award Emoji")
end
end
desc 'Award a new Emoji' do
detail 'This feature was introduced in 8.9'
success Entities::AwardEmoji
end
params do
requires :name, type: String, desc: 'The name of a award_emoji (without colons)'
end
post endpoint do
not_found!('Award Emoji') unless can_read_awardable? && can_award_awardable?
award = awardable.create_award_emoji(params[:name], current_user)
if award.persisted?
present award, with: Entities::AwardEmoji
else
not_found!("Award Emoji #{award.errors.messages}")
end
end
desc 'Delete a +awardables+ award emoji' do
detail 'This feature was introduced in 8.9'
success Entities::AwardEmoji
end
params do
requires :award_id, type: Integer, desc: 'The ID of an award emoji'
end
delete "#{endpoint}/:award_id" do
award = awardable.award_emoji.find(params[:award_id])
unauthorized! unless award.user == current_user || current_user.admin?
award.destroy
present award, with: Entities::AwardEmoji
end
end
end
end
helpers do
def can_read_awardable?
can?(current_user, read_ability(awardable), awardable)
end
def can_award_awardable?
awardable.user_can_award?(current_user, params[:name])
end
def awardable
@awardable ||=
begin
if params.include?(:note_id)
note_id = params.delete(:note_id)
awardable.notes.find(note_id)
elsif params.include?(:issue_id)
user_project.issues.find(params[:issue_id])
elsif params.include?(:merge_request_id)
user_project.merge_requests.find(params[:merge_request_id])
else
user_project.snippets.find(params[:snippet_id])
end
end
end
def read_ability(awardable)
case awardable
when Note
read_ability(awardable.noteable)
else
:"read_#{awardable.class.to_s.underscore}"
end
end
end
end
end
end
module API
module V3
class Boards < Grape::API
before { authenticate! }
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: { id: %r{[^/]+} } do
desc 'Get all project boards' do
detail 'This feature was introduced in 8.13'
success ::API::Entities::Board
end
get ':id/boards' do
authorize!(:read_board, user_project)
present user_project.boards, with: ::API::Entities::Board
end
params do
requires :board_id, type: Integer, desc: 'The ID of a board'
end
segment ':id/boards/:board_id' do
helpers do
def project_board
board = user_project.boards.first
if params[:board_id] == board.id
board
else
not_found!('Board')
end
end
def board_lists
project_board.lists.destroyable
end
end
desc 'Get the lists of a project board' do
detail 'Does not include `done` list. This feature was introduced in 8.13'
success ::API::Entities::List
end
get '/lists' do
authorize!(:read_board, user_project)
present board_lists, with: ::API::Entities::List
end
desc 'Delete a board list' do
detail 'This feature was introduced in 8.13'
success ::API::Entities::List
end
params do
requires :list_id, type: Integer, desc: 'The ID of a board list'
end
delete "/lists/:list_id" do
authorize!(:admin_list, user_project)
list = board_lists.find(params[:list_id])
service = ::Boards::Lists::DestroyService.new(user_project, current_user)
if service.execute(list)
present list, with: ::API::Entities::List
else
render_api_error!({ error: 'List could not be deleted!' }, 400)
end
end
end
end
end
end
end
require 'mime/types'
module API
module V3
class Branches < Grape::API
before { authenticate! }
before { authorize! :download_code, user_project }
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: { id: %r{[^/]+} } do
desc 'Get a project repository branches' do
success ::API::Entities::Branch
end
get ":id/repository/branches" do
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42276')
repository = user_project.repository
branches = repository.branches.sort_by(&:name)
merged_branch_names = repository.merged_branch_names(branches.map(&:name))
present branches, with: ::API::Entities::Branch, project: user_project, merged_branch_names: merged_branch_names
end
desc 'Delete a branch'
params do
requires :branch, type: String, desc: 'The name of the branch'
end
delete ":id/repository/branches/:branch", requirements: { branch: /.+/ } do
authorize_push_project
result = DeleteBranchService.new(user_project, current_user)
.execute(params[:branch])
if result[:status] == :success
status(200)
{
branch_name: params[:branch]
}
else
render_api_error!(result[:message], result[:return_code])
end
end
desc 'Delete all merged branches'
delete ":id/repository/merged_branches" do
DeleteMergedBranchesService.new(user_project, current_user).async_execute
status(200)
end
desc 'Create branch' do
success ::API::Entities::Branch
end
params do
requires :branch_name, type: String, desc: 'The name of the branch'
requires :ref, type: String, desc: 'Create branch from commit sha or existing branch'
end
post ":id/repository/branches" do
authorize_push_project
result = CreateBranchService.new(user_project, current_user)
.execute(params[:branch_name], params[:ref])
if result[:status] == :success
present result[:branch],
with: ::API::Entities::Branch,
project: user_project
else
render_api_error!(result[:message], 400)
end
end
end
end
end
end
module API
module V3
class BroadcastMessages < Grape::API
include PaginationParams
before { authenticate! }
before { authenticated_as_admin! }
resource :broadcast_messages do
helpers do
def find_message
BroadcastMessage.find(params[:id])
end
end
desc 'Delete a broadcast message' do
detail 'This feature was introduced in GitLab 8.12.'
success ::API::Entities::BroadcastMessage
end
params do
requires :id, type: Integer, desc: 'Broadcast message ID'
end
delete ':id' do
message = find_message
present message.destroy, with: ::API::Entities::BroadcastMessage
end
end
end
end
end
module API
module V3
class Builds < Grape::API
include PaginationParams
before { authenticate! }
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
helpers do
params :optional_scope do
optional :scope, types: [String, Array[String]], desc: 'The scope of builds to show',
values: %w(pending running failed success canceled skipped),
coerce_with: ->(scope) {
if scope.is_a?(String)
[scope]
elsif scope.is_a?(::Hash)
scope.values
else
['unknown']
end
}
end
end
desc 'Get a project builds' do
success ::API::V3::Entities::Build
end
params do
use :optional_scope
use :pagination
end
get ':id/builds' do
builds = user_project.builds.order('id DESC')
builds = filter_builds(builds, params[:scope])
builds = builds.preload(:user, :job_artifacts_archive, :runner, pipeline: :project)
present paginate(builds), with: ::API::V3::Entities::Build
end
desc 'Get builds for a specific commit of a project' do
success ::API::V3::Entities::Build
end
params do
requires :sha, type: String, desc: 'The SHA id of a commit'
use :optional_scope
use :pagination
end
get ':id/repository/commits/:sha/builds' do
authorize_read_builds!
break not_found! unless user_project.commit(params[:sha])
pipelines = user_project.pipelines.where(sha: params[:sha])
builds = user_project.builds.where(pipeline: pipelines).order('id DESC')
builds = filter_builds(builds, params[:scope])
present paginate(builds), with: ::API::V3::Entities::Build
end
desc 'Get a specific build of a project' do
success ::API::V3::Entities::Build
end
params do
requires :build_id, type: Integer, desc: 'The ID of a build'
end
get ':id/builds/:build_id' do
authorize_read_builds!
build = get_build!(params[:build_id])
present build, with: ::API::V3::Entities::Build
end
desc 'Download the artifacts file from build' do
detail 'This feature was introduced in GitLab 8.5'
end
params do
requires :build_id, type: Integer, desc: 'The ID of a build'
end
get ':id/builds/:build_id/artifacts' do
authorize_read_builds!
build = get_build!(params[:build_id])
present_carrierwave_file!(build.artifacts_file)
end
desc 'Download the artifacts file from build' do
detail 'This feature was introduced in GitLab 8.10'
end
params do
requires :ref_name, type: String, desc: 'The ref from repository'
requires :job, type: String, desc: 'The name for the build'
end
get ':id/builds/artifacts/:ref_name/download',
requirements: { ref_name: /.+/ } do
authorize_read_builds!
builds = user_project.latest_successful_builds_for(params[:ref_name])
latest_build = builds.find_by!(name: params[:job])
present_carrierwave_file!(latest_build.artifacts_file)
end
# TODO: We should use `present_disk_file!` and leave this implementation for backward compatibility (when build trace
# is saved in the DB instead of file). But before that, we need to consider how to replace the value of
# `runners_token` with some mask (like `xxxxxx`) when sending trace file directly by workhorse.
desc 'Get a trace of a specific build of a project'
params do
requires :build_id, type: Integer, desc: 'The ID of a build'
end
get ':id/builds/:build_id/trace' do
authorize_read_builds!
build = get_build!(params[:build_id])
header 'Content-Disposition', "infile; filename=\"#{build.id}.log\""
content_type 'text/plain'
env['api.format'] = :binary
trace = build.trace.raw
body trace
end
desc 'Cancel a specific build of a project' do
success ::API::V3::Entities::Build
end
params do
requires :build_id, type: Integer, desc: 'The ID of a build'
end
post ':id/builds/:build_id/cancel' do
authorize_update_builds!
build = get_build!(params[:build_id])
authorize!(:update_build, build)
build.cancel
present build, with: ::API::V3::Entities::Build
end
desc 'Retry a specific build of a project' do
success ::API::V3::Entities::Build
end
params do
requires :build_id, type: Integer, desc: 'The ID of a build'
end
post ':id/builds/:build_id/retry' do
authorize_update_builds!
build = get_build!(params[:build_id])
authorize!(:update_build, build)
break forbidden!('Build is not retryable') unless build.retryable?
build = Ci::Build.retry(build, current_user)
present build, with: ::API::V3::Entities::Build
end
desc 'Erase build (remove artifacts and build trace)' do
success ::API::V3::Entities::Build
end
params do
requires :build_id, type: Integer, desc: 'The ID of a build'
end
post ':id/builds/:build_id/erase' do
authorize_update_builds!
build = get_build!(params[:build_id])
authorize!(:erase_build, build)
break forbidden!('Build is not erasable!') unless build.erasable?
build.erase(erased_by: current_user)
present build, with: ::API::V3::Entities::Build
end
desc 'Keep the artifacts to prevent them from being deleted' do
success ::API::V3::Entities::Build
end
params do
requires :build_id, type: Integer, desc: 'The ID of a build'
end
post ':id/builds/:build_id/artifacts/keep' do
authorize_update_builds!
build = get_build!(params[:build_id])
authorize!(:update_build, build)
break not_found!(build) unless build.artifacts?
build.keep_artifacts!
status 200
present build, with: ::API::V3::Entities::Build
end
desc 'Trigger a manual build' do
success ::API::V3::Entities::Build
detail 'This feature was added in GitLab 8.11'
end
params do
requires :build_id, type: Integer, desc: 'The ID of a Build'
end
post ":id/builds/:build_id/play" do
authorize_read_builds!
build = get_build!(params[:build_id])
authorize!(:update_build, build)
bad_request!("Unplayable Job") unless build.playable?
build.play(current_user)
status 200
present build, with: ::API::V3::Entities::Build
end
end
helpers do
def find_build(id)
user_project.builds.find_by(id: id.to_i)
end
def get_build!(id)
find_build(id) || not_found!
end
def filter_builds(builds, scope)
return builds if scope.nil? || scope.empty?
available_statuses = ::CommitStatus::AVAILABLE_STATUSES
unknown = scope - available_statuses
render_api_error!('Scope contains invalid value(s)', 400) unless unknown.empty?
builds.where(status: available_statuses && scope)
end
def authorize_read_builds!
authorize! :read_build, user_project
end
def authorize_update_builds!
authorize! :update_build, user_project
end
end
end
end
end
require 'mime/types'
module API
module V3
class Commits < Grape::API
include PaginationParams
before { authenticate! }
before { authorize! :download_code, user_project }
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
desc 'Get a project repository commits' do
success ::API::Entities::Commit
end
params do
optional :ref_name, type: String, desc: 'The name of a repository branch or tag, if not given the default branch is used'
optional :since, type: DateTime, desc: 'Only commits after or in this date will be returned'
optional :until, type: DateTime, desc: 'Only commits before or in this date will be returned'
optional :page, type: Integer, default: 0, desc: 'The page for pagination'
optional :per_page, type: Integer, default: 20, desc: 'The number of results per page'
optional :path, type: String, desc: 'The file path'
end
get ":id/repository/commits" do
ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
offset = params[:page] * params[:per_page]
commits = user_project.repository.commits(ref,
path: params[:path],
limit: params[:per_page],
offset: offset,
after: params[:since],
before: params[:until])
present commits, with: ::API::Entities::Commit
end
desc 'Commit multiple file changes as one commit' do
success ::API::Entities::CommitDetail
detail 'This feature was introduced in GitLab 8.13'
end
params do
requires :branch_name, type: String, desc: 'The name of branch'
requires :commit_message, type: String, desc: 'Commit message'
requires :actions, type: Array[Hash], desc: 'Actions to perform in commit'
optional :author_email, type: String, desc: 'Author email for commit'
optional :author_name, type: String, desc: 'Author name for commit'
end
post ":id/repository/commits" do
authorize! :push_code, user_project
attrs = declared_params.dup
branch = attrs.delete(:branch_name)
attrs.merge!(start_branch: branch, branch_name: branch)
result = ::Files::MultiService.new(user_project, current_user, attrs).execute
if result[:status] == :success
commit_detail = user_project.repository.commits(result[:result], limit: 1).first
present commit_detail, with: ::API::Entities::CommitDetail
else
render_api_error!(result[:message], 400)
end
end
desc 'Get a specific commit of a project' do
success ::API::Entities::CommitDetail
failure [[404, 'Not Found']]
end
params do
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
optional :stats, type: Boolean, default: true, desc: 'Include commit stats'
end
get ":id/repository/commits/:sha", requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha])
not_found! "Commit" unless commit
present commit, with: ::API::Entities::CommitDetail, stats: params[:stats]
end
desc 'Get the diff for a specific commit of a project' do
failure [[404, 'Not Found']]
end
params do
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end
get ":id/repository/commits/:sha/diff", requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha])
not_found! "Commit" unless commit
commit.raw_diffs.to_a
end
desc "Get a commit's comments" do
success ::API::Entities::CommitNote
failure [[404, 'Not Found']]
end
params do
use :pagination
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end
get ':id/repository/commits/:sha/comments', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit
notes = commit.notes.order(:created_at)
present paginate(notes), with: ::API::Entities::CommitNote
end
desc 'Cherry pick commit into a branch' do
detail 'This feature was introduced in GitLab 8.15'
success ::API::Entities::Commit
end
params do
requires :sha, type: String, desc: 'A commit sha to be cherry picked'
requires :branch, type: String, desc: 'The name of the branch'
end
post ':id/repository/commits/:sha/cherry_pick', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
authorize! :push_code, user_project
commit = user_project.commit(params[:sha])
not_found!('Commit') unless commit
branch = user_project.repository.find_branch(params[:branch])
not_found!('Branch') unless branch
commit_params = {
commit: commit,
start_branch: params[:branch],
branch_name: params[:branch]
}
result = ::Commits::CherryPickService.new(user_project, current_user, commit_params).execute
if result[:status] == :success
branch = user_project.repository.find_branch(params[:branch])
present user_project.repository.commit(branch.dereferenced_target), with: ::API::Entities::Commit
else
render_api_error!(result[:message], 400)
end
end
desc 'Post comment to commit' do
success ::API::Entities::CommitNote
end
params do
requires :sha, type: String, regexp: /\A\h{6,40}\z/, desc: "The commit's SHA"
requires :note, type: String, desc: 'The text of the comment'
optional :path, type: String, desc: 'The file path'
given :path do
requires :line, type: Integer, desc: 'The line number'
requires :line_type, type: String, values: %w(new old), default: 'new', desc: 'The type of the line'
end
end
post ':id/repository/commits/:sha/comments', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit
opts = {
note: params[:note],
noteable_type: 'Commit',
commit_id: commit.id
}
if params[:path]
commit.raw_diffs(limits: false).each do |diff|
next unless diff.new_path == params[:path]
lines = Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
lines.each do |line|
next unless line.new_pos == params[:line] && line.type == params[:line_type]
break opts[:line_code] = Gitlab::Git.diff_line_code(diff.new_path, line.new_pos, line.old_pos)
end
break if opts[:line_code]
end
opts[:type] = LegacyDiffNote.name if opts[:line_code]
end
note = ::Notes::CreateService.new(user_project, current_user, opts).execute
if note.save
present note, with: ::API::Entities::CommitNote
else
render_api_error!("Failed to save note #{note.errors.messages}", 400)
end
end
end
end
end
end
module API
module V3
class DeployKeys < Grape::API
before { authenticate! }
helpers do
def add_deploy_keys_project(project, attrs = {})
project.deploy_keys_projects.create(attrs)
end
def find_by_deploy_key(project, key_id)
project.deploy_keys_projects.find_by!(deploy_key: key_id)
end
end
get "deploy_keys" do
authenticated_as_admin!
keys = DeployKey.all
present keys, with: ::API::Entities::SSHKey
end
params do
requires :id, type: String, desc: 'The ID of the project'
end
resource :projects, requirements: { id: %r{[^/]+} } do
before { authorize_admin_project }
%w(keys deploy_keys).each do |path|
desc "Get a specific project's deploy keys" do
success ::API::Entities::DeployKeysProject
end
get ":id/#{path}" do
keys = user_project.deploy_keys_projects.preload(:deploy_key)
present keys, with: ::API::Entities::DeployKeysProject
end
desc 'Get single deploy key' do
success ::API::Entities::DeployKeysProject
end
params do
requires :key_id, type: Integer, desc: 'The ID of the deploy key'
end
get ":id/#{path}/:key_id" do
key = find_by_deploy_key(user_project, params[:key_id])
present key, with: ::API::Entities::DeployKeysProject
end
desc 'Add new deploy key to currently authenticated user' do
success ::API::Entities::DeployKeysProject
end
params do
requires :key, type: String, desc: 'The new deploy key'
requires :title, type: String, desc: 'The name of the deploy key'
optional :can_push, type: Boolean, desc: "Can deploy key push to the project's repository"
end
post ":id/#{path}" do
params[:key].strip!
# Check for an existing key joined to this project
key = user_project.deploy_keys_projects
.joins(:deploy_key)
.find_by(keys: { key: params[:key] })
if key
present key, with: ::API::Entities::DeployKeysProject
break
end
# Check for available deploy keys in other projects
key = current_user.accessible_deploy_keys.find_by(key: params[:key])
if key
added_key = add_deploy_keys_project(user_project, deploy_key: key, can_push: !!params[:can_push])
present added_key, with: ::API::Entities::DeployKeysProject
break
end
# Create a new deploy key
key_attributes = { can_push: !!params[:can_push],
deploy_key_attributes: declared_params.except(:can_push) }
key = add_deploy_keys_project(user_project, key_attributes)
if key.valid?
present key, with: ::API::Entities::DeployKeysProject
else
render_validation_error!(key)
end
end
desc 'Enable a deploy key for a project' do
detail 'This feature was added in GitLab 8.11'
success ::API::Entities::SSHKey
end
params do
requires :key_id, type: Integer, desc: 'The ID of the deploy key'
end
post ":id/#{path}/:key_id/enable" do
key = ::Projects::EnableDeployKeyService.new(user_project,
current_user, declared_params).execute
if key
present key, with: ::API::Entities::SSHKey
else
not_found!('Deploy Key')
end
end
desc 'Disable a deploy key for a project' do
detail 'This feature was added in GitLab 8.11'
success ::API::Entities::SSHKey
end
params do
requires :key_id, type: Integer, desc: 'The ID of the deploy key'
end
delete ":id/#{path}/:key_id/disable" do
key = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id])
key.destroy
present key.deploy_key, with: ::API::Entities::SSHKey
end
desc 'Delete deploy key for a project' do
success Key
end
params do
requires :key_id, type: Integer, desc: 'The ID of the deploy key'
end
delete ":id/#{path}/:key_id" do
key = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id])
if key
key.destroy
else
not_found!('Deploy Key')
end
end
end
end
end
end
end
module API
module V3
# Deployments RESTful API endpoints
class Deployments < Grape::API
include PaginationParams
before { authenticate! }
params do
requires :id, type: String, desc: 'The project ID'
end
resource :projects, requirements: { id: %r{[^/]+} } do
desc 'Get all deployments of the project' do
detail 'This feature was introduced in GitLab 8.11.'
success ::API::V3::Deployments
end
params do
use :pagination
end
get ':id/deployments' do
authorize! :read_deployment, user_project
present paginate(user_project.deployments), with: ::API::V3::Deployments
end
desc 'Gets a specific deployment' do
detail 'This feature was introduced in GitLab 8.11.'
success ::API::V3::Deployments
end
params do
requires :deployment_id, type: Integer, desc: 'The deployment ID'
end
get ':id/deployments/:deployment_id' do
authorize! :read_deployment, user_project
deployment = user_project.deployments.find(params[:deployment_id])
present deployment, with: ::API::V3::Deployments
end
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment