Commit 8c8b94e7 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent eadb77d8
...@@ -31,7 +31,16 @@ ...@@ -31,7 +31,16 @@
} }
} }
.ci-status-icon-preparing, .ci-status-icon-preparing {
svg {
fill: $gray-500;
}
&.add-border {
@include borderless-status-icon($gray-500);
}
}
.ci-status-icon-running { .ci-status-icon-running {
svg { svg {
fill: $blue-400; fill: $blue-400;
......
...@@ -123,7 +123,7 @@ ul.content-list { ...@@ -123,7 +123,7 @@ ul.content-list {
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
} }
a { a:not(.default-link-color) {
color: $gl-text-color; color: $gl-text-color;
} }
......
...@@ -37,6 +37,10 @@ ...@@ -37,6 +37,10 @@
} }
} }
&.ci-preparing {
@include status-color($gray-100, $gray-500, $gray-600);
}
&.ci-pending, &.ci-pending,
&.ci-failed-with-warnings, &.ci-failed-with-warnings,
&.ci-success-with-warnings { &.ci-success-with-warnings {
...@@ -44,7 +48,6 @@ ...@@ -44,7 +48,6 @@
} }
&.ci-info, &.ci-info,
&.ci-preparing,
&.ci-running { &.ci-running {
@include status-color($blue-100, $blue-500, $blue-600); @include status-color($blue-100, $blue-500, $blue-600);
} }
......
...@@ -6,9 +6,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -6,9 +6,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
before_action :set_application_setting before_action :set_application_setting
before_action :whitelist_query_limiting, only: [:usage_data] before_action :whitelist_query_limiting, only: [:usage_data]
VALID_SETTING_PANELS = %w(general integrations repository templates VALID_SETTING_PANELS = %w(general integrations repository
ci_cd reporting metrics_and_profiling ci_cd reporting metrics_and_profiling
network geo preferences).freeze network preferences).freeze
VALID_SETTING_PANELS.each do |action| VALID_SETTING_PANELS.each do |action|
define_method(action) { perform_update if submitted? } define_method(action) { perform_update if submitted? }
...@@ -145,10 +145,15 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -145,10 +145,15 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
end end
def render_update_error def render_update_error
action = VALID_SETTING_PANELS.include?(action_name) ? action_name : :general action = valid_setting_panels.include?(action_name) ? action_name : :general
render action render action
end end
# overridden in EE
def valid_setting_panels
VALID_SETTING_PANELS
end
end end
Admin::ApplicationSettingsController.prepend_if_ee('EE::Admin::ApplicationSettingsController') Admin::ApplicationSettingsController.prepend_if_ee('EE::Admin::ApplicationSettingsController')
...@@ -3,8 +3,20 @@ ...@@ -3,8 +3,20 @@
module CycleAnalyticsParams module CycleAnalyticsParams
extend ActiveSupport::Concern extend ActiveSupport::Concern
def cycle_analytics_project_params
return {} unless params[:cycle_analytics].present?
params[:cycle_analytics].permit(:start_date, :created_after, :created_before, :branch_name)
end
def cycle_analytics_group_params
return {} unless params[:cycle_analytics].present?
params[:cycle_analytics].permit(:start_date, :created_after, :created_before, project_ids: [])
end
def options(params) def options(params)
@options ||= { from: start_date(params), current_user: current_user } @options ||= { from: start_date(params), current_user: current_user }.merge(date_range(params))
end end
def start_date(params) def start_date(params)
...@@ -17,6 +29,17 @@ module CycleAnalyticsParams ...@@ -17,6 +29,17 @@ module CycleAnalyticsParams
90.days.ago 90.days.ago
end end
end end
def date_range(params)
{}.tap do |date_range_params|
date_range_params[:from] = to_utc_time(params[:created_after]).beginning_of_day if params[:created_after]
date_range_params[:to] = to_utc_time(params[:created_before]).end_of_day if params[:created_before]
end.compact
end
def to_utc_time(field)
Date.parse(field).to_time.utc
end
end end
CycleAnalyticsParams.prepend_if_ee('EE::CycleAnalyticsParams') CycleAnalyticsParams.prepend_if_ee('EE::CycleAnalyticsParams')
...@@ -23,7 +23,7 @@ module Projects ...@@ -23,7 +23,7 @@ module Projects
end end
def test def test
options(cycle_analytics_params)[:branch] = cycle_analytics_params[:branch_name] options(cycle_analytics_project_params)[:branch] = cycle_analytics_project_params[:branch_name]
render_events(cycle_analytics[:test].events) render_events(cycle_analytics[:test].events)
end end
...@@ -50,13 +50,7 @@ module Projects ...@@ -50,13 +50,7 @@ module Projects
end end
def cycle_analytics def cycle_analytics
@cycle_analytics ||= ::CycleAnalytics::ProjectLevel.new(project, options: options(cycle_analytics_params)) @cycle_analytics ||= ::CycleAnalytics::ProjectLevel.new(project, options: options(cycle_analytics_project_params))
end
def cycle_analytics_params
return {} unless params[:cycle_analytics].present?
params[:cycle_analytics].permit(:start_date, :branch_name)
end end
end end
end end
......
...@@ -9,7 +9,7 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController ...@@ -9,7 +9,7 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
before_action :authorize_read_cycle_analytics! before_action :authorize_read_cycle_analytics!
def show def show
@cycle_analytics = ::CycleAnalytics::ProjectLevel.new(@project, options: options(cycle_analytics_params)) @cycle_analytics = ::CycleAnalytics::ProjectLevel.new(@project, options: options(cycle_analytics_project_params))
@cycle_analytics_no_data = @cycle_analytics.no_stats? @cycle_analytics_no_data = @cycle_analytics.no_stats?
...@@ -27,12 +27,6 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController ...@@ -27,12 +27,6 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
private private
def cycle_analytics_params
return {} unless params[:cycle_analytics].present?
params[:cycle_analytics].permit(:start_date)
end
def cycle_analytics_json def cycle_analytics_json
{ {
summary: @cycle_analytics.summary, summary: @cycle_analytics.summary,
......
...@@ -77,6 +77,8 @@ module CiStatusHelper ...@@ -77,6 +77,8 @@ module CiStatusHelper
'status_failed' 'status_failed'
when 'pending' when 'pending'
'status_pending' 'status_pending'
when 'preparing'
'status_preparing'
when 'running' when 'running'
'status_running' 'status_running'
when 'play' when 'play'
......
...@@ -13,6 +13,7 @@ module CycleAnalytics ...@@ -13,6 +13,7 @@ module CycleAnalytics
def summary def summary
@summary ||= ::Gitlab::CycleAnalytics::StageSummary.new(project, @summary ||= ::Gitlab::CycleAnalytics::StageSummary.new(project,
from: options[:from], from: options[:from],
to: options[:to],
current_user: options[:current_user]).data current_user: options[:current_user]).data
end end
......
- page_title _("Container Registry")
%section %section
.row.registry-placeholder.prepend-bottom-10 .row.registry-placeholder.prepend-bottom-10
.col-12 .col-12
......
...@@ -19,9 +19,15 @@ ...@@ -19,9 +19,15 @@
- else - else
%p %p
= s_("TagsPage|Can't find HEAD commit for this tag") = s_("TagsPage|Can't find HEAD commit for this tag")
- if release && release.description.present?
.description.md.prepend-top-default - if release
= markdown_field(release, :description) .text-secondary
= icon('rocket')
= _("Release")
= link_to release.name, project_releases_path(@project, anchor: release.tag), class: 'default-link-color'
- if release.description.present?
.description.md.prepend-top-default
= markdown_field(release, :description)
.row-fixed-content.controls.flex-row .row-fixed-content.controls.flex-row
= render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name] = render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name]
......
---
title: Add missing page title to projects/container-registry
merge_request: 18114
author:
type: changed
---
title: Add pipeline preparing status icons
merge_request: 17923
author:
type: added
...@@ -491,6 +491,9 @@ Gitlab.ee do ...@@ -491,6 +491,9 @@ Gitlab.ee do
Settings.cron_jobs['historical_data_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['historical_data_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['historical_data_worker']['cron'] ||= '0 12 * * *' Settings.cron_jobs['historical_data_worker']['cron'] ||= '0 12 * * *'
Settings.cron_jobs['historical_data_worker']['job_class'] = 'HistoricalDataWorker' Settings.cron_jobs['historical_data_worker']['job_class'] = 'HistoricalDataWorker'
Settings.cron_jobs['import_software_licenses_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['import_software_licenses_worker']['cron'] ||= '0 3 * * 0'
Settings.cron_jobs['import_software_licenses_worker']['job_class'] = 'ImportSoftwareLicensesWorker'
Settings.cron_jobs['ldap_group_sync_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['ldap_group_sync_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['ldap_group_sync_worker']['cron'] ||= '0 * * * *' Settings.cron_jobs['ldap_group_sync_worker']['cron'] ||= '0 * * * *'
Settings.cron_jobs['ldap_group_sync_worker']['job_class'] = 'LdapAllGroupsSyncWorker' Settings.cron_jobs['ldap_group_sync_worker']['job_class'] = 'LdapAllGroupsSyncWorker'
......
...@@ -114,7 +114,7 @@ namespace :admin do ...@@ -114,7 +114,7 @@ namespace :admin do
put :reset_registration_token put :reset_registration_token
put :reset_health_check_token put :reset_health_check_token
put :clear_repository_check_states put :clear_repository_check_states
match :general, :integrations, :repository, :templates, :ci_cd, :reporting, :metrics_and_profiling, :network, :geo, :preferences, via: [:get, :patch] match :general, :integrations, :repository, :ci_cd, :reporting, :metrics_and_profiling, :network, :preferences, via: [:get, :patch]
get :lets_encrypt_terms_of_service get :lets_encrypt_terms_of_service
end end
......
# frozen_string_literal: true
class AddSpdxIdToSoftwareLicenses < ActiveRecord::Migration[5.2]
DOWNTIME = false
def up
add_column :software_licenses, :spdx_identifier, :string, limit: 255
end
def down
remove_column :software_licenses, :spdx_identifier
end
end
# frozen_string_literal: true
class AddIndexToSoftwareLicensesOnSpdxId < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index :software_licenses, :spdx_identifier
end
def down
remove_concurrent_index :software_licenses, :spdx_identifier
end
end
# frozen_string_literal: true
class BackfillSoftwareLicensesSpdxIdentifiers < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
CURRENT_LICENSES = {
'AGPL-1.0' => 'AGPL-1.0',
'AGPL-3.0' => 'AGPL-3.0',
'Apache 2.0' => 'Apache-2.0',
'Artistic-2.0' => 'Artistic-2.0',
'BSD' => 'BSD-4-Clause',
'CC0 1.0 Universal' => 'CC0-1.0',
'CDDL-1.0' => 'CDDL-1.0',
'CDDL-1.1' => 'CDDL-1.1',
'EPL-1.0' => 'EPL-1.0',
'EPL-2.0' => 'EPL-2.0',
'GPLv2' => 'GPL-2.0',
'GPLv3' => 'GPL-3.0',
'ISC' => 'ISC',
'LGPL' => 'LGPL-3.0-only',
'LGPL-2.1' => 'LGPL-2.1',
'MIT' => 'MIT',
'Mozilla Public License 2.0' => 'MPL-2.0',
'MS-PL' => 'MS-PL',
'MS-RL' => 'MS-RL',
'New BSD' => 'BSD-3-Clause',
'Python Software Foundation License' => 'Python-2.0',
'ruby' => 'Ruby',
'Simplified BSD' => 'BSD-2-Clause',
'WTFPL' => 'WTFPL',
'Zlib' => 'Zlib'
}.freeze
disable_ddl_transaction!
# 25 records to be updated on GitLab.com
def up
return unless Gitlab.ee?
say "Expect #{CURRENT_LICENSES.count} updates to the software_licenses table to occur"
CURRENT_LICENSES.each do |name, spdx_identifier|
# The following cop is disabled because of https://gitlab.com/gitlab-org/gitlab/issues/33470
# For more context see https://gitlab.com/gitlab-org/gitlab/merge_requests/17004#note_226264823
# rubocop:disable Migration/UpdateColumnInBatches
update_column_in_batches(:software_licenses, :spdx_identifier, spdx_identifier) do |table, query|
query.where(table[:name].eq(name))
end
end
end
def down
return unless Gitlab.ee?
update_column_in_batches(:software_licenses, :spdx_identifier, nil)
end
end
...@@ -3350,7 +3350,9 @@ ActiveRecord::Schema.define(version: 2019_09_29_180827) do ...@@ -3350,7 +3350,9 @@ ActiveRecord::Schema.define(version: 2019_09_29_180827) do
create_table "software_licenses", id: :serial, force: :cascade do |t| create_table "software_licenses", id: :serial, force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
t.string "spdx_identifier", limit: 255
t.index ["name"], name: "index_software_licenses_on_name" t.index ["name"], name: "index_software_licenses_on_name"
t.index ["spdx_identifier"], name: "index_software_licenses_on_spdx_identifier"
end end
create_table "spam_logs", id: :serial, force: :cascade do |t| create_table "spam_logs", id: :serial, force: :cascade do |t|
......
...@@ -15,7 +15,7 @@ module Gitlab ...@@ -15,7 +15,7 @@ module Gitlab
failed: '#e05d44', failed: '#e05d44',
running: '#dfb317', running: '#dfb317',
pending: '#dfb317', pending: '#dfb317',
preparing: '#dfb317', preparing: '#a7a7a7',
canceled: '#9f9f9f', canceled: '#9f9f9f',
skipped: '#9f9f9f', skipped: '#9f9f9f',
unknown: '#9f9f9f' unknown: '#9f9f9f'
......
...@@ -12,20 +12,12 @@ module Gitlab ...@@ -12,20 +12,12 @@ module Gitlab
s_('CiStatusLabel|preparing') s_('CiStatusLabel|preparing')
end end
##
# TODO: shared with 'created'
# until we get one for 'preparing'
#
def icon def icon
'status_created' 'status_preparing'
end end
##
# TODO: shared with 'created'
# until we get one for 'preparing'
#
def favicon def favicon
'favicon_status_created' 'favicon_status_preparing'
end end
end end
end end
......
...@@ -23,6 +23,7 @@ module Gitlab ...@@ -23,6 +23,7 @@ module Gitlab
.project(routes_table[:path].as("namespace_path")) .project(routes_table[:path].as("namespace_path"))
query = limit_query(query, project_ids) query = limit_query(query, project_ids)
query = limit_query_by_date_range(query)
# Load merge_requests # Load merge_requests
...@@ -34,7 +35,12 @@ module Gitlab ...@@ -34,7 +35,12 @@ module Gitlab
def limit_query(query, project_ids) def limit_query(query, project_ids)
query.where(issue_table[:project_id].in(project_ids)) query.where(issue_table[:project_id].in(project_ids))
.where(routes_table[:source_type].eq('Namespace')) .where(routes_table[:source_type].eq('Namespace'))
.where(issue_table[:created_at].gteq(options[:from])) end
def limit_query_by_date_range(query)
query = query.where(issue_table[:created_at].gteq(options[:from]))
query = query.where(issue_table[:created_at].lteq(options[:to])) if options[:to]
query
end end
def load_merge_requests(query) def load_merge_requests(query)
......
...@@ -12,14 +12,12 @@ module Gitlab ...@@ -12,14 +12,12 @@ module Gitlab
.project(routes_table[:path].as("namespace_path")) .project(routes_table[:path].as("namespace_path"))
query = limit_query(query, project_ids) query = limit_query(query, project_ids)
limit_query_by_date_range(query)
query
end end
def limit_query(query, project_ids) def limit_query(query, project_ids)
query.where(issue_table[:project_id].in(project_ids)) query.where(issue_table[:project_id].in(project_ids))
.where(routes_table[:source_type].eq('Namespace')) .where(routes_table[:source_type].eq('Namespace'))
.where(issue_table[:created_at].gteq(options[:from]))
.where(issue_metrics_table[:first_added_to_board_at].not_eq(nil).or(issue_metrics_table[:first_associated_with_milestone_at].not_eq(nil))) .where(issue_metrics_table[:first_added_to_board_at].not_eq(nil).or(issue_metrics_table[:first_associated_with_milestone_at].not_eq(nil)))
end end
end end
......
...@@ -14,12 +14,11 @@ module Gitlab ...@@ -14,12 +14,11 @@ module Gitlab
.where(routes_table[:source_type].eq('Namespace')) .where(routes_table[:source_type].eq('Namespace'))
query = limit_query(query) query = limit_query(query)
query limit_query_by_date_range(query)
end end
def limit_query(query) def limit_query(query)
query.where(issue_table[:created_at].gteq(options[:from])) query.where(issue_metrics_table[:first_added_to_board_at].not_eq(nil).or(issue_metrics_table[:first_associated_with_milestone_at].not_eq(nil)))
.where(issue_metrics_table[:first_added_to_board_at].not_eq(nil).or(issue_metrics_table[:first_associated_with_milestone_at].not_eq(nil)))
.where(issue_metrics_table[:first_mentioned_in_commit_at].not_eq(nil)) .where(issue_metrics_table[:first_mentioned_in_commit_at].not_eq(nil))
end end
end end
......
...@@ -3,16 +3,17 @@ ...@@ -3,16 +3,17 @@
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class StageSummary class StageSummary
def initialize(project, from:, current_user:) def initialize(project, from:, to: nil, current_user:)
@project = project @project = project
@from = from @from = from
@to = to
@current_user = current_user @current_user = current_user
end end
def data def data
[serialize(Summary::Issue.new(project: @project, from: @from, current_user: @current_user)), [serialize(Summary::Issue.new(project: @project, from: @from, to: @to, current_user: @current_user)),
serialize(Summary::Commit.new(project: @project, from: @from)), serialize(Summary::Commit.new(project: @project, from: @from, to: @to)),
serialize(Summary::Deploy.new(project: @project, from: @from))] serialize(Summary::Deploy.new(project: @project, from: @from, to: @to))]
end end
private private
......
...@@ -4,9 +4,10 @@ module Gitlab ...@@ -4,9 +4,10 @@ module Gitlab
module CycleAnalytics module CycleAnalytics
module Summary module Summary
class Base class Base
def initialize(project:, from:) def initialize(project:, from:, to: nil)
@project = project @project = project
@from = from @from = from
@to = to
end end
def title def title
......
...@@ -21,7 +21,7 @@ module Gitlab ...@@ -21,7 +21,7 @@ module Gitlab
def count_commits def count_commits
return unless ref return unless ref
gitaly_commit_client.commit_count(ref, after: @from) gitaly_commit_client.commit_count(ref, after: @from, before: @to)
end end
def gitaly_commit_client def gitaly_commit_client
......
...@@ -4,12 +4,18 @@ module Gitlab ...@@ -4,12 +4,18 @@ module Gitlab
module CycleAnalytics module CycleAnalytics
module Summary module Summary
class Deploy < Base class Deploy < Base
include Gitlab::Utils::StrongMemoize
def title def title
n_('Deploy', 'Deploys', value) n_('Deploy', 'Deploys', value)
end end
def value def value
@value ||= @project.deployments.where("created_at > ?", @from).count strong_memoize(:value) do
query = @project.deployments.where("created_at >= ?", @from)
query = query.where("created_at <= ?", @to) if @to
query.count
end
end end
end end
end end
......
...@@ -4,9 +4,10 @@ module Gitlab ...@@ -4,9 +4,10 @@ module Gitlab
module CycleAnalytics module CycleAnalytics
module Summary module Summary
class Issue < Base class Issue < Base
def initialize(project:, from:, current_user:) def initialize(project:, from:, to: nil, current_user:)
@project = project @project = project
@from = from @from = from
@to = to
@current_user = current_user @current_user = current_user
end end
...@@ -15,7 +16,7 @@ module Gitlab ...@@ -15,7 +16,7 @@ module Gitlab
end end
def value def value
@value ||= IssuesFinder.new(@current_user, project_id: @project.id).execute.created_after(@from).count @value ||= IssuesFinder.new(@current_user, project_id: @project.id, created_after: @from, created_before: @to).execute.count
end end
end end
end end
......
...@@ -53,7 +53,7 @@ module Gitlab ...@@ -53,7 +53,7 @@ module Gitlab
@legacy_disk_path = File.expand_path(storage['path'], Rails.root) if storage['path'] @legacy_disk_path = File.expand_path(storage['path'], Rails.root) if storage['path']
storage['path'] = Deprecated storage['path'] = Deprecated
@hash = storage @hash = storage.with_indifferent_access
end end
def gitaly_address def gitaly_address
......
...@@ -13117,6 +13117,9 @@ msgstr "" ...@@ -13117,6 +13117,9 @@ msgstr ""
msgid "Related merge requests" msgid "Related merge requests"
msgstr "" msgstr ""
msgid "Release"
msgstr ""
msgid "Releases" msgid "Releases"
msgstr "" msgstr ""
......
...@@ -118,7 +118,7 @@ describe Admin::ApplicationSettingsController do ...@@ -118,7 +118,7 @@ describe Admin::ApplicationSettingsController do
end end
describe 'verify panel actions' do describe 'verify panel actions' do
(Admin::ApplicationSettingsController::VALID_SETTING_PANELS - %w(templates geo)).each do |valid_action| Admin::ApplicationSettingsController::VALID_SETTING_PANELS.each do |valid_action|
it_behaves_like 'renders correct panels' do it_behaves_like 'renders correct panels' do
let(:action) { valid_action } let(:action) { valid_action }
end end
......
...@@ -17,6 +17,11 @@ describe 'Container Registry', :js do ...@@ -17,6 +17,11 @@ describe 'Container Registry', :js do
stub_container_registry_tags(repository: :any, tags: []) stub_container_registry_tags(repository: :any, tags: [])
end end
it 'has a page title set' do
visit_container_registry
expect(page).to have_title(_('Container Registry'))
end
context 'when there are no image repositories' do context 'when there are no image repositories' do
it 'user visits container registry main page' do it 'user visits container registry main page' do
visit_container_registry visit_container_registry
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -67,7 +67,7 @@ describe Gitlab::Badge::Pipeline::Template do ...@@ -67,7 +67,7 @@ describe Gitlab::Badge::Pipeline::Template do
end end
it 'has expected color' do it 'has expected color' do
expect(template.value_color).to eq '#dfb317' expect(template.value_color).to eq '#a7a7a7'
end end
end end
......
...@@ -16,11 +16,11 @@ describe Gitlab::Ci::Status::Preparing do ...@@ -16,11 +16,11 @@ describe Gitlab::Ci::Status::Preparing do
end end
describe '#icon' do describe '#icon' do
it { expect(subject.icon).to eq 'status_created' } it { expect(subject.icon).to eq 'status_preparing' }
end end
describe '#favicon' do describe '#favicon' do
it { expect(subject.favicon).to eq 'favicon_status_created' } it { expect(subject.favicon).to eq 'favicon_status_preparing' }
end end
describe '#group' do describe '#group' do
......
...@@ -12,7 +12,8 @@ describe Gitlab::CycleAnalytics::CodeStage do ...@@ -12,7 +12,8 @@ describe Gitlab::CycleAnalytics::CodeStage do
let(:issue_3) { create(:issue, project: project, created_at: 60.minutes.ago) } let(:issue_3) { create(:issue, project: project, created_at: 60.minutes.ago) }
let(:mr_1) { create(:merge_request, source_project: project, created_at: 15.minutes.ago) } let(:mr_1) { create(:merge_request, source_project: project, created_at: 15.minutes.ago) }
let(:mr_2) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'A') } let(:mr_2) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'A') }
let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } let(:stage_options) { { from: 2.days.ago, current_user: project.creator, project: project } }
let(:stage) { described_class.new(options: stage_options) }
before do before do
issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 45.minutes.ago) issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 45.minutes.ago)
...@@ -33,6 +34,8 @@ describe Gitlab::CycleAnalytics::CodeStage do ...@@ -33,6 +34,8 @@ describe Gitlab::CycleAnalytics::CodeStage do
it 'counts median from issues with metrics' do it 'counts median from issues with metrics' do
expect(stage.project_median).to eq(ISSUES_MEDIAN) expect(stage.project_median).to eq(ISSUES_MEDIAN)
end end
include_examples 'calculate #median with date range'
end end
describe '#events' do describe '#events' do
......
...@@ -10,7 +10,8 @@ describe Gitlab::CycleAnalytics::IssueStage do ...@@ -10,7 +10,8 @@ describe Gitlab::CycleAnalytics::IssueStage do
let(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } let(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) }
let(:issue_3) { create(:issue, project: project, created_at: 30.minutes.ago) } let(:issue_3) { create(:issue, project: project, created_at: 30.minutes.ago) }
let!(:issue_without_milestone) { create(:issue, project: project, created_at: 1.minute.ago) } let!(:issue_without_milestone) { create(:issue, project: project, created_at: 1.minute.ago) }
let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } let(:stage_options) { { from: 2.days.ago, current_user: project.creator, project: project } }
let(:stage) { described_class.new(options: stage_options) }
before do before do
issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago ) issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago )
...@@ -28,6 +29,8 @@ describe Gitlab::CycleAnalytics::IssueStage do ...@@ -28,6 +29,8 @@ describe Gitlab::CycleAnalytics::IssueStage do
it 'counts median from issues with metrics' do it 'counts median from issues with metrics' do
expect(stage.project_median).to eq(ISSUES_MEDIAN) expect(stage.project_median).to eq(ISSUES_MEDIAN)
end end
include_examples 'calculate #median with date range'
end end
describe '#events' do describe '#events' do
......
...@@ -10,7 +10,8 @@ describe Gitlab::CycleAnalytics::PlanStage do ...@@ -10,7 +10,8 @@ describe Gitlab::CycleAnalytics::PlanStage do
let!(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } let!(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) }
let!(:issue_3) { create(:issue, project: project, created_at: 30.minutes.ago) } let!(:issue_3) { create(:issue, project: project, created_at: 30.minutes.ago) }
let!(:issue_without_milestone) { create(:issue, project: project, created_at: 1.minute.ago) } let!(:issue_without_milestone) { create(:issue, project: project, created_at: 1.minute.ago) }
let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } let(:stage_options) { { from: 2.days.ago, current_user: project.creator, project: project } }
let(:stage) { described_class.new(options: stage_options) }
before do before do
issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 10.minutes.ago) issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 10.minutes.ago)
...@@ -28,6 +29,8 @@ describe Gitlab::CycleAnalytics::PlanStage do ...@@ -28,6 +29,8 @@ describe Gitlab::CycleAnalytics::PlanStage do
it 'counts median from issues with metrics' do it 'counts median from issues with metrics' do
expect(stage.project_median).to eq(ISSUES_MEDIAN) expect(stage.project_median).to eq(ISSUES_MEDIAN)
end end
include_examples 'calculate #median with date range'
end end
describe '#events' do describe '#events' do
......
...@@ -32,3 +32,23 @@ shared_examples 'base stage' do ...@@ -32,3 +32,23 @@ shared_examples 'base stage' do
expect(stage.events).not_to be_nil expect(stage.events).not_to be_nil
end end
end end
shared_examples 'calculate #median with date range' do
context 'when valid date range is given' do
before do
stage_options[:from] = 5.days.ago
stage_options[:to] = 5.days.from_now
end
it { expect(stage.project_median).to eq(ISSUES_MEDIAN) }
end
context 'when records are out of the date range' do
before do
stage_options[:from] = 2.years.ago
stage_options[:to] = 1.year.ago
end
it { expect(stage.project_median).to eq(nil) }
end
end
...@@ -4,52 +4,98 @@ require 'spec_helper' ...@@ -4,52 +4,98 @@ require 'spec_helper'
describe Gitlab::CycleAnalytics::StageSummary do describe Gitlab::CycleAnalytics::StageSummary do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:from) { 1.day.ago } let(:options) { { from: 1.day.ago, current_user: user } }
let(:user) { create(:user, :admin) } let(:user) { create(:user, :admin) }
subject { described_class.new(project, from: Time.now, current_user: user).data } let(:stage_summary) { described_class.new(project, options).data }
describe "#new_issues" do describe "#new_issues" do
subject { stage_summary.first[:value] }
it "finds the number of issues created after the 'from date'" do it "finds the number of issues created after the 'from date'" do
Timecop.freeze(5.days.ago) { create(:issue, project: project) } Timecop.freeze(5.days.ago) { create(:issue, project: project) }
Timecop.freeze(5.days.from_now) { create(:issue, project: project) } Timecop.freeze(5.days.from_now) { create(:issue, project: project) }
expect(subject.first[:value]).to eq(1) expect(subject).to eq(1)
end end
it "doesn't find issues from other projects" do it "doesn't find issues from other projects" do
Timecop.freeze(5.days.from_now) { create(:issue, project: create(:project)) } Timecop.freeze(5.days.from_now) { create(:issue, project: create(:project)) }
expect(subject.first[:value]).to eq(0) expect(subject).to eq(0)
end
context 'when `to` parameter is given' do
before do
Timecop.freeze(5.days.ago) { create(:issue, project: project) }
Timecop.freeze(5.days.from_now) { create(:issue, project: project) }
end
it "doesn't find any record" do
options[:to] = Time.now
expect(subject).to eq(0)
end
it "finds records created between `from` and `to` range" do
options[:from] = 10.days.ago
options[:to] = 10.days.from_now
expect(subject).to eq(2)
end
end end
end end
describe "#commits" do describe "#commits" do
subject { stage_summary.second[:value] }
it "finds the number of commits created after the 'from date'" do it "finds the number of commits created after the 'from date'" do
Timecop.freeze(5.days.ago) { create_commit("Test message", project, user, 'master') } Timecop.freeze(5.days.ago) { create_commit("Test message", project, user, 'master') }
Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master') } Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master') }
expect(subject.second[:value]).to eq(1) expect(subject).to eq(1)
end end
it "doesn't find commits from other projects" do it "doesn't find commits from other projects" do
Timecop.freeze(5.days.from_now) { create_commit("Test message", create(:project, :repository), user, 'master') } Timecop.freeze(5.days.from_now) { create_commit("Test message", create(:project, :repository), user, 'master') }
expect(subject.second[:value]).to eq(0) expect(subject).to eq(0)
end end
it "finds a large (> 100) snumber of commits if present" do it "finds a large (> 100) snumber of commits if present" do
Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master', count: 100) } Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master', count: 100) }
expect(subject.second[:value]).to eq(100) expect(subject).to eq(100)
end
context 'when `to` parameter is given' do
before do
Timecop.freeze(5.days.ago) { create_commit("Test message", project, user, 'master') }
Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master') }
end
it "doesn't find any record" do
options[:to] = Time.now
expect(subject).to eq(0)
end
it "finds records created between `from` and `to` range" do
options[:from] = 10.days.ago
options[:to] = 10.days.from_now
expect(subject).to eq(2)
end
end end
end end
describe "#deploys" do describe "#deploys" do
subject { stage_summary.third[:value] }
it "finds the number of deploys made created after the 'from date'" do it "finds the number of deploys made created after the 'from date'" do
Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) } Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) }
Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) } Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
expect(subject.third[:value]).to eq(1) expect(subject).to eq(1)
end end
it "doesn't find commits from other projects" do it "doesn't find commits from other projects" do
...@@ -57,7 +103,27 @@ describe Gitlab::CycleAnalytics::StageSummary do ...@@ -57,7 +103,27 @@ describe Gitlab::CycleAnalytics::StageSummary do
create(:deployment, :success, project: create(:project, :repository)) create(:deployment, :success, project: create(:project, :repository))
end end
expect(subject.third[:value]).to eq(0) expect(subject).to eq(0)
end
context 'when `to` parameter is given' do
before do
Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) }
Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
end
it "doesn't find any record" do
options[:to] = Time.now
expect(subject).to eq(0)
end
it "finds records created between `from` and `to` range" do
options[:from] = 10.days.ago
options[:to] = 10.days.from_now
expect(subject).to eq(2)
end
end end
end end
end end
...@@ -16,7 +16,8 @@ describe Gitlab::CycleAnalytics::StagingStage do ...@@ -16,7 +16,8 @@ describe Gitlab::CycleAnalytics::StagingStage do
let(:build_1) { create(:ci_build, project: project) } let(:build_1) { create(:ci_build, project: project) }
let(:build_2) { create(:ci_build, project: project) } let(:build_2) { create(:ci_build, project: project) }
let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } let(:stage_options) { { from: 2.days.ago, current_user: project.creator, project: project } }
let(:stage) { described_class.new(options: stage_options) }
before do before do
mr_1.metrics.update!(merged_at: 80.minutes.ago, first_deployed_to_production_at: 50.minutes.ago, pipeline_id: build_1.commit_id) mr_1.metrics.update!(merged_at: 80.minutes.ago, first_deployed_to_production_at: 50.minutes.ago, pipeline_id: build_1.commit_id)
...@@ -38,6 +39,8 @@ describe Gitlab::CycleAnalytics::StagingStage do ...@@ -38,6 +39,8 @@ describe Gitlab::CycleAnalytics::StagingStage do
it 'counts median from issues with metrics' do it 'counts median from issues with metrics' do
expect(stage.project_median).to eq(ISSUES_MEDIAN) expect(stage.project_median).to eq(ISSUES_MEDIAN)
end end
it_behaves_like 'calculate #median with date range'
end end
describe '#events' do describe '#events' do
......
...@@ -6,7 +6,8 @@ require 'lib/gitlab/cycle_analytics/shared_stage_spec' ...@@ -6,7 +6,8 @@ require 'lib/gitlab/cycle_analytics/shared_stage_spec'
describe Gitlab::CycleAnalytics::TestStage do describe Gitlab::CycleAnalytics::TestStage do
let(:stage_name) { :test } let(:stage_name) { :test }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } let(:stage_options) { { from: 2.days.ago, current_user: project.creator, project: project } }
let(:stage) { described_class.new(options: stage_options) }
it_behaves_like 'base stage' it_behaves_like 'base stage'
...@@ -40,5 +41,7 @@ describe Gitlab::CycleAnalytics::TestStage do ...@@ -40,5 +41,7 @@ describe Gitlab::CycleAnalytics::TestStage do
it 'counts median from issues with metrics' do it 'counts median from issues with metrics' do
expect(stage.project_median).to eq(ISSUES_MEDIAN) expect(stage.project_median).to eq(ISSUES_MEDIAN)
end end
include_examples 'calculate #median with date range'
end end
end end
...@@ -57,6 +57,7 @@ RSpec.describe Gitlab::Favicon, :request_store do ...@@ -57,6 +57,7 @@ RSpec.describe Gitlab::Favicon, :request_store do
favicon_status_manual favicon_status_manual
favicon_status_not_found favicon_status_not_found
favicon_status_pending favicon_status_pending
favicon_status_preparing
favicon_status_running favicon_status_running
favicon_status_scheduled favicon_status_scheduled
favicon_status_skipped favicon_status_skipped
......
...@@ -27,6 +27,38 @@ describe Gitlab::GitalyClient::StorageSettings do ...@@ -27,6 +27,38 @@ describe Gitlab::GitalyClient::StorageSettings do
end end
end end
describe '.gitaly_address' do
context 'when the storage settings have no gitaly address but one is requested' do
it 'raises an error' do
expect do
described_class.new("path" => Rails.root).gitaly_address
end.to raise_error("key not found: \"gitaly_address\"")
end
end
context 'when the storage settings have a gitaly address and one is requested' do
it 'returns the setting value' do
expect(described_class.new("path" => Rails.root, "gitaly_address" => "test").gitaly_address).to eq("test")
end
end
context 'when the storage settings have a gitaly address keyed symbolically' do
it 'raises no error' do
expect do
described_class.new("path" => Rails.root, :gitaly_address => "test").gitaly_address
end.not_to raise_error
end
end
context 'when the storage settings have a gitaly address keyed with a string' do
it 'raises no error' do
expect do
described_class.new("path" => Rails.root, "gitaly_address" => "test").gitaly_address
end.not_to raise_error
end
end
end
describe '.disk_access_denied?' do describe '.disk_access_denied?' do
context 'when Rugged is enabled', :enable_rugged do context 'when Rugged is enabled', :enable_rugged do
it 'returns false' do it 'returns false' do
......
...@@ -23,6 +23,11 @@ describe 'projects/tags/index' do ...@@ -23,6 +23,11 @@ describe 'projects/tags/index' do
expect(rendered).to have_button('Last updated') expect(rendered).to have_button('Last updated')
end end
it 'renders links to the Releases page for tags associated with a release' do
render
expect(rendered).to have_link(release.name, href: project_releases_path(project, anchor: release.tag))
end
context 'when the most recent build for a tag has artifacts' do context 'when the most recent build for a tag has artifacts' do
let!(:build) { create(:ci_build, :success, :artifacts, pipeline: pipeline) } let!(:build) { create(:ci_build, :success, :artifacts, pipeline: pipeline) }
......
...@@ -990,10 +990,10 @@ ...@@ -990,10 +990,10 @@
dependencies: dependencies:
vue-eslint-parser "^6.0.4" vue-eslint-parser "^6.0.4"
"@gitlab/svgs@^1.75.0": "@gitlab/svgs@^1.76.0":
version "1.75.0" version "1.76.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.75.0.tgz#93f9e6bdef78dd84ac88d8273711dc1f25e4e5ac" resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.76.0.tgz#2def3b5542d23259e81c889c75059a5d1f1e3f61"
integrity sha512-hOCfF73++yG+KTYxaQNMkbDUg0XKije41g6XR2dgj7466rzZmebG/nt6pUXonmlqy/NLGaRUPBKs0zuM7tcLhA== integrity sha512-wTCNSq3CxNrEzrJdEbf8GwHfhzEsUMJNEuGTBGGhe1qc0sY5z/U3s3HG7tdAOrB5pec9JarRXzc7g5ax9bsopQ==
"@gitlab/ui@5.27.0": "@gitlab/ui@5.27.0":
version "5.27.0" version "5.27.0"
......
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