From d5e0416021aa6de53b89f9d415f368226d9326e5 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 22 Oct 2019 21:06:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- app/helpers/application_settings_helper.rb | 4 +- app/models/application_setting.rb | 5 +++ app/models/application_setting_implementation.rb | 4 +- .../admin/application_settings/_pendo.html.haml | 24 +++++++++++ .../application_settings/integrations.html.haml | 3 +- app/views/layouts/_head.html.haml | 3 +- app/views/layouts/_pendo.html.haml | 17 ++++++++ .../11930-handle-multiple-entries-dast-report.yml | 5 +++ ...pting-to-view-gitlab-com-group-billing-page.yml | 5 +++ changelogs/unreleased/add-pendo-snippet.yml | 5 +++ .../environments-dashboard-ux-tweaks.yml | 5 +++ ...18_add_pendo_enabled_to_application_settings.rb | 15 +++++++ ...195620_add_pendo_url_to_application_settings.rb | 9 ++++ db/schema.rb | 2 + doc/api/settings.md | 3 +- doc/ci/yaml/README.md | 43 ++++++++++++++++++- doc/user/project/merge_requests/index.md | 5 +++ .../merge_requests/merge_when_pipeline_succeeds.md | 5 +++ doc/user/project/push_options.md | 30 ++++++++++++++ lib/api/settings.rb | 4 ++ locale/gitlab.pot | 12 ++++++ spec/helpers/application_settings_helper_spec.rb | 5 +++ spec/models/application_setting_spec.rb | 30 ++++++++++++++ spec/requests/api/settings_spec.rb | 48 ++++++++++++++++++++++ spec/views/layouts/_head.html.haml_spec.rb | 24 ++++++++++- 25 files changed, 308 insertions(+), 7 deletions(-) create mode 100644 app/views/admin/application_settings/_pendo.html.haml create mode 100644 app/views/layouts/_pendo.html.haml create mode 100644 changelogs/unreleased/11930-handle-multiple-entries-dast-report.yml create mode 100644 changelogs/unreleased/31364-error-when-attempting-to-view-gitlab-com-group-billing-page.yml create mode 100644 changelogs/unreleased/add-pendo-snippet.yml create mode 100644 changelogs/unreleased/environments-dashboard-ux-tweaks.yml create mode 100644 db/migrate/20191003195218_add_pendo_enabled_to_application_settings.rb create mode 100644 db/migrate/20191003195620_add_pendo_url_to_application_settings.rb diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index df17b82412f..7b5a1a02b98 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -292,7 +292,9 @@ module ApplicationSettingsHelper :snowplow_site_id, :push_event_hooks_limit, :push_event_activities_limit, - :custom_http_clone_url_root + :custom_http_clone_url_root, + :pendo_enabled, + :pendo_url ] end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index a07933d4975..4ecc9bc2153 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -104,6 +104,11 @@ class ApplicationSetting < ApplicationRecord hostname: true, if: :snowplow_enabled + validates :pendo_url, + presence: true, + public_url: true, + if: :pendo_enabled + validates :max_attachment_size, presence: true, numericality: { only_integer: true, greater_than: 0 } diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index 0c0ffb67c9a..0312183d11f 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -129,7 +129,9 @@ module ApplicationSettingImplementation snowplow_cookie_domain: nil, snowplow_enabled: false, snowplow_site_id: nil, - custom_http_clone_url_root: nil + custom_http_clone_url_root: nil, + pendo_enabled: false, + pendo_url: nil } end diff --git a/app/views/admin/application_settings/_pendo.html.haml b/app/views/admin/application_settings/_pendo.html.haml new file mode 100644 index 00000000000..c165610b332 --- /dev/null +++ b/app/views/admin/application_settings/_pendo.html.haml @@ -0,0 +1,24 @@ +- expanded = true if !@application_setting.valid? && @application_setting.errors.any? { |k| k.to_s.start_with?('pendo_') } +%section.settings.as-pendo.no-animate#js-pendo-settings{ class: ('expanded' if expanded) } + .settings-header + %h4 + = _('Pendo') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded ? _('Collapse') : _('Expand') + %p + = _('Configure the %{link} integration.').html_safe % { link: link_to('Pendo', 'https://www.pendo.io/', target: '_blank') } + .settings-content + + = form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-pendo-settings'), html: { class: 'fieldset-form' } do |f| + = form_errors(@application_setting) if expanded + + %fieldset + .form-group + .form-check + = f.check_box :pendo_enabled, class: 'form-check-input' + = f.label :pendo_enabled, _('Enable pendo tracking'), class: 'form-check-label' + .form-group + = f.label :pendo_url, _('Pendo endpoint'), class: 'label-light' + = f.text_field :pendo_url, class: 'form-control', placeholder: 'https://cdn.pendo.io/agent/static/your-api-key/pendo.js' + + = f.submit _('Save changes'), class: 'btn btn-success' diff --git a/app/views/admin/application_settings/integrations.html.haml b/app/views/admin/application_settings/integrations.html.haml index 310e86b1377..399f3566cef 100644 --- a/app/views/admin/application_settings/integrations.html.haml +++ b/app/views/admin/application_settings/integrations.html.haml @@ -28,4 +28,5 @@ .settings-content = render 'third_party_offers', application_setting: @application_setting -= render_if_exists 'admin/application_settings/snowplow', expanded: expanded_by_default? += render 'admin/application_settings/snowplow', expanded: expanded_by_default? += render 'admin/application_settings/pendo' diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index b8c9f0ae1e8..d7319b18092 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -89,4 +89,5 @@ = render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id') = render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id') - = render_if_exists 'layouts/snowplow' + = render 'layouts/snowplow' + = render 'layouts/pendo' diff --git a/app/views/layouts/_pendo.html.haml b/app/views/layouts/_pendo.html.haml new file mode 100644 index 00000000000..08b1acbe3d3 --- /dev/null +++ b/app/views/layouts/_pendo.html.haml @@ -0,0 +1,17 @@ +- return unless Gitlab::CurrentSettings.pendo_enabled? + += javascript_tag nonce: true do + :plain + ;var trackable = !['1', 'yes'].includes(window.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack); + if (trackable){ + (function(p,e,n,d,o){var v,w,x,y,z;o=p[d]=p[d]||{};o._q=[]; + v=['initialize','identify','updateOptions','pageLoad'];for(w=0,x=v.length;w
In GitLab [Enterprise Edition](https://about.gitlab.com/pricing/), these are available: `artifacts:reports:codequality`, `artifacts:reports:sast`, `artifacts:reports:dependency_scanning`, `artifacts:reports:container_scanning`, `artifacts:reports:dast`, `artifacts:reports:license_management`, `artifacts:reports:performance` and `artifacts:reports:metrics`. | +| [`artifacts`](#artifacts) | List of files and directories to attach to a job on success. Also available: `artifacts:paths`, `artifacts:expose_as`, `artifacts:name`, `artifacts:untracked`, `artifacts:when`, `artifacts:expire_in`, `artifacts:reports`, and `artifacts:reports:junit`.

In GitLab [Enterprise Edition](https://about.gitlab.com/pricing/), these are available: `artifacts:reports:codequality`, `artifacts:reports:sast`, `artifacts:reports:dependency_scanning`, `artifacts:reports:container_scanning`, `artifacts:reports:dast`, `artifacts:reports:license_management`, `artifacts:reports:performance` and `artifacts:reports:metrics`. | | [`dependencies`](#dependencies) | Restrict which artifacts are passed to a specific job by providing a list of jobs to fetch artifacts from. | | [`coverage`](#coverage) | Code coverage settings for a given job. | | [`retry`](#retry) | When and how many times a job can be auto-retried in case of a failure. | @@ -1627,6 +1627,47 @@ release-job: - tags ``` +#### `artifacts:expose_as` + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/15018) in GitLab 12.5. + +The `expose_as` keyword can be used to expose [job artifacts](../../user/project/pipelines/job_artifacts.md) +in the [merge request](../../user/project/merge_requests/index.md) UI. + +For example, to match a single file: + +```yml +test: + script: [ 'echo 1' ] + artifacts: + expose_as: 'artifact 1' + paths: ['path/to/file.txt'] +``` + +With this configuration, GitLab will add a link **artifact 1** to the relevant merge request +that points to `file1.txt`. + +An example that will match an entire directory: + +```yml +test: + script: [ 'echo 1' ] + artifacts: + expose_as: 'artifact 1' + paths: ['path/to/directory/'] +``` + +Note the following: + +- A maximum of 10 job artifacts per merge request can be exposed. +- Glob patterns are unsupported. +- If a directory is specified, the link will be to the job [artifacts browser](../../user/project/pipelines/job_artifacts.md#browsing-artifacts) if there is more than + one file in the directory. +- For exposed single file artifacts with `.html`, `.htm`, `.txt`, `.json`, `.xml`, + and `.log` extensions, if [GitLab Pages](../../administration/pages/index.md) is: + - Enabled, GitLab will automatically render the artifact. + - Not enabled, you will see the file in the artifacts browser. + #### `artifacts:name` > Introduced in GitLab 8.6 and GitLab Runner v1.1.0. diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md index 2ab7c3fb15b..f673a697c78 100644 --- a/doc/user/project/merge_requests/index.md +++ b/doc/user/project/merge_requests/index.md @@ -493,6 +493,11 @@ For more information, [read about pipelines](../../../ci/pipelines.md). Find out about [bulk editing merge requests](../../project/bulk_editing.md). +## Display arbitrary job artifacts + +To configure pipelines to job [artifacts](../pipelines/job_artifacts.md) that can be displayed in +merge requests, see [`artifacts:expose_as`](../../../ci/yaml/README.md#artifactsexpose_as). + ## Troubleshooting Sometimes things don't go as expected in a merge request, here are some diff --git a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md index dab2184448a..6630179ea47 100644 --- a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md +++ b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md @@ -85,3 +85,8 @@ questions that you know someone might ask. Each scenario can be a third-level heading, e.g. `### Getting error message X`. If you have none to add when creating a doc, leave this section in place but commented out to help encourage others to add to it in the future. --> + +## Use it from the command line + +You can use [Push Options](../push_options.md) to trigger this feature when +pushing. diff --git a/doc/user/project/push_options.md b/doc/user/project/push_options.md index 51c46dbd1d4..8952f845b96 100644 --- a/doc/user/project/push_options.md +++ b/doc/user/project/push_options.md @@ -75,3 +75,33 @@ merge request, and target a branch named `my-target-branch`: ```shell git push -o merge_request.create -o merge_request.target=my-target-branch ``` + +Additionally if you want the merge request to merge as soon as the pipeline succeeds you can do: + +```shell +git push -o merge_request.create -o merge_request.target=my-target-branch -o merge_request.merge_when_pipeline_succeeds +``` + +## Useful Git aliases + +As shown above, Git push options can cause Git commands to grow very long. If +you use the same push options frequently, it's useful to create [Git +aliases](https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases). Git aliases +are command line shortcuts for Git which can significantly simplify the use of +long Git commands. + +### Merge when pipeline succeeds alias + +To set up a Git alias for the [merge when pipeline succeeds Git push +option](#push-options-for-merge-requests): + +```shell +git config --global alias.mwps "push -o merge_request.create -o merge_request.target=master -o merge_request.merge_when_pipeline_succeeds" +``` + +Then to quickly push a local branch that will target master and merge when the +pipeline succeeds: + +```shell +git mwps origin +``` diff --git a/lib/api/settings.rb b/lib/api/settings.rb index c90ba0c9b5d..ffa0472bdbb 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -140,6 +140,10 @@ module API optional :snowplow_cookie_domain, type: String, desc: 'The Snowplow cookie domain' optional :snowplow_site_id, type: String, desc: 'The Snowplow site name / application ic' end + optional :pendo_enabled, type: Grape::API::Boolean, desc: 'Enable Pendo tracking' + given pendo_enabled: ->(val) { val } do + requires :pendo_url, type: String, desc: 'The Pendo url endpoint' + end ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type| optional :"#{type}_key_restriction", diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 8cc6e2f7682..7f3b6cbbcf8 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2415,6 +2415,9 @@ msgstr "" msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}, or start a free 30-day trial of GitLab.com Gold." msgstr "" +msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}." +msgstr "" + msgid "BillingPlans|Learn more about each plan by visiting our %{pricing_page_link}." msgstr "" @@ -6072,6 +6075,9 @@ msgstr "" msgid "Enable or disable version check and usage ping." msgstr "" +msgid "Enable pendo tracking" +msgstr "" + msgid "Enable protected paths rate limit" msgstr "" @@ -11663,6 +11669,12 @@ msgstr "" msgid "Pending" msgstr "" +msgid "Pendo" +msgstr "" + +msgid "Pendo endpoint" +msgstr "" + msgid "People without permission will never get a notification and won't be able to comment." msgstr "" diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index 705523f1110..38af4aab0ef 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -36,4 +36,9 @@ describe ApplicationSettingsHelper do it_behaves_like 'when HTTP protocol is in use', 'https' it_behaves_like 'when HTTP protocol is in use', 'http' + + context 'with tracking parameters' do + it { expect(visible_attributes).to include(*%i(snowplow_collector_hostname snowplow_cookie_domain snowplow_enabled snowplow_site_id))} + it { expect(visible_attributes).to include(*%i(pendo_enabled pendo_url))} + end end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 7bef3d30064..d16e83bb5df 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -64,6 +64,36 @@ describe ApplicationSetting do it { is_expected.not_to allow_value('three').for(:push_event_activities_limit) } it { is_expected.not_to allow_value(nil).for(:push_event_activities_limit) } + context 'when snowplow is enabled' do + before do + setting.snowplow_enabled = true + end + + it { is_expected.not_to allow_value(nil).for(:snowplow_collector_hostname) } + it { is_expected.to allow_value("snowplow.gitlab.com").for(:snowplow_collector_hostname) } + it { is_expected.not_to allow_value('/example').for(:snowplow_collector_hostname) } + end + + context 'when snowplow is not enabled' do + it { is_expected.to allow_value(nil).for(:snowplow_collector_hostname) } + end + + context 'when pendo is enabled' do + before do + setting.pendo_enabled = true + end + + it { is_expected.not_to allow_value(nil).for(:pendo_url) } + it { is_expected.to allow_value(http).for(:pendo_url) } + it { is_expected.to allow_value(https).for(:pendo_url) } + it { is_expected.not_to allow_value(ftp).for(:pendo_url) } + it { is_expected.not_to allow_value('http://127.0.0.1').for(:pendo_url) } + end + + context 'when pendo is not enabled' do + it { is_expected.to allow_value(nil).for(:pendo_url) } + end + context "when user accepted let's encrypt terms of service" do before do setting.update(lets_encrypt_terms_of_service_accepted: true) diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb index f3bfb258029..ffaa29fd924 100644 --- a/spec/requests/api/settings_spec.rb +++ b/spec/requests/api/settings_spec.rb @@ -220,6 +220,54 @@ describe API::Settings, 'Settings' do end end + context "pendo tracking settings" do + let(:settings) do + { + pendo_url: "https://pendo.example.com", + pendo_enabled: true + } + end + + let(:attribute_names) { settings.keys.map(&:to_s) } + + it "includes the attributes in the API" do + get api("/application/settings", admin) + + expect(response).to have_gitlab_http_status(200) + attribute_names.each do |attribute| + expect(json_response.keys).to include(attribute) + end + end + + it "allows updating the settings" do + put api("/application/settings", admin), params: settings + + expect(response).to have_gitlab_http_status(200) + settings.each do |attribute, value| + expect(ApplicationSetting.current.public_send(attribute)).to eq(value) + end + end + + context "missing pendo_url value when pendo_enabled is true" do + it "returns a blank parameter error message" do + put api("/application/settings", admin), params: { pendo_enabled: true } + + expect(response).to have_gitlab_http_status(400) + expect(json_response["error"]).to eq("pendo_url is missing") + end + + it "handles validation errors" do + put api("/application/settings", admin), params: settings.merge({ + pendo_url: nil + }) + + expect(response).to have_gitlab_http_status(400) + message = json_response["message"] + expect(message["pendo_url"]).to include("can't be blank") + end + end + end + context "missing plantuml_url value when plantuml_enabled is true" do it "returns a blank parameter error message" do put api("/application/settings", admin), params: { plantuml_enabled: true } diff --git a/spec/views/layouts/_head.html.haml_spec.rb b/spec/views/layouts/_head.html.haml_spec.rb index e9b3334fffc..41e685f185a 100644 --- a/spec/views/layouts/_head.html.haml_spec.rb +++ b/spec/views/layouts/_head.html.haml_spec.rb @@ -84,7 +84,7 @@ describe 'layouts/_head' do allow(Gitlab::CurrentSettings).to receive(:snowplow_collector_hostname).and_return('www.snow.plow') end - it 'add a snowplow script tag with asset host' do + it 'adds a snowplow script tag with asset host' do render expect(rendered).to match('http://test.host/assets/snowplow/') expect(rendered).to match('window.snowplow') @@ -92,6 +92,28 @@ describe 'layouts/_head' do end end + context 'when pendo is enabled' do + it 'adds a pendo initialization snippet with url', :aggregate_failures do + allow(Gitlab::CurrentSettings).to receive(:pendo_enabled?).and_return(true) + allow(Gitlab::CurrentSettings).to receive(:pendo_url).and_return('www.pen.do') + + render + + expect(rendered).to match('pendo.initialize') + expect(rendered).to match('www.pen.do') + end + end + + context 'when pendo is not enabled' do + it 'do not add pendo snippet' do + allow(Gitlab::CurrentSettings).to receive(:pendo_enabled?).and_return(false) + + render + + expect(rendered).not_to match('pendo.initialize') + end + end + context 'when a Piwik config is set' do let(:piwik_host) { 'piwik.example.com' } -- cgit v1.2.3