Commit afda6ff5 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab-ce master

parents f7f4d01d 84655c3f
<script> <script>
import { GlPopover, GlSkeletonLoading } from '@gitlab/ui'; import { GlPopover, GlSkeletonLoading } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import UserAvatarImage from '../user_avatar/user_avatar_image.vue'; import UserAvatarImage from '../user_avatar/user_avatar_image.vue';
import { glEmojiTag } from '../../../emoji'; import { glEmojiTag } from '../../../emoji';
...@@ -28,23 +27,6 @@ export default { ...@@ -28,23 +27,6 @@ export default {
}, },
}, },
computed: { computed: {
jobLine() {
if (this.user.bio && this.user.organization) {
return sprintf(
__('%{bio} at %{organization}'),
{
bio: this.user.bio,
organization: this.user.organization,
},
false,
);
} else if (this.user.bio) {
return this.user.bio;
} else if (this.user.organization) {
return this.user.organization;
}
return null;
},
statusHtml() { statusHtml() {
if (this.user.status.emoji && this.user.status.message) { if (this.user.status.emoji && this.user.status.message) {
return `${glEmojiTag(this.user.status.emoji)} ${this.user.status.message}`; return `${glEmojiTag(this.user.status.emoji)} ${this.user.status.message}`;
...@@ -86,7 +68,8 @@ export default { ...@@ -86,7 +68,8 @@ export default {
<gl-skeleton-loading v-else :lines="1" class="animation-container-small mb-1" /> <gl-skeleton-loading v-else :lines="1" class="animation-container-small mb-1" />
</div> </div>
<div class="text-secondary"> <div class="text-secondary">
{{ jobLine }} <div v-if="user.bio" class="js-bio">{{ user.bio }}</div>
<div v-if="user.organization" class="js-organization">{{ user.organization }}</div>
<gl-skeleton-loading <gl-skeleton-loading
v-if="jobInfoIsLoading" v-if="jobInfoIsLoading"
:lines="1" :lines="1"
......
...@@ -56,7 +56,9 @@ module Emails ...@@ -56,7 +56,9 @@ module Emails
@milestone = milestone @milestone = milestone
@milestone_url = milestone_url(@milestone) @milestone_url = milestone_url(@milestone)
mail_answer_thread(@issue, issue_thread_options(updated_by_user_id, recipient_id, reason)) mail_answer_thread(@issue, issue_thread_options(updated_by_user_id, recipient_id, reason).merge({
template_name: 'changed_milestone_email'
}))
end end
def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id, reason = nil) def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id, reason = nil)
......
...@@ -51,7 +51,9 @@ module Emails ...@@ -51,7 +51,9 @@ module Emails
@milestone = milestone @milestone = milestone
@milestone_url = milestone_url(@milestone) @milestone_url = milestone_url(@milestone)
mail_answer_thread(@merge_request, merge_request_thread_options(updated_by_user_id, recipient_id, reason)) mail_answer_thread(@merge_request, merge_request_thread_options(updated_by_user_id, recipient_id, reason).merge({
template_name: 'changed_milestone_email'
}))
end end
def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id, reason = nil) def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id, reason = nil)
......
...@@ -16,6 +16,7 @@ class Notify < BaseMailer ...@@ -16,6 +16,7 @@ class Notify < BaseMailer
include Emails::AutoDevops include Emails::AutoDevops
include Emails::RemoteMirrors include Emails::RemoteMirrors
helper MilestonesHelper
helper MergeRequestsHelper helper MergeRequestsHelper
helper DiffHelper helper DiffHelper
helper BlobHelper helper BlobHelper
......
%p %p
Milestone changed to Milestone changed to
%strong= link_to(@milestone.name, @milestone_url) %strong= link_to(@milestone.name, @milestone_url)
- if date_range = milestone_date_range(@milestone)
= "(#{date_range})"
Milestone changed to <%= @milestone.name %><% if date_range = milestone_date_range(@milestone) %> (<%= date_range %>)<% end %> ( <%= @milestone_url %> )
Milestone changed to <%= @milestone.name %> ( <%= @milestone_url %> )
%p
Milestone changed to
%strong= link_to(@milestone.name, @milestone_url)
Milestone changed to <%= @milestone.name %> ( <%= @milestone_url %> )
---
title: Add date range in milestone change email notifications
merge_request: 23762
author:
type: changed
---
title: Split bio into individual line in extended user tooltips
merge_request: 23940
author:
type: other
...@@ -254,15 +254,19 @@ install it manually. ...@@ -254,15 +254,19 @@ install it manually.
GitLab provides a one-click install for various applications which can GitLab provides a one-click install for various applications which can
be added directly to your configured cluster. Those applications are be added directly to your configured cluster. Those applications are
needed for [Review Apps](../../../ci/review_apps/index.md) and needed for [Review Apps](../../../ci/review_apps/index.md) and
[deployments](../../../ci/environments.md). [deployments](../../../ci/environments.md). You can install them after you
[create a cluster](#adding-and-creating-a-new-gke-cluster-via-gitlab).
To see a list of available applications to install:
1. Navigate to your project's **Operations > Kubernetes**.
1. Select your cluster.
Install Helm Tiller first because it's used to install other applications.
NOTE: **Note:** NOTE: **Note:**
With the exception of Knative, the applications will be installed in a dedicated namespace called As of GitLab 11.6, Helm Tiller will be upgraded to the latest version supported
`gitlab-managed-apps`. In case you have added an existing Kubernetes cluster by GitLab before installing any of the applications.
with Tiller already installed, you should be careful as GitLab cannot
detect it. In this event, installing Tiller via the applications will
result in the cluster having it twice. This can lead to confusion during
deployments.
| Application | GitLab version | Description | Helm Chart | | Application | GitLab version | Description | Helm Chart |
| ----------- | :------------: | ----------- | --------------- | | ----------- | :------------: | ----------- | --------------- |
...@@ -274,9 +278,14 @@ deployments. ...@@ -274,9 +278,14 @@ deployments.
| [JupyterHub](http://jupyter.org/) | 11.0+ | [JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) is a multi-user service for managing notebooks across a team. [Jupyter Notebooks](https://jupyter-notebook.readthedocs.io/en/latest/) provide a web-based interactive programming environment used for data analysis, visualization, and machine learning. We use a [custom Jupyter image](https://gitlab.com/gitlab-org/jupyterhub-user-image/blob/master/Dockerfile) that installs additional useful packages on top of the base Jupyter. You will also see ready-to-use DevOps Runbooks built with Nurtch's [Rubix library](https://github.com/amit1rrr/rubix). More information on creating executable runbooks can be found in [our Nurtch documentation](runbooks/index.md#nurtch-executable-runbooks). **Note**: Authentication will be enabled for any user of the GitLab server via OAuth2. HTTPS will be supported in a future release. | [jupyter/jupyterhub](https://jupyterhub.github.io/helm-chart/) | | [JupyterHub](http://jupyter.org/) | 11.0+ | [JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) is a multi-user service for managing notebooks across a team. [Jupyter Notebooks](https://jupyter-notebook.readthedocs.io/en/latest/) provide a web-based interactive programming environment used for data analysis, visualization, and machine learning. We use a [custom Jupyter image](https://gitlab.com/gitlab-org/jupyterhub-user-image/blob/master/Dockerfile) that installs additional useful packages on top of the base Jupyter. You will also see ready-to-use DevOps Runbooks built with Nurtch's [Rubix library](https://github.com/amit1rrr/rubix). More information on creating executable runbooks can be found in [our Nurtch documentation](runbooks/index.md#nurtch-executable-runbooks). **Note**: Authentication will be enabled for any user of the GitLab server via OAuth2. HTTPS will be supported in a future release. | [jupyter/jupyterhub](https://jupyterhub.github.io/helm-chart/) |
| [Knative](https://cloud.google.com/knative) | 11.5+ | Knative provides a platform to create, deploy, and manage serverless workloads from a Kubernetes cluster. It is used in conjunction with, and includes [Istio](https://istio.io) to provide an external IP address for all programs hosted by Knative. You will be prompted to enter a wildcard domain where your applications will be exposed. Configure your DNS server to use the external IP address for that domain. For any application created and installed, they will be accessible as `<program_name>.<kubernetes_namespace>.<domain_name>`. This will require your kubernetes cluster to have [RBAC enabled](#role-based-access-control-rbac). | [knative/knative](https://storage.googleapis.com/triggermesh-charts) | [Knative](https://cloud.google.com/knative) | 11.5+ | Knative provides a platform to create, deploy, and manage serverless workloads from a Kubernetes cluster. It is used in conjunction with, and includes [Istio](https://istio.io) to provide an external IP address for all programs hosted by Knative. You will be prompted to enter a wildcard domain where your applications will be exposed. Configure your DNS server to use the external IP address for that domain. For any application created and installed, they will be accessible as `<program_name>.<kubernetes_namespace>.<domain_name>`. This will require your kubernetes cluster to have [RBAC enabled](#role-based-access-control-rbac). | [knative/knative](https://storage.googleapis.com/triggermesh-charts)
NOTE: **Note:** With the exception of Knative, the applications will be installed in a dedicated
As of GitLab 11.6 Helm Tiller will be upgraded to the latest version supported namespace called `gitlab-managed-apps`.
by GitLab before installing any of the above applications.
CAUTION: **Caution:**
If you have an existing Kubernetes cluster with Tiller already installed,
you should be careful as GitLab cannot detect it. In this case, installing
Tiller via the applications will result in the cluster having it twice, which
can lead to confusion during deployments.
## Getting the external IP address ## Getting the external IP address
......
...@@ -89,7 +89,7 @@ describe('User Popover Component', () => { ...@@ -89,7 +89,7 @@ describe('User Popover Component', () => {
expect(vm.$el.textContent).toContain('GitLab'); expect(vm.$el.textContent).toContain('GitLab');
}); });
it('should have full job line when we have bio and organization', () => { it('should display bio and organization in separate lines', () => {
const testProps = Object.assign({}, DEFAULT_PROPS); const testProps = Object.assign({}, DEFAULT_PROPS);
testProps.user.bio = 'Engineer'; testProps.user.bio = 'Engineer';
testProps.user.organization = 'GitLab'; testProps.user.organization = 'GitLab';
...@@ -99,20 +99,24 @@ describe('User Popover Component', () => { ...@@ -99,20 +99,24 @@ describe('User Popover Component', () => {
target: document.querySelector('.js-user-link'), target: document.querySelector('.js-user-link'),
}); });
expect(vm.$el.textContent).toContain('Engineer at GitLab'); expect(vm.$el.querySelector('.js-bio').textContent).toContain('Engineer');
expect(vm.$el.querySelector('.js-organization').textContent).toContain('GitLab');
}); });
it('should not encode special characters when we have bio and organization', () => { it('should not encode special characters in bio and organization', () => {
const testProps = Object.assign({}, DEFAULT_PROPS); const testProps = Object.assign({}, DEFAULT_PROPS);
testProps.user.bio = 'Manager & Team Lead'; testProps.user.bio = 'Manager & Team Lead';
testProps.user.organization = 'GitLab'; testProps.user.organization = 'Me & my <funky> Company';
vm = mountComponent(UserPopover, { vm = mountComponent(UserPopover, {
...DEFAULT_PROPS, ...DEFAULT_PROPS,
target: document.querySelector('.js-user-link'), target: document.querySelector('.js-user-link'),
}); });
expect(vm.$el.textContent).toContain('Manager & Team Lead at GitLab'); expect(vm.$el.querySelector('.js-bio').textContent).toContain('Manager & Team Lead');
expect(vm.$el.querySelector('.js-organization').textContent).toContain(
'Me & my <funky> Company',
);
}); });
}); });
......
# frozen_string_literal: true
require 'spec_helper'
describe 'notify/changed_milestone_email.html.haml' do
let(:milestone) { create(:milestone, title: 'some-milestone') }
let(:milestone_link) { milestone_url(milestone) }
before do
assign(:milestone, milestone)
assign(:milestone_url, milestone_link)
end
context 'milestone without start and due dates' do
it 'renders without date range' do
render
expect(rendered).to have_content('Milestone changed to some-milestone', exact: true)
expect(rendered).to have_link('some-milestone', href: milestone_link)
end
end
context 'milestone with start and due dates' do
before do
milestone.update(start_date: '2018-01-01', due_date: '2018-12-31')
end
it 'renders with date range' do
render
expect(rendered).to have_content('Milestone changed to some-milestone (Jan 1, 2018–Dec 31, 2018)', exact: true)
expect(rendered).to have_link('some-milestone', href: milestone_link)
end
end
end
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