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
0
Merge Requests
0
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
Jérome Perrin
gitlab-ce
Commits
6902848a
Commit
6902848a
authored
Sep 18, 2017
by
Markus Koller
Committed by
Markus Koller
Nov 06, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support custom attributes on projects
parent
823a9d35
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
137 additions
and
13 deletions
+137
-13
app/finders/projects_finder.rb
app/finders/projects_finder.rb
+3
-0
app/models/project.rb
app/models/project.rb
+1
-0
app/models/project_custom_attribute.rb
app/models/project_custom_attribute.rb
+6
-0
db/migrate/20170918111708_create_project_custom_attributes.rb
...igrate/20170918111708_create_project_custom_attributes.rb
+15
-0
db/schema.rb
db/schema.rb
+12
-0
doc/api/custom_attributes.md
doc/api/custom_attributes.md
+14
-8
doc/api/projects.md
doc/api/projects.md
+6
-0
lib/api/helpers.rb
lib/api/helpers.rb
+1
-0
lib/api/projects.rb
lib/api/projects.rb
+2
-0
lib/gitlab/import_export/import_export.yml
lib/gitlab/import_export/import_export.yml
+1
-0
lib/gitlab/import_export/relation_factory.rb
lib/gitlab/import_export/relation_factory.rb
+2
-1
spec/factories/project_custom_attributes.rb
spec/factories/project_custom_attributes.rb
+7
-0
spec/lib/gitlab/import_export/all_models.yml
spec/lib/gitlab/import_export/all_models.yml
+1
-0
spec/lib/gitlab/import_export/project.json
spec/lib/gitlab/import_export/project.json
+19
-1
spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+4
-0
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+7
-0
spec/lib/gitlab/import_export/safe_model_attributes.yml
spec/lib/gitlab/import_export/safe_model_attributes.yml
+8
-1
spec/models/project_custom_attribute_spec.rb
spec/models/project_custom_attribute_spec.rb
+16
-0
spec/models/project_spec.rb
spec/models/project_spec.rb
+1
-0
spec/requests/api/projects_spec.rb
spec/requests/api/projects_spec.rb
+5
-0
spec/requests/api/users_spec.rb
spec/requests/api/users_spec.rb
+2
-1
spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
...xamples/requests/api/custom_attributes_shared_examples.rb
+4
-1
No files found.
app/finders/projects_finder.rb
View file @
6902848a
...
...
@@ -18,6 +18,8 @@
# non_archived: boolean
#
class
ProjectsFinder
<
UnionFinder
include
CustomAttributesFilter
attr_accessor
:params
attr_reader
:current_user
,
:project_ids_relation
...
...
@@ -44,6 +46,7 @@ class ProjectsFinder < UnionFinder
collection
=
by_tags
(
collection
)
collection
=
by_search
(
collection
)
collection
=
by_archived
(
collection
)
collection
=
by_custom_attributes
(
collection
)
sort
(
collection
)
end
...
...
app/models/project.rb
View file @
6902848a
...
...
@@ -213,6 +213,7 @@ class Project < ActiveRecord::Base
has_many
:active_runners
,
->
{
active
},
through: :runner_projects
,
source: :runner
,
class_name:
'Ci::Runner'
has_one
:auto_devops
,
class_name:
'ProjectAutoDevops'
has_many
:custom_attributes
,
class_name:
'ProjectCustomAttribute'
accepts_nested_attributes_for
:variables
,
allow_destroy:
true
accepts_nested_attributes_for
:project_feature
,
update_only:
true
...
...
app/models/project_custom_attribute.rb
0 → 100644
View file @
6902848a
class
ProjectCustomAttribute
<
ActiveRecord
::
Base
belongs_to
:project
validates
:project
,
:key
,
:value
,
presence:
true
validates
:key
,
uniqueness:
{
scope:
[
:project_id
]
}
end
db/migrate/20170918111708_create_project_custom_attributes.rb
0 → 100644
View file @
6902848a
class
CreateProjectCustomAttributes
<
ActiveRecord
::
Migration
DOWNTIME
=
false
def
change
create_table
:project_custom_attributes
do
|
t
|
t
.
timestamps_with_timezone
null:
false
t
.
references
:project
,
null:
false
,
foreign_key:
{
on_delete: :cascade
}
t
.
string
:key
,
null:
false
t
.
string
:value
,
null:
false
t
.
index
[
:project_id
,
:key
],
unique:
true
t
.
index
[
:key
,
:value
]
end
end
end
db/schema.rb
View file @
6902848a
...
...
@@ -1214,6 +1214,17 @@ ActiveRecord::Schema.define(version: 20171026082505) do
add_index
"project_auto_devops"
,
[
"project_id"
],
name:
"index_project_auto_devops_on_project_id"
,
unique:
true
,
using: :btree
create_table
"project_custom_attributes"
,
force: :cascade
do
|
t
|
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
integer
"project_id"
,
null:
false
t
.
string
"key"
,
null:
false
t
.
string
"value"
,
null:
false
end
add_index
"project_custom_attributes"
,
[
"key"
,
"value"
],
name:
"index_project_custom_attributes_on_key_and_value"
,
using: :btree
add_index
"project_custom_attributes"
,
[
"project_id"
,
"key"
],
name:
"index_project_custom_attributes_on_project_id_and_key"
,
unique:
true
,
using: :btree
create_table
"project_features"
,
force: :cascade
do
|
t
|
t
.
integer
"project_id"
t
.
integer
"merge_requests_access_level"
...
...
@@ -1859,6 +1870,7 @@ ActiveRecord::Schema.define(version: 20171026082505) do
add_foreign_key
"project_authorizations"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"project_authorizations"
,
"users"
,
on_delete: :cascade
add_foreign_key
"project_auto_devops"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"project_custom_attributes"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"project_features"
,
"projects"
,
name:
"fk_18513d9b92"
,
on_delete: :cascade
add_foreign_key
"project_group_links"
,
"projects"
,
name:
"fk_daa8cee94c"
,
on_delete: :cascade
add_foreign_key
"project_import_data"
,
"projects"
,
name:
"fk_ffb9ee3a10"
,
on_delete: :cascade
...
...
doc/api/custom_attributes.md
View file @
6902848a
# Custom Attributes API
Every API call to custom attributes must be authenticated as administrator.
Custom attributes are currently available on users and projects, which will
be referred to as "resource" in this documentation.
## List custom attributes
Get all custom attributes on a
user
.
Get all custom attributes on a
resource
.
```
GET /users/:id/custom_attributes
GET /projects/:id/custom_attributes
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
|
`id`
| integer | yes | The ID of a
user
|
|
`id`
| integer | yes | The ID of a
resource
|
```
bash
curl
--header
"PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK"
https://gitlab.example.com/api/v4/users/42/custom_attributes
...
...
@@ -35,15 +38,16 @@ Example response:
## Single custom attribute
Get a single custom attribute on a
user
.
Get a single custom attribute on a
resource
.
```
GET /users/:id/custom_attributes/:key
GET /projects/:id/custom_attributes/:key
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
|
`id`
| integer | yes | The ID of a
user
|
|
`id`
| integer | yes | The ID of a
resource
|
|
`key`
| string | yes | The key of the custom attribute |
```
bash
...
...
@@ -61,16 +65,17 @@ Example response:
## Set custom attribute
Set a custom attribute on a
user
. The attribute will be updated if it already exists,
Set a custom attribute on a
resource
. The attribute will be updated if it already exists,
or newly created otherwise.
```
PUT /users/:id/custom_attributes/:key
PUT /projects/:id/custom_attributes/:key
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
|
`id`
| integer | yes | The ID of a
user
|
|
`id`
| integer | yes | The ID of a
resource
|
|
`key`
| string | yes | The key of the custom attribute |
|
`value`
| string | yes | The value of the custom attribute |
...
...
@@ -89,15 +94,16 @@ Example response:
## Delete custom attribute
Delete a custom attribute on a
user
.
Delete a custom attribute on a
resource
.
```
DELETE /users/:id/custom_attributes/:key
DELETE /projects/:id/custom_attributes/:key
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
|
`id`
| integer | yes | The ID of a
user
|
|
`id`
| integer | yes | The ID of a
resource
|
|
`key`
| string | yes | The key of the custom attribute |
```
bash
...
...
doc/api/projects.md
View file @
6902848a
...
...
@@ -192,6 +192,12 @@ GET /projects
]
```
You can filter by
[
custom attributes
](
custom_attributes.md
)
with:
```
GET /projects?custom_attributes[key]=value&custom_attributes[other_key]=other_value
```
## List user projects
Get a list of visible projects for the given user. When accessed without
...
...
lib/api/helpers.rb
View file @
6902848a
...
...
@@ -328,6 +328,7 @@ module API
finder_params
[
:archived
]
=
params
[
:archived
]
finder_params
[
:search
]
=
params
[
:search
]
if
params
[
:search
]
finder_params
[
:user
]
=
params
.
delete
(
:user
)
if
params
[
:user
]
finder_params
[
:custom_attributes
]
=
params
[
:custom_attributes
]
if
params
[
:custom_attributes
]
finder_params
end
...
...
lib/api/projects.rb
View file @
6902848a
...
...
@@ -119,6 +119,8 @@ module API
end
resource
:projects
do
include
CustomAttributesEndpoints
desc
'Get a list of visible projects for authenticated user'
do
success
Entities
::
BasicProjectDetails
end
...
...
lib/gitlab/import_export/import_export.yml
View file @
6902848a
...
...
@@ -63,6 +63,7 @@ project_tree:
-
protected_tags
:
-
:create_access_levels
-
:project_feature
-
:custom_attributes
# Only include the following attributes for the models specified.
included_attributes
:
...
...
lib/gitlab/import_export/relation_factory.rb
View file @
6902848a
...
...
@@ -17,7 +17,8 @@ module Gitlab
labels: :project_labels
,
priorities: :label_priorities
,
auto_devops: :project_auto_devops
,
label: :project_label
}.
freeze
label: :project_label
,
custom_attributes:
'ProjectCustomAttribute'
}.
freeze
USER_REFERENCES
=
%w[author_id assignee_id updated_by_id user_id created_by_id last_edited_by_id merge_user_id resolved_by_id]
.
freeze
...
...
spec/factories/project_custom_attributes.rb
0 → 100644
View file @
6902848a
FactoryGirl
.
define
do
factory
:project_custom_attribute
do
project
sequence
(
:key
)
{
|
n
|
"key
#{
n
}
"
}
sequence
(
:value
)
{
|
n
|
"value
#{
n
}
"
}
end
end
spec/lib/gitlab/import_export/all_models.yml
View file @
6902848a
...
...
@@ -276,6 +276,7 @@ project:
-
root_of_fork_network
-
fork_network_member
-
fork_network
-
custom_attributes
award_emoji
:
-
awardable
-
user
...
...
spec/lib/gitlab/import_export/project.json
View file @
6902848a
...
...
@@ -7408,5 +7408,23 @@
"snippets_access_level"
:
20
,
"updated_at"
:
"2016-09-23T11:58:28.000Z"
,
"wiki_access_level"
:
20
}
},
"custom_attributes"
:
[
{
"id"
:
1
,
"created_at"
:
"2017-10-19T15:36:23.466Z"
,
"updated_at"
:
"2017-10-19T15:36:23.466Z"
,
"project_id"
:
5
,
"key"
:
"foo"
,
"value"
:
"foo"
},
{
"id"
:
2
,
"created_at"
:
"2017-10-19T15:37:21.904Z"
,
"updated_at"
:
"2017-10-19T15:37:21.904Z"
,
"project_id"
:
5
,
"key"
:
"bar"
,
"value"
:
"bar"
}
]
}
spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
View file @
6902848a
...
...
@@ -133,6 +133,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
expect
(
@project
.
project_feature
).
not_to
be_nil
end
it
'has custom attributes'
do
expect
(
@project
.
custom_attributes
.
count
).
to
eq
(
2
)
end
it
'restores the correct service'
do
expect
(
CustomIssueTrackerService
.
first
).
not_to
be_nil
end
...
...
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
View file @
6902848a
...
...
@@ -168,6 +168,10 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
expect
(
project_feature
[
"builds_access_level"
]).
to
eq
(
ProjectFeature
::
PRIVATE
)
end
it
'has custom attributes'
do
expect
(
saved_project_json
[
'custom_attributes'
].
count
).
to
eq
(
2
)
end
it
'does not complain about non UTF-8 characters in MR diffs'
do
ActiveRecord
::
Base
.
connection
.
execute
(
"UPDATE merge_request_diffs SET st_diffs = '---
\n
- :diff: !binary |-
\n
LS0tIC9kZXYvbnVsbAorKysgYi9pbWFnZXMvbnVjb3IucGRmCkBAIC0wLDAg
\n
KzEsMTY3OSBAQAorJVBERi0xLjUNJeLjz9MNCisxIDAgb2JqDTw8L01ldGFk
\n
YXR'"
)
...
...
@@ -279,6 +283,9 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
create
(
:event
,
:created
,
target:
milestone
,
project:
project
,
author:
user
)
create
(
:service
,
project:
project
,
type:
'CustomIssueTrackerService'
,
category:
'issue_tracker'
)
create
(
:project_custom_attribute
,
project:
project
)
create
(
:project_custom_attribute
,
project:
project
)
project
end
...
...
spec/lib/gitlab/import_export/safe_model_attributes.yml
View file @
6902848a
...
...
@@ -508,4 +508,11 @@ ProjectAutoDevops:
-
updated_at
IssueAssignee
:
-
user_id
-
issue_id
\ No newline at end of file
-
issue_id
ProjectCustomAttribute
:
-
id
-
created_at
-
updated_at
-
project_id
-
key
-
value
spec/models/project_custom_attribute_spec.rb
0 → 100644
View file @
6902848a
require
'spec_helper'
describe
ProjectCustomAttribute
do
describe
'assocations'
do
it
{
is_expected
.
to
belong_to
(
:project
)
}
end
describe
'validations'
do
subject
{
build
:project_custom_attribute
}
it
{
is_expected
.
to
validate_presence_of
(
:project
)
}
it
{
is_expected
.
to
validate_presence_of
(
:key
)
}
it
{
is_expected
.
to
validate_presence_of
(
:value
)
}
it
{
is_expected
.
to
validate_uniqueness_of
(
:key
).
scoped_to
(
:project_id
)
}
end
end
spec/models/project_spec.rb
View file @
6902848a
...
...
@@ -79,6 +79,7 @@ describe Project do
it
{
is_expected
.
to
have_many
(
:pipeline_schedules
)
}
it
{
is_expected
.
to
have_many
(
:members_and_requesters
)
}
it
{
is_expected
.
to
have_one
(
:cluster
)
}
it
{
is_expected
.
to
have_many
(
:custom_attributes
).
class_name
(
'ProjectCustomAttribute'
)
}
context
'after initialized'
do
it
"has a project_feature"
do
...
...
spec/requests/api/projects_spec.rb
View file @
6902848a
...
...
@@ -1856,4 +1856,9 @@ describe API::Projects do
end
end
end
it_behaves_like
'custom attributes endpoints'
,
'projects'
do
let
(
:attributable
)
{
project
}
let
(
:other_attributable
)
{
project2
}
end
end
spec/requests/api/users_spec.rb
View file @
6902848a
...
...
@@ -1880,7 +1880,8 @@ describe API::Users do
end
end
i
nclude_examples
'custom attributes endpoints'
,
'users'
do
i
t_behaves_like
'custom attributes endpoints'
,
'users'
do
let
(
:attributable
)
{
user
}
let
(
:other_attributable
)
{
admin
}
end
end
spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
View file @
6902848a
...
...
@@ -3,7 +3,9 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
let!
(
:custom_attribute2
)
{
attributable
.
custom_attributes
.
create
key:
'bar'
,
value:
'bar'
}
describe
"GET /
#{
attributable_name
}
with custom attributes filter"
do
let!
(
:other_attributable
)
{
create
attributable
.
class
.
name
.
underscore
}
before
do
other_attributable
end
context
'with an unauthorized user'
do
it
'does not filter by custom attributes'
do
...
...
@@ -11,6 +13,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
.
size
).
to
be
2
expect
(
json_response
.
map
{
|
r
|
r
[
'id'
]
}).
to
contain_exactly
attributable
.
id
,
other_attributable
.
id
end
end
...
...
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