Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
fd856c69
Commit
fd856c69
authored
7 years ago
by
Felipe Artur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Group milestones API endpoint
parent
9bd93670
Changes
11
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
833 additions
and
4 deletions
+833
-4
doc/api/README.md
doc/api/README.md
+2
-1
doc/api/group_milestones.md
doc/api/group_milestones.md
+120
-0
lib/api/api.rb
lib/api/api.rb
+2
-1
lib/api/entities.rb
lib/api/entities.rb
+2
-2
lib/api/group_milestones.rb
lib/api/group_milestones.rb
+85
-0
lib/api/helpers.rb
lib/api/helpers.rb
+4
-0
lib/api/milestone_responses.rb
lib/api/milestone_responses.rb
+98
-0
lib/api/project_milestones.rb
lib/api/project_milestones.rb
+91
-0
spec/requests/api/group_milestones_spec.rb
spec/requests/api/group_milestones_spec.rb
+21
-0
spec/requests/api/project_milestones_spec.rb
spec/requests/api/project_milestones_spec.rb
+25
-0
spec/support/api/milestones_shared_examples.rb
spec/support/api/milestones_shared_examples.rb
+383
-0
No files found.
doc/api/README.md
View file @
fd856c69
...
...
@@ -30,7 +30,8 @@ following locations:
-
[
Labels
](
labels.md
)
-
[
License
](
license.md
)
-
[
Merge Requests
](
merge_requests.md
)
-
[
Milestones
](
milestones.md
)
-
[
Project milestones
](
milestones.md
)
-
[
Group milestones
](
group_milestones.md
)
-
[
Namespaces
](
namespaces.md
)
-
[
Notes
](
notes.md
)
(
comments
)
-
[
Notification settings
](
notification_settings.md
)
...
...
This diff is collapsed.
Click to expand it.
doc/api/group_milestones.md
0 → 100644
View file @
fd856c69
# Group milestones API
## List group milestones
Returns a list of group milestones.
```
GET /groups/:id/milestones
GET /groups/:id/milestones?iids=42
GET /groups/:id/milestones?iids[]=42&iids[]=43
GET /groups/:id/milestones?state=active
GET /groups/:id/milestones?state=closed
GET /groups/:id/milestones?search=version
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
|
`id`
| integer/string | yes | The ID or
[
URL-encoded path of the group
](
README.md#namespaced-path-encoding
)
owned by the authenticated user |
|
`iids`
| Array[integer] | optional | Return only the milestones having the given
`iids`
|
|
`state`
| string | optional | Return only
`active`
or
`closed`
milestones
` |
| `
search
` | string | optional | Return only milestones with a title or description matching the provided string |
```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/5/milestones
```
Example Response:
```json
[
{
"id": 12,
"iid": 3,
"group_id": 16,
"title": "10.0",
"description": "Version",
"due_date": "2013-11-29",
"start_date": "2013-11-10",
"state": "active",
"updated_at": "2013-10-02T09:24:18Z",
"created_at": "2013-10-02T09:24:18Z"
}
]
```
## Get single milestone
Gets a single group milestone.
```
GET /groups/:id/milestones/:milestone_id
```
Parameters:
- `
id
` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user
- `
milestone_id
` (required) - The ID of the group milestone
## Create new milestone
Creates a new group milestone.
```
POST /groups/:id/milestones
```
Parameters:
- `
id
` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user
- `
title
` (required) - The title of an milestone
- `
description
` (optional) - The description of the milestone
- `
due_date
` (optional) - The due date of the milestone
- `
start_date
` (optional) - The start date of the milestone
## Edit milestone
Updates an existing group milestone.
```
PUT /groups/:id/milestones/:milestone_id
```
Parameters:
- `
id
` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user
- `
milestone_id
` (required) - The ID of a group milestone
- `
title
` (optional) - The title of a milestone
- `
description
` (optional) - The description of a milestone
- `
due_date
` (optional) - The due date of the milestone
- `
start_date
` (optional) - The start date of the milestone
- `
state_event
` (optional) - The state event of the milestone (close|activate)
## Get all issues assigned to a single milestone
Gets all issues assigned to a single group milestone.
```
GET /groups/:id/milestones/:milestone_id/issues
```
Parameters:
- `
id
` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user
- `
milestone_id
` (required) - The ID of a group milestone
## Get all merge requests assigned to a single milestone
Gets all merge requests assigned to a single group milestone.
```
GET /groups/:id/milestones/:milestone_id/merge_requests
```
Parameters:
- `
id
` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user
- `
milestone_id
`
(required) - The ID of a group milestone
This diff is collapsed.
Click to expand it.
lib/api/api.rb
View file @
fd856c69
...
...
@@ -118,7 +118,8 @@ module API
mount
::
API
::
Members
mount
::
API
::
MergeRequestDiffs
mount
::
API
::
MergeRequests
mount
::
API
::
Milestones
mount
::
API
::
ProjectMilestones
mount
::
API
::
GroupMilestones
mount
::
API
::
Namespaces
mount
::
API
::
Notes
mount
::
API
::
NotificationSettings
...
...
This diff is collapsed.
Click to expand it.
lib/api/entities.rb
View file @
fd856c69
...
...
@@ -298,8 +298,8 @@ module API
class
Milestone
<
Grape
::
Entity
expose
:id
,
:iid
expose
(
:project_id
)
{
|
entity
|
entity
&
.
project_id
}
expose
(
:group_id
)
{
|
entity
|
entity
&
.
group_id
}
expose
:project_id
,
if:
->
(
entity
,
options
)
{
entity
&
.
project_id
}
expose
:group_id
,
if:
->
(
entity
,
options
)
{
entity
&
.
group_id
}
expose
:title
,
:description
expose
:state
,
:created_at
,
:updated_at
expose
:due_date
...
...
This diff is collapsed.
Click to expand it.
lib/api/group_milestones.rb
0 → 100644
View file @
fd856c69
module
API
class
GroupMilestones
<
Grape
::
API
include
MilestoneResponses
include
PaginationParams
before
do
authenticate!
end
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a group'
end
resource
:groups
,
requirements:
{
id:
%r{[^/]+}
}
do
desc
'Get a list of group milestones'
do
success
Entities
::
Milestone
end
params
do
use
:list_params
end
get
":id/milestones"
do
list_milestones_for
(
user_group
)
end
desc
'Get a single group milestone'
do
success
Entities
::
Milestone
end
params
do
requires
:milestone_id
,
type:
Integer
,
desc:
'The ID of a group milestone'
end
get
":id/milestones/:milestone_id"
do
authorize!
:read_group
,
user_group
get_milestone_for
(
user_group
)
end
desc
'Create a new group milestone'
do
success
Entities
::
Milestone
end
params
do
requires
:title
,
type:
String
,
desc:
'The title of the milestone'
use
:optional_params
end
post
":id/milestones"
do
authorize!
:admin_milestones
,
user_group
create_milestone_for
(
user_group
)
end
desc
'Update an existing group milestone'
do
success
Entities
::
Milestone
end
params
do
use
:update_params
end
put
":id/milestones/:milestone_id"
do
authorize!
:admin_milestones
,
user_group
update_milestone_for
(
user_group
)
end
desc
'Get all issues for a single group milestone'
do
success
Entities
::
IssueBasic
end
params
do
requires
:milestone_id
,
type:
Integer
,
desc:
'The ID of a group milestone'
use
:pagination
end
get
":id/milestones/:milestone_id/issues"
do
milestone_issuables_for
(
user_group
,
:issue
)
end
desc
'Get all merge requests for a single group milestone'
do
detail
'This feature was introduced in GitLab 9.'
success
Entities
::
MergeRequestBasic
end
params
do
requires
:milestone_id
,
type:
Integer
,
desc:
'The ID of a group milestone'
use
:pagination
end
get
':id/milestones/:milestone_id/merge_requests'
do
milestone_issuables_for
(
user_group
,
:merge_request
)
end
end
end
end
This diff is collapsed.
Click to expand it.
lib/api/helpers.rb
View file @
fd856c69
...
...
@@ -27,6 +27,10 @@ module API
initial_current_user
!=
current_user
end
def
user_group
@group
||=
find_group!
(
params
[
:id
])
end
def
user_project
@project
||=
find_project!
(
params
[
:id
])
end
...
...
This diff is collapsed.
Click to expand it.
lib/api/milestone_responses.rb
0 → 100644
View file @
fd856c69
module
API
module
MilestoneResponses
extend
ActiveSupport
::
Concern
included
do
helpers
do
params
:optional_params
do
optional
:description
,
type:
String
,
desc:
'The description of the milestone'
optional
:due_date
,
type:
String
,
desc:
'The due date of the milestone. The ISO 8601 date format (%Y-%m-%d)'
optional
:start_date
,
type:
String
,
desc:
'The start date of the milestone. The ISO 8601 date format (%Y-%m-%d)'
end
params
:list_params
do
optional
:state
,
type:
String
,
values:
%w[active closed all]
,
default:
'all'
,
desc:
'Return "active", "closed", or "all" milestones'
optional
:iids
,
type:
Array
[
Integer
],
desc:
'The IIDs of the milestones'
optional
:search
,
type:
String
,
desc:
'The search criteria for the title or description of the milestone'
use
:pagination
end
params
:update_params
do
requires
:milestone_id
,
type:
Integer
,
desc:
'The milestone ID number'
optional
:title
,
type:
String
,
desc:
'The title of the milestone'
optional
:state_event
,
type:
String
,
values:
%w[close activate]
,
desc:
'The state event of the milestone '
use
:optional_params
at_least_one_of
:title
,
:description
,
:due_date
,
:state_event
end
def
list_milestones_for
(
parent
)
milestones
=
parent
.
milestones
milestones
=
Milestone
.
filter_by_state
(
milestones
,
params
[
:state
])
milestones
=
filter_by_iid
(
milestones
,
params
[
:iids
])
if
params
[
:iids
].
present?
milestones
=
filter_by_search
(
milestones
,
params
[
:search
])
if
params
[
:search
]
present
paginate
(
milestones
),
with:
Entities
::
Milestone
end
def
get_milestone_for
(
parent
)
milestone
=
parent
.
milestones
.
find
(
params
[
:milestone_id
])
present
milestone
,
with:
Entities
::
Milestone
end
def
create_milestone_for
(
parent
)
milestone
=
::
Milestones
::
CreateService
.
new
(
parent
,
current_user
,
declared_params
).
execute
if
milestone
.
valid?
present
milestone
,
with:
Entities
::
Milestone
else
render_api_error!
(
"Failed to create milestone
#{
milestone
.
errors
.
messages
}
"
,
400
)
end
end
def
update_milestone_for
(
parent
)
milestone
=
parent
.
milestones
.
find
(
params
.
delete
(
:milestone_id
))
milestone_params
=
declared_params
(
include_missing:
false
)
milestone
=
::
Milestones
::
UpdateService
.
new
(
parent
,
current_user
,
milestone_params
).
execute
(
milestone
)
if
milestone
.
valid?
present
milestone
,
with:
Entities
::
Milestone
else
render_api_error!
(
"Failed to update milestone
#{
milestone
.
errors
.
messages
}
"
,
400
)
end
end
def
milestone_issuables_for
(
parent
,
type
)
milestone
=
parent
.
milestones
.
find
(
params
[
:milestone_id
])
finder_klass
,
entity
=
get_finder_and_entity
(
type
)
params
=
build_finder_params
(
milestone
,
parent
)
issuables
=
finder_klass
.
new
(
current_user
,
params
).
execute
present
paginate
(
issuables
),
with:
entity
,
current_user:
current_user
end
def
build_finder_params
(
milestone
,
parent
)
finder_params
=
{
milestone_title:
milestone
.
title
,
sort:
'label_priority'
}
if
parent
.
is_a?
(
Group
)
finder_params
.
merge
(
group_id:
parent
.
id
)
else
finder_params
.
merge
(
project_id:
parent
.
id
)
end
end
def
get_finder_and_entity
(
type
)
if
type
==
:issue
[
IssuesFinder
,
Entities
::
IssueBasic
]
else
[
MergeRequestsFinder
,
Entities
::
MergeRequestBasic
]
end
end
end
end
end
end
This diff is collapsed.
Click to expand it.
lib/api/milestones.rb
→
lib/api/
project_
milestones.rb
View file @
fd856c69
module
API
class
Milestones
<
Grape
::
API
class
Project
Milestones
<
Grape
::
API
include
PaginationParams
include
MilestoneResponses
before
{
authenticate!
}
helpers
do
def
filter_milestones_state
(
milestones
,
state
)
case
state
when
'active'
then
milestones
.
active
when
'closed'
then
milestones
.
closed
else
milestones
end
end
params
:optional_params
do
optional
:description
,
type:
String
,
desc:
'The description of the milestone'
optional
:due_date
,
type:
String
,
desc:
'The due date of the milestone. The ISO 8601 date format (%Y-%m-%d)'
optional
:start_date
,
type:
String
,
desc:
'The start date of the milestone. The ISO 8601 date format (%Y-%m-%d)'
end
before
do
authenticate!
end
params
do
...
...
@@ -28,21 +15,12 @@ module API
success
Entities
::
Milestone
end
params
do
optional
:state
,
type:
String
,
values:
%w[active closed all]
,
default:
'all'
,
desc:
'Return "active", "closed", or "all" milestones'
optional
:iids
,
type:
Array
[
Integer
],
desc:
'The IIDs of the milestones'
optional
:search
,
type:
String
,
desc:
'The search criteria for the title or description of the milestone'
use
:pagination
use
:list_params
end
get
":id/milestones"
do
authorize!
:read_milestone
,
user_project
milestones
=
user_project
.
milestones
milestones
=
filter_milestones_state
(
milestones
,
params
[
:state
])
milestones
=
filter_by_iid
(
milestones
,
params
[
:iids
])
if
params
[
:iids
].
present?
milestones
=
filter_by_search
(
milestones
,
params
[
:search
])
if
params
[
:search
]
present
paginate
(
milestones
),
with:
Entities
::
Milestone
list_milestones_for
(
user_project
)
end
desc
'Get a single project milestone'
do
...
...
@@ -54,8 +32,7 @@ module API
get
":id/milestones/:milestone_id"
do
authorize!
:read_milestone
,
user_project
milestone
=
user_project
.
milestones
.
find
(
params
[
:milestone_id
])
present
milestone
,
with:
Entities
::
Milestone
get_milestone_for
(
user_project
)
end
desc
'Create a new project milestone'
do
...
...
@@ -68,38 +45,19 @@ module API
post
":id/milestones"
do
authorize!
:admin_milestone
,
user_project
milestone
=
::
Milestones
::
CreateService
.
new
(
user_project
,
current_user
,
declared_params
).
execute
if
milestone
.
valid?
present
milestone
,
with:
Entities
::
Milestone
else
render_api_error!
(
"Failed to create milestone
#{
milestone
.
errors
.
messages
}
"
,
400
)
end
create_milestone_for
(
user_project
)
end
desc
'Update an existing project milestone'
do
success
Entities
::
Milestone
end
params
do
requires
:milestone_id
,
type:
Integer
,
desc:
'The ID of a project milestone'
optional
:title
,
type:
String
,
desc:
'The title of the milestone'
optional
:state_event
,
type:
String
,
values:
%w[close activate]
,
desc:
'The state event of the milestone '
use
:optional_params
at_least_one_of
:title
,
:description
,
:due_date
,
:state_event
use
:update_params
end
put
":id/milestones/:milestone_id"
do
authorize!
:admin_milestone
,
user_project
milestone
=
user_project
.
milestones
.
find
(
params
.
delete
(
:milestone_id
))
milestone_params
=
declared_params
(
include_missing:
false
)
milestone
=
::
Milestones
::
UpdateService
.
new
(
user_project
,
current_user
,
milestone_params
).
execute
(
milestone
)
if
milestone
.
valid?
present
milestone
,
with:
Entities
::
Milestone
else
render_api_error!
(
"Failed to update milestone
#{
milestone
.
errors
.
messages
}
"
,
400
)
end
update_milestone_for
(
user_project
)
end
desc
'Get all issues for a single project milestone'
do
...
...
@@ -112,16 +70,7 @@ module API
get
":id/milestones/:milestone_id/issues"
do
authorize!
:read_milestone
,
user_project
milestone
=
user_project
.
milestones
.
find
(
params
[
:milestone_id
])
finder_params
=
{
project_id:
user_project
.
id
,
milestone_title:
milestone
.
title
,
sort:
'label_priority'
}
issues
=
IssuesFinder
.
new
(
current_user
,
finder_params
).
execute
present
paginate
(
issues
),
with:
Entities
::
IssueBasic
,
current_user:
current_user
,
project:
user_project
milestone_issuables_for
(
user_project
,
:issue
)
end
desc
'Get all merge requests for a single project milestone'
do
...
...
@@ -135,19 +84,7 @@ module API
get
':id/milestones/:milestone_id/merge_requests'
do
authorize!
:read_milestone
,
user_project
milestone
=
user_project
.
milestones
.
find
(
params
[
:milestone_id
])
finder_params
=
{
project_id:
user_project
.
id
,
milestone_title:
milestone
.
title
,
sort:
'label_priority'
}
merge_requests
=
MergeRequestsFinder
.
new
(
current_user
,
finder_params
).
execute
present
paginate
(
merge_requests
),
with:
Entities
::
MergeRequestBasic
,
current_user:
current_user
,
project:
user_project
milestone_issuables_for
(
user_project
,
:merge_request
)
end
end
end
...
...
This diff is collapsed.
Click to expand it.
spec/requests/api/group_milestones_spec.rb
0 → 100644
View file @
fd856c69
require
'spec_helper'
describe
API
::
GroupMilestones
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
,
:private
)
}
let
(
:project
)
{
create
(
:empty_project
,
namespace:
group
)
}
let!
(
:group_member
)
{
create
(
:group_member
,
group:
group
,
user:
user
)
}
let!
(
:closed_milestone
)
{
create
(
:closed_milestone
,
group:
group
,
title:
'version1'
,
description:
'closed milestone'
)
}
let!
(
:milestone
)
{
create
(
:milestone
,
group:
group
,
title:
'version2'
,
description:
'open milestone'
)
}
it_behaves_like
'group and project milestones'
,
"/groups/:id/milestones"
do
let
(
:route
)
{
"/groups/
#{
group
.
id
}
/milestones"
}
end
def
setup_for_group
context_group
.
update
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
)
context_group
.
add_developer
(
user
)
public_project
.
update
(
namespace:
context_group
)
context_group
.
reload
end
end
This diff is collapsed.
Click to expand it.
spec/requests/api/project_milestones_spec.rb
0 → 100644
View file @
fd856c69
require
'spec_helper'
describe
API
::
ProjectMilestones
do
let
(
:user
)
{
create
(
:user
)
}
let!
(
:project
)
{
create
(
:empty_project
,
namespace:
user
.
namespace
)
}
let!
(
:closed_milestone
)
{
create
(
:closed_milestone
,
project:
project
,
title:
'version1'
,
description:
'closed milestone'
)
}
let!
(
:milestone
)
{
create
(
:milestone
,
project:
project
,
title:
'version2'
,
description:
'open milestone'
)
}
before
do
project
.
team
<<
[
user
,
:developer
]
end
it_behaves_like
'group and project milestones'
,
"/projects/:id/milestones"
do
let
(
:route
)
{
"/projects/
#{
project
.
id
}
/milestones"
}
end
describe
'PUT /projects/:id/milestones/:milestone_id to test observer on close'
do
it
'creates an activity event when an milestone is closed'
do
expect
(
Event
).
to
receive
(
:create
)
put
api
(
"/projects/
#{
project
.
id
}
/milestones/
#{
milestone
.
id
}
"
,
user
),
state_event:
'close'
end
end
end
This diff is collapsed.
Click to expand it.
spec/support/api/milestones_shared_examples.rb
0 → 100644
View file @
fd856c69
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment