Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
heptapod
heptapod
Commits
a57deffe0dd7
Commit
a57deffe
authored
Sep 18, 2017
by
Markus Koller
Browse files
Support custom attributes on projects
parent
04d0134a4718
Changes
22
Hide whitespace changes
Inline
Side-by-side
app/finders/projects_finder.rb
View file @
a57deffe
...
...
@@ -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 @@
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 @
a57deffe
...
...
@@ -213,6 +213,7 @@
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 @
a57deffe
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 @
a57deffe
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 @
a57deffe
...
...
@@ -1214,6 +1214,17 @@
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 @@
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 @
a57deffe
# 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
...
...
@@ -4,7 +6,7 @@
## List custom attributes
Get all custom attributes on a
user
.
Get all custom attributes on a
resource
.
```
GET /users/:id/custom_attributes
...
...
@@ -8,7 +10,8 @@
```
GET /users/:id/custom_attributes
GET /projects/:id/custom_attributes
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
...
...
@@ -11,8 +14,8 @@
```
| 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,7 +38,7 @@
## 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
...
...
@@ -39,7 +42,8 @@
```
GET /users/:id/custom_attributes/:key
GET /projects/:id/custom_attributes/:key
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
...
...
@@ -42,8 +46,8 @@
```
| 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,8 +65,8 @@
## 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
...
...
@@ -65,8 +69,9 @@
or newly created otherwise.
```
PUT /users/:id/custom_attributes/:key
PUT /projects/:id/custom_attributes/:key
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
...
...
@@ -69,8 +74,8 @@
```
| 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,7 +94,7 @@
## Delete custom attribute
Delete a custom attribute on a
user
.
Delete a custom attribute on a
resource
.
```
DELETE /users/:id/custom_attributes/:key
...
...
@@ -93,7 +98,8 @@
```
DELETE /users/:id/custom_attributes/:key
DELETE /projects/:id/custom_attributes/:key
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
...
...
@@ -96,8 +102,8 @@
```
| 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 @
a57deffe
...
...
@@ -192,6 +192,12 @@
]
```
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 @
a57deffe
...
...
@@ -328,6 +328,7 @@
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 @
a57deffe
...
...
@@ -119,6 +119,8 @@
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 @
a57deffe
...
...
@@ -63,6 +63,7 @@
-
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 @
a57deffe
...
...
@@ -17,7 +17,8 @@
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 @
a57deffe
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 @
a57deffe
...
...
@@ -276,6 +276,7 @@
-
root_of_fork_network
-
fork_network_member
-
fork_network
-
custom_attributes
award_emoji
:
-
awardable
-
user
...
...
spec/lib/gitlab/import_export/project.json
View file @
a57deffe
...
...
@@ -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 @
a57deffe
...
...
@@ -133,6 +133,10 @@
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 @
a57deffe
...
...
@@ -168,6 +168,10 @@
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 @@
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 @
a57deffe
...
...
@@ -508,4 +508,11 @@
-
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 @
a57deffe
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 @
a57deffe
...
...
@@ -79,6 +79,7 @@
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 @
a57deffe
...
...
@@ -1856,4 +1856,9 @@
end
end
end
it_behaves_like
'custom attributes endpoints'
,
'projects'
do
let
(
:attributable
)
{
project
}
let
(
:other_attributable
)
{
project2
}
end
end
Prev
1
2
Next
Write
Preview
Supports
Markdown
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