Commit 39b0e286 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@12-4-stable-ee

parent 9fc4650d
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
## 12.4.1
### Security (6 changes)
- Do not display project labels that are not visible for user accessing group labels.
- Do not index system notes for issue update.
- Redact search results based on Ability.allowed?.
- Do not show private cross references in epic notes.
- Filter out packages the user does'nt have permission to see at group level.
- Fixes a Open Redirect issue in `InternalRedirect`.
## 12.4.0
### Security (2 changes)
- Prevent IDOR when adding groups to protected environments.
- Hide approvers if a rule has any hidden groups.
### Removed (1 change)
- Remove db_load_balancing_index gauge metric. !17561
### Fixed (26 changes, 1 of them is from the community)
- Admin settings errors now shown in the correct panel. !14374
- Add missing error handling for epic quick actions. !15648
- Fix project exports clobbering concurrent export paths. !16280
- Fixes scroll handle icon in time series. !16354
- Remove hardcoded Medium confidence for Container Scanning vulnerabilities. !16395
- Fixed renaming changed files. !16539
- Fix project-defined metrics dashboards not rendering. !16589
- Remove duplication of Licenses in Dependency List page. !16946
- Backfill SPDX identifiers in software_licenses table. !17004
- Monitor charts: Validate form for creating an alert before submitting. !17109
- Hide Push rules link when you dont have a license installed. !17530
- Operations Dashboard: fix minimum query message. !17574
- Fix page layout for sidebar on designs view. !17579
- Display error for invalid insights config. !17589
- Display appropriate approval status icon next to license. !17613
- Fix deduplication of WASC vulnerabilities in the Security dashboard. !17778
- Fix burndown negative count edge case. !18053
- Change design management empty state button style. !18060 (George Tsiolis)
- Decouple dependency list parser from v1.0 license scanning report. !18103
- Respect Group SSO Enforcement on projects where the user is an owner. !18154
- Scoped labels do not remove old label in board sidebar. !18313
- Restrict number of users input to positive numbers. !18381
- Fix undefined method log_geo_deleted_event for MergeRequestDiff. !18405
- Add default empty values to prevent parser errors from approving the Vulnerability-Check rule. !18423
- Fix time tracking info when the sidebar is collapsed.
- Fix Discussion tab counter on Issues.
### Changed (18 changes, 1 of them is from the community)
- Style burndown charts with gitlab-ui. !15463
- Add epic_iid parameter to issues API. !15640
- Use a single badge to show number of active alerts on metrics dashboards. !15789
- Allow files with .svg extensions to be uploaded as designs for Design Management. !16160
- Implement dismissal behaviour when dismissed vulnerabilities are hidden. !16207
- Remove environment_metrics_show_multiple_dashboards feature flag. !16640
- Make name an optional parameter of releases. !16647
- Expose epics closed_at on API. !17156
- Add static_context API param when editing GitHub project service. !17397
- Support variable expansion in branch property of bridge jobs. !17430
- Add environment dropdown to pod logs screen. !17532
- Parse v2 license scanning reports. !17646
- Remove broken HTML5 routing behaviour from Pipeline Security Dashboard. !17767
- Change Prometheus Alert details list from bulleted to description list. !18116 (Vitali Tatarintev)
- Check for software license violations using SPDX identifiers. !18300
- Move 'Advanced search' message to search page title. !18349
- Add alert message for feature 'require approval from code owners' being moved. !18715
- Enable Productivity Analytics feature by default. !18754
### Performance (1 change)
- Reduce excessive GC on pull mirrors. !17931
### Added (35 changes)
- Allow Design Management files and data to be included in the project exporter/importer. !14702
- Create system notes for design events. !14791
- Paginate SCIM responses using count and startIndex. !14892
- Front-End UI for design deletion. !15034
- Add max issue count to lists. !15116
- Sign in / sign up step for trial. !15289
- Add notification for updated privacy policy. !15435
- Show Billing Plan as Cards in profile and groups. !15437
- Add Audit Event API. !15698
- Add configurable Code Owner approvals for protected branches. !15862
- Add Alerts Service to Projects. !16117
- Add Conan check_credentials API endpoint. !16215
- Initial endpoint for exposing Cycle Analytics stages for the new frontend. !16240
- Add ability to multi select issue board cards. !16317
- Add License-Check approval UI. !16371
- Add links to associated releases on Tags page. !16479
- Frontend implementation for improved trial sign-up experience for GitLab.com (SaaS) users. !16732
- Return Todos for Designs via the REST API. !16885
- Set active insights dashboard tab from hash fragment. !16904
- Extend group IP restriction to Git activity. !16980
- Inactivate pipeline retries for Merge Trains. !17065
- Expose time when the build was generated. !17113
- Add new table for recording commit counts per file. !17277
- Add vendored template for Browser Performance Testing. !17319
- Link Gitlab managed Prometheus alerts and issues. !17477
- Disable insights tab navigation whilst current page loads. !17678
- Drop all merge requests from merge trains when the project-level setting is disabled. !17774
- Implement DAST for default branches. !17789
- Add rack attack settings for prometheus and generic alert endpoint. !17859
- Add Licenses list backend usage ping. !17925
- Associate self-managed Prometheus Alerts and Issues. !18046
- Operator can see all projects using an instance level cluster. !18173
- Expose subscribed attribute for Epics in GraphQL. !18607
- Expose epic participants on GraphQL. !18691
- Adds a generic alert integration which can accept alerts from any source via a generic webhook receiver.
### Other (4 changes)
- Productivity analytics: Add scatterplot. !15569
- Updated sidebar navigation icons to be horizontally centered when bar is condensed. !16820
- Pin major version of SAST analyzers. !17110
- Docs for protected branch code owner approval API. !17132
## 12.3.4 ## 12.3.4
### Fixed (2 changes) ### Fixed (2 changes)
......
...@@ -4,11 +4,12 @@ entry. ...@@ -4,11 +4,12 @@ entry.
## 12.4.1 ## 12.4.1
### Security (12 changes) ### Security (14 changes)
- Standardize error response when route is missing. - Standardize error response when route is missing.
- Do not display project labels that are not visible for user accessing group labels. - Do not display project labels that are not visible for user accessing group labels.
- Show cross-referenced label and milestones in issues' activities only to authorized users. - Show cross-referenced label and milestones in issues' activities only to authorized users.
- Show cross-referenced label and milestones in issues' activities only to authorized users.
- Analyze incoming GraphQL queries and check for recursion. - Analyze incoming GraphQL queries and check for recursion.
- Disallow unprivileged users from commenting on private repository commits. - Disallow unprivileged users from commenting on private repository commits.
- Don't allow maintainers of a target project to delete the source branch of a merge request from a fork. - Don't allow maintainers of a target project to delete the source branch of a merge request from a fork.
...@@ -17,6 +18,7 @@ entry. ...@@ -17,6 +18,7 @@ entry.
- Return 404 on LFS request if project doesn't exist. - Return 404 on LFS request if project doesn't exist.
- Mask sentry auth token in Error Tracking dashboard. - Mask sentry auth token in Error Tracking dashboard.
- Fixes a Open Redirect issue in `InternalRedirect`. - Fixes a Open Redirect issue in `InternalRedirect`.
- Remove deploy access level when project/group link is deleted.
- Sanitize all wiki markup formats with GitLab sanitization pipelines. - Sanitize all wiki markup formats with GitLab sanitization pipelines.
......
...@@ -4,7 +4,11 @@ export const serializeFormEntries = entries => ...@@ -4,7 +4,11 @@ export const serializeFormEntries = entries =>
export const serializeForm = form => { export const serializeForm = form => {
const fdata = new FormData(form); const fdata = new FormData(form);
const entries = Array.from(fdata.keys()).map(key => { const entries = Array.from(fdata.keys()).map(key => {
const val = fdata.getAll(key); let val = fdata.getAll(key);
// Microsoft Edge has a bug in FormData.getAll() that returns an undefined
// value for each form element that does not match the given key:
// https://github.com/jimmywarting/FormData/issues/80
val = val.filter(n => n);
return { name: key, value: val.length === 1 ? val[0] : val }; return { name: key, value: val.length === 1 ? val[0] : val };
}); });
......
...@@ -41,7 +41,7 @@ export const isValidDate = dateString => { ...@@ -41,7 +41,7 @@ export const isValidDate = dateString => {
return true; return true;
} }
return false; return false;
} catch { } catch (e) {
return false; return false;
} }
}; };
......
...@@ -34,7 +34,7 @@ module UploadsActions ...@@ -34,7 +34,7 @@ module UploadsActions
headers['Pragma'] = '' headers['Pragma'] = ''
ttl, directives = *cache_settings ttl, directives = *cache_settings
ttl ||= 6.months ttl ||= 0
directives ||= { private: true, must_revalidate: true } directives ||= { private: true, must_revalidate: true }
expires_in ttl, directives expires_in ttl, directives
......
...@@ -59,7 +59,7 @@ class User < ApplicationRecord ...@@ -59,7 +59,7 @@ class User < ApplicationRecord
# Removed in GitLab 12.3. Keep until after 2019-09-22. # Removed in GitLab 12.3. Keep until after 2019-09-22.
self.ignored_columns += %i[support_bot] self.ignored_columns += %i[support_bot]
MINIMUM_INACTIVE_DAYS = 14 MINIMUM_INACTIVE_DAYS = 180
# Override Devise::Models::Trackable#update_tracked_fields! # Override Devise::Models::Trackable#update_tracked_fields!
# to limit database writes to at most once every hour # to limit database writes to at most once every hour
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
= link_to new_project_path, class: "blank-state blank-state-link" do = link_to new_project_path, class: "blank-state blank-state-link" do
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/add_new_project") = custom_icon("add_new_project", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Create a project Create a project
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
- if current_user.can_create_group? - if current_user.can_create_group?
= link_to new_group_path, class: "blank-state blank-state-link" do = link_to new_group_path, class: "blank-state blank-state-link" do
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/add_new_group") = custom_icon("add_new_group", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Create a group Create a group
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
= link_to new_admin_user_path, class: "blank-state blank-state-link" do = link_to new_admin_user_path, class: "blank-state blank-state-link" do
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/add_new_user") = custom_icon("add_new_user", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Add people Add people
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
= link_to admin_root_path, class: "blank-state blank-state-link" do = link_to admin_root_path, class: "blank-state blank-state-link" do
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/configure_server") = custom_icon("configure_server", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Configure GitLab Configure GitLab
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
- if current_user.can_create_project? - if current_user.can_create_project?
= link_to new_project_path, class: "blank-state blank-state-link" do = link_to new_project_path, class: "blank-state blank-state-link" do
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/add_new_project") = custom_icon("add_new_project", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Create a project Create a project
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
- else - else
.blank-state .blank-state
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/add_new_project") = custom_icon("add_new_project", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Create a project Create a project
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
- if current_user.can_create_group? - if current_user.can_create_group?
= link_to new_group_path, class: "blank-state blank-state-link" do = link_to new_group_path, class: "blank-state blank-state-link" do
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/add_new_group") = custom_icon("add_new_group", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Create a group Create a group
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
- if public_project_count > 0 - if public_project_count > 0
= link_to trending_explore_projects_path, class: "blank-state blank-state-link" do = link_to trending_explore_projects_path, class: "blank-state blank-state-link" do
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/globe") = custom_icon("globe", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Explore public projects Explore public projects
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
= link_to "https://docs.gitlab.com/", class: "blank-state blank-state-link" do = link_to "https://docs.gitlab.com/", class: "blank-state blank-state-link" do
.blank-state-icon .blank-state-icon
= image_tag("illustrations/welcome/lightbulb") = custom_icon("lightbulb", size: 50)
.blank-state-body .blank-state-body
%h3.blank-state-title %h3.blank-state-title
Learn more about GitLab Learn more about GitLab
......
...@@ -7,3 +7,7 @@ ...@@ -7,3 +7,7 @@
= link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link' = link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link'
| |
= link_to _('Dismiss'), '#', class: 'hide-auto-devops-implicitly-enabled-banner alert-link', data: { project_id: project.id } = link_to _('Dismiss'), '#', class: 'hide-auto-devops-implicitly-enabled-banner alert-link', data: { project_id: project.id }
- unless Gitlab.config.registry.enabled
%div
= icon('exclamation-triangle')
= _('Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for AutoDevOps to work.')
---
title: Removes arrow icons for old collapsible sections
merge_request:
author:
type: fixed
---
title: Fix Prometheus duplicate metrics
merge_request: 19327
author:
type: fixed
---
title: Disable upload HTTP caching to fix case when object storage is enabled and
proxy_download is disabled
merge_request: 19494
author:
type: fixed
---
title: Add extra sentence about registry to AutoDevOps popup
merge_request: 19092
author:
type: changed
---
title: Fixed welcome screen icons not showing
merge_request: 19148
author:
type: fixed
---
title: Disable protected path throttling by default
merge_request: 19185
author:
type: fixed
---
title: Clean up duplicate indexes on ci_trigger_requests
merge_request: 19053
author:
type: fixed
---
title: Extend gRPC timeouts for Rake tasks
merge_request: 19461
author:
type: fixed
---
title: Fix project imports not working with serialized data
merge_request: 19124
author:
type: fixed
---
title: Fix ref switcher not working on Microsoft Edge
merge_request: 19335
author:
type: fixed
---
title: Increase timeout for FetchInternalRemote RPC call
merge_request: 18908
author:
type: fixed
---
title: Increased deactivation threshold to 180 days
merge_request: 18902
author:
type: changed
...@@ -10,7 +10,12 @@ class ReplaceCiTriggerRequestsIndex < ActiveRecord::Migration[5.2] ...@@ -10,7 +10,12 @@ class ReplaceCiTriggerRequestsIndex < ActiveRecord::Migration[5.2]
def up def up
add_concurrent_index :ci_trigger_requests, [:trigger_id, :id], order: { id: :desc } add_concurrent_index :ci_trigger_requests, [:trigger_id, :id], order: { id: :desc }
remove_concurrent_index :ci_trigger_requests, [:trigger_id] # Some installations have legacy, duplicate indexes on
# ci_trigger_requests.trigger_id. Rails won't drop them without an
# explicit name: https://gitlab.com/gitlab-org/gitlab/issues/34818
old_index_names.each do |name|
remove_concurrent_index :ci_trigger_requests, [:trigger_id], name: name
end
end end
def down def down
...@@ -18,4 +23,10 @@ class ReplaceCiTriggerRequestsIndex < ActiveRecord::Migration[5.2] ...@@ -18,4 +23,10 @@ class ReplaceCiTriggerRequestsIndex < ActiveRecord::Migration[5.2]
remove_concurrent_index :ci_trigger_requests, [:trigger_id, :id], order: { id: :desc } remove_concurrent_index :ci_trigger_requests, [:trigger_id, :id], order: { id: :desc }
end end
private
def old_index_names
indexes(:ci_trigger_requests).select { |i| i.columns == ['trigger_id'] }.map(&:name)
end
end end
# frozen_string_literal: true
class ChangeDefaultValueOfThrottleProtectedPaths < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
change_column_default :application_settings, :throttle_protected_paths_enabled, false
# Because we already set the value to true in the previous
# migration, this feature was switched on inadvertently in GitLab
# 12.4. This migration toggles it back off to ensure we don't
# inadvertently block legitimate users. The admin will have to
# re-enable it in the application settings.
unless omnibus_protected_paths_present?
execute "UPDATE application_settings SET throttle_protected_paths_enabled = #{false_value}"
end
end
def down
change_column_default :application_settings, :throttle_protected_paths_enabled, true
execute "UPDATE application_settings SET throttle_protected_paths_enabled = #{true_value}"
end
private
def omnibus_protected_paths_present?
Rack::Attack.throttles.key?('protected paths')
rescue e
say "Error while checking if Omnibus protected paths were already enabled: #{e.message}"
say 'Continuing. Protected paths will remain enabled.'
# Return true so we don't take a risk
true
end
end
...@@ -62,6 +62,7 @@ class SyncIssuablesStateId < ActiveRecord::Migration[5.2] ...@@ -62,6 +62,7 @@ class SyncIssuablesStateId < ActiveRecord::Migration[5.2]
CASE state CASE state
WHEN 'opened' THEN 1 WHEN 'opened' THEN 1
WHEN 'closed' THEN 2 WHEN 'closed' THEN 2
ELSE 2
END END
SQL SQL
end end
...@@ -73,6 +74,7 @@ class SyncIssuablesStateId < ActiveRecord::Migration[5.2] ...@@ -73,6 +74,7 @@ class SyncIssuablesStateId < ActiveRecord::Migration[5.2]
WHEN 'closed' THEN 2 WHEN 'closed' THEN 2
WHEN 'merged' THEN 3 WHEN 'merged' THEN 3
WHEN 'locked' THEN 4 WHEN 'locked' THEN 4
ELSE 2
END END
SQL SQL
end end
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_10_16_220135) do ActiveRecord::Schema.define(version: 2019_10_26_041447) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm" enable_extension "pg_trgm"
...@@ -331,7 +331,7 @@ ActiveRecord::Schema.define(version: 2019_10_16_220135) do ...@@ -331,7 +331,7 @@ ActiveRecord::Schema.define(version: 2019_10_16_220135) do
t.string "encrypted_asset_proxy_secret_key_iv" t.string "encrypted_asset_proxy_secret_key_iv"
t.string "static_objects_external_storage_url", limit: 255 t.string "static_objects_external_storage_url", limit: 255
t.string "static_objects_external_storage_auth_token", limit: 255 t.string "static_objects_external_storage_auth_token", limit: 255
t.boolean "throttle_protected_paths_enabled", default: true, null: false t.boolean "throttle_protected_paths_enabled", default: false, null: false
t.integer "throttle_protected_paths_requests_per_period", default: 10, null: false t.integer "throttle_protected_paths_requests_per_period", default: 10, null: false
t.integer "throttle_protected_paths_period_in_seconds", default: 60, null: false t.integer "throttle_protected_paths_period_in_seconds", default: 60, null: false
t.string "protected_paths", limit: 255, default: ["/users/password", "/users/sign_in", "/api/v3/session.json", "/api/v3/session", "/api/v4/session.json", "/api/v4/session", "/users", "/users/confirmation", "/unsubscribes/", "/import/github/personal_access_token"], array: true t.string "protected_paths", limit: 255, default: ["/users/password", "/users/sign_in", "/api/v3/session.json", "/api/v3/session", "/api/v4/session.json", "/api/v4/session", "/users", "/users/confirmation", "/unsubscribes/", "/import/github/personal_access_token"], array: true
......
...@@ -1172,7 +1172,7 @@ Returns: ...@@ -1172,7 +1172,7 @@ Returns:
- `404 User Not Found` if user cannot be found. - `404 User Not Found` if user cannot be found.
- `403 Forbidden` when trying to deactivate a user: - `403 Forbidden` when trying to deactivate a user:
- Blocked by admin or by LDAP synchronization. - Blocked by admin or by LDAP synchronization.
- That has any activity in past 14 days. These cannot be deactivated. - That has any activity in past 180 days. These users cannot be deactivated.
## Activate user ## Activate user
......
...@@ -32,11 +32,10 @@ to protect trigger tokens. ...@@ -32,11 +32,10 @@ to protect trigger tokens.
You can use the `CI_JOB_TOKEN` [variable][predef] (used to authenticate You can use the `CI_JOB_TOKEN` [variable][predef] (used to authenticate
with the [GitLab Container Registry][registry]) in the following cases. with the [GitLab Container Registry][registry]) in the following cases.
#### When used with multi-project pipelines **(PREMIUM)** #### When used with multi-project pipelines
> **Note**: > - Use of `CI_JOB_TOKEN` for multi-project pipelines was [introduced][ee-2017] in [GitLab Premium][ee] 9.3.
The use of `CI_JOB_TOKEN` for multi-project pipelines was [introduced][ee-2017] > - Use of `CI_JOB_TOKEN` for multi-project pipelines was [made available](https://gitlab.com/gitlab-org/gitlab/issues/31573) in all tiers in GitLab 12.4.
in [GitLab Premium][ee] 9.3.
This way of triggering can only be used when invoked inside `.gitlab-ci.yml`, This way of triggering can only be used when invoked inside `.gitlab-ci.yml`,
and it creates a dependent pipeline relation visible on the and it creates a dependent pipeline relation visible on the
......
# Productivity Analytics **(PREMIUM)** # Productivity Analytics **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12079) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3 (enabled by default using the feature flags `productivity_analytics`, `productivity_analytics_scatterplot_enabled`). > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12079) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
Track development velocity with Productivity Analytics. Track development velocity with Productivity Analytics.
...@@ -52,3 +52,29 @@ The **Productivity Analytics** dashboard can be accessed only: ...@@ -52,3 +52,29 @@ The **Productivity Analytics** dashboard can be accessed only:
- On [Premium or Silver tier](https://about.gitlab.com/pricing/) and above. - On [Premium or Silver tier](https://about.gitlab.com/pricing/) and above.
- By users with [Reporter access](../permissions.md) and above. - By users with [Reporter access](../permissions.md) and above.
## Enabling and disabling using feature flags
Productivity Analytics is:
- [Enabled by default](https://gitlab.com/gitlab-org/gitlab/merge_requests/18754) from GitLab 12.4,
but can be disabled using the following feature flags:
- `productivity_analytics`.
- `productivity_analytics_scatterplot_enabled`.
- Disabled by default in GitLab 12.3, but can be enabled using the following feature flag:
- `productivity_analytics`.
A GitLab administrator can:
- Disable this feature from GitLab 12.4 by running the follow in a Rails console:
```ruby
Feature.disable(:productivity_analytics)
Feature.disable(:productivity_analytics_scatterplot_enabled)
```
- Enable this feature in GitLab 12.3 by running the following in a Rails console:
```ruby
Feature.enable(:productivity_analytics)
```
...@@ -71,7 +71,7 @@ To do this: ...@@ -71,7 +71,7 @@ To do this:
Please note that for the deactivation option to be visible to an admin, the user: Please note that for the deactivation option to be visible to an admin, the user:
- Must be currently active. - Must be currently active.
- Should not have any activity in the last 14 days. - Should not have any activity in the last 180 days.
### Activating a user ### Activating a user
......
...@@ -220,7 +220,7 @@ module Gitlab ...@@ -220,7 +220,7 @@ module Gitlab
return if @sections.include?(section) return if @sections.include?(section)
@sections << section @sections << section
write_raw %{<div class="js-section-start section-start fa fa-caret-down pr-2 cursor-pointer" data-timestamp="#{timestamp}" data-section="#{data_section_names}" role="button"></div>} write_raw %{<div class="section-start" data-timestamp="#{timestamp}" data-section="#{data_section_names}" role="button"></div>}
@lineno_in_section = 0 @lineno_in_section = 0
end end
...@@ -308,7 +308,7 @@ module Gitlab ...@@ -308,7 +308,7 @@ module Gitlab
css_classes << "section" css_classes << "section"
css_classes << if @lineno_in_section == 0 css_classes << if @lineno_in_section == 0
"js-section-header section-header cursor-pointer" "section-header"
else else
"line" "line"
end end
......
...@@ -362,13 +362,17 @@ module Gitlab ...@@ -362,13 +362,17 @@ module Gitlab
end end
def self.long_timeout def self.long_timeout
if Sidekiq.server? if web_app_server?
6.hours
else
default_timeout default_timeout
else
6.hours
end end
end end
def self.web_app_server?
defined?(::Unicorn) || defined?(::Puma)
end
def self.storage_metadata_file_path(storage) def self.storage_metadata_file_path(storage)
Gitlab::GitalyClient::StorageSettings.allow_disk_access do Gitlab::GitalyClient::StorageSettings.allow_disk_access do
File.join( File.join(
......
...@@ -49,7 +49,7 @@ module Gitlab ...@@ -49,7 +49,7 @@ module Gitlab
response = GitalyClient.call(@storage, :remote_service, response = GitalyClient.call(@storage, :remote_service,
:fetch_internal_remote, request, :fetch_internal_remote, request,
timeout: GitalyClient.medium_timeout, timeout: GitalyClient.long_timeout,
remote_storage: repository.storage) remote_storage: repository.storage)
response.result response.result
......
...@@ -292,9 +292,11 @@ module Gitlab ...@@ -292,9 +292,11 @@ module Gitlab
existing_object existing_object
else else
object = relation_class.new # Because of single-type inheritance, we need to be careful to use the `type` field
# See https://gitlab.com/gitlab-org/gitlab/issues/34860#note_235321497
# Use #assign_attributes here to call object custom setters inheritance_column = relation_class.try(:inheritance_column)
inheritance_attributes = parsed_relation_hash.slice(inheritance_column)
object = relation_class.new(inheritance_attributes)
object.assign_attributes(parsed_relation_hash) object.assign_attributes(parsed_relation_hash)
object object
end end
......
...@@ -35,7 +35,7 @@ module Gitlab ...@@ -35,7 +35,7 @@ module Gitlab
def self.initialize_http_request_duration_seconds def self.initialize_http_request_duration_seconds
HTTP_METHODS.each do |method, statuses| HTTP_METHODS.each do |method, statuses|
statuses.each do |status| statuses.each do |status|
http_request_duration_seconds.get({ method: method, status: status }) http_request_duration_seconds.get({ method: method, status: status.to_i })
end end
end end
end end
......
...@@ -4361,6 +4361,9 @@ msgstr "" ...@@ -4361,6 +4361,9 @@ msgstr ""
msgid "Container registry images" msgid "Container registry images"
msgstr "" msgstr ""
msgid "Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for AutoDevOps to work."
msgstr ""
msgid "ContainerRegistry|Container Registry" msgid "ContainerRegistry|Container Registry"
msgstr "" msgstr ""
......
...@@ -123,7 +123,7 @@ describe Admin::UsersController do ...@@ -123,7 +123,7 @@ describe Admin::UsersController do
put :deactivate, params: { id: user.username } put :deactivate, params: { id: user.username }
user.reload user.reload
expect(user.deactivated?).to be_falsey expect(user.deactivated?).to be_falsey
expect(flash[:notice]).to eq("The user you are trying to deactivate has been active in the past 14 days and cannot be deactivated") expect(flash[:notice]).to eq("The user you are trying to deactivate has been active in the past #{::User::MINIMUM_INACTIVE_DAYS} days and cannot be deactivated")
end end
end end
end end
......
...@@ -7,9 +7,9 @@ shared_examples 'content 5 min private cached with revalidation' do ...@@ -7,9 +7,9 @@ shared_examples 'content 5 min private cached with revalidation' do
end end
end end
shared_examples 'content long term private cached with revalidation' do shared_examples 'content not cached' do
it 'ensures content will not be cached without revalidation' do it 'ensures content will not be cached without revalidation' do
expect(subject['Cache-Control']).to eq('max-age=15778476, private, must-revalidate') expect(subject['Cache-Control']).to eq('max-age=0, private, must-revalidate')
end end
end end
...@@ -490,7 +490,7 @@ describe UploadsController do ...@@ -490,7 +490,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content long term private cached with revalidation' do it_behaves_like 'content not cached' do
subject do subject do
get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' }
...@@ -510,7 +510,7 @@ describe UploadsController do ...@@ -510,7 +510,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content long term private cached with revalidation' do it_behaves_like 'content not cached' do
subject do subject do
get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' }
...@@ -563,7 +563,7 @@ describe UploadsController do ...@@ -563,7 +563,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content long term private cached with revalidation' do it_behaves_like 'content not cached' do
subject do subject do
get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' }
......
...@@ -57,5 +57,18 @@ describe 'Project > Show > User interacts with auto devops implicitly enabled ba ...@@ -57,5 +57,18 @@ describe 'Project > Show > User interacts with auto devops implicitly enabled ba
expect(page).not_to have_css('.auto-devops-implicitly-enabled-banner') expect(page).not_to have_css('.auto-devops-implicitly-enabled-banner')
end end
end end
context 'when AutoDevOps enabled but container registry is disabled' do
before do
stub_application_setting(auto_devops_enabled: true)
stub_container_registry_config(enabled: false)
visit project_path(project)
end
it 'shows message that container registry is disabled' do
expect(page).to have_content('Container registry is not enabled on this GitLab instance')
end
end
end end
end end
...@@ -6226,7 +6226,9 @@ ...@@ -6226,7 +6226,9 @@
"job_id": null, "job_id": null,
"name": "test build 1", "name": "test build 1",
"deploy": false, "deploy": false,
"options": null, "options": {
"image": "busybox:latest"
},
"allow_failure": false, "allow_failure": false,
"stage": "test", "stage": "test",
"trigger_request_id": null, "trigger_request_id": null,
......
...@@ -70,5 +70,27 @@ describe('lib/utils/forms', () => { ...@@ -70,5 +70,27 @@ describe('lib/utils/forms', () => {
bar: ['bar-value2', 'bar-value1'], bar: ['bar-value2', 'bar-value1'],
}); });
}); });
it('handles Microsoft Edge FormData.getAll() bug', () => {
const formData = [
{ type: 'checkbox', name: 'foo', value: 'foo-value1' },
{ type: 'text', name: 'bar', value: 'bar-value2' },
];
const form = createDummyForm(formData);
jest
.spyOn(FormData.prototype, 'getAll')
.mockImplementation(name =>
formData.map(elem => (elem.name === name ? elem.value : undefined)),
);
const data = serializeForm(form);
expect(data).toEqual({
foo: 'foo-value1',
bar: 'bar-value2',
});
});
}); });
}); });
...@@ -39,13 +39,25 @@ describe('Release block', () => { ...@@ -39,13 +39,25 @@ describe('Release block', () => {
const milestoneListLabel = () => wrapper.find('.js-milestone-list-label'); const milestoneListLabel = () => wrapper.find('.js-milestone-list-label');
const editButton = () => wrapper.find('.js-edit-button'); const editButton = () => wrapper.find('.js-edit-button');
const RealDate = Date;
beforeEach(() => { beforeEach(() => {
// timeago.js calls Date(), so let's mock that case to avoid time-dependent test failures.
const constantDate = new Date('2019-10-25T00:12:00');
/* eslint no-global-assign:off */
global.Date = jest.fn((...props) =>
props.length ? new RealDate(...props) : new RealDate(constantDate),
);
Object.assign(Date, RealDate);
releaseClone = JSON.parse(JSON.stringify(release)); releaseClone = JSON.parse(JSON.stringify(release));
}); });
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
global.Date = RealDate;
}); });
describe('with default props', () => { describe('with default props', () => {
......
...@@ -10,7 +10,7 @@ describe('Job Log', () => { ...@@ -10,7 +10,7 @@ describe('Job Log', () => {
let vm; let vm;
const trace = const trace =
'<span>Running with gitlab-runner 12.1.0 (de7731dd)<br/></span><span> on docker-auto-scale-com d5ae8d25<br/></span><div class="js-section-start fa fa-caret-down append-right-8 cursor-pointer" data-timestamp="1565502765" data-section="prepare-executor" role="button"></div><span class="section js-section-header section-header js-s-prepare-executor">Using Docker executor with image ruby:2.6 ...<br/></span>'; '<span>Running with gitlab-runner 12.1.0 (de7731dd)<br/></span><span> on docker-auto-scale-com d5ae8d25<br/></span><div class="append-right-8" data-timestamp="1565502765" data-section="prepare-executor" role="button"></div><span class="section section-header js-s-prepare-executor">Using Docker executor with image ruby:2.6 ...<br/></span>';
beforeEach(() => { beforeEach(() => {
store = createStore(); store = createStore();
......
...@@ -1189,18 +1189,3 @@ export const jobsInStage = { ...@@ -1189,18 +1189,3 @@ export const jobsInStage = {
path: '/gitlab-org/gitlab-shell/pipelines/27#build', path: '/gitlab-org/gitlab-shell/pipelines/27#build',
dropdown_path: '/gitlab-org/gitlab-shell/pipelines/27/stage.json?stage=build', dropdown_path: '/gitlab-org/gitlab-shell/pipelines/27/stage.json?stage=build',
}; };
export const logWithCollapsibleSections = {
append: false,
complete: true,
html:
'<div class="js-section-start fa fa-caret-down append-right-8 cursor-pointer" data-timestamp="1559571405" data-section="after-script" role="button"></div><span class="term-fg-l-green term-bold section js-section-header js-s-after-script">Running after script...</span><span class="section js-section-header js-s-after-script"><br /></span><span class="section s_after-script line"></span><span class="section js-s-after-script"></span><span class="term-fg-l-green term-bold section js-s-after-script">$ date</span><span class="section js-s-after-script"><br /></span><span class="section s_after-script line"></span><span class="section js-s-after-script">Mon Jun 3 14:16:46 UTC 2019<br /></span><span class="section s_after-script line"></span><span class="section js-s-after-script"></span><div class="section-end" data-section="after-script"></div><div class="js-section-start fa fa-caret-down append-right-8 cursor-pointer"data-timestamp="1559571408" data-section="archive-cache" role="button" ></div><span class="term-fg-l-green term-bold section js-section-header js-s-archive-cache">Not uploading cache debian-stretch-ruby-2.6.3-node-10.x-3 due to policy</span><span class="section js-section-header js-s-archive-cache"><br /></span><span class="section s_archive-cache line"></span><span class="section js-s-archive-cache"></span><div class="section-end" data-section="archive-cache"></div><div class="js-section-start fa fa-caret-down append-right-8 cursor-pointer" data-timestamp="1559571409" data-section="upload-artifacts-on-success" role="button"></div><span class="term-fg-l-green term-bold section js-section-header js-s-upload-artifacts-on-success">Uploading artifacts...</span><span class="section js-section-header js-s-upload-artifacts-on-success"><br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success">coverage/: found 5 matching files </span><span class="section js-s-upload-artifacts-on-success"> <br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success">knapsack/: found 4 matching files </span><span class="section js-s-upload-artifacts-on-success"> <br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success">rspec_flaky/: found 4 matching files </span><span class="section js-s-upload-artifacts-on-success"> <br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success">rspec_profiling/: found 1 matching files </span><span class="section js-s-upload-artifacts-on-success"> <br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success"></span><span class="term-fg-yellow section js-s-upload-artifacts-on-success">WARNING: tmp/capybara/: no matching files </span><span class="section js-s-upload-artifacts-on-success"> <br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success">Uploading artifacts to coordinator... ok </span><span class="section js-s-upload-artifacts-on-success"> id</span><span class="section js-s-upload-artifacts-on-success">=224162288 responseStatus</span><span class="section js-s-upload-artifacts-on-success">=201 Created token</span><span class="section js-s-upload-artifacts-on-success">=bBmyXJNW<br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success"></span><span class="term-fg-l-green term-bold section js-s-upload-artifacts-on-success">Uploading artifacts...</span><span class="section js-s-upload-artifacts-on-success"><br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success">junit_rspec.xml: found 1 matching files </span><span class="section js-s-upload-artifacts-on-success"> <br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success">Uploading artifacts to coordinator... ok </span><span class="section js-s-upload-artifacts-on-success"> id</span><span class="section js-s-upload-artifacts-on-success">=224162288 responseStatus</span><span class="section js-s-upload-artifacts-on-success">=201 Created token</span><span class="section js-s-upload-artifacts-on-success">=bBmyXJNW<br /></span><span class="section s_upload-artifacts-on-success line"></span><span class="section js-s-upload-artifacts-on-success"></span><div class="section-end" data-section="upload-artifacts-on-success"></div><span class="term-fg-l-green term-bold">Job succeeded<br /><span class="term-fg-l-green term-bold"></span></span>',
id: 1385,
offset: 0,
size: 78815,
state:
'eyJvZmZzZXQiOjc4ODE1LCJuX29wZW5fdGFncyI6MCwiZmdfY29sb3IiOm51bGwsImJnX2NvbG9yIjpudWxsLCJzdHlsZV9tYXNrIjowLCJzZWN0aW9ucyI6W10sImxpbmVub19pbl9zZWN0aW9uIjoxMX0=',
status: 'success',
total: 78815,
truncated: false,
};
...@@ -209,7 +209,7 @@ describe Gitlab::Ci::Ansi2html do ...@@ -209,7 +209,7 @@ describe Gitlab::Ci::Ansi2html do
let(:section_start) { "section_start:#{section_start_time.to_i}:#{section_name}\r\033[0K"} let(:section_start) { "section_start:#{section_start_time.to_i}:#{section_name}\r\033[0K"}
let(:section_end) { "section_end:#{section_end_time.to_i}:#{section_name}\r\033[0K"} let(:section_end) { "section_end:#{section_end_time.to_i}:#{section_name}\r\033[0K"}
let(:section_start_html) do let(:section_start_html) do
'<div class="js-section-start section-start fa fa-caret-down pr-2 cursor-pointer"' \ '<div class="section-start"' \
" data-timestamp=\"#{section_start_time.to_i}\" data-section=\"#{class_name(section_name)}\"" \ " data-timestamp=\"#{section_start_time.to_i}\" data-section=\"#{class_name(section_name)}\"" \
' role="button"></div>' ' role="button"></div>'
end end
...@@ -233,8 +233,8 @@ describe Gitlab::Ci::Ansi2html do ...@@ -233,8 +233,8 @@ describe Gitlab::Ci::Ansi2html do
it 'prints light red' do it 'prints light red' do
text = "#{section_start}\e[91mHello\e[0m\nLine 1\nLine 2\nLine 3\n#{section_end}" text = "#{section_start}\e[91mHello\e[0m\nLine 1\nLine 2\nLine 3\n#{section_end}"
header = %{<span class="term-fg-l-red section js-section-header section-header cursor-pointer js-s-#{class_name(section_name)}">Hello</span>} header = %{<span class="term-fg-l-red section section-header js-s-#{class_name(section_name)}">Hello</span>}
line_break = %{<span class="section js-section-header section-header cursor-pointer js-s-#{class_name(section_name)}"><br/></span>} line_break = %{<span class="section section-header js-s-#{class_name(section_name)}"><br/></span>}
output_line = %{<span class="section line js-s-#{class_name(section_name)}">Line 1<br/>Line 2<br/>Line 3<br/></span>} output_line = %{<span class="section line js-s-#{class_name(section_name)}">Line 1<br/>Line 2<br/>Line 3<br/></span>}
html = "#{section_start_html}#{header}#{line_break}#{output_line}#{section_end_html}" html = "#{section_start_html}#{header}#{line_break}#{output_line}#{section_end_html}"
......
...@@ -17,6 +17,28 @@ describe Gitlab::GitalyClient do ...@@ -17,6 +17,28 @@ describe Gitlab::GitalyClient do
}) })
end end
describe '.long_timeout' do
context 'default case' do
it { expect(subject.long_timeout).to eq(6.hours) }
end
context 'running in Unicorn' do
before do
stub_const('Unicorn', 1)
end
it { expect(subject.long_timeout).to eq(55) }
end
context 'running in Puma' do
before do
stub_const('Puma', 1)
end
it { expect(subject.long_timeout).to eq(55) }
end
end
describe '.filesystem_id_from_disk' do describe '.filesystem_id_from_disk' do
it 'catches errors' do it 'catches errors' do
[Errno::ENOENT, Errno::EACCES, JSON::ParserError].each do |error| [Errno::ENOENT, Errno::EACCES, JSON::ParserError].each do |error|
......
...@@ -283,6 +283,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do ...@@ -283,6 +283,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
it 'correctly restores association between a pipeline and a job' do it 'correctly restores association between a pipeline and a job' do
expect(CommitStatus.all).to all(have_attributes(pipeline_id: a_value > 0)) expect(CommitStatus.all).to all(have_attributes(pipeline_id: a_value > 0))
end end
it 'restores a Hash for CommitStatus options' do
expect(CommitStatus.all.map(&:options).compact).to all(be_a(Hash))
end
end end
end end
end end
......
...@@ -69,7 +69,7 @@ describe Gitlab::Metrics::RequestsRackMiddleware do ...@@ -69,7 +69,7 @@ describe Gitlab::Metrics::RequestsRackMiddleware do
expected_labels = [] expected_labels = []
described_class::HTTP_METHODS.each do |method, statuses| described_class::HTTP_METHODS.each do |method, statuses|
statuses.each do |status| statuses.each do |status|
expected_labels << { method: method, status: status } expected_labels << { method: method, status: status.to_i }
end end
end end
......
...@@ -19,19 +19,23 @@ describe SyncIssuablesStateId, :migration, :sidekiq do ...@@ -19,19 +19,23 @@ describe SyncIssuablesStateId, :migration, :sidekiq do
it 'migrates state column to state_id as integer' do it 'migrates state column to state_id as integer' do
opened_issue = issues.create!(description: 'first', state: 'opened') opened_issue = issues.create!(description: 'first', state: 'opened')
closed_issue = issues.create!(description: 'second', state: 'closed') closed_issue = issues.create!(description: 'second', state: 'closed')
unknown_state_issue = issues.create!(description: 'second', state: 'unknown')
opened_merge_request = merge_requests.create!(state: 'opened', target_project_id: project.id, target_branch: 'feature1', source_branch: 'master') opened_merge_request = merge_requests.create!(state: 'opened', target_project_id: project.id, target_branch: 'feature1', source_branch: 'master')
closed_merge_request = merge_requests.create!(state: 'closed', target_project_id: project.id, target_branch: 'feature2', source_branch: 'master') closed_merge_request = merge_requests.create!(state: 'closed', target_project_id: project.id, target_branch: 'feature2', source_branch: 'master')
merged_merge_request = merge_requests.create!(state: 'merged', target_project_id: project.id, target_branch: 'feature3', source_branch: 'master') merged_merge_request = merge_requests.create!(state: 'merged', target_project_id: project.id, target_branch: 'feature3', source_branch: 'master')
locked_merge_request = merge_requests.create!(state: 'locked', target_project_id: project.id, target_branch: 'feature4', source_branch: 'master') locked_merge_request = merge_requests.create!(state: 'locked', target_project_id: project.id, target_branch: 'feature4', source_branch: 'master')
unknown_state_merge_request = merge_requests.create!(state: 'unknown', target_project_id: project.id, target_branch: 'feature4', source_branch: 'master')
migrate! migrate!
expect(opened_issue.reload.state_id).to eq(state_ids[:opened]) expect(opened_issue.reload.state_id).to eq(state_ids[:opened])
expect(closed_issue.reload.state_id).to eq(state_ids[:closed]) expect(closed_issue.reload.state_id).to eq(state_ids[:closed])
expect(unknown_state_issue.reload.state_id).to eq(state_ids[:closed])
expect(opened_merge_request.reload.state_id).to eq(state_ids[:opened]) expect(opened_merge_request.reload.state_id).to eq(state_ids[:opened])
expect(closed_merge_request.reload.state_id).to eq(state_ids[:closed]) expect(closed_merge_request.reload.state_id).to eq(state_ids[:closed])
expect(merged_merge_request.reload.state_id).to eq(state_ids[:merged]) expect(merged_merge_request.reload.state_id).to eq(state_ids[:merged])
expect(locked_merge_request.reload.state_id).to eq(state_ids[:locked]) expect(locked_merge_request.reload.state_id).to eq(state_ids[:locked])
expect(unknown_state_merge_request.reload.state_id).to eq(state_ids[:closed])
end end
end end
end end
...@@ -4,7 +4,7 @@ shared_examples_for 'matches_cross_reference_regex? fails fast' do ...@@ -4,7 +4,7 @@ shared_examples_for 'matches_cross_reference_regex? fails fast' do
it 'fails fast for long strings' do it 'fails fast for long strings' do
# took well under 1 second in CI https://dev.gitlab.org/gitlab/gitlabhq/merge_requests/3267#note_172823 # took well under 1 second in CI https://dev.gitlab.org/gitlab/gitlabhq/merge_requests/3267#note_172823
expect do expect do
Timeout.timeout(3.seconds) { mentionable.matches_cross_reference_regex? } Timeout.timeout(6.seconds) { mentionable.matches_cross_reference_regex? }
end.not_to raise_error end.not_to raise_error
end 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