Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-01 12:10:39 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-01 12:10:39 +0300
commit1bab0ba591263cd739af2d2c7c3f1b03678a59b6 (patch)
tree39f499cf5c77338a6c1b94a2cad17153bcb7cada
parent2d03845a7606dc48107ac33e7a66a00956e76955 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--CHANGELOG.md7
-rw-r--r--app/assets/javascripts/releases/components/milestone_list.vue45
-rw-r--r--app/assets/javascripts/releases/components/release_block.vue46
-rw-r--r--app/views/projects/pages/_access.html.haml6
-rw-r--r--app/views/projects/pages/_destroy.haml10
-rw-r--r--app/views/projects/pages/_https_only.html.haml5
-rw-r--r--app/views/projects/pages/_list.html.haml19
-rw-r--r--app/views/projects/pages/_no_domains.html.haml5
-rw-r--r--app/views/projects/pages/_use.html.haml10
-rw-r--r--app/views/projects/pages/show.html.haml11
-rw-r--r--changelogs/unreleased/12-3-stable.yml5
-rw-r--r--changelogs/unreleased/29020-update-release-blocks-for-multiple-milestone-support.yml5
-rw-r--r--changelogs/unreleased/sh-fix-gitaly-nplus-one-issues-related-mrs.yml5
-rw-r--r--db/post_migrate/20190905091812_schedule_project_any_approval_rule_migration.rb2
-rw-r--r--db/post_migrate/20190905091831_schedule_merge_request_any_approval_rule_migration.rb2
-rw-r--r--doc/api/issues.md67
-rw-r--r--doc/api/scim.md5
-rw-r--r--lib/api/entities.rb2
-rw-r--r--lib/api/issues.rb3
-rw-r--r--locale/gitlab.pot82
-rw-r--r--spec/frontend/releases/components/milestone_list_spec.js56
-rw-r--r--spec/frontend/releases/components/release_block_spec.js49
-rw-r--r--spec/frontend/releases/mock_data.js2
-rw-r--r--spec/requests/api/issues/get_project_issues_spec.rb2
24 files changed, 266 insertions, 185 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 65058d746c5..c2ffec09cb2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -636,19 +636,12 @@ entry.
## 12.1.12
-<<<<<<< HEAD
-### Security (11 changes)
-=======
### Security (12 changes)
->>>>>>> master
- Add a policy check for system notes that may not be visible due to cross references to private items.
- Display only participants that user has permission to see on milestone page.
- Do not disclose project milestones on group milestones page when project milestones access is disabled in project settings.
-<<<<<<< HEAD
-=======
- Check permissions before showing head pipeline blocking merge requests.
->>>>>>> master
- Fix new project path being disclosed through unsubscribe link of issue/merge requests.
- Prevent bypassing email verification using Salesforce.
- Do not show resource label events referencing not accessible labels.
diff --git a/app/assets/javascripts/releases/components/milestone_list.vue b/app/assets/javascripts/releases/components/milestone_list.vue
deleted file mode 100644
index 53416f0ab4d..00000000000
--- a/app/assets/javascripts/releases/components/milestone_list.vue
+++ /dev/null
@@ -1,45 +0,0 @@
-<script>
-import { GlLink, GlTooltipDirective } from '@gitlab/ui';
-import Icon from '~/vue_shared/components/icon.vue';
-import { s__ } from '~/locale';
-
-export default {
- name: 'MilestoneList',
- components: {
- GlLink,
- Icon,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- props: {
- milestones: {
- type: Array,
- required: true,
- },
- },
- computed: {
- labelText() {
- return this.milestones.length === 1 ? s__('Milestone') : s__('Milestones');
- },
- },
-};
-</script>
-<template>
- <div>
- <icon name="flag" class="align-middle" /> <span class="js-label-text">{{ labelText }}</span>
- <template v-for="(milestone, index) in milestones">
- <gl-link
- :key="milestone.id"
- v-gl-tooltip
- :title="milestone.description"
- :href="milestone.web_url"
- >
- {{ milestone.title }}
- </gl-link>
- <template v-if="index !== milestones.length - 1">
- &bull;
- </template>
- </template>
- </div>
-</template>
diff --git a/app/assets/javascripts/releases/components/release_block.vue b/app/assets/javascripts/releases/components/release_block.vue
index 32bf05a7629..7b6bd9913a8 100644
--- a/app/assets/javascripts/releases/components/release_block.vue
+++ b/app/assets/javascripts/releases/components/release_block.vue
@@ -5,8 +5,7 @@ import { GlTooltipDirective, GlLink, GlBadge } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
-import MilestoneList from './milestone_list.vue';
-import { __, sprintf } from '../../locale';
+import { __, n__, sprintf } from '../../locale';
export default {
name: 'ReleaseBlock',
@@ -15,7 +14,6 @@ export default {
GlBadge,
Icon,
UserAvatarLink,
- MilestoneList,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -57,19 +55,11 @@ export default {
hasAuthor() {
return !_.isEmpty(this.author);
},
- milestones() {
- // At the moment, a release can only be associated to
- // one milestone. This will be expanded to be many-to-many
- // in the near future, so we pass the milestone as an
- // array here in anticipation of this change.
- return [this.release.milestone];
- },
shouldRenderMilestones() {
- // Similar to the `milestones` computed above,
- // this check will need to be updated once
- // the API begins sending an array of milestones
- // instead of just a single object.
- return Boolean(this.release.milestone);
+ return !_.isEmpty(this.release.milestones);
+ },
+ labelText() {
+ return n__('Milestone', 'Milestones', this.release.milestones.length);
},
},
};
@@ -101,11 +91,27 @@ export default {
<span v-else v-gl-tooltip.bottom :title="__('Tag')">{{ release.tag_name }}</span>
</div>
- <milestone-list
- v-if="shouldRenderMilestones"
- class="append-right-4 js-milestone-list"
- :milestones="milestones"
- />
+ <template v-if="shouldRenderMilestones">
+ <div class="js-milestone-list-label">
+ <icon name="flag" class="align-middle" />
+ <span class="js-label-text">{{ labelText }}</span>
+ </div>
+
+ <template v-for="(milestone, index) in release.milestones">
+ <gl-link
+ :key="milestone.id"
+ v-gl-tooltip
+ :title="milestone.description"
+ :href="milestone.web_url"
+ class="append-right-4 prepend-left-4 js-milestone-link"
+ >
+ {{ milestone.title }}
+ </gl-link>
+ <template v-if="index !== release.milestones.length - 1">
+ &bull;
+ </template>
+ </template>
+ </template>
<div class="append-right-4">
&bull;
diff --git a/app/views/projects/pages/_access.html.haml b/app/views/projects/pages/_access.html.haml
index 7b6d46964a2..178f0acc5b9 100644
--- a/app/views/projects/pages/_access.html.haml
+++ b/app/views/projects/pages/_access.html.haml
@@ -1,11 +1,11 @@
- if @project.pages_deployed?
.card
.card-header
- Access pages
+ = s_('GitLabPages|Access pages')
.card-body
%p
%strong
- = _("Your pages are served under:")
+ = s_('GitLabPages|Your pages are served under:')
%p
= external_link(@project.pages_url, @project.pages_url)
@@ -14,4 +14,4 @@
%p
= external_link(domain.url, domain.url)
.card-footer.alert-primary
- = _("It may take up to 30 minutes before the site is available after the first deployment.")
+ = s_('GitLabPages|It may take up to 30 minutes before the site is available after the first deployment.')
diff --git a/app/views/projects/pages/_destroy.haml b/app/views/projects/pages/_destroy.haml
index 138e2864bad..58dbbb5bcfc 100644
--- a/app/views/projects/pages/_destroy.haml
+++ b/app/views/projects/pages/_destroy.haml
@@ -1,12 +1,14 @@
- if @project.pages_deployed?
- if can?(current_user, :remove_pages, @project)
.card.border-danger
- .card-header.bg-danger.text-white Remove pages
+ .card-header.bg-danger.text-white
+ = s_('GitLabPages|Remove pages')
.errors-holder
.card-body
%p
- Removing pages will prevent them from being exposed to the outside world.
+ = s_('GitLabPages|Removing pages will prevent them from being exposed to the outside world.')
.form-actions
- = link_to 'Remove pages', project_pages_path(@project), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove"
+ = link_to s_('GitLabPages|Remove pages'), project_pages_path(@project), data: { confirm: s_('GitLabPages|Are you sure?')}, method: :delete, class: "btn btn-remove"
- else
- .nothing-here-block Only project maintainers can remove pages
+ .nothing-here-block
+ = s_('GitLabPages|Only project maintainers can remove pages')
diff --git a/app/views/projects/pages/_https_only.html.haml b/app/views/projects/pages/_https_only.html.haml
index 74478ee011c..d8c4a5f0a5d 100644
--- a/app/views/projects/pages/_https_only.html.haml
+++ b/app/views/projects/pages/_https_only.html.haml
@@ -3,8 +3,9 @@
.form-check
= f.check_box :pages_https_only, class: 'form-check-input', disabled: pages_https_only_disabled?
= f.label :pages_https_only, class: pages_https_only_label_class do
- %strong Force HTTPS (requires valid certificates)
+ %strong
+ = s_('GitLabPages|Force HTTPS (requires valid certificates)')
- unless pages_https_only_disabled?
.prepend-top-10
- = f.submit 'Save', class: 'btn btn-success'
+ = f.submit s_('GitLabPages|Save'), class: 'btn btn-success'
diff --git a/app/views/projects/pages/_list.html.haml b/app/views/projects/pages/_list.html.haml
index c4285e7f3d2..b05491f2c6e 100644
--- a/app/views/projects/pages/_list.html.haml
+++ b/app/views/projects/pages/_list.html.haml
@@ -8,20 +8,25 @@
- @domains.each do |domain|
%li.pages-domain-list-item.list-group-item.d-flex.justify-content-between
- if verification_enabled
- - tooltip, status = domain.unverified? ? [_('Unverified'), 'failed'] : [_('Verified'), 'success']
+ - tooltip, status = domain.unverified? ? [s_('GitLabPages|Unverified'), 'failed'] : [s_('GitLabPages|Verified'), 'success']
.domain-status.ci-status-icon.has-tooltip{ class: "ci-status-icon-#{status}", title: tooltip }
= sprite_icon("status_#{status}", size: 16 )
.domain-name
= external_link(domain.url, domain.url)
- if domain.subject
%div
- %span.badge.badge-gray Certificate: #{domain.subject}
+ %span.badge.badge-gray
+ = s_('GitLabPages|Certificate: %{subject}') % { subject: domain.subject }
- if domain.expired?
- %span.badge.badge-danger Expired
+ %span.badge.badge-danger
+ = s_('GitLabPages|Expired')
%div
- = link_to 'Details', project_pages_domain_path(@project, domain), class: "btn btn-sm btn-grouped"
- = link_to 'Remove', project_pages_domain_path(@project, domain), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-sm btn-grouped"
+ = link_to s_('GitLabPages|Details'), project_pages_domain_path(@project, domain), class: "btn btn-sm btn-grouped"
+ = link_to s_('GitLabPages|Remove'), project_pages_domain_path(@project, domain), data: { confirm: s_('GitLabPages|Are you sure?')}, method: :delete, class: "btn btn-remove btn-sm btn-grouped"
- if verification_enabled && domain.unverified?
%li.list-group-item.bs-callout-warning
- #{domain.domain} is not verified. To learn how to verify ownership, visit your
- #{link_to 'domain details', project_pages_domain_path(@project, domain)}.
+ - details_link_start = "<a href='#{project_pages_domain_path(@project, domain)}'>".html_safe
+ - details_link_end = '</a>'.html_safe
+ = s_('GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}.').html_safe % { domain: domain.domain,
+ link_start: details_link_start,
+ link_end: details_link_end }
diff --git a/app/views/projects/pages/_no_domains.html.haml b/app/views/projects/pages/_no_domains.html.haml
index 8c93cf7a8ad..8d6e403b93a 100644
--- a/app/views/projects/pages/_no_domains.html.haml
+++ b/app/views/projects/pages/_no_domains.html.haml
@@ -1,7 +1,6 @@
- if can?(current_user, :update_pages, @project)
.card
.card-header
- Domains
+ = s_('GitLabPages|Domains')
.nothing-here-block
- Support for domains and certificates is disabled.
- Ask your system's administrator to enable it.
+ = s_("GitLabPages|Support for domains and certificates is disabled. Ask your system's administrator to enable it.")
diff --git a/app/views/projects/pages/_use.html.haml b/app/views/projects/pages/_use.html.haml
index 988dabef3a0..ab44fd77e1e 100644
--- a/app/views/projects/pages/_use.html.haml
+++ b/app/views/projects/pages/_use.html.haml
@@ -1,10 +1,10 @@
- unless @project.pages_deployed?
.card.border-info
.card-header.bg-info.text-white
- Configure pages
+ = s_('GitLabPages|Configure pages')
.card-body
%p
- Learn how to upload your static site and have it served by
- GitLab by following the
- = succeed '.' do
- = link_to 'documentation on GitLab Pages', help_page_path('user/project/pages/index.md'), target: '_blank'
+ - link_start = "<a href='#{help_page_path('user/project/pages/index.md')}' target='_blank' rel='noopener noreferrer'>".html_safe
+ - link_end = '</a>'.html_safe
+ = s_('GitLabPages|Learn how to upload your static site and have it served by GitLab by following the %{link_start}documentation on GitLab Pages%{link_end}.').html_safe % { link_start: link_start,
+ link_end: link_end }
diff --git a/app/views/projects/pages/show.html.haml b/app/views/projects/pages/show.html.haml
index 88ab486a248..0e1f281410a 100644
--- a/app/views/projects/pages/show.html.haml
+++ b/app/views/projects/pages/show.html.haml
@@ -1,17 +1,14 @@
- page_title 'Pages'
%h3.page-title.with-button
- Pages
+ = s_('GitLabPages|Pages')
- if can?(current_user, :update_pages, @project) && (Gitlab.config.pages.external_http || Gitlab.config.pages.external_https)
- = link_to new_project_pages_domain_path(@project), class: 'btn btn-success float-right', title: 'New Domain' do
- New Domain
+ = link_to new_project_pages_domain_path(@project), class: 'btn btn-success float-right', title: s_('GitLabPages|New Domain') do
+ = s_('GitLabPages|New Domain')
%p.light
- With GitLab Pages you can host your static websites on GitLab.
- Combined with the power of GitLab CI and the help of GitLab Runner
- you can deploy static pages for your individual projects, your user or your group.
-
+ = s_('GitLabPages|With GitLab Pages you can host your static websites on GitLab. Combined with the power of GitLab CI and the help of GitLab Runner you can deploy static pages for your individual projects, your user or your group.')
- if Gitlab.config.pages.external_https
= render 'https_only'
diff --git a/changelogs/unreleased/12-3-stable.yml b/changelogs/unreleased/12-3-stable.yml
deleted file mode 100644
index e532a8aba9f..00000000000
--- a/changelogs/unreleased/12-3-stable.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Gitaly SearchBlobs flag RPC injection
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/29020-update-release-blocks-for-multiple-milestone-support.yml b/changelogs/unreleased/29020-update-release-blocks-for-multiple-milestone-support.yml
new file mode 100644
index 00000000000..9520302068e
--- /dev/null
+++ b/changelogs/unreleased/29020-update-release-blocks-for-multiple-milestone-support.yml
@@ -0,0 +1,5 @@
+---
+title: Add support for the association of multiple milestones to the Releases page
+merge_request: 17091
+author:
+type: changed
diff --git a/changelogs/unreleased/sh-fix-gitaly-nplus-one-issues-related-mrs.yml b/changelogs/unreleased/sh-fix-gitaly-nplus-one-issues-related-mrs.yml
new file mode 100644
index 00000000000..4cc0e8f0746
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-gitaly-nplus-one-issues-related-mrs.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Gitaly N+1 queries in related merge requests API
+merge_request: 17850
+author:
+type: performance
diff --git a/db/post_migrate/20190905091812_schedule_project_any_approval_rule_migration.rb b/db/post_migrate/20190905091812_schedule_project_any_approval_rule_migration.rb
index ef1cb452c26..be47e4dfdf5 100644
--- a/db/post_migrate/20190905091812_schedule_project_any_approval_rule_migration.rb
+++ b/db/post_migrate/20190905091812_schedule_project_any_approval_rule_migration.rb
@@ -22,6 +22,8 @@ class ScheduleProjectAnyApprovalRuleMigration < ActiveRecord::Migration[5.2]
end
def up
+ return unless Gitlab.ee?
+
add_concurrent_index :projects, :id,
name: 'tmp_projects_with_approvals_before_merge',
where: 'approvals_before_merge <> 0'
diff --git a/db/post_migrate/20190905091831_schedule_merge_request_any_approval_rule_migration.rb b/db/post_migrate/20190905091831_schedule_merge_request_any_approval_rule_migration.rb
index 4a8398a9eea..cdec87270f0 100644
--- a/db/post_migrate/20190905091831_schedule_merge_request_any_approval_rule_migration.rb
+++ b/db/post_migrate/20190905091831_schedule_merge_request_any_approval_rule_migration.rb
@@ -22,6 +22,8 @@ class ScheduleMergeRequestAnyApprovalRuleMigration < ActiveRecord::Migration[5.2
end
def up
+ return unless Gitlab.ee?
+
add_concurrent_index :merge_requests, :id,
name: 'tmp_merge_requests_with_approvals_before_merge',
where: 'approvals_before_merge <> 0'
diff --git a/doc/api/issues.md b/doc/api/issues.md
index e323ebce7ca..12a63ce6e24 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -1370,8 +1370,11 @@ Example response:
"state": "opened",
"created_at": "2018-09-18T14:36:15.510Z",
"updated_at": "2018-09-19T07:45:13.089Z",
+ "closed_by": null,
+ "closed_at": null,
"target_branch": "v2.x",
"source_branch": "so_long_jquery",
+ "user_notes_count": 9,
"upvotes": 0,
"downvotes": 0,
"author": {
@@ -1411,10 +1414,10 @@ Example response:
"merge_status": "cannot_be_merged",
"sha": "3b7b528e9353295c1c125dad281ac5b5deae5f12",
"merge_commit_sha": null,
- "user_notes_count": 9,
"discussion_locked": null,
"should_remove_source_branch": null,
"force_remove_source_branch": false,
+ "reference": "!11",
"web_url": "https://gitlab.example.com/twitter/flight/merge_requests/4",
"time_stats": {
"time_estimate": 0,
@@ -1422,7 +1425,67 @@ Example response:
"human_time_estimate": null,
"human_total_time_spent": null
},
- "squash": false
+ "squash": false,
+ "task_completion_status": {
+ "count": 0,
+ "completed_count": 0
+ },
+ "changes_count": "10",
+ "latest_build_started_at": "2018-12-05T01:16:41.723Z",
+ "latest_build_finished_at": "2018-12-05T02:35:54.046Z",
+ "first_deployed_to_production_at": null,
+ "pipeline": {
+ "id": 38980952,
+ "sha": "81c6a84c7aebd45a1ac2c654aa87f11e32338e0a",
+ "ref": "test-branch",
+ "status": "success",
+ "web_url": "https://gitlab.com/gitlab-org/gitlab/pipelines/38980952"
+ },
+ "head_pipeline": {
+ "id": 38980952,
+ "sha": "81c6a84c7aebd45a1ac2c654aa87f11e32338e0a",
+ "ref": "test-branch",
+ "status": "success",
+ "web_url": "https://gitlab.example.com/twitter/flight/pipelines/38980952",
+ "before_sha": "3c738a37eb23cf4c0ed0d45d6ddde8aad4a8da51",
+ "tag": false,
+ "yaml_errors": null,
+ "user": {
+ "id": 19,
+ "name": "Jody Baumbach",
+ "username": "felipa.kuvalis",
+ "state": "active",
+ "avatar_url": "https://www.gravatar.com/avatar/6541fc75fc4e87e203529bd275fafd07?s=80&d=identicon",
+ "web_url": "https://gitlab.example.com/felipa.kuvalis"
+ },
+ "created_at": "2018-12-05T01:16:13.342Z",
+ "updated_at": "2018-12-05T02:35:54.086Z",
+ "started_at": "2018-12-05T01:16:41.723Z",
+ "finished_at": "2018-12-05T02:35:54.046Z",
+ "committed_at": null,
+ "duration": 4436,
+ "coverage": "46.68",
+ "detailed_status": {
+ "icon": "status_warning",
+ "text": "passed",
+ "label": "passed with warnings",
+ "group": "success-with-warnings",
+ "tooltip": "passed",
+ "has_details": true,
+ "details_path": "/twitter/flight/pipelines/38",
+ "illustration": null,
+ "favicon": "https://gitlab.example.com/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png"
+ }
+ },
+ "diff_refs": {
+ "base_sha": "d052d768f0126e8cddf80afd8b1eb07f406a3fcb",
+ "head_sha": "81c6a84c7aebd45a1ac2c654aa87f11e32338e0a",
+ "start_sha": "d052d768f0126e8cddf80afd8b1eb07f406a3fcb"
+ },
+ "merge_error": null,
+ "user": {
+ "can_merge": true
+ }
}
]
```
diff --git a/doc/api/scim.md b/doc/api/scim.md
index bc4f2bf9040..8cbd6103e88 100644
--- a/doc/api/scim.md
+++ b/doc/api/scim.md
@@ -24,6 +24,11 @@ Parameters:
|:----------|:--------|:---------|:----------------------------------------------------------------------------------------------------------------------------------------|
| `filter` | string | yes | A [filter](#available-filters) expression. |
| `group_path` | string | yes | Full path to the group. |
+| `startIndex` | integer | no | The 1-based index indicating where to start returning results from. A value of less than one will be interpreted as 1. |
+| `count` | integer | no | Desired maximum number of query results. |
+
+NOTE: **Note:**
+Pagination follows the [SCIM spec](https://tools.ietf.org/html/rfc7644#section-3.4.2.4) rather than GitLab pagination as used elsewhere. If records change between requests it is possible for a page to either be missing records that have moved to a different page or repeat records from a previous request.
Example request:
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 4ea7d359908..876dcfa48c6 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -771,7 +771,7 @@ module API
end
class MergeRequest < MergeRequestBasic
- expose :subscribed do |merge_request, options|
+ expose :subscribed, if: -> (_, options) { options.fetch(:include_subscribed, true) } do |merge_request, options|
merge_request.subscribed?(options[:current_user], options[:project])
end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index de6af980896..4208385a48d 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -343,7 +343,8 @@ module API
present paginate(::Kaminari.paginate_array(merge_requests)),
with: Entities::MergeRequest,
current_user: current_user,
- project: user_project
+ project: user_project,
+ include_subscribed: false
end
desc 'List merge requests closing issue' do
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 183f2db050f..8eb7d4d5a8d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2328,9 +2328,6 @@ msgstr ""
msgid "BillingPlans|Your GitLab.com trial will <strong>expire after %{expiration_date}</strong>. You can learn more about GitLab.com Gold by reading about our %{features_link}."
msgstr ""
-msgid "BillingPlans|Your Gold trial will <strong>expire after %{expiration_date}</strong>. You can learn more about GitLab.com Gold by reading about our %{features_link}."
-msgstr ""
-
msgid "BillingPlans|features"
msgstr ""
@@ -7562,6 +7559,75 @@ msgstr ""
msgid "GitLab.com import"
msgstr ""
+msgid "GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}."
+msgstr ""
+
+msgid "GitLabPages|Access pages"
+msgstr ""
+
+msgid "GitLabPages|Are you sure?"
+msgstr ""
+
+msgid "GitLabPages|Certificate: %{subject}"
+msgstr ""
+
+msgid "GitLabPages|Configure pages"
+msgstr ""
+
+msgid "GitLabPages|Details"
+msgstr ""
+
+msgid "GitLabPages|Domains"
+msgstr ""
+
+msgid "GitLabPages|Expired"
+msgstr ""
+
+msgid "GitLabPages|Force HTTPS (requires valid certificates)"
+msgstr ""
+
+msgid "GitLabPages|It may take up to 30 minutes before the site is available after the first deployment."
+msgstr ""
+
+msgid "GitLabPages|Learn how to upload your static site and have it served by GitLab by following the %{link_start}documentation on GitLab Pages%{link_end}."
+msgstr ""
+
+msgid "GitLabPages|New Domain"
+msgstr ""
+
+msgid "GitLabPages|Only project maintainers can remove pages"
+msgstr ""
+
+msgid "GitLabPages|Pages"
+msgstr ""
+
+msgid "GitLabPages|Remove"
+msgstr ""
+
+msgid "GitLabPages|Remove pages"
+msgstr ""
+
+msgid "GitLabPages|Removing pages will prevent them from being exposed to the outside world."
+msgstr ""
+
+msgid "GitLabPages|Save"
+msgstr ""
+
+msgid "GitLabPages|Support for domains and certificates is disabled. Ask your system's administrator to enable it."
+msgstr ""
+
+msgid "GitLabPages|Unverified"
+msgstr ""
+
+msgid "GitLabPages|Verified"
+msgstr ""
+
+msgid "GitLabPages|With GitLab Pages you can host your static websites on GitLab. Combined with the power of GitLab CI and the help of GitLab Runner you can deploy static pages for your individual projects, your user or your group."
+msgstr ""
+
+msgid "GitLabPages|Your pages are served under:"
+msgstr ""
+
msgid "Gitaly"
msgstr ""
@@ -8751,9 +8817,6 @@ msgstr ""
msgid "IssuesAnalytics|Total:"
msgstr ""
-msgid "It may take up to 30 minutes before the site is available after the first deployment."
-msgstr ""
-
msgid "It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected."
msgstr ""
@@ -9993,7 +10056,9 @@ msgid "Migration successful."
msgstr ""
msgid "Milestone"
-msgstr ""
+msgid_plural "Milestones"
+msgstr[0] ""
+msgstr[1] ""
msgid "Milestone lists not available with your current license"
msgstr ""
@@ -18478,9 +18543,6 @@ msgstr ""
msgid "Your new personal access token has been created."
msgstr ""
-msgid "Your pages are served under:"
-msgstr ""
-
msgid "Your password reset token has expired."
msgstr ""
diff --git a/spec/frontend/releases/components/milestone_list_spec.js b/spec/frontend/releases/components/milestone_list_spec.js
deleted file mode 100644
index f267177ddab..00000000000
--- a/spec/frontend/releases/components/milestone_list_spec.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import { GlLink } from '@gitlab/ui';
-import MilestoneList from '~/releases/components/milestone_list.vue';
-import Icon from '~/vue_shared/components/icon.vue';
-import _ from 'underscore';
-import { milestones } from '../mock_data';
-
-describe('Milestone list', () => {
- let wrapper;
-
- const factory = milestonesProp => {
- wrapper = shallowMount(MilestoneList, {
- propsData: {
- milestones: milestonesProp,
- },
- sync: false,
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('renders the milestone icon', () => {
- factory(milestones);
-
- expect(wrapper.find(Icon).exists()).toBe(true);
- });
-
- it('renders the label as "Milestone" if only a single milestone is passed in', () => {
- factory(milestones.slice(0, 1));
-
- expect(wrapper.find('.js-label-text').text()).toEqual('Milestone');
- });
-
- it('renders the label as "Milestones" if more than one milestone is passed in', () => {
- factory(milestones);
-
- expect(wrapper.find('.js-label-text').text()).toEqual('Milestones');
- });
-
- it('renders a link to the milestone with a tooltip', () => {
- const milestone = _.first(milestones);
- factory([milestone]);
-
- const milestoneLink = wrapper.find(GlLink);
-
- expect(milestoneLink.exists()).toBe(true);
-
- expect(milestoneLink.text()).toBe(milestone.title);
-
- expect(milestoneLink.attributes('href')).toBe(milestone.web_url);
-
- expect(milestoneLink.attributes('data-original-title')).toBe(milestone.description);
- });
-});
diff --git a/spec/frontend/releases/components/release_block_spec.js b/spec/frontend/releases/components/release_block_spec.js
index 229d3799ee1..5ce85a37121 100644
--- a/spec/frontend/releases/components/release_block_spec.js
+++ b/spec/frontend/releases/components/release_block_spec.js
@@ -3,6 +3,7 @@ import ReleaseBlock from '~/releases/components/release_block.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import { first } from 'underscore';
import { release } from '../mock_data';
+import Icon from '~/vue_shared/components/icon.vue';
describe('Release block', () => {
let wrapper;
@@ -15,7 +16,7 @@ describe('Release block', () => {
});
};
- const milestoneListExists = () => wrapper.find('.js-milestone-list').exists();
+ const milestoneListLabel = () => wrapper.find('.js-milestone-list-label');
afterEach(() => {
wrapper.destroy();
@@ -98,20 +99,56 @@ describe('Release block', () => {
});
});
- it('renders the milestone list if at least one milestone is associated to the release', () => {
- factory(release);
+ it('renders the milestone icon', () => {
+ expect(
+ milestoneListLabel()
+ .find(Icon)
+ .exists(),
+ ).toBe(true);
+ });
+
+ it('renders the label as "Milestones" if more than one milestone is passed in', () => {
+ expect(
+ milestoneListLabel()
+ .find('.js-label-text')
+ .text(),
+ ).toEqual('Milestones');
+ });
+
+ it('renders a link to the milestone with a tooltip', () => {
+ const milestone = first(release.milestones);
+ const milestoneLink = wrapper.find('.js-milestone-link');
+
+ expect(milestoneLink.exists()).toBe(true);
+
+ expect(milestoneLink.text()).toBe(milestone.title);
- expect(milestoneListExists()).toBe(true);
+ expect(milestoneLink.attributes('href')).toBe(milestone.web_url);
+
+ expect(milestoneLink.attributes('data-original-title')).toBe(milestone.description);
});
});
it('does not render the milestone list if no milestones are associated to the release', () => {
const releaseClone = JSON.parse(JSON.stringify(release));
- delete releaseClone.milestone;
+ delete releaseClone.milestones;
+
+ factory(releaseClone);
+
+ expect(milestoneListLabel().exists()).toBe(false);
+ });
+
+ it('renders the label as "Milestone" if only a single milestone is passed in', () => {
+ const releaseClone = JSON.parse(JSON.stringify(release));
+ releaseClone.milestones = releaseClone.milestones.slice(0, 1);
factory(releaseClone);
- expect(milestoneListExists()).toBe(false);
+ expect(
+ milestoneListLabel()
+ .find('.js-label-text')
+ .text(),
+ ).toEqual('Milestone');
});
it('renders upcoming release badge', () => {
diff --git a/spec/frontend/releases/mock_data.js b/spec/frontend/releases/mock_data.js
index aff441e675e..328199343f5 100644
--- a/spec/frontend/releases/mock_data.js
+++ b/spec/frontend/releases/mock_data.js
@@ -57,7 +57,7 @@ export const release = {
committed_date: '2019-08-26T17:47:07.000Z',
},
upcoming_release: false,
- milestone: milestones[0],
+ milestones,
assets: {
count: 5,
sources: [
diff --git a/spec/requests/api/issues/get_project_issues_spec.rb b/spec/requests/api/issues/get_project_issues_spec.rb
index c10f5b2bd58..06a43ea6b02 100644
--- a/spec/requests/api/issues/get_project_issues_spec.rb
+++ b/spec/requests/api/issues/get_project_issues_spec.rb
@@ -736,6 +736,8 @@ describe API::Issues do
get_related_merge_requests(project.id, issue.iid)
expect_paginated_array_response(related_mr.id)
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.last).not_to have_key('subscribed')
end
it 'renders 404 if project is not visible' do