Commit a9a7f192 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch 'project-topics-get-projects' into 'master'

API: Add 'topics' field to 'project' entity in place of 'tag_list' [RUN ALL RSPEC]

See merge request gitlab-org/gitlab!62206
parents 7113b604 94c60aa6
......@@ -250,7 +250,8 @@ Example response:
"path_with_namespace": "diaspora/diaspora-project-site",
"created_at": "2018-07-03T05:48:49.982Z",
"default_branch": null,
"tag_list": [],
"tag_list": [], //deprecated, use `topics` instead
"topics": [],
"ssh_url_to_repo": "ssh://user@example.com/diaspora/diaspora-project-site.git",
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
......
......@@ -302,7 +302,8 @@ Example response:
"id": 9,
"description": "foo",
"default_branch": "master",
"tag_list": [],
"tag_list": [], //deprecated, use `topics` instead
"topics": [],
"archived": false,
"visibility": "internal",
"ssh_url_to_repo": "git@gitlab.example.com/html5-boilerplate.git",
......@@ -381,9 +382,8 @@ Example response:
"path_with_namespace":"h5bp/html5-boilerplate",
"created_at":"2020-04-27T06:13:22.642Z",
"default_branch":"master",
"tag_list":[
],
"tag_list":[], //deprecated, use `topics` instead
"topics":[],
"ssh_url_to_repo":"ssh://git@gitlab.com/h5bp/html5-boilerplate.git",
"http_url_to_repo":"http://gitlab.com/h5bp/html5-boilerplate.git",
"web_url":"http://gitlab.com/h5bp/html5-boilerplate",
......@@ -540,7 +540,8 @@ Example response:
"id": 7,
"description": "Voluptas veniam qui et beatae voluptas doloremque explicabo facilis.",
"default_branch": "master",
"tag_list": [],
"tag_list": [], //deprecated, use `topics` instead
"topics": [],
"archived": false,
"visibility": "public",
"ssh_url_to_repo": "git@gitlab.example.com:twitter/typeahead-js.git",
......@@ -578,7 +579,8 @@ Example response:
"id": 6,
"description": "Aspernatur omnis repudiandae qui voluptatibus eaque.",
"default_branch": "master",
"tag_list": [],
"tag_list": [], //deprecated, use `topics` instead
"topics": [],
"archived": false,
"visibility": "internal",
"ssh_url_to_repo": "git@gitlab.example.com:twitter/flight.git",
......@@ -618,7 +620,8 @@ Example response:
"id": 8,
"description": "Velit eveniet provident fugiat saepe eligendi autem.",
"default_branch": "master",
"tag_list": [],
"tag_list": [], //deprecated, use `topics` instead
"topics": [],
"archived": false,
"visibility": "private",
"ssh_url_to_repo": "git@gitlab.example.com:h5bp/html5-boilerplate.git",
......@@ -886,7 +889,8 @@ Example response:
"id": 9,
"description": "foo",
"default_branch": "master",
"tag_list": [],
"tag_list": [], //deprecated, use `topics` instead
"topics": [],
"public": false,
"archived": false,
"visibility": "internal",
......
......@@ -151,7 +151,8 @@ Example response:
"path_with_namespace":"root/project-with-clusters-api",
"created_at":"2019-01-02T20:13:32.600Z",
"default_branch":null,
"tag_list":[],
"tag_list":[], //deprecated, use `topics` instead
"topics":[],
"ssh_url_to_repo":"ssh://gitlab.example.com/root/project-with-clusters-api.git",
"http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git",
"web_url":"https://gitlab.example.com/root/project-with-clusters-api",
......@@ -247,7 +248,8 @@ Example response:
"path_with_namespace":"root/project-with-clusters-api",
"created_at":"2019-01-02T20:13:32.600Z",
"default_branch":null,
"tag_list":[],
"tag_list":[], //deprecated, use `topics` instead
"topics":[],
"ssh_url_to_repo":"ssh:://gitlab.example.com/root/project-with-clusters-api.git",
"http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git",
"web_url":"https://gitlab.example.com/root/project-with-clusters-api",
......@@ -357,7 +359,8 @@ Example response:
"path_with_namespace":"root/project-with-clusters-api",
"created_at":"2019-01-02T20:13:32.600Z",
"default_branch":null,
"tag_list":[],
"tag_list":[], //deprecated, use `topics` instead
"topics":[],
"ssh_url_to_repo":"ssh:://gitlab.example.com/root/project-with-clusters-api.git",
"http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git",
"web_url":"https://gitlab.example.com/root/project-with-clusters-api",
......
......@@ -59,7 +59,7 @@ GET /projects
| `sort` | string | **{dotted-circle}** No | Return projects sorted in `asc` or `desc` order. Default is `desc`. |
| `starred` | boolean | **{dotted-circle}** No | Limit by projects starred by the current user. |
| `statistics` | boolean | **{dotted-circle}** No | Include project statistics. |
| `topic` | string | **{dotted-circle}** No | Comma-separated topic names. Limit results to projects that match all of given topics. See `tag_list` attribute. |
| `topic` | string | **{dotted-circle}** No | Comma-separated topic names. Limit results to projects that match all of given topics. See `topics` attribute. |
| `visibility` | string | **{dotted-circle}** No | Limit by visibility `public`, `internal`, or `private`. |
| `wiki_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the wiki checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2). |
| `with_custom_attributes` | boolean | **{dotted-circle}** No | Include [custom attributes](custom_attributes.md) in response. _(admins only)_ |
......@@ -82,7 +82,11 @@ When `simple=true` or the user is unauthenticated this returns something like:
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora client"
],
"topics": [
"example",
"disapora client"
],
......@@ -116,7 +120,11 @@ When the user is authenticated and `simple` is not set this returns something li
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora client"
],
"topics": [
"example",
"disapora client"
],
......@@ -200,7 +208,11 @@ When the user is authenticated and `simple` is not set this returns something li
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"readme_url": "http://example.com/brightbox/puppet/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"puppet"
],
"topics": [
"example",
"puppet"
],
......@@ -300,6 +312,10 @@ When the user is authenticated and `simple` is not set this returns something li
]
```
NOTE:
The `tag_list` attribute has been deprecated
and is removed in API v5 in favor of the `topics` attribute.
NOTE:
For users of [GitLab Premium or higher](https://about.gitlab.com/pricing/),
the `marked_for_deletion_at` attribute has been deprecated, and is removed
......@@ -378,7 +394,11 @@ GET /users/:user_id/projects
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora client"
],
"topics": [
"example",
"disapora client"
],
......@@ -462,7 +482,11 @@ GET /users/:user_id/projects
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"readme_url": "http://example.com/brightbox/puppet/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"puppet"
],
"topics": [
"example",
"puppet"
],
......@@ -606,7 +630,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora client"
],
"topics": [
"example",
"disapora client"
],
......@@ -683,7 +711,11 @@ Example response:
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"readme_url": "http://example.com/brightbox/puppet/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"puppet"
],
"topics": [
"example",
"puppet"
],
......@@ -804,7 +836,11 @@ GET /projects/:id
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora project"
],
"topics": [
"example",
"disapora project"
],
......@@ -940,6 +976,10 @@ GET /projects/:id
}
```
NOTE:
The `tag_list` attribute has been deprecated
and is removed in API v5 in favor of the `topics` attribute.
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/)
can also see the `approvals_before_merge` parameter:
......@@ -974,7 +1014,8 @@ If the project is a fork, and you provide a valid token to authenticate, the
"path_with_namespace":"gitlab-org/gitlab-foss",
"created_at":"2013-09-26T06:02:36.000Z",
"default_branch":"master",
"tag_list":[],
"tag_list":[], //deprecated, use `topics` instead
"topics":[],
"ssh_url_to_repo":"git@gitlab.com:gitlab-org/gitlab-foss.git",
"http_url_to_repo":"https://gitlab.com/gitlab-org/gitlab-foss.git",
"web_url":"https://gitlab.com/gitlab-org/gitlab-foss",
......@@ -1393,7 +1434,11 @@ Example responses:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora project"
],
"topics": [
"example",
"disapora project"
],
......@@ -1480,7 +1525,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora project"
],
"topics": [
"example",
"disapora project"
],
......@@ -1573,7 +1622,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora project"
],
"topics": [
"example",
"disapora project"
],
......@@ -1741,7 +1794,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora project"
],
"topics": [
"example",
"disapora project"
],
......@@ -1855,7 +1912,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
"tag_list": [
"tag_list": [ //deprecated, use `topics` instead
"example",
"disapora project"
],
"topics": [
"example",
"disapora project"
],
......@@ -2441,7 +2502,8 @@ Example response:
"path_with_namespace": "cute-cats/hello-world",
"created_at": "2020-10-15T16:25:22.415Z",
"default_branch": "master",
"tag_list": [],
"tag_list": [], //deprecated, use `topics` instead
"topics": [],
"ssh_url_to_repo": "git@gitlab.example.com:cute-cats/hello-world.git",
"http_url_to_repo": "https://gitlab.example.com/cute-cats/hello-world.git",
"web_url": "https://gitlab.example.com/cute-cats/hello-world",
......
......@@ -54,7 +54,8 @@ Example response:
"path_with_namespace": "twitter/flight",
"created_at": "2017-09-05T07:58:01.621Z",
"default_branch": "master",
"tag_list":[],
"tag_list":[], //deprecated, use `topics` instead
"topics":[],
"ssh_url_to_repo": "ssh://jarka@localhost:2222/twitter/flight.git",
"http_url_to_repo": "http://localhost:3000/twitter/flight.git",
"web_url": "http://localhost:3000/twitter/flight",
......@@ -475,7 +476,8 @@ Example response:
"path_with_namespace": "twitter/flight",
"created_at": "2017-09-05T07:58:01.621Z",
"default_branch": "master",
"tag_list":[],
"tag_list":[], //deprecated, use `topics` instead
"topics":[],
"ssh_url_to_repo": "ssh://jarka@localhost:2222/twitter/flight.git",
"http_url_to_repo": "http://localhost:3000/twitter/flight.git",
"web_url": "http://localhost:3000/twitter/flight",
......
......@@ -4,6 +4,7 @@
"description": "foo",
"default_branch": "master",
"tag_list": [],
"topics": [],
"archived": false,
"visibility": "internal",
"ssh_url_to_repo": "git@gitlab.example.com/html5-boilerplate.git",
......
......@@ -102,6 +102,7 @@ export function mockProjectData(
created_at: '2019-02-01T15:40:27.522Z',
default_branch: 'main',
tag_list: [],
topics: [],
avatar_url: null,
web_url: 'https://mock-web_url/',
namespace: {
......
......@@ -4,15 +4,13 @@ module API
module Entities
class BasicProjectDetails < Entities::ProjectIdentity
include ::API::ProjectsRelationBuilder
include Gitlab::Utils::StrongMemoize
expose :default_branch, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) }
# Avoids an N+1 query: https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-168273770
expose :tag_list do |project|
# Tags is a preloaded association. If we perform then sorting
# through the database, it will trigger a new query, ending up
# in an N+1 if we have several projects
project.tags.pluck(:name).sort # rubocop:disable CodeReuse/ActiveRecord
end
expose :topic_names, as: :tag_list
expose :topic_names, as: :topics
expose :ssh_url_to_repo, :http_url_to_repo, :web_url, :readme_url
......@@ -40,7 +38,7 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
def self.preload_relation(projects_relation, options = {})
# Preloading tags, should be done with using only `:tags`,
# Preloading topics, should be done with using only `:tags`,
# as `:tags` are defined as: `has_many :tags, through: :taggings`
# N+1 is solved then by using `subject.tags.map(&:name)`
# MR describing the solution: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/20555
......@@ -50,6 +48,19 @@ module API
.preload(namespace: [:route, :owner])
end
# rubocop: enable CodeReuse/ActiveRecord
private
alias_method :project, :object
def topic_names
# Topics is a preloaded association. If we perform then sorting
# through the database, it will trigger a new query, ending up
# in an N+1 if we have several projects
strong_memoize(:topic_names) do
project.tags.pluck(:name).sort # rubocop:disable CodeReuse/ActiveRecord
end
end
end
end
end
......@@ -15,6 +15,7 @@
"description",
"default_branch",
"tag_list",
"topics",
"ssh_url_to_repo",
"http_url_to_repo",
"web_url",
......@@ -34,6 +35,7 @@
"description": { "type": ["string", "null"] },
"default_branch": { "type": ["string", "null"] },
"tag_list": { "type": "array" },
"topics": { "type": "array" },
"ssh_url_to_repo": { "type": "string" },
"http_url_to_repo": { "type": "string" },
"web_url": { "type": "string" },
......
......@@ -15,6 +15,12 @@
"type": "string"
}
},
"topics": {
"type": "array",
"items": {
"type": "string"
}
},
"ssh_url_to_repo": { "type": "string" },
"http_url_to_repo": { "type": "string" },
"web_url": { "type": "string" },
......@@ -37,7 +43,7 @@
},
"required": [
"id", "name", "name_with_namespace", "description", "path",
"path_with_namespace", "created_at", "default_branch", "tag_list",
"path_with_namespace", "created_at", "default_branch", "tag_list", "topics",
"ssh_url_to_repo", "http_url_to_repo", "web_url", "readme_url", "avatar_url",
"star_count", "forks_count", "last_activity_at", "namespace"
],
......
......@@ -3,6 +3,7 @@
"description": "",
"default_branch": null,
"tag_list": [],
"topics": [],
"public": true,
"archived": false,
"visibility_level": 20,
......@@ -54,6 +55,7 @@
"description": "Voluptatem quae nulla eius numquam ullam voluptatibus quia modi.",
"default_branch": "master",
"tag_list": [],
"topics": [],
"public": false,
"archived": false,
"visibility_level": 0,
......@@ -114,6 +116,7 @@
"description": "Modi odio mollitia dolorem qui.",
"default_branch": "master",
"tag_list": [],
"topics": [],
"public": false,
"archived": false,
"visibility_level": 0,
......@@ -162,6 +165,7 @@
"description": "Omnis asperiores ipsa et beatae quidem necessitatibus quia.",
"default_branch": "master",
"tag_list": [],
"topics": [],
"public": true,
"archived": false,
"visibility_level": 20,
......@@ -210,6 +214,7 @@
"description": "Voluptatem commodi voluptate placeat architecto beatae illum dolores fugiat.",
"default_branch": "master",
"tag_list": [],
"topics": [],
"public": false,
"archived": false,
"visibility_level": 0,
......@@ -258,6 +263,7 @@
"description": "Aut molestias quas est ut aperiam officia quod libero.",
"default_branch": "master",
"tag_list": [],
"topics": [],
"public": true,
"archived": false,
"visibility_level": 20,
......@@ -309,6 +315,7 @@
"description": "Excepturi molestiae quia repellendus omnis est illo illum eligendi.",
"default_branch": "master",
"tag_list": [],
"topics": [],
"public": true,
"archived": false,
"visibility_level": 20,
......@@ -357,6 +364,7 @@
"description": "Adipisci quaerat dignissimos enim sed ipsam dolorem quia.",
"default_branch": "master",
"tag_list": [],
"topics": [],
"public": false,
"archived": false,
"visibility_level": 10,
......@@ -408,6 +416,7 @@
"description": "Vel voluptatem maxime saepe ex quia.",
"default_branch": "master",
"tag_list": [],
"topics": [],
"public": false,
"archived": false,
"visibility_level": 0,
......
......@@ -69,6 +69,7 @@ itself: # project
- shared_with_groups
- ssh_url_to_repo
- tag_list
- topics
- web_url
build_auto_devops: # auto_devops
......
......@@ -184,13 +184,14 @@ RSpec.describe API::Projects do
end
end
it 'includes the project labels as the tag_list' do
it 'includes project topics' do
get api('/projects', user)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first.keys).to include('tag_list')
expect(json_response.first.keys).to include('tag_list') # deprecated in favor of 'topics'
expect(json_response.first.keys).to include('topics')
end
it 'includes open_issues_count' do
......@@ -1892,7 +1893,8 @@ RSpec.describe API::Projects do
expect(json_response['id']).to eq(project.id)
expect(json_response['description']).to eq(project.description)
expect(json_response['default_branch']).to eq(project.default_branch)
expect(json_response['tag_list']).to be_an Array
expect(json_response['tag_list']).to be_an Array # deprecated in favor of 'topics'
expect(json_response['topics']).to be_an Array
expect(json_response['archived']).to be_falsey
expect(json_response['visibility']).to be_present
expect(json_response['ssh_url_to_repo']).to be_present
......@@ -1969,7 +1971,8 @@ RSpec.describe API::Projects do
expect(json_response['id']).to eq(project.id)
expect(json_response['description']).to eq(project.description)
expect(json_response['default_branch']).to eq(project.default_branch)
expect(json_response['tag_list']).to be_an Array
expect(json_response['tag_list']).to be_an Array # deprecated in favor of 'topics'
expect(json_response['topics']).to be_an Array
expect(json_response['archived']).to be_falsey
expect(json_response['visibility']).to be_present
expect(json_response['ssh_url_to_repo']).to be_present
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment