Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2019-10-22 21:06:42 +00:00
parent 24fe7aa2aa
commit d5e0416021
25 changed files with 308 additions and 7 deletions

View file

@ -292,7 +292,9 @@ module ApplicationSettingsHelper
:snowplow_site_id, :snowplow_site_id,
:push_event_hooks_limit, :push_event_hooks_limit,
:push_event_activities_limit, :push_event_activities_limit,
:custom_http_clone_url_root :custom_http_clone_url_root,
:pendo_enabled,
:pendo_url
] ]
end end

View file

@ -104,6 +104,11 @@ class ApplicationSetting < ApplicationRecord
hostname: true, hostname: true,
if: :snowplow_enabled if: :snowplow_enabled
validates :pendo_url,
presence: true,
public_url: true,
if: :pendo_enabled
validates :max_attachment_size, validates :max_attachment_size,
presence: true, presence: true,
numericality: { only_integer: true, greater_than: 0 } numericality: { only_integer: true, greater_than: 0 }

View file

@ -129,7 +129,9 @@ module ApplicationSettingImplementation
snowplow_cookie_domain: nil, snowplow_cookie_domain: nil,
snowplow_enabled: false, snowplow_enabled: false,
snowplow_site_id: nil, snowplow_site_id: nil,
custom_http_clone_url_root: nil custom_http_clone_url_root: nil,
pendo_enabled: false,
pendo_url: nil
} }
end end

View file

@ -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'

View file

@ -28,4 +28,5 @@
.settings-content .settings-content
= render 'third_party_offers', application_setting: @application_setting = 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'

View file

@ -89,4 +89,5 @@
= render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id') = 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 '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'

View file

@ -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<x;++w)(function(m){
o[m]=o[m]||function(){o._q[m===v[0]?'unshift':'push']([m].concat([].slice.call(arguments,0)));};})(v[w]);
y=e.createElement(n);y.async=!0;y.src='#{Gitlab::CurrentSettings.pendo_url}';
z=e.getElementsByTagName(n)[0];z.parentNode.insertBefore(y,z);})(window,document,'script','pendo');
pendo.initialize({
visitor: {
id: '#{current_user&.id}',
}
});};

View file

@ -0,0 +1,5 @@
---
title: The Security Dashboard displays DAST vulnerabilities for all the scanned sites, not just the first
merge_request: 17779
author:
type: added

View file

@ -0,0 +1,5 @@
---
title: Fix error when viewing group billing page
merge_request: 18740
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Adds Application Settings and ui settings in the integration admin area for Pendo
merge_request: 15086
author:
type: added

View file

@ -0,0 +1,5 @@
---
title: Minor UX improvements to Environments Dashboard page
merge_request: 18280
author:
type: changed

View file

@ -0,0 +1,15 @@
class AddPendoEnabledToApplicationSettings < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default :application_settings, :pendo_enabled, :boolean, default: false, allow_null: false
end
def down
remove_column :application_settings, :pendo_enabled
end
end

View file

@ -0,0 +1,9 @@
class AddPendoUrlToApplicationSettings < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :application_settings, :pendo_url, :string, limit: 255
end
end

View file

@ -341,6 +341,8 @@ ActiveRecord::Schema.define(version: 2019_10_17_045817) do
t.integer "push_event_hooks_limit", default: 3, null: false t.integer "push_event_hooks_limit", default: 3, null: false
t.integer "push_event_activities_limit", default: 3, null: false t.integer "push_event_activities_limit", default: 3, null: false
t.string "custom_http_clone_url_root", limit: 511 t.string "custom_http_clone_url_root", limit: 511
t.boolean "pendo_enabled", default: false, null: false
t.string "pendo_url", limit: 255
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id" t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id"
t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id" t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id"
t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id" t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id"

View file

@ -257,7 +257,6 @@ are listed in the descriptions of the relevant settings.
| `housekeeping_incremental_repack_period` | integer | required by: `housekeeping_enabled` | Number of Git pushes after which an incremental `git repack` is run. | | `housekeeping_incremental_repack_period` | integer | required by: `housekeeping_enabled` | Number of Git pushes after which an incremental `git repack` is run. |
| `html_emails_enabled` | boolean | no | Enable HTML emails. | | `html_emails_enabled` | boolean | no | Enable HTML emails. |
| `import_sources` | array of strings | no | Sources to allow project import from, possible values: `github`, `bitbucket`, `bitbucket_server`, `gitlab`, `google_code`, `fogbugz`, `git`, `gitlab_project`, `gitea`, `manifest`, and `phabricator`. | | `import_sources` | array of strings | no | Sources to allow project import from, possible values: `github`, `bitbucket`, `bitbucket_server`, `gitlab`, `google_code`, `fogbugz`, `git`, `gitlab_project`, `gitea`, `manifest`, and `phabricator`. |
| `instance_statistics_visibility_private` | boolean | no | When set to `true` Instance statistics will only be available to admins. | | `instance_statistics_visibility_private` | boolean | no | When set to `true` Instance statistics will only be available to admins. |
| `local_markdown_version` | integer | no | Increase this value when any cached markdown should be invalidated. | | `local_markdown_version` | integer | no | Increase this value when any cached markdown should be invalidated. |
| `max_artifacts_size` | integer | no | Maximum artifacts size in MB | | `max_artifacts_size` | integer | no | Maximum artifacts size in MB |
@ -317,6 +316,8 @@ are listed in the descriptions of the relevant settings.
| `snowplow_cookie_domain` | string | no | The Snowplow cookie domain. (e.g. `.gitlab.com`) | | `snowplow_cookie_domain` | string | no | The Snowplow cookie domain. (e.g. `.gitlab.com`) |
| `snowplow_enabled` | boolean | no | Enable snowplow tracking. | | `snowplow_enabled` | boolean | no | Enable snowplow tracking. |
| `snowplow_site_id` | string | no | The Snowplow site name / application id. (e.g. `gitlab`) | | `snowplow_site_id` | string | no | The Snowplow site name / application id. (e.g. `gitlab`) |
| `pendo_url` | string | required by: `pendo_enabled` | The Pendo endpoint url with js snippet. (e.g. `https://cdn.pendo.io/agent/static/your-api-key/pendo.js`) |
| `pendo_enabled` | boolean | no | Enable pendo tracking. |
| `terminal_max_session_time` | integer | no | Maximum time for web terminal websocket connection (in seconds). Set to `0` for unlimited time. | | `terminal_max_session_time` | integer | no | Maximum time for web terminal websocket connection (in seconds). Set to `0` for unlimited time. |
| `terms` | text | required by: `enforce_terms` | (**Required by:** `enforce_terms`) Markdown content for the ToS. | | `terms` | text | required by: `enforce_terms` | (**Required by:** `enforce_terms`) Markdown content for the ToS. |
| `throttle_authenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_api_period_in_seconds` and `throttle_authenticated_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (e.g. from crawlers or abusive bots). | | `throttle_authenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_api_period_in_seconds` and `throttle_authenticated_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (e.g. from crawlers or abusive bots). |

View file

