Read about our upcoming Code of Conduct on this issue

Commit 94ddd37e authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 858a0c2a3227
......@@ -4,6 +4,7 @@ import ArtifactsApp from './artifacts_list_app.vue';
import Deployment from './deployment.vue';
import MrWidgetContainer from './mr_widget_container.vue';
import MrWidgetPipeline from './mr_widget_pipeline.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
* Renders the pipeline and related deployments from the store.
......@@ -23,6 +24,7 @@ export default {
MergeTrainPositionIndicator: () =>
mixins: [glFeatureFlagsMixin()],
props: {
mr: {
type: Object,
......@@ -62,7 +64,7 @@ export default {
return this.isPostMerge ? :;
showVisualReviewAppLink() {
return && this.glFeatures.anonymousVisualReviewFeedback;
showMergeTrainPositionIndicator() {
return _.isNumber(;
......@@ -18,7 +18,14 @@ export default {
<a :href="link" target="_blank" rel="noopener noreferrer nofollow" :class="cssClass">
rel="noopener noreferrer nofollow"
{{ __('View app') }} <icon class="fgray" name="external-link" />
......@@ -1773,7 +1773,6 @@ def after_import
InternalId.flush_records!(project: self)
......@@ -42,6 +42,14 @@ class ProjectImportState < ApplicationRecord
after_transition any => :finished do |state, _|
if state.jid.present?
state.update_column(:jid, nil)
after_transition started: :finished do |state, _|
project = state.project
......@@ -81,14 +89,6 @@ def started?
status == 'started' && project.import?
def remove_jid
return unless jid
update_column(:jid, nil)
# Refreshes the expiration time of the associated import job ID.
# This method can be used by asynchronous importers to refresh the status,
......@@ -18,8 +18,20 @@ def item_link(clusterable_presenter)
def gke_cluster_url
"{}/#{name}" if gcp?
def provider_label
if aws?
s_('ClusterIntegration|Elastic Kubernetes Service')
elsif gcp?
s_('ClusterIntegration|Google Kubernetes Engine')
def provider_management_url
if aws?
elsif gcp?
def can_read_cluster?
......@@ -8,10 +8,10 @@
- unless @cluster.provided_by_user?
= s_('ClusterIntegration|Google Kubernetes Engine')
= @cluster.provider_label
- link_gke = link_to(s_('ClusterIntegration|Google Kubernetes Engine'), @cluster.gke_cluster_url, target: '_blank', rel: 'noopener noreferrer')
= s_('ClusterIntegration|Manage your Kubernetes cluster by visiting %{link_gke}').html_safe % { link_gke: link_gke }
- provider_link = link_to(@cluster.provider_label, @cluster.provider_management_url, target: '_blank', rel: 'noopener noreferrer')
= s_('ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}').html_safe % { provider_link: provider_link }
= form_for @cluster, url: clusterable.cluster_path(@cluster), as: :cluster, html: { class: 'cluster_management_form' } do |field|
title: Update external link to provider in cluster settings
merge_request: 20425
type: fixed
title: Remove authentication step from visual review tools instructions
type: changed
title: Improve job tokens and provide access helper
merge_request: 19793
type: other
......@@ -60,11 +60,11 @@ mvn package
The above sequence of commands will generate a WAR file that can be deployed
using Tomcat:
sudo apt-get install tomcat7
sudo cp target/plantuml.war /var/lib/tomcat7/webapps/plantuml.war
sudo chown tomcat7:tomcat7 /var/lib/tomcat7/webapps/plantuml.war
sudo service tomcat7 restart
sudo apt-get install tomcat8
sudo cp target/plantuml.war /var/lib/tomcat8/webapps/plantuml.war
sudo chown tomcat8:tomcat8 /var/lib/tomcat8/webapps/plantuml.war
sudo service tomcat8 restart
Once the Tomcat service restarts the PlantUML service will be ready and
......@@ -74,7 +74,7 @@ listening for requests on port 8080:
you can change these defaults by editing the `/etc/tomcat7/server.xml` file.
you can change these defaults by editing the `/etc/tomcat8/server.xml` file.
Note that the default URL is different than when using the Docker-based image,
where the service is available at the root of URL with no relative path. Adjust
......@@ -163,6 +163,13 @@ that spawned the Review App.
### Configuring Visual Reviews
Ensure that the `anonymous_visual_review_feedback` feature flag is enabled.
Administrators can enable with a Rails console as follows:
The feedback form is served through a script you add to pages in your Review App.
If you have [Developer permissions](../../user/ to the project,
you can access it by clicking the **Review** button in the **Pipeline** section
......@@ -221,6 +228,19 @@ NOTE: **Note:**
Future enhancements [are planned](
to make this process even easier.
### Determining merge request ID
The visual review tools retrieve the merge request ID from the `data-merge-request-id`
data attribute included in the `script` HTML tag used to add the visual review tools
to your review app.
​After determining the ID for the merge request to link to a visual review app, you
can supply the ID by either:​​
- Hardcoding it in the script tag via the data attribute `data-merge-request-id` of the app.
- Dynamically adding the `data-merge-request-id` value during the build of the app.
- Supplying it manually through the visual review form in the app.
### Using Visual Reviews
After Visual Reviews has been [enabled](#configuring-visual-reviews) for the
......@@ -231,25 +251,15 @@ the bottom-right corner.
To use the feedback form:
1. Create a [personal access token](../../user/profile/
with the API scope selected.
1. Paste the token into the feedback box when prompted. If you select **Remember me**,
your browser stores the token so that future visits to Review Apps at the same URL
will not require you to re-enter the token. To clear the token, click **Log out**.
1. Make a comment on the visual review. You can make use of all the
[Markdown annotations](../../user/ that are also available in
merge request comments.
1. Submit your feedback anonymously or add your name.
1. Finally, click **Send feedback**.
After you make and submit a comment in the visual review box, it will appear
automatically in the respective merge request.
TIP: **Tip:**
Because tokens must be entered on a per-domain basis and they can only be accessed
once, different review apps will not remember your token. You can save the token
to your password manager specifically for the purpose of Visual Reviews. This way,
you will not need to create additional tokens for each merge request.
## Limitations
Review App limitations are the same as [environments limitations](../
......@@ -55,7 +55,7 @@ To select a cluster management project to use:
### Configuring your pipeline
After designating a project as the management project for the cluster,
write a [`.gitlab-ci,yml`](../../ci/yaml/ in that project. For example:
write a [`.gitlab-ci.yml`](../../ci/yaml/ in that project. For example:
configure cluster:
......@@ -12,7 +12,7 @@ requests are located.
In GitLab, you can create project and group labels:
- **Project labels** can be assigned to epics, issues and merge requests in that project only.
- **Project labels** can be assigned to issues and merge requests in that project only.
- **Group labels** can be assigned to any epics, issue and merge request in any project in
that group, or any subgroups of the group.
......@@ -3673,6 +3673,9 @@ msgstr ""
msgid "ClusterIntegration|Did you know?"
msgstr ""
msgid "ClusterIntegration|Elastic Kubernetes Service"
msgstr ""
msgid "ClusterIntegration|Elastic Stack"
msgstr ""
......@@ -3904,7 +3907,7 @@ msgstr ""
msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to create Kubernetes clusters"
msgstr ""
msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{link_gke}"
msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}"
msgstr ""
msgid "ClusterIntegration|No IAM Roles found"
......@@ -19327,13 +19330,10 @@ msgstr ""
msgid "VisualReviewApp|%{stepStart}Step 2%{stepEnd}. Add it to the %{headTags} tags of every page of your application, ensuring the merge request ID is set or not set as required. "
msgstr ""
msgid "VisualReviewApp|%{stepStart}Step 3%{stepEnd}. Open the Review App and provide a %{linkStart}personal access token%{linkEnd}."
msgstr ""
msgid "VisualReviewApp|%{stepStart}Step 4%{stepEnd}. If not previously %{linkStart}configured%{linkEnd} by a developer, enter the merge request ID for the review when prompted. The ID of this merge request is %{stepStart}%{mrId}%{stepStart}."
msgid "VisualReviewApp|%{stepStart}Step 3%{stepEnd}. If not previously %{linkStart}configured%{linkEnd} by a developer, enter the merge request ID for the review when prompted. The ID of this merge request is %{stepStart}%{mrId}%{stepStart}."
msgstr ""
msgid "VisualReviewApp|%{stepStart}Step 5%{stepEnd}. Leave feedback in the Review App."
msgid "VisualReviewApp|%{stepStart}Step 4%{stepEnd}. Leave feedback in the Review App."
msgstr ""
msgid "VisualReviewApp|Copy merge request ID"
import Vue from 'vue';
import component from '~/vue_merge_request_widget/components/review_app_link.vue';
import { mockTracking, triggerEvent } from 'spec/helpers/tracking_helper';
import mountComponent from '../../helpers/vue_mount_component_helper';
describe('review app link', () => {
......@@ -35,4 +36,13 @@ describe('review app link', () => {
it('renders svg icon', () => {
it('tracks an event when clicked', () => {
const spy = mockTracking('_category_', el, spyOn);
expect(spy).toHaveBeenCalledWith('_category_', 'open_review_app', {
label: 'review_app',
......@@ -284,7 +284,20 @@ export const mockStore = {
targetBranch: 'target-branch',
sourceBranch: 'source-branch',
sourceBranchLink: 'source-branch-link',
deployments: [{ id: 0, name: 'bogus' }, { id: 1, name: 'bogus-docs' }],
deployments: [
id: 0,
name: 'bogus',
external_url: '',
external_url_formatted: '',
id: 1,
name: 'bogus-docs',
external_url: '',
external_url_formatted: '',
postMergeDeployments: [{ id: 0, name: 'prod' }, { id: 1, name: 'prod-docs' }],
troubleshootingDocsPath: 'troubleshooting-docs-path',
ciStatus: 'ci-status',
......@@ -95,30 +95,28 @@
describe '#remove_jid', :clean_gitlab_redis_cache do
let(:project) { }
describe 'clearing `jid` after finish', :clean_gitlab_redis_cache do
context 'without an JID' do
it 'does nothing' do
import_state = create(:import_state)
import_state = create(:import_state, :started)
.not_to receive(:unset)
context 'with an JID' do
it 'unsets the JID' do
import_state = create(:import_state, jid: '123')
import_state = create(:import_state, :started, jid: '123')
.to receive(:unset)
expect(import_state.jid).to be_nil
......@@ -4335,7 +4335,6 @@ def enable_lfs
expect( receive(:after_import)
expect(import_state).to receive(:finish)
expect(project).to receive(:update_project_counter_caches)
expect(import_state).to receive(:remove_jid)
expect(project).to receive(:after_create_default_branch)
expect(project).to receive(:refresh_markdown_cache!)
expect(InternalId).to receive(:flush_records!).with(project: project)
......@@ -153,11 +153,42 @@
describe '#gke_cluster_url' do
subject { }
describe '#provider_label' do
let(:cluster) { create(:cluster, provider_type: provider_type) }
it { include( }
it { include( }
subject { }
context 'AWS provider' do
let(:provider_type) { :aws }
it { eq('Elastic Kubernetes Service') }
context 'GCP provider' do
let(:provider_type) { :gcp }
it { eq('Google Kubernetes Engine') }
describe '#provider_management_url' do
let(:cluster) { provider.cluster }
subject { }
context 'AWS provider' do
let(:provider) { create(:cluster_provider_aws) }
it { include(provider.region) }
it { include( }
context 'GCP provider' do
let(:provider) { create(:cluster_provider_gcp) }
it { include( }
it { include( }
describe '#cluster_type_description' do
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