diff --git a/.rubocop_todo/style/lambda.yml b/.rubocop_todo/style/lambda.yml index f37c2c4967e..9da29f7bb59 100644 --- a/.rubocop_todo/style/lambda.yml +++ b/.rubocop_todo/style/lambda.yml @@ -49,7 +49,6 @@ Style/Lambda: - 'lib/gitlab/action_cable/request_store_callbacks.rb' - 'lib/gitlab/checks/diff_check.rb' - 'lib/gitlab/database/load_balancing/action_cable_callbacks.rb' - - 'lib/gitlab/memory/watchdog/configurator.rb' - 'lib/gitlab/middleware/rack_multipart_tempfile_factory.rb' - 'lib/gitlab/omniauth_initializer.rb' - 'lib/gitlab/prometheus/queries/query_additional_metrics.rb' diff --git a/app/assets/javascripts/flash.js b/app/assets/javascripts/flash.js index dc6c4642e94..9e804b60d59 100644 --- a/app/assets/javascripts/flash.js +++ b/app/assets/javascripts/flash.js @@ -114,6 +114,7 @@ const addDismissFlashClickListener = (flashEl, fadeTransition) => { * @param {object} [options.parent] - Reference to parent element under which alert needs to appear. Defaults to `document`. * @param {Function} [options.onDismiss] - Handler to call when this alert is dismissed. * @param {string} [options.containerSelector] - Selector for the container of the alert + * @param {boolean} [options.preservePrevious] - Set to `true` to preserve previous alerts. Defaults to `false`. * @param {object} [options.primaryButton] - Object describing primary button of alert * @param {string} [options.primaryButton.link] - Href of primary button * @param {string} [options.primaryButton.text] - Text of primary button @@ -131,6 +132,7 @@ const createAlert = function createAlert({ variant = VARIANT_DANGER, parent = document, containerSelector = '.flash-container', + preservePrevious = false, primaryButton = null, secondaryButton = null, onDismiss = null, @@ -143,7 +145,11 @@ const createAlert = function createAlert({ if (!alertContainer) return null; const el = document.createElement('div'); - alertContainer.appendChild(el); + if (preservePrevious) { + alertContainer.appendChild(el); + } else { + alertContainer.replaceChildren(el); + } return new Vue({ el, diff --git a/app/assets/javascripts/projects/default_project_templates.js b/app/assets/javascripts/projects/default_project_templates.js index 3671b24b502..497d8acc4a9 100644 --- a/app/assets/javascripts/projects/default_project_templates.js +++ b/app/assets/javascripts/projects/default_project_templates.js @@ -113,4 +113,8 @@ export default { text: s__('ProjectTemplates|Jsonnet for Dynamic Child Pipelines'), icon: '.template-option .icon-gitlab_logo', }, + bridgetown: { + text: s__('ProjectTemplates|Pages/Bridgetown'), + icon: '.template-option .icon-gitlab_logo', + }, }; diff --git a/config/feature_flags/development/schema_linting.yml b/config/feature_flags/development/schema_linting.yml index 6c1cbdb5248..0abca3e03dc 100644 --- a/config/feature_flags/development/schema_linting.yml +++ b/config/feature_flags/development/schema_linting.yml @@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/255919 milestone: '13.2' type: development group: group::editor -default_enabled: false +default_enabled: true diff --git a/db/docs/ci_job_token_project_scope_links.yml b/db/docs/ci_job_token_project_scope_links.yml index 9102ef0db93..de6d69d1c64 100644 --- a/db/docs/ci_job_token_project_scope_links.yml +++ b/db/docs/ci_job_token_project_scope_links.yml @@ -4,7 +4,10 @@ classes: - Ci::JobToken::ProjectScopeLink feature_categories: - continuous_integration -description: The connection between a source project, which defines the job token scope, and a target project, which is the one allowed to be accessed by the job token. +description: | + Links a source project and target project, allowing a project's job token to give access to another project. + Using the outbound direction, the source project's job token can access target projects. + Using the inbound direction, the source project can be accessed by the target project's job token. introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62733 milestone: '14.0' gitlab_schema: gitlab_ci diff --git a/db/migrate/20221110183103_add_dashboard_fields_to_namespace_details.rb b/db/migrate/20221110183103_add_dashboard_fields_to_namespace_details.rb new file mode 100644 index 00000000000..73e8ccbcb51 --- /dev/null +++ b/db/migrate/20221110183103_add_dashboard_fields_to_namespace_details.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class AddDashboardFieldsToNamespaceDetails < Gitlab::Database::Migration[2.0] + enable_lock_retries! + + def change + add_column :namespace_details, :dashboard_notification_at, :datetime_with_timezone + add_column :namespace_details, :dashboard_enforcement_at, :datetime_with_timezone + end +end diff --git a/db/schema_migrations/20221110183103 b/db/schema_migrations/20221110183103 new file mode 100644 index 00000000000..08b3a8823df --- /dev/null +++ b/db/schema_migrations/20221110183103 @@ -0,0 +1 @@ +3a8b69f61d48ed02d1015cf63b1dd89fb7206a3d5ce9668126cfdc52048f1e61 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 3331998bdbf..c7c8d98589a 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -18034,7 +18034,9 @@ CREATE TABLE namespace_details ( description text, description_html text, free_user_cap_over_limt_notified_at timestamp with time zone, - free_user_cap_over_limit_notified_at timestamp with time zone + free_user_cap_over_limit_notified_at timestamp with time zone, + dashboard_notification_at timestamp with time zone, + dashboard_enforcement_at timestamp with time zone ); CREATE TABLE namespace_limits ( diff --git a/doc/operations/incident_management/incidents.md b/doc/operations/incident_management/incidents.md index a5d38b1a27c..5c7c76896d3 100644 --- a/doc/operations/incident_management/incidents.md +++ b/doc/operations/incident_management/incidents.md @@ -66,8 +66,9 @@ You can set up a webhook with PagerDuty to automatically create a GitLab inciden for each PagerDuty incident. This configuration requires you to make changes in both PagerDuty and GitLab: -1. Sign in as a user with the Maintainer role. -1. Navigate to **Settings > Monitor > Incidents** and expand **Incidents**. +1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, select **Settings > Monitor** +1. Expand **Incidents**. 1. Select the **PagerDuty integration** tab: ![PagerDuty incidents integration](img/pagerduty_incidents_integration_v13_3.png) diff --git a/doc/user/product_analytics/index.md b/doc/user/product_analytics/index.md index 8e340fff32a..ebeb1f171a8 100644 --- a/doc/user/product_analytics/index.md +++ b/doc/user/product_analytics/index.md @@ -4,9 +4,9 @@ group: Product Analytics info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- -# Product analytics **(ULTIMATE)** **Alpha** +# Product analytics **(ULTIMATE)** -> Introduced in GitLab 15.4 [with a flag](../../administration/feature_flags.md) named `cube_api_proxy`. Disabled by default. +> Introduced in GitLab 15.4 as an [Alpha](../../policy/alpha-beta-support.md#alpha-features) feature [with a flag](../../administration/feature_flags.md) named `cube_api_proxy`. Disabled by default. FLAG: On self-managed GitLab, by default this feature is not available. To make it available per project or for your entire instance, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `cube_api_proxy`. @@ -17,6 +17,33 @@ This feature is not ready for production use. You can view the [product category](https://about.gitlab.com/direction/analytics/product-analytics/) page for more information about our direction. This page is a work in progress and will be updated as we add more features. +## Enable product analytics + +You can enable and configure product analytics to track events +within your project applications on a self-managed instance. + +Prerequisite: + +- You must be an administrator of a self-managed GitLab instance. + +1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, select **Settings > General**. +1. Expand the **Product analytics** section. +1. Select **Enable product analytics** and enter the configuration values. + The following table shows the required configuration parameters and example values: + + | Name | Value | + |------------------------------|----------------------------| + | Jitsu host | `https://jitsu.gitlab.com` | + | Jitsu project ID | `g0maofw84gx5sjxgse2k` | + | Jitsu administrator email | `jitsu.admin@gitlab.com` | + | Jitsu administrator password | `` | + | Clickhouse URL | `https://:@clickhouse.gitlab.com:8123` | + | Cube API URL | `https://cube.gitlab.com` | + | Cube API key | `25718201b3e9...ae6bbdc62dbb` | + +1. Select **Save changes**. + ## Product analytics dashboards Each project can define an unlimited number of dashboards. These dashboards are defined using our YAML schema and stored diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md index f9e61ad78ad..64f9b53f891 100644 --- a/doc/user/shortcuts.md +++ b/doc/user/shortcuts.md @@ -37,6 +37,7 @@ These shortcuts are available in most areas of GitLab: | f | Put cursor in the filter bar. | | Shift + i | Go to your Issues page. | | Shift + m | Go to your [Merge requests](project/merge_requests/index.md) page. | +| Shift + r | Go to your Review requests page. | | Shift + t | Go to your To-Do List page. | | p, then b | Show or hide the Performance Bar. | | Escape | Hide tooltips or popovers. | diff --git a/lib/gitlab/ci/config/external/mapper.rb b/lib/gitlab/ci/config/external/mapper.rb index fc03ac125fd..5e93aef9617 100644 --- a/lib/gitlab/ci/config/external/mapper.rb +++ b/lib/gitlab/ci/config/external/mapper.rb @@ -52,14 +52,8 @@ module Gitlab .each(&method(:verify!)) end - def normalize_location(location) - logger.instrument(:config_mapper_normalize) do - normalize_location_without_instrumentation(location) - end - end - # convert location if String to canonical form - def normalize_location_without_instrumentation(location) + def normalize_location(location) if location.is_a?(String) expanded_location = expand_variables(location) normalize_location_string(expanded_location) diff --git a/lib/gitlab/ci/config/external/processor.rb b/lib/gitlab/ci/config/external/processor.rb index 6a4aee26d80..e15b51fbff4 100644 --- a/lib/gitlab/ci/config/external/processor.rb +++ b/lib/gitlab/ci/config/external/processor.rb @@ -32,9 +32,7 @@ module Gitlab def validate_external_files! @external_files.each do |file| - logger.instrument(:config_external_verify) do - raise IncludeError, file.error_message unless file.valid? - end + raise IncludeError, file.error_message unless file.valid? end end diff --git a/lib/gitlab/ci/pipeline/chain/seed.rb b/lib/gitlab/ci/pipeline/chain/seed.rb index 3f5df5ce71c..ae98c55e425 100644 --- a/lib/gitlab/ci/pipeline/chain/seed.rb +++ b/lib/gitlab/ci/pipeline/chain/seed.rb @@ -62,12 +62,10 @@ module Gitlab def root_variables strong_memoize(:root_variables) do - logger.instrument(:pipeline_seed_merge_variables, once: true) do - ::Gitlab::Ci::Variables::Helpers.merge_variables( - @command.yaml_processor_result.root_variables, - @command.workflow_rules_result.variables - ) - end + ::Gitlab::Ci::Variables::Helpers.merge_variables( + @command.yaml_processor_result.root_variables, + @command.workflow_rules_result.variables + ) end end end diff --git a/lib/gitlab/memory/watchdog/configuration.rb b/lib/gitlab/memory/watchdog/configuration.rb index 4bad9475531..885772d6119 100644 --- a/lib/gitlab/memory/watchdog/configuration.rb +++ b/lib/gitlab/memory/watchdog/configuration.rb @@ -10,7 +10,6 @@ module Gitlab end def push(monitor_class, *args, **kwargs, &block) - remove(monitor_class) @monitors.push(build_monitor_state(monitor_class, *args, **kwargs, &block)) end @@ -22,14 +21,11 @@ module Gitlab private - def remove(monitor_class) - @monitors.delete_if { |monitor| monitor.monitor_class == monitor_class } - end - - def build_monitor_state(monitor_class, *args, max_strikes:, **kwargs, &block) + def build_monitor_state(monitor_class, *args, max_strikes:, monitor_name: nil, **kwargs, &block) monitor = build_monitor(monitor_class, *args, **kwargs, &block) + monitor_name ||= monitor_class.name.demodulize.underscore - Gitlab::Memory::Watchdog::MonitorState.new(monitor, max_strikes: max_strikes) + Gitlab::Memory::Watchdog::MonitorState.new(monitor, max_strikes: max_strikes, monitor_name: monitor_name) end def build_monitor(monitor_class, *args, **kwargs, &block) diff --git a/lib/gitlab/memory/watchdog/configurator.rb b/lib/gitlab/memory/watchdog/configurator.rb index b6917873e5a..610d8ca9e97 100644 --- a/lib/gitlab/memory/watchdog/configurator.rb +++ b/lib/gitlab/memory/watchdog/configurator.rb @@ -4,25 +4,33 @@ module Gitlab module Memory class Watchdog class Configurator + DEFAULT_PUMA_WORKER_RSS_LIMIT_MB = 1200 + DEFAULT_SLEEP_INTERVAL_S = 60 + DEFAULT_SIDEKIQ_SLEEP_INTERVAL_S = 3 + MIN_SIDEKIQ_SLEEP_INTERVAL_S = 2 + DEFAULT_MAX_STRIKES = 5 + DEFAULT_MAX_HEAP_FRAG = 0.5 + DEFAULT_MAX_MEM_GROWTH = 3.0 + # grace_time / sleep_interval = max_strikes allowed for Sidekiq process to violate defined limits. + DEFAULT_SIDEKIQ_GRACE_TIME_S = 300 + class << self def configure_for_puma - lambda do |config| + ->(config) do config.logger = Gitlab::AppLogger config.handler = Gitlab::Memory::Watchdog::PumaHandler.new config.write_heap_dumps = write_heap_dumps? - config.sleep_time_seconds = ENV.fetch('GITLAB_MEMWD_SLEEP_TIME_SEC', 60).to_i + config.sleep_time_seconds = ENV.fetch('GITLAB_MEMWD_SLEEP_TIME_SEC', DEFAULT_SLEEP_INTERVAL_S).to_i config.monitors(&configure_monitors_for_puma) end end def configure_for_sidekiq - lambda do |config| + ->(config) do config.logger = Sidekiq.logger config.handler = Gitlab::Memory::Watchdog::TermProcessHandler.new config.write_heap_dumps = write_heap_dumps? - config.sleep_time_seconds = [ - ENV.fetch('SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL', 3).to_i, 2 - ].max + config.sleep_time_seconds = sidekiq_sleep_time config.monitors(&configure_monitors_for_sidekiq) end end @@ -34,12 +42,12 @@ module Gitlab end def configure_monitors_for_puma - lambda do |stack| - max_strikes = ENV.fetch('GITLAB_MEMWD_MAX_STRIKES', 5).to_i + ->(stack) do + max_strikes = ENV.fetch('GITLAB_MEMWD_MAX_STRIKES', DEFAULT_MAX_STRIKES).to_i if Gitlab::Utils.to_boolean(ENV['DISABLE_PUMA_WORKER_KILLER']) - max_heap_frag = ENV.fetch('GITLAB_MEMWD_MAX_HEAP_FRAG', 0.5).to_f - max_mem_growth = ENV.fetch('GITLAB_MEMWD_MAX_MEM_GROWTH', 3.0).to_f + max_heap_frag = ENV.fetch('GITLAB_MEMWD_MAX_HEAP_FRAG', DEFAULT_MAX_HEAP_FRAG).to_f + max_mem_growth = ENV.fetch('GITLAB_MEMWD_MAX_MEM_GROWTH', DEFAULT_MAX_MEM_GROWTH).to_f # stack.push MonitorClass, args*, max_strikes:, kwargs**, &block stack.push Gitlab::Memory::Watchdog::Monitor::HeapFragmentation, @@ -50,17 +58,44 @@ module Gitlab max_mem_growth: max_mem_growth, max_strikes: max_strikes else - memory_limit = ENV.fetch('PUMA_WORKER_MAX_MEMORY', 1200).to_i + memory_limit = ENV.fetch('PUMA_WORKER_MAX_MEMORY', DEFAULT_PUMA_WORKER_RSS_LIMIT_MB).to_i stack.push Gitlab::Memory::Watchdog::Monitor::RssMemoryLimit, - memory_limit: memory_limit.megabytes, + memory_limit_bytes: memory_limit.megabytes, max_strikes: max_strikes end end end + def sidekiq_sleep_time + [ + ENV.fetch('SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL', DEFAULT_SIDEKIQ_SLEEP_INTERVAL_S).to_i, + MIN_SIDEKIQ_SLEEP_INTERVAL_S + ].max + end + def configure_monitors_for_sidekiq - # NOP - At the moment we don't run watchdog for Sidekiq + ->(stack) do + if ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS'].to_i.nonzero? + soft_limit_bytes = ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS'].to_i.kilobytes + grace_time = ENV.fetch('SIDEKIQ_MEMORY_KILLER_GRACE_TIME', DEFAULT_SIDEKIQ_GRACE_TIME_S).to_i + max_strikes = grace_time / sidekiq_sleep_time + + stack.push Gitlab::Memory::Watchdog::Monitor::RssMemoryLimit, + memory_limit_bytes: soft_limit_bytes, + max_strikes: max_strikes.to_i, + monitor_name: :rss_memory_soft_limit + end + + if ENV['SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS'].to_i.nonzero? + hard_limit_bytes = ENV['SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS'].to_i.kilobytes + + stack.push Gitlab::Memory::Watchdog::Monitor::RssMemoryLimit, + memory_limit_bytes: hard_limit_bytes, + max_strikes: 0, + monitor_name: :rss_memory_hard_limit + end + end end end end diff --git a/lib/gitlab/memory/watchdog/monitor/heap_fragmentation.rb b/lib/gitlab/memory/watchdog/monitor/heap_fragmentation.rb index 8f230980eac..ce99b68464e 100644 --- a/lib/gitlab/memory/watchdog/monitor/heap_fragmentation.rb +++ b/lib/gitlab/memory/watchdog/monitor/heap_fragmentation.rb @@ -4,10 +4,7 @@ module Gitlab module Memory class Watchdog module Monitor - # A monitor that observes Ruby heap fragmentation and calls - # memory_violation_callback when the Ruby heap has been fragmented for an extended - # period of time. - # + # A monitor that observes Ruby heap fragmentation. # See Gitlab::Metrics::Memory for how heap fragmentation is defined. class HeapFragmentation attr_reader :max_heap_fragmentation diff --git a/lib/gitlab/memory/watchdog/monitor/rss_memory_limit.rb b/lib/gitlab/memory/watchdog/monitor/rss_memory_limit.rb index 3e7de024630..bcd122f0090 100644 --- a/lib/gitlab/memory/watchdog/monitor/rss_memory_limit.rb +++ b/lib/gitlab/memory/watchdog/monitor/rss_memory_limit.rb @@ -5,27 +5,27 @@ module Gitlab class Watchdog module Monitor class RssMemoryLimit - attr_reader :memory_limit + attr_reader :memory_limit_bytes - def initialize(memory_limit:) - @memory_limit = memory_limit + def initialize(memory_limit_bytes:) + @memory_limit_bytes = memory_limit_bytes end def call - worker_rss = Gitlab::Metrics::System.memory_usage_rss[:total] + worker_rss_bytes = Gitlab::Metrics::System.memory_usage_rss[:total] - return { threshold_violated: false, payload: {} } if worker_rss <= memory_limit + return { threshold_violated: false, payload: {} } if worker_rss_bytes <= memory_limit_bytes - { threshold_violated: true, payload: payload(worker_rss, memory_limit) } + { threshold_violated: true, payload: payload(worker_rss_bytes, memory_limit_bytes) } end private - def payload(worker_rss, memory_limit) + def payload(worker_rss_bytes, memory_limit_bytes) { message: 'rss memory limit exceeded', - memwd_rss_bytes: worker_rss, - memwd_max_rss_bytes: memory_limit + memwd_rss_bytes: worker_rss_bytes, + memwd_max_rss_bytes: memory_limit_bytes } end end diff --git a/lib/gitlab/memory/watchdog/monitor_state.rb b/lib/gitlab/memory/watchdog/monitor_state.rb index 73be5de3e45..2562599d2ab 100644 --- a/lib/gitlab/memory/watchdog/monitor_state.rb +++ b/lib/gitlab/memory/watchdog/monitor_state.rb @@ -5,12 +5,12 @@ module Gitlab class Watchdog class MonitorState class Result - attr_reader :payload + attr_reader :payload, :monitor_name - def initialize(strikes_exceeded:, threshold_violated:, monitor_class:, payload: ) + def initialize(strikes_exceeded:, threshold_violated:, monitor_name:, payload: ) @strikes_exceeded = strikes_exceeded @threshold_violated = threshold_violated - @monitor_class = monitor_class + @monitor_name = monitor_name.to_s.to_sym @payload = payload end @@ -21,15 +21,12 @@ module Gitlab def threshold_violated? @threshold_violated end - - def monitor_name - @monitor_class.name.demodulize.underscore.to_sym - end end - def initialize(monitor, max_strikes:) + def initialize(monitor, max_strikes:, monitor_name:) @monitor = monitor @max_strikes = max_strikes + @monitor_name = monitor_name @strikes = 0 end @@ -47,16 +44,12 @@ module Gitlab build_result(monitor_result) end - def monitor_class - @monitor.class - end - private def build_result(monitor_result) Result.new( strikes_exceeded: strikes_exceeded?, - monitor_class: monitor_class, + monitor_name: @monitor_name, threshold_violated: monitor_result[:threshold_violated], payload: payload.merge(monitor_result[:payload])) end diff --git a/lib/gitlab/project_template.rb b/lib/gitlab/project_template.rb index 51a5bedc44b..40f5359adcf 100644 --- a/lib/gitlab/project_template.rb +++ b/lib/gitlab/project_template.rb @@ -60,6 +60,7 @@ module Gitlab ProjectTemplate.new('dotnetcore', '.NET Core', _('A .NET Core console application template, customizable for any .NET Core project'), 'https://gitlab.com/gitlab-org/project-templates/dotnetcore', 'illustrations/third-party-logos/dotnet.svg'), ProjectTemplate.new('android', 'Android', _('A ready-to-go template for use with Android apps'), 'https://gitlab.com/gitlab-org/project-templates/android', 'illustrations/logos/android.svg'), ProjectTemplate.new('gomicro', 'Go Micro', _('Go Micro is a framework for micro service development'), 'https://gitlab.com/gitlab-org/project-templates/go-micro', 'illustrations/logos/gomicro.svg'), + ProjectTemplate.new('bridgetown', 'Pages/Bridgetown', _('Everything you need to create a GitLab Pages site using Bridgetown'), 'https://gitlab.com/gitlab-org/project-templates/bridgetown'), ProjectTemplate.new('gatsby', 'Pages/Gatsby', _('Everything you need to create a GitLab Pages site using Gatsby'), 'https://gitlab.com/pages/gatsby', 'illustrations/third-party-logos/gatsby.svg'), ProjectTemplate.new('hugo', 'Pages/Hugo', _('Everything you need to create a GitLab Pages site using Hugo'), 'https://gitlab.com/pages/hugo', 'illustrations/logos/hugo.svg'), ProjectTemplate.new('pelican', 'Pages/Pelican', _('Everything you need to create a GitLab Pages site using Pelican'), 'https://gitlab.com/pages/pelican', 'illustrations/third-party-logos/pelican.svg'), diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 78b870a8266..2d2327ee463 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -16167,6 +16167,9 @@ msgstr "" msgid "Everything on your to-do list is marked as done." msgstr "" +msgid "Everything you need to create a GitLab Pages site using Bridgetown" +msgstr "" + msgid "Everything you need to create a GitLab Pages site using Gatsby" msgstr "" @@ -32557,6 +32560,9 @@ msgstr "" msgid "ProjectTemplates|NodeJS Express" msgstr "" +msgid "ProjectTemplates|Pages/Bridgetown" +msgstr "" + msgid "ProjectTemplates|Pages/Gatsby" msgstr "" diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb index 93a47a40a7e..985edf3efc1 100644 --- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb +++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb @@ -4,7 +4,7 @@ # rubocop:disable Rails/Pluck, Layout/LineLength, RSpec/MultipleMemoizedHelpers module QA - RSpec.describe "Manage", only: { job: "large-gitlab-import" } do + RSpec.describe "Manage", :skip_live_env, only: { job: "large-gitlab-import" } do describe "Gitlab migration", orchestrated: false, product_group: :import do include_context "with gitlab group migration" diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb index 37db26096d3..0521c5e02a8 100644 --- a/spec/controllers/groups/labels_controller_spec.rb +++ b/spec/controllers/groups/labels_controller_spec.rb @@ -54,7 +54,7 @@ RSpec.describe Groups::LabelsController do get :index, params: { group_id: group.to_param } end - it 'avoids N+1 queries' do + it 'avoids N+1 queries', :use_clean_rails_redis_caching do control = ActiveRecord::QueryRecorder.new(skip_cached: false) { get :index, params: { group_id: group.to_param } } create_list(:group_label, 3, group: group) diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb index a5259522fe2..dfa6ed639b6 100644 --- a/spec/controllers/projects/labels_controller_spec.rb +++ b/spec/controllers/projects/labels_controller_spec.rb @@ -100,7 +100,7 @@ RSpec.describe Projects::LabelsController do list_labels end - it 'avoids N+1 queries' do + it 'avoids N+1 queries', :use_clean_rails_redis_caching do control = ActiveRecord::QueryRecorder.new(skip_cached: false) { list_labels } create_list(:label, 3, project: project) diff --git a/spec/frontend/flash_spec.js b/spec/frontend/flash_spec.js index a105b0b165c..ade36cd1637 100644 --- a/spec/frontend/flash_spec.js +++ b/spec/frontend/flash_spec.js @@ -12,6 +12,9 @@ import createFlash, { jest.mock('@sentry/browser'); describe('Flash', () => { + const findTextContent = (containerSelector = '.flash-container') => + document.querySelector(containerSelector).textContent.replace(/\s+/g, ' ').trim(); + describe('hideFlash', () => { let el; @@ -99,7 +102,7 @@ describe('Flash', () => { it('adds alert element into the document by default', () => { alert = createAlert({ message: mockMessage }); - expect(document.querySelector('.flash-container').textContent.trim()).toBe(mockMessage); + expect(findTextContent()).toBe(mockMessage); expect(document.querySelector('.flash-container .gl-alert')).not.toBeNull(); }); @@ -202,8 +205,7 @@ describe('Flash', () => { message: mockMessage, }); - const text = document.querySelector('.flash-container').textContent.trim(); - expect(text).toBe(`${mockTitle} ${mockMessage}`); + expect(findTextContent()).toBe(`${mockTitle} ${mockMessage}`); }); }); @@ -319,6 +321,22 @@ describe('Flash', () => { }); }); }); + + describe('when called multiple times', () => { + it('clears previous alerts', () => { + createAlert({ message: 'message 1' }); + createAlert({ message: 'message 2' }); + + expect(findTextContent()).toBe('message 2'); + }); + + it('preserves alerts when `preservePrevious` is true', () => { + createAlert({ message: 'message 1' }); + createAlert({ message: 'message 2', preservePrevious: true }); + + expect(findTextContent()).toBe('message 1 message 2'); + }); + }); }); }); diff --git a/spec/lib/gitlab/memory/watchdog/configuration_spec.rb b/spec/lib/gitlab/memory/watchdog/configuration_spec.rb index 38a39f6a33a..8c9b26ce2c4 100644 --- a/spec/lib/gitlab/memory/watchdog/configuration_spec.rb +++ b/spec/lib/gitlab/memory/watchdog/configuration_spec.rb @@ -38,6 +38,8 @@ RSpec.describe Gitlab::Memory::Watchdog::Configuration do describe '#monitors' do context 'when monitors are configured to be used' do + let(:monitor_name1) { :monitor1 } + let(:monitor_name2) { :monitor2 } let(:payload1) do { message: 'monitor_1_text', @@ -96,7 +98,7 @@ RSpec.describe Gitlab::Memory::Watchdog::Configuration do expect(payloads).to eq([payload1, payload2]) expect(thresholds).to eq([false, true]) expect(strikes).to eq([false, true]) - expect(monitor_names).to eq([:monitor1, :monitor2]) + expect(monitor_names).to eq([monitor_name1, monitor_name2]) end end @@ -119,18 +121,19 @@ RSpec.describe Gitlab::Memory::Watchdog::Configuration do include_examples 'executes monitors and returns correct results' end - end - context 'when same monitor class is configured twice' do - before do - configuration.monitors.push monitor_class_1, max_strikes: 1 - configuration.monitors.push monitor_class_1, max_strikes: 1 - end + context 'when monitors are configured with monitor name' do + let(:monitor_name1) { :mon_one } + let(:monitor_name2) { :mon_two } - it 'calls same monitor only once' do - expect do |b| - configuration.monitors.call_each(&b) - end.to yield_control.once + before do + configuration.monitors do |stack| + stack.push monitor_class_1, false, { message: 'monitor_1_text' }, max_strikes: 5, monitor_name: :mon_one + stack.push monitor_class_2, true, { message: 'monitor_2_text' }, max_strikes: 0, monitor_name: :mon_two + end + end + + include_examples 'executes monitors and returns correct results' end end end diff --git a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb index 18da85eaaed..ec61d027329 100644 --- a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb +++ b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb @@ -130,11 +130,11 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do it_behaves_like 'as configurator', Gitlab::Memory::Watchdog::PumaHandler, 'GITLAB_MEMWD_SLEEP_TIME_SEC', - 60 + described_class::DEFAULT_SLEEP_INTERVAL_S context 'with DISABLE_PUMA_WORKER_KILLER set to true' do - let(:primary_memory) { 2048 } - let(:worker_memory) { max_mem_growth * primary_memory + 1 } + let(:primary_memory_bytes) { 2_097_152_000 } + let(:worker_memory_bytes) { max_mem_growth * primary_memory_bytes + 1 } let(:expected_payloads) do { heap_fragmentation: { @@ -147,9 +147,9 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do }, unique_memory_growth: { message: 'memory limit exceeded', - memwd_uss_bytes: worker_memory, - memwd_ref_uss_bytes: primary_memory, - memwd_max_uss_bytes: max_mem_growth * primary_memory, + memwd_uss_bytes: worker_memory_bytes, + memwd_ref_uss_bytes: primary_memory_bytes, + memwd_max_uss_bytes: max_mem_growth * primary_memory_bytes, memwd_max_strikes: max_strikes, memwd_cur_strikes: 1 } @@ -159,10 +159,10 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do before do stub_env('DISABLE_PUMA_WORKER_KILLER', true) allow(Gitlab::Metrics::Memory).to receive(:gc_heap_fragmentation).and_return(max_heap_fragmentation + 0.1) - allow(Gitlab::Metrics::System).to receive(:memory_usage_uss_pss).and_return({ uss: worker_memory }) + allow(Gitlab::Metrics::System).to receive(:memory_usage_uss_pss).and_return({ uss: worker_memory_bytes }) allow(Gitlab::Metrics::System).to receive(:memory_usage_uss_pss).with( pid: Gitlab::Cluster::PRIMARY_PID - ).and_return({ uss: primary_memory }) + ).and_return({ uss: primary_memory_bytes }) end context 'when settings are set via environment variables' do @@ -180,21 +180,22 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do end context 'when settings are not set via environment variables' do - let(:max_heap_fragmentation) { 0.5 } - let(:max_mem_growth) { 3.0 } - let(:max_strikes) { 5 } + let(:max_heap_fragmentation) { described_class::DEFAULT_MAX_HEAP_FRAG } + let(:max_mem_growth) { described_class::DEFAULT_MAX_MEM_GROWTH } + let(:max_strikes) { described_class::DEFAULT_MAX_STRIKES } it_behaves_like 'as monitor configurator' end end context 'with DISABLE_PUMA_WORKER_KILLER set to false' do + let(:memory_limit_bytes) { memory_limit_mb.megabytes } let(:expected_payloads) do { rss_memory_limit: { message: 'rss memory limit exceeded', - memwd_rss_bytes: memory_limit + 1, - memwd_max_rss_bytes: memory_limit, + memwd_rss_bytes: memory_limit_bytes + 1, + memwd_max_rss_bytes: memory_limit_bytes, memwd_max_strikes: max_strikes, memwd_cur_strikes: 1 } @@ -203,15 +204,15 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do before do stub_env('DISABLE_PUMA_WORKER_KILLER', false) - allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return({ total: memory_limit + 1 }) + allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return({ total: memory_limit_bytes + 1 }) end context 'when settings are set via environment variables' do - let(:memory_limit) { 1300.megabytes } + let(:memory_limit_mb) { 1300 } let(:max_strikes) { 4 } before do - stub_env('PUMA_WORKER_MAX_MEMORY', 1300) + stub_env('PUMA_WORKER_MAX_MEMORY', memory_limit_mb) stub_env('GITLAB_MEMWD_MAX_STRIKES', 4) end @@ -219,8 +220,8 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do end context 'when settings are not set via environment variables' do - let(:memory_limit) { 1200.megabytes } - let(:max_strikes) { 5 } + let(:memory_limit_mb) { described_class::DEFAULT_PUMA_WORKER_RSS_LIMIT_MB } + let(:max_strikes) { described_class::DEFAULT_MAX_STRIKES } it_behaves_like 'as monitor configurator' end @@ -236,6 +237,113 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do it_behaves_like 'as configurator', Gitlab::Memory::Watchdog::TermProcessHandler, 'SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL', - 3 + described_class::DEFAULT_SIDEKIQ_SLEEP_INTERVAL_S + + context 'when sleep_time_seconds is less than MIN_SIDEKIQ_SLEEP_INTERVAL_S seconds' do + before do + stub_env('SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL', 0) + end + + it 'configures the correct sleep time' do + configurator.call(configuration) + + expect(configuration.sleep_time_seconds).to eq(described_class::MIN_SIDEKIQ_SLEEP_INTERVAL_S) + end + end + + context 'with monitors' do + let(:soft_limit_bytes) { soft_limit_kb.kilobytes } + let(:hard_limit_bytes) { hard_limit_kb.kilobytes } + + context 'when settings are set via environment variables' do + let(:soft_limit_kb) { 2000001 } + let(:hard_limit_kb) { 300000 } + let(:max_strikes) { 150 } + let(:grace_time) { 300 } + let(:expected_payloads) do + { + rss_memory_soft_limit: { + message: 'rss memory limit exceeded', + memwd_rss_bytes: soft_limit_bytes + 1, + memwd_max_rss_bytes: soft_limit_bytes, + memwd_max_strikes: max_strikes, + memwd_cur_strikes: 1 + }, + rss_memory_hard_limit: { + message: 'rss memory limit exceeded', + memwd_rss_bytes: hard_limit_bytes + 1, + memwd_max_rss_bytes: hard_limit_bytes, + memwd_max_strikes: 0, + memwd_cur_strikes: 1 + } + } + end + + before do + stub_env('SIDEKIQ_MEMORY_KILLER_MAX_RSS', soft_limit_kb) + stub_env('SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS', hard_limit_kb) + stub_env('SIDEKIQ_MEMORY_KILLER_GRACE_TIME', grace_time) + stub_env('SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL', 2) + allow(Gitlab::Metrics::System).to receive(:memory_usage_rss) + .and_return({ total: soft_limit_bytes + 1 }, { total: hard_limit_bytes + 1 }) + end + + it_behaves_like 'as monitor configurator' + end + + context 'when only SIDEKIQ_MEMORY_KILLER_MAX_RSS is set via environment variable' do + let(:soft_limit_kb) { 2000000 } + let(:max_strikes) do + described_class::DEFAULT_SIDEKIQ_GRACE_TIME_S / described_class::DEFAULT_SIDEKIQ_SLEEP_INTERVAL_S + end + + let(:expected_payloads) do + { + rss_memory_soft_limit: { + message: 'rss memory limit exceeded', + memwd_rss_bytes: soft_limit_bytes + 1, + memwd_max_rss_bytes: soft_limit_bytes, + memwd_max_strikes: max_strikes, + memwd_cur_strikes: 1 + } + } + end + + before do + allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return({ total: soft_limit_bytes + 1 }) + stub_env('SIDEKIQ_MEMORY_KILLER_MAX_RSS', soft_limit_kb) + end + + it_behaves_like 'as monitor configurator' + end + + context 'when only SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS is set via environment variable' do + let(:hard_limit_kb) { 2000000 } + let(:expected_payloads) do + { + rss_memory_hard_limit: { + message: 'rss memory limit exceeded', + memwd_rss_bytes: hard_limit_bytes + 1, + memwd_max_rss_bytes: hard_limit_bytes, + memwd_max_strikes: 0, + memwd_cur_strikes: 1 + } + } + end + + before do + allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return({ total: hard_limit_bytes + 1 }) + stub_env('SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS', hard_limit_kb) + end + + it_behaves_like 'as monitor configurator' + end + + context 'when both SIDEKIQ_MEMORY_KILLER_MAX_RSS and SIDEKIQ_MEMORY_KILLER_HARD_LIMIT_RSS are not set' do + let(:expected_payloads) { {} } + + it_behaves_like 'as monitor configurator' + end + end end end diff --git a/spec/lib/gitlab/memory/watchdog/monitor/rss_memory_limit_spec.rb b/spec/lib/gitlab/memory/watchdog/monitor/rss_memory_limit_spec.rb index 9e25cfda782..fffe5d5ff00 100644 --- a/spec/lib/gitlab/memory/watchdog/monitor/rss_memory_limit_spec.rb +++ b/spec/lib/gitlab/memory/watchdog/monitor/rss_memory_limit_spec.rb @@ -4,25 +4,25 @@ require 'fast_spec_helper' require 'support/shared_examples/lib/gitlab/memory/watchdog/monitor_result_shared_examples' RSpec.describe Gitlab::Memory::Watchdog::Monitor::RssMemoryLimit do - let(:memory_limit) { 2048 } - let(:worker_memory) { 1024 } + let(:memory_limit_bytes) { 2_097_152_000 } + let(:worker_memory_bytes) { 1_048_576_000 } subject(:monitor) do - described_class.new(memory_limit: memory_limit) + described_class.new(memory_limit_bytes: memory_limit_bytes) end before do - allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return({ total: worker_memory }) + allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return({ total: worker_memory_bytes }) end describe '#call' do context 'when process exceeds threshold' do - let(:worker_memory) { memory_limit + 1 } + let(:worker_memory_bytes) { memory_limit_bytes + 1 } let(:payload) do { message: 'rss memory limit exceeded', - memwd_rss_bytes: worker_memory, - memwd_max_rss_bytes: memory_limit + memwd_rss_bytes: worker_memory_bytes, + memwd_max_rss_bytes: memory_limit_bytes } end @@ -30,7 +30,7 @@ RSpec.describe Gitlab::Memory::Watchdog::Monitor::RssMemoryLimit do end context 'when process does not exceed threshold' do - let(:worker_memory) { memory_limit - 1 } + let(:worker_memory_bytes) { memory_limit_bytes - 1 } let(:payload) { {} } include_examples 'returns Watchdog Monitor result', threshold_violated: false diff --git a/spec/lib/gitlab/memory/watchdog/monitor_state_spec.rb b/spec/lib/gitlab/memory/watchdog/monitor_state_spec.rb index ace1353c6e3..7802e274c53 100644 --- a/spec/lib/gitlab/memory/watchdog/monitor_state_spec.rb +++ b/spec/lib/gitlab/memory/watchdog/monitor_state_spec.rb @@ -7,6 +7,7 @@ RSpec.describe Gitlab::Memory::Watchdog::MonitorState do let(:payload) { { message: 'DummyMessage' } } let(:threshold_violated) { true } let(:monitor) { monitor_class.new(threshold_violated, payload) } + let(:monitor_name) { :dummy_monitor_name } let(:monitor_class) do Struct.new(:threshold_violated, :payload) do def call @@ -19,7 +20,7 @@ RSpec.describe Gitlab::Memory::Watchdog::MonitorState do end end - subject(:monitor_state) { described_class.new(monitor, max_strikes: max_strikes) } + subject(:monitor_state) { described_class.new(monitor, max_strikes: max_strikes, monitor_name: monitor_name) } shared_examples 'returns correct result' do it 'returns correct result', :aggregate_failures do @@ -29,7 +30,7 @@ RSpec.describe Gitlab::Memory::Watchdog::MonitorState do expect(result.strikes_exceeded?).to eq(strikes_exceeded) expect(result.threshold_violated?).to eq(threshold_violated) expect(result.payload).to eq(expected_payload) - expect(result.monitor_name).to eq(:monitor_name) + expect(result.monitor_name).to eq(monitor_name) end end @@ -63,10 +64,4 @@ RSpec.describe Gitlab::Memory::Watchdog::MonitorState do end end end - - describe '#monitor_class' do - subject { monitor_state.monitor_class } - - it { is_expected.to eq(monitor_class) } - end end diff --git a/spec/models/ci/build_metadata_spec.rb b/spec/models/ci/build_metadata_spec.rb index 3028f49a49c..65ef9308485 100644 --- a/spec/models/ci/build_metadata_spec.rb +++ b/spec/models/ci/build_metadata_spec.rb @@ -6,7 +6,6 @@ RSpec.describe Ci::BuildMetadata do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, :repository, group: group, build_timeout: 2000) } - let_it_be(:pipeline) do create(:ci_pipeline, project: project, sha: project.commit.id, @@ -14,7 +13,9 @@ RSpec.describe Ci::BuildMetadata do status: 'success') end - let(:job) { create(:ci_build, pipeline: pipeline) } + let_it_be_with_reload(:runner) { create(:ci_runner) } + + let(:job) { create(:ci_build, pipeline: pipeline, runner: runner) } let(:metadata) { job.metadata } it_behaves_like 'having unique enum values' @@ -32,63 +33,110 @@ RSpec.describe Ci::BuildMetadata do end end - context 'when project timeout is set' do - context 'when runner is assigned to the job' do + context 'when job, project and runner timeouts are set' do + context 'when job timeout is lower then runner timeout' do before do - job.update!(runner: runner) + runner.update!(maximum_timeout: 4000) + job.update!(options: { job_timeout: 3000 }) end - context 'when runner timeout is not set' do - let(:runner) { create(:ci_runner, maximum_timeout: nil) } - - it_behaves_like 'sets timeout', 'project_timeout_source', 2000 - end - - context 'when runner timeout is lower than project timeout' do - let(:runner) { create(:ci_runner, maximum_timeout: 1900) } - - it_behaves_like 'sets timeout', 'runner_timeout_source', 1900 - end - - context 'when runner timeout is higher than project timeout' do - let(:runner) { create(:ci_runner, maximum_timeout: 2100) } - - it_behaves_like 'sets timeout', 'project_timeout_source', 2000 - end + it_behaves_like 'sets timeout', 'job_timeout_source', 3000 end - context 'when job timeout is set' do - context 'when job timeout is higher than project timeout' do - let(:job) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 3000 }) } - - it_behaves_like 'sets timeout', 'job_timeout_source', 3000 + context 'when runner timeout is lower then job timeout' do + before do + runner.update!(maximum_timeout: 2000) + job.update!(options: { job_timeout: 3000 }) end - context 'when job timeout is lower than project timeout' do - let(:job) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 1000 }) } + it_behaves_like 'sets timeout', 'runner_timeout_source', 2000 + end + end - it_behaves_like 'sets timeout', 'job_timeout_source', 1000 + context 'when job, project timeout values are set and runner is assigned' do + context 'when runner has no timeout set' do + before do + runner.update!(maximum_timeout: nil) + job.update!(options: { job_timeout: 3000 }) end + + it_behaves_like 'sets timeout', 'job_timeout_source', 3000 + end + end + + context 'when only job and project timeouts are defined' do + context 'when job timeout is lower then project timeout' do + before do + job.update!(options: { job_timeout: 1000 }) + end + + it_behaves_like 'sets timeout', 'job_timeout_source', 1000 end - context 'when both runner and job timeouts are set' do + context 'when project timeout is lower then job timeout' do before do - job.update!(runner: runner) + job.update!(options: { job_timeout: 3000 }) end - context 'when job timeout is higher than runner timeout' do - let(:job) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 3000 }) } - let(:runner) { create(:ci_runner, maximum_timeout: 2100) } + it_behaves_like 'sets timeout', 'job_timeout_source', 3000 + end + end - it_behaves_like 'sets timeout', 'runner_timeout_source', 2100 + context 'when only project and runner timeouts are defined' do + before do + runner.update!(maximum_timeout: 1900) + end + + context 'when runner timeout is lower then project timeout' do + it_behaves_like 'sets timeout', 'runner_timeout_source', 1900 + end + + context 'when project timeout is lower then runner timeout' do + before do + runner.update!(maximum_timeout: 2100) end - context 'when job timeout is lower than runner timeout' do - let(:job) { create(:ci_build, pipeline: pipeline, options: { job_timeout: 1900 }) } - let(:runner) { create(:ci_runner, maximum_timeout: 2100) } + it_behaves_like 'sets timeout', 'project_timeout_source', 2000 + end + end - it_behaves_like 'sets timeout', 'job_timeout_source', 1900 + context 'when only job and runner timeouts are defined' do + context 'when runner timeout is lower them job timeout' do + before do + job.update!(options: { job_timeout: 2000 }) + runner.update!(maximum_timeout: 1900) end + + it_behaves_like 'sets timeout', 'runner_timeout_source', 1900 + end + + context 'when job timeout is lower them runner timeout' do + before do + job.update!(options: { job_timeout: 1000 }) + runner.update!(maximum_timeout: 1900) + end + + it_behaves_like 'sets timeout', 'job_timeout_source', 1000 + end + end + + context 'when only job timeout is defined and runner is assigned, but has no timeout set' do + before do + job.update!(options: { job_timeout: 1000 }) + runner.update!(maximum_timeout: nil) + end + + it_behaves_like 'sets timeout', 'job_timeout_source', 1000 + end + + context 'when only one timeout value is defined' do + context 'when only project timeout value is defined' do + before do + job.update!(options: { job_timeout: nil }) + runner.update!(maximum_timeout: nil) + end + + it_behaves_like 'sets timeout', 'project_timeout_source', 2000 end end end diff --git a/spec/requests/api/project_import_spec.rb b/spec/requests/api/project_import_spec.rb index 05fe55b06a1..3087f0cac7d 100644 --- a/spec/requests/api/project_import_spec.rb +++ b/spec/requests/api/project_import_spec.rb @@ -44,7 +44,7 @@ RSpec.describe API::ProjectImport, :aggregate_failures do it_behaves_like 'requires authentication' - it 'executes a limited number of queries' do + it 'executes a limited number of queries', :use_clean_rails_redis_caching do control_count = ActiveRecord::QueryRecorder.new { subject }.count expect(control_count).to be <= 111 diff --git a/spec/support/helpers/project_template_test_helper.rb b/spec/support/helpers/project_template_test_helper.rb index eab41f6a1cf..1990cd4551a 100644 --- a/spec/support/helpers/project_template_test_helper.rb +++ b/spec/support/helpers/project_template_test_helper.rb @@ -9,7 +9,7 @@ module ProjectTemplateTestHelper nfjekyll nfplainhtml nfgitbook nfhexo salesforcedx serverless_framework tencent_serverless_framework jsonnet cluster_management kotlin_native_linux - pelican + pelican bridgetown ] end end diff --git a/vendor/project_templates/bridgetown.tar.gz b/vendor/project_templates/bridgetown.tar.gz new file mode 100644 index 00000000000..1fb89694d0f Binary files /dev/null and b/vendor/project_templates/bridgetown.tar.gz differ