@ -106,7 +106,7 @@ The following table lists available parameters for jobs:
| [`when`](#when) | When to run job. Also available: `when:manual` and `when:delayed`. | | [`when`](#when) | When to run job. Also available: `when:manual` and `when:delayed`. |
| [`environment`](#environment) | Name of an environment to which the job deploys. Also available: `environment:name`, `environment:url`, `environment:on_stop`, and `environment:action`. | | [`environment`](#environment) | Name of an environment to which the job deploys. Also available: `environment:name`, `environment:url`, `environment:on_stop`, and `environment:action`. |
| [`cache`](#cache) | List of files that should be cached between subsequent runs. Also available: `cache:paths`, `cache:key`, `cache:untracked`, and `cache:policy`. | | [`cache`](#cache) | List of files that should be cached between subsequent runs. Also available: `cache:paths`, `cache:key`, `cache:untracked`, and `cache:policy`. |
| [`artifacts`](#artifacts) | List of files and directories to attach to a job on success. Also available: `artifacts:paths`, `artifacts:name`, `artifacts:untracked`, `artifacts:when`, `artifacts:expire_in`, `artifacts:reports`, and `artifacts:reports:junit`.<br><br>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`.<br><br>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. | | [`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. | | [`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. | | [`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 - 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` #### `artifacts:name`
> Introduced in GitLab 8.6 and GitLab Runner v1.1.0. > Introduced in GitLab 8.6 and GitLab Runner v1.1.0.

View file

@ -493,6 +493,11 @@ For more information, [read about pipelines](../../../ci/pipelines.md).
Find out about [bulk editing merge requests](../../project/bulk_editing.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 ## Troubleshooting
Sometimes things don't go as expected in a merge request, here are some Sometimes things don't go as expected in a merge request, here are some

View file

@ -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`. 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 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. --> 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.

View file

@ -75,3 +75,33 @@ merge request, and target a branch named `my-target-branch`:
```shell ```shell
git push -o merge_request.create -o merge_request.target=my-target-branch 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 <local-branch-name>
```

View file

@ -140,6 +140,10 @@ module API
optional :snowplow_cookie_domain, type: String, desc: 'The Snowplow cookie domain' optional :snowplow_cookie_domain, type: String, desc: 'The Snowplow cookie domain'
optional :snowplow_site_id, type: String, desc: 'The Snowplow site name / application ic' optional :snowplow_site_id, type: String, desc: 'The Snowplow site name / application ic'
end 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| ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type|
optional :"#{type}_key_restriction", optional :"#{type}_key_restriction",

View file

@ -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." msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}, or start a free 30-day trial of GitLab.com Gold."
msgstr "" 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}." msgid "BillingPlans|Learn more about each plan by visiting our %{pricing_page_link}."
msgstr "" msgstr ""
@ -6072,6 +6075,9 @@ msgstr ""
msgid "Enable or disable version check and usage ping." msgid "Enable or disable version check and usage ping."
msgstr "" msgstr ""
msgid "Enable pendo tracking"
msgstr ""
msgid "Enable protected paths rate limit" msgid "Enable protected paths rate limit"
msgstr "" msgstr ""
@ -11663,6 +11669,12 @@ msgstr ""
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
msgid "Pendo"
msgstr ""
msgid "Pendo endpoint"
msgstr ""
msgid "People without permission will never get a notification and won't be able to comment." msgid "People without permission will never get a notification and won't be able to comment."
msgstr "" msgstr ""

View file

@ -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', 'https'
it_behaves_like 'when HTTP protocol is in use', 'http' 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 end

View file

@ -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('three').for(:push_event_activities_limit) }
it { is_expected.not_to allow_value(nil).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 context "when user accepted let's encrypt terms of service" do
before do before do
setting.update(lets_encrypt_terms_of_service_accepted: true) setting.update(lets_encrypt_terms_of_service_accepted: true)

View file

@ -220,6 +220,54 @@ describe API::Settings, 'Settings' do
end end
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 context "missing plantuml_url value when plantuml_enabled is true" do
it "returns a blank parameter error message" do it "returns a blank parameter error message" do
put api("/application/settings", admin), params: { plantuml_enabled: true } put api("/application/settings", admin), params: { plantuml_enabled: true }

View file

@ -84,7 +84,7 @@ describe 'layouts/_head' do
allow(Gitlab::CurrentSettings).to receive(:snowplow_collector_hostname).and_return('www.snow.plow') allow(Gitlab::CurrentSettings).to receive(:snowplow_collector_hostname).and_return('www.snow.plow')
end end
it 'add a snowplow script tag with asset host' do it 'adds a snowplow script tag with asset host' do
render render
expect(rendered).to match('http://test.host/assets/snowplow/') expect(rendered).to match('http://test.host/assets/snowplow/')
expect(rendered).to match('window.snowplow') expect(rendered).to match('window.snowplow')
@ -92,6 +92,28 @@ describe 'layouts/_head' do
end end
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 context 'when a Piwik config is set' do
let(:piwik_host) { 'piwik.example.com' } let(:piwik_host) { 'piwik.example.com' }