diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb
index 5d27d30eaa3530b3d7f3d59e8864cc454eea1dc8..a4f1948053981983c0077801b8243c0e1abc4acc 100644
--- a/app/helpers/accounts_helper.rb
+++ b/app/helpers/accounts_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module AccountsHelper
   def incoming_email_token_enabled?
     current_user.incoming_email_token && Gitlab::IncomingEmail.supports_issue_creation?
diff --git a/app/helpers/active_sessions_helper.rb b/app/helpers/active_sessions_helper.rb
index 97b6dac67c504d951507e42bb7ceb983d40ae2bf..84aa1160f12ec10121662e408a83ef00523e004a 100644
--- a/app/helpers/active_sessions_helper.rb
+++ b/app/helpers/active_sessions_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ActiveSessionsHelper
   # Maps a device type as defined in `ActiveSession` to an svg icon name and
   # outputs the icon html.
diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb
index a9ec02995306e47abb57ebd7be3c8a4f1a245a5d..0b579084a130911cf1c2b32a0a6ea0df59721422 100644
--- a/app/helpers/appearances_helper.rb
+++ b/app/helpers/appearances_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module AppearancesHelper
   prepend EE::AppearancesHelper
 
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 59056655286574b52e56622f458369fe774ad8fc..153dcbb3b7ac2d20fab1378484940e472e2e801f 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'digest/md5'
 require 'uri'
 
@@ -111,11 +113,11 @@ def extra_config
   #
   # Returns an HTML-safe String
   def time_ago_with_tooltip(time, placement: 'top', html_class: '', short_format: false)
-    css_classes = short_format ? 'js-short-timeago' : 'js-timeago'
-    css_classes << " #{html_class}" unless html_class.blank?
+    css_classes = [short_format ? 'js-short-timeago' : 'js-timeago']
+    css_classes << html_class unless html_class.blank?
 
     element = content_tag :time, l(time, format: "%b %d, %Y"),
-      class: css_classes,
+      class: css_classes.join(' '),
       title: l(time.to_time.in_time_zone, format: :timeago_tooltip),
       datetime: time.to_time.getutc.iso8601,
       data: {
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 8b022b2b888199a9e079ff7c6b2f97515977fb66..69547b4c5952dc860fed7fc779b5ebab2477caac 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ApplicationSettingsHelper
   prepend EE::ApplicationSettingsHelper
   extend self
@@ -74,12 +76,12 @@ def import_sources_checkboxes(help_block_id, options = {})
   def oauth_providers_checkboxes
     button_based_providers.map do |source|
       disabled = Gitlab::CurrentSettings.disabled_oauth_sign_in_sources.include?(source.to_s)
-      css_class = 'btn'
-      css_class << ' active' unless disabled
+      css_class = ['btn']
+      css_class << 'active' unless disabled
       checkbox_name = 'application_setting[enabled_oauth_sign_in_sources][]'
       name = Gitlab::Auth::OAuth::Provider.label_for(source)
 
-      label_tag(checkbox_name, class: css_class) do
+      label_tag(checkbox_name, class: css_class.join(' ')) do
         check_box_tag(checkbox_name, source, !disabled,
                       autocomplete: 'off',
                       id: name.tr(' ', '_')) + name
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index 95eb4f3a7e40582a7f63136fc45b39de81d966f4..a191b2451279ed3bbcb206a0fa104aa2522e899f 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module AuthHelper
   prepend EE::AuthHelper
 
diff --git a/app/helpers/auto_devops_helper.rb b/app/helpers/auto_devops_helper.rb
index 7b076728685a9a67d651b7a4fb2c289713563598..62fc6fb279fc3631f5686f1cebc6ada03bc2344b 100644
--- a/app/helpers/auto_devops_helper.rb
+++ b/app/helpers/auto_devops_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module AutoDevopsHelper
   def show_auto_devops_callout?(project)
     Feature.get(:auto_devops_banner_disabled).off? &&
diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb
index 494f785e30574d895481edf557882641fca0ebb9..321811a3ca3c42a90f9fb29ce5a01b95cf81f3f0 100644
--- a/app/helpers/avatars_helper.rb
+++ b/app/helpers/avatars_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module AvatarsHelper
   def project_icon(project_id, options = {})
     source_icon(Project, project_id, options)
@@ -125,9 +127,9 @@ def source_icon(klass, source_id, options = {})
 
   def source_identicon(source, options = {})
     bg_key = (source.id % 7) + 1
-    options[:class] ||= ''
-    options[:class] << ' identicon'
-    options[:class] << " bg#{bg_key}"
+
+    options[:class] =
+      [*options[:class], "identicon bg#{bg_key}"].join(' ')
 
     content_tag(:div, class: options[:class].strip) do
       source.name[0, 1].upcase
diff --git a/app/helpers/award_emoji_helper.rb b/app/helpers/award_emoji_helper.rb
index e22757c0cfe61b74da28ad5ede150c57ea78f5bc..1244527bf052d548161cde51c0ac0917814ca5e2 100644
--- a/app/helpers/award_emoji_helper.rb
+++ b/app/helpers/award_emoji_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module AwardEmojiHelper
   prepend EE::AwardEmojiHelper
 
diff --git a/app/helpers/blame_helper.rb b/app/helpers/blame_helper.rb
index 089d9e3e38790540649e99fd8e247a64850ee1c7..82c74e2416d52ffb2440c6f932a4c899d9ce407b 100644
--- a/app/helpers/blame_helper.rb
+++ b/app/helpers/blame_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module BlameHelper
   def age_map_duration(blame_groups, project)
     now = Time.zone.now
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 96f7415ae9859337f1a57b874a92a7e7aebbf12a..9cbd5b5f785957bab599881383966818698710ca 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module BlobHelper
   def highlight(blob_name, blob_content, repository: nil, plain: false)
     plain ||= blob_content.length > Blob::MAXIMUM_TEXT_HIGHLIGHT_SIZE
diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb
index 5fcc7ad4e14418bda47284c33e405e1fdba65854..bd6e10b0e5a619b52aeed4091f98fb03ed77a3fb 100644
--- a/app/helpers/boards_helper.rb
+++ b/app/helpers/boards_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module BoardsHelper
   prepend EE::BoardsHelper
 
diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb
index b406bae28ff44e5312c23df6cbe8ec69f2b98f11..fe022c3cf8c63780326fafd6d9f51b67b08920c1 100644
--- a/app/helpers/branches_helper.rb
+++ b/app/helpers/branches_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module BranchesHelper
   prepend EE::BranchesHelper
 
diff --git a/app/helpers/breadcrumbs_helper.rb b/app/helpers/breadcrumbs_helper.rb
index e88fe6bcd7e9fcdb3b5364de78fe93f1eb6416ec..b067376cea0cc0519462cd32b2c22ea74bf58eea 100644
--- a/app/helpers/breadcrumbs_helper.rb
+++ b/app/helpers/breadcrumbs_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module BreadcrumbsHelper
   def add_to_breadcrumbs(text, link)
     @breadcrumbs_extra_links ||= []
diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb
index 0a15c29cfb5841fa67d7eeae063a2f15621b11fc..289cb44f1e8a0014f3848e109abd371a1f5d14f2 100644
--- a/app/helpers/broadcast_messages_helper.rb
+++ b/app/helpers/broadcast_messages_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module BroadcastMessagesHelper
   def broadcast_message(message)
     return unless message.present?
@@ -8,18 +10,17 @@ def broadcast_message(message)
   end
 
   def broadcast_message_style(broadcast_message)
-    style = ''
+    style = []
 
     if broadcast_message.color.present?
       style << "background-color: #{broadcast_message.color}"
-      style << '; ' if broadcast_message.font.present?
     end
 
     if broadcast_message.font.present?
       style << "color: #{broadcast_message.font}"
     end
 
-    style
+    style.join('; ')
   end
 
   def broadcast_message_status(broadcast_message)
diff --git a/app/helpers/builds_helper.rb b/app/helpers/builds_helper.rb
index 4ec63fdaffc440fdfbb19091b8732070822955c1..3c8caec3fe5733192d2434590d803ed2f8766547 100644
--- a/app/helpers/builds_helper.rb
+++ b/app/helpers/builds_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module BuildsHelper
   def build_summary(build, skip: false)
     if build.has_trace?
@@ -12,10 +14,10 @@ def build_summary(build, skip: false)
   end
 
   def sidebar_build_class(build, current_build)
-    build_class = ''
-    build_class += ' active' if build.id === current_build.id
-    build_class += ' retried' if build.retried?
-    build_class
+    build_class = []
+    build_class << 'active' if build.id === current_build.id
+    build_class << 'retried' if build.retried?
+    build_class.join(' ')
   end
 
   def javascript_build_options
diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb
index 937120d9c8d1dbc6e9c35e433a43d2c4419f239d..97758c7bbca31a1c6c286c24c0f0313407baa938 100644
--- a/app/helpers/button_helper.rb
+++ b/app/helpers/button_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ButtonHelper
   # Output a "Copy to Clipboard" button
   #
@@ -95,8 +97,7 @@ def dropdown_item_with_description(title, description, href: nil, data: nil)
   end
 
   def kerberos_clone_button(project)
-    klass = 'kerberos-selector'
-    klass << ' has-tooltip'
+    klass = 'kerberos-selector has-tooltip'
 
     content_tag :a, 'KRB5',
       class: klass,
diff --git a/app/helpers/calendar_helper.rb b/app/helpers/calendar_helper.rb
index c54b91b0ce5a229996f8b78dbb4e18bf5259ac90..ad4116fc3da824cad6644c4ca3d2c748e9d6cd4c 100644
--- a/app/helpers/calendar_helper.rb
+++ b/app/helpers/calendar_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module CalendarHelper
   def calendar_url_options
     { format: :ics,
diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb
index 330959e536dc1f5983c06fe8cafc3fef661ae4de..f8d36dce45d1ec2e4897e13aafa3681d8259e1c7 100644
--- a/app/helpers/ci_status_helper.rb
+++ b/app/helpers/ci_status_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 ##
 # DEPRECATED
 #
diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb
index 350600c284a195a6eb76e0bdaf186929557025b7..6df17590d0342e45ce0b8830c025f0a00c84de39 100644
--- a/app/helpers/clusters_helper.rb
+++ b/app/helpers/clusters_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ClustersHelper
   def has_multiple_clusters?(project)
     project.feature_available?(:multiple_clusters)
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 7a942c44ac41ed733256fe4151eb254ec9739e03..d52cfd6e37ab0f934b815a8ea237665d5bf70a5b 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module CommitsHelper
   # Returns a link to the commit author. If the author has a matching user and
   # is a member of the current @project it will link to the team member page.
diff --git a/app/helpers/compare_helper.rb b/app/helpers/compare_helper.rb
index 2df5b5d1695f151e362a6b0aca3df6fb4839de3b..9ece8b0bc5bb81d294c130fce51d614238f08ac5 100644
--- a/app/helpers/compare_helper.rb
+++ b/app/helpers/compare_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module CompareHelper
   def create_mr_button?(from = params[:from], to = params[:to], project = @project)
     from.present? &&
diff --git a/app/helpers/components_helper.rb b/app/helpers/components_helper.rb
index 8893209b3146f255e54a8e92a25e13b641570b31..d0ef86851adc461e8524f7dfd804cc14987faaf3 100644
--- a/app/helpers/components_helper.rb
+++ b/app/helpers/components_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ComponentsHelper
   def gitlab_workhorse_version
     if request.headers['Gitlab-Workhorse'].present?
diff --git a/app/helpers/conversational_development_index_helper.rb b/app/helpers/conversational_development_index_helper.rb
index 1ff5441581112fd7f0663e425103739624a05063..37e5bb325fb9426e91817b07a2f8bb6e89551a4c 100644
--- a/app/helpers/conversational_development_index_helper.rb
+++ b/app/helpers/conversational_development_index_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ConversationalDevelopmentIndexHelper
   def score_level(score)
     if score < 33.33
diff --git a/app/helpers/count_helper.rb b/app/helpers/count_helper.rb
index 5cd98f40f78ad59512303025a763c240d4d99620..e16223a82c98f4b01af490abcff3164e7b483a56 100644
--- a/app/helpers/count_helper.rb
+++ b/app/helpers/count_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module CountHelper
   def approximate_count_with_delimiters(count_data, model)
     count = count_data[model]
diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb
index 19aa55a8d4929e5e52133fdacb4b2e0a4ad19081..463f4145bddde2f2c19a1bec09e6663b074ac1a6 100644
--- a/app/helpers/dashboard_helper.rb
+++ b/app/helpers/dashboard_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module DashboardHelper
   def assigned_issues_dashboard_path
     issues_dashboard_path(assignee_id: current_user.id)
diff --git a/app/helpers/defer_script_tag_helper.rb b/app/helpers/defer_script_tag_helper.rb
index e1567556e5ebcd34bc365e926871d0f0ab8c10c8..d91c6d52683f69dd0af14f5d734cbc7fbaf87ca6 100644
--- a/app/helpers/defer_script_tag_helper.rb
+++ b/app/helpers/defer_script_tag_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module DeferScriptTagHelper
   # Override the default ActionView `javascript_include_tag` helper to support page specific deferred loading
   def javascript_include_tag(*sources)
diff --git a/app/helpers/deploy_tokens_helper.rb b/app/helpers/deploy_tokens_helper.rb
index bd921322476bcbada18eb5ec8538ea61a565389f..80a5bb44c6961145529a1bac66ad367989a46325 100644
--- a/app/helpers/deploy_tokens_helper.rb
+++ b/app/helpers/deploy_tokens_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module DeployTokensHelper
   def expand_deploy_tokens_section?(deploy_token)
     deploy_token.persisted? ||
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 1bb82fd81503831b212b2e5549f5ebaaa70695f0..7684734c0143fa5a7ab6eb144be1fa0cfa9cb57f 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module DiffHelper
   def mark_inline_diffs(old_line, new_line)
     old_diffs, new_diffs = Gitlab::Diff::InlineDiff.new(old_line, new_line).inline_diffs
@@ -39,7 +41,8 @@ def diff_match_line(old_pos, new_pos, text: '', view: :inline, bottom: false)
     line_num_class = %w[diff-line-num unfold js-unfold]
     line_num_class << 'js-unfold-bottom' if bottom
 
-    html = ''
+    html = []
+
     if old_pos
       html << content_tag(:td, '...', class: [*line_num_class, 'old_line'], data: { linenumber: old_pos })
       html << content_tag(:td, text, class: [*content_line_class, 'left-side']) if view == :parallel
@@ -50,7 +53,7 @@ def diff_match_line(old_pos, new_pos, text: '', view: :inline, bottom: false)
       html << content_tag(:td, text, class: [*content_line_class, ('right-side' if view == :parallel)])
     end
 
-    html.html_safe
+    html.join.html_safe
   end
 
   def diff_line_content(line)
@@ -215,9 +218,7 @@ def params_with_whitespace
   end
 
   def toggle_whitespace_link(url, options)
-    options[:class] ||= ''
-    options[:class] << ' btn btn-default'
-
+    options[:class] = [*options[:class], 'btn btn-default'].join(' ')
     link_to "#{hide_whitespace? ? 'Show' : 'Hide'} whitespace changes", url, class: options[:class]
   end
 
diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb
index a6c9dd672b87a75015b86c7e73542511d93ee607..8d8c62f129180bcc7321de2e20ea212199ebcbc0 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module DropdownsHelper
   def dropdown_tag(toggle_text, options: {}, &block)
     content_tag :div, class: "dropdown #{options[:wrapper_class] if options.key?(:wrapper_class)}" do
@@ -14,7 +16,7 @@ def dropdown_tag(toggle_text, options: {}, &block)
       end
 
       dropdown_output << content_tag(:div, class: "dropdown-menu dropdown-select #{options[:dropdown_class] if options.key?(:dropdown_class)}") do
-        output = ""
+        output = []
 
         if options.key?(:title)
           output << dropdown_title(options[:title])
@@ -35,8 +37,7 @@ def dropdown_tag(toggle_text, options: {}, &block)
         end
 
         output << dropdown_loading
-
-        output.html_safe
+        output.join.html_safe
       end
 
       dropdown_output.html_safe
@@ -59,7 +60,7 @@ def dropdown_toggle_link(toggle_text, data_attr, options = {})
 
   def dropdown_title(title, options: {})
     content_tag :div, class: "dropdown-title" do
-      title_output = ""
+      title_output = []
 
       if options.fetch(:back, false)
         title_output << content_tag(:button, class: "dropdown-title-button dropdown-menu-back", aria: { label: "Go back" }, type: "button") do
@@ -75,7 +76,7 @@ def dropdown_title(title, options: {})
         end
       end
 
-      title_output.html_safe
+      title_output.join.html_safe
     end
   end
 
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
index 4bfd246c287433ee1cbdde52a263f52eb2acfb50..c6c479faf70c1e9d5424cc26bc1dd0cff1cda69d 100644
--- a/app/helpers/emails_helper.rb
+++ b/app/helpers/emails_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module EmailsHelper
   prepend EE::EmailsHelper
 
@@ -51,8 +53,8 @@ def password_reset_token_valid_time
 
   def reset_token_expire_message
     link_tag = link_to('request a new one', new_user_password_url(user_email: @user.email))
-    msg = "This link is valid for #{password_reset_token_valid_time}.  "
-    msg << "After it expires, you can #{link_tag}."
+    "This link is valid for #{password_reset_token_valid_time}.  " \
+    "After it expires, you can #{link_tag}."
   end
 
   def header_logo
diff --git a/app/helpers/emoji_helper.rb b/app/helpers/emoji_helper.rb
index 482f68f412bff2e769f62f4c6b06183afb12a4f8..51b7fd7f3523b14a3f01095cfaf45e4aa01bd08f 100644
--- a/app/helpers/emoji_helper.rb
+++ b/app/helpers/emoji_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module EmojiHelper
   def emoji_icon(*args)
     raw Gitlab::Emoji.gl_emoji_tag(*args)
diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb
index 1e78a189c085612d24f37ad5cd63a96754726ba8..4b3ef2de7013973a5f4690f4a2fe0c5bc8afd136 100644
--- a/app/helpers/environment_helper.rb
+++ b/app/helpers/environment_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module EnvironmentHelper
   def environment_for_build(project, build)
     return unless build.environment
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index 3bbad15fcfdcebb524fb2c5c480db8d21e85d839..b9cc37d016b94e1623fb10aef325018f7e927592 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module EnvironmentsHelper
   prepend ::EE::EnvironmentsHelper
 
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index 269acf5b2e2ccfaf12bd46c5daed4eb2b529d9f4..401e2dab379f49ebabf6e516171ebad1035176ea 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module EventsHelper
   ICON_NAMES_BY_EVENT_TYPE = {
     'pushed to' => 'commit',
diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb
index f062a91a166b8cd9c7eb93e49f121ad3581108a7..62be591ec47fa2c6045301d99ea249d5d406306e 100644
--- a/app/helpers/explore_helper.rb
+++ b/app/helpers/explore_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ExploreHelper
   def filter_projects_path(options = {})
     exist_opts = {
diff --git a/app/helpers/external_wiki_helper.rb b/app/helpers/external_wiki_helper.rb
index 8cf890b74a87dd7dcd5c74c11dd2bac3eba1c2ce..e36d63b2946a8ae6b435f2daee5b43f32a7f0cb9 100644
--- a/app/helpers/external_wiki_helper.rb
+++ b/app/helpers/external_wiki_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ExternalWikiHelper
   def get_project_wiki_path(project)
     external_wiki_service = project.external_wiki
diff --git a/app/helpers/favicon_helper.rb b/app/helpers/favicon_helper.rb
index 3a5342a8d9d4cb388c889c11f3501f13dba36cac..4a809731d97fa19753c4befddc22129902fb9bbf 100644
--- a/app/helpers/favicon_helper.rb
+++ b/app/helpers/favicon_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module FaviconHelper
   def favicon_extension_whitelist
     FaviconUploader::EXTENSION_WHITELIST
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
index 556558c6d798af9e2b44f4aaec494a06655009f1..917f3b786cd70527a8213abe6f82326c20a824bd 100644
--- a/app/helpers/form_helper.rb
+++ b/app/helpers/form_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module FormHelper
   prepend ::EE::FormHelper
 
diff --git a/app/helpers/git_helper.rb b/app/helpers/git_helper.rb
index 8ab394384f30081ee9830a3e84cbc65e6144455e..5edc6dcf454c619ae4d7dc2f20bec99b00527452 100644
--- a/app/helpers/git_helper.rb
+++ b/app/helpers/git_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module GitHelper
   def strip_gpg_signature(text)
     text.gsub(/-----BEGIN PGP SIGNATURE-----(.*)-----END PGP SIGNATURE-----/m, "")
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index 060c1f4af3324540559d7c7a3f9fb1434c3902fc..3daf549d8b095532971d1717e196e7f8701213f7 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 # Shorter routing method for some project items
 module GitlabRoutingHelper
   include EE::GitlabRoutingHelper
diff --git a/app/helpers/graph_helper.rb b/app/helpers/graph_helper.rb
index 1022070ab6f975393b1608187bcf91ddc94a880a..49b15cde0099e1648526ec2636feed0f8f047e83 100644
--- a/app/helpers/graph_helper.rb
+++ b/app/helpers/graph_helper.rb
@@ -1,12 +1,14 @@
+# frozen_string_literal: true
+
 module GraphHelper
   def refs(repo, commit)
-    refs = commit.ref_names(repo).join(' ')
+    refs = [commit.ref_names(repo).join(' ')]
 
     # append note count
     notes_count = @graph.notes[commit.id]
     refs << "[#{pluralize(notes_count, 'note')}]" if notes_count > 0
 
-    refs
+    refs.join
   end
 
   def parents_zip_spaces(parents, parent_spaces)
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index e17b2f4b93548f426b9ea3101f8e7ae9804befc3..0e3894f7733370bdbf75751fa0706f341dcc0849 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module GroupsHelper
   prepend EE::GroupsHelper
 
@@ -45,22 +47,22 @@ def group_icon_url(group, options = {})
 
   def group_title(group, name = nil, url = nil)
     @has_group_title = true
-    full_title = ''
+    full_title = []
 
     group.ancestors.reverse.each_with_index do |parent, index|
       if index > 0
         add_to_breadcrumb_dropdown(group_title_link(parent, hidable: false, show_avatar: true, for_dropdown: true), location: :before)
       else
-        full_title += breadcrumb_list_item group_title_link(parent, hidable: false)
+        full_title << breadcrumb_list_item(group_title_link(parent, hidable: false))
       end
     end
 
-    full_title += render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :before, title: _("Show parent subgroups")
+    full_title << render("layouts/nav/breadcrumbs/collapsed_dropdown", location: :before, title: _("Show parent subgroups"))
 
-    full_title += breadcrumb_list_item group_title_link(group)
-    full_title += ' &middot; '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path breadcrumb-item-text js-breadcrumb-item-text') if name
+    full_title << breadcrumb_list_item(group_title_link(group))
+    full_title << ' &middot; '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path breadcrumb-item-text js-breadcrumb-item-text') if name
 
-    full_title.html_safe
+    full_title.join.html_safe
   end
 
   def projects_lfs_status(group)
@@ -140,15 +142,8 @@ def get_group_sidebar_links
 
   def group_title_link(group, hidable: false, show_avatar: false, for_dropdown: false)
     link_to(group_path(group), class: "group-path #{'breadcrumb-item-text' unless for_dropdown} js-breadcrumb-item-text #{'hidable' if hidable}") do
-      output =
-        if (group.try(:avatar_url) || show_avatar) && !Rails.env.test?
-          group_icon(group, class: "avatar-tile", width: 15, height: 15)
-        else
-          ""
-        end
-
-      output << simple_sanitize(group.name)
-      output.html_safe
+      icon = group_icon(group, class: "avatar-tile", width: 15, height: 15) if (group.try(:avatar_url) || show_avatar) && !Rails.env.test?
+      [icon, simple_sanitize(group.name)].join.html_safe
     end
   end
 
diff --git a/app/helpers/hooks_helper.rb b/app/helpers/hooks_helper.rb
index 0a356ba55d2f29687d669a10bd4af427bda87ad5..c4b399391922205c9e6e338637ff6ea479a9272a 100644
--- a/app/helpers/hooks_helper.rb
+++ b/app/helpers/hooks_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module HooksHelper
   def link_to_test_hook(hook, trigger)
     path = case hook
diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb
index a5612372aa6338b4bc1649b1c23156feabe138b2..037004327b9e10b4ef45cc5695f698fe6e0aba3b 100644
--- a/app/helpers/icons_helper.rb
+++ b/app/helpers/icons_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'json'
 
 module IconsHelper
@@ -47,9 +49,10 @@ def sprite_icon(icon_name, size: nil, css_class: nil)
       end
     end
 
-    css_classes = size ? "s#{size}" : ""
-    css_classes << " #{css_class}" unless css_class.blank?
-    content_tag(:svg, content_tag(:use, "", { "xlink:href" => "#{sprite_icon_path}##{icon_name}" } ), class: css_classes.empty? ? nil : css_classes)
+    css_classes = []
+    css_classes << "s#{size}" if size
+    css_classes << "#{css_class}" unless css_class.blank?
+    content_tag(:svg, content_tag(:use, "", { "xlink:href" => "#{sprite_icon_path}##{icon_name}" } ), class: css_classes.empty? ? nil : css_classes.join(' '))
   end
 
   def external_snippet_icon(name)
@@ -70,10 +73,10 @@ def audit_icon(names, options = {})
   end
 
   def spinner(text = nil, visible = false)
-    css_class = 'loading'
-    css_class << ' hide' unless visible
+    css_class = ['loading']
+    css_class << 'hide' unless visible
 
-    content_tag :div, class: css_class do
+    content_tag :div, class: css_class.join(' ') do
       icon('spinner spin') + text
     end
   end
@@ -97,9 +100,10 @@ def visibility_level_icon(level, fw: true, options: {})
         'globe'
       end
 
-    name << " fw" if fw
+    name = [name]
+    name << "fw" if fw
 
-    icon(name, options)
+    icon(name.join(' '), options)
   end
 
   def file_type_icon_class(type, mode, name)
diff --git a/app/helpers/import_helper.rb b/app/helpers/import_helper.rb
index c65f1565425a4a0ad03cf7271f79c8edab1978df..3d0eb3d0d51d1a96d1a62ea83c9de1f129aec59b 100644
--- a/app/helpers/import_helper.rb
+++ b/app/helpers/import_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ImportHelper
   include ::Gitlab::Utils::StrongMemoize
 
diff --git a/app/helpers/instance_configuration_helper.rb b/app/helpers/instance_configuration_helper.rb
index cee319f20bc2501443984e56bd0d174ac65c3013..f695be327437ffe21a68ed35d5e44ac4b9f85043 100644
--- a/app/helpers/instance_configuration_helper.rb
+++ b/app/helpers/instance_configuration_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module InstanceConfigurationHelper
   def instance_configuration_cell_html(value, &block)
     return '-' unless value.to_s.presence
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 3dc6311026327e5ce3f2e412efc1113c9fe93075..85b888f532374b05d6be8dad3c3937d73efa6319 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module IssuablesHelper
   prepend EE::IssuablesHelper
 
@@ -169,8 +171,9 @@ def to_url_reference(issuable)
   end
 
   def issuable_meta(issuable, project, text)
-    output = ""
+    output = []
     output << "Opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe
+
     output << content_tag(:strong) do
       author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "d-none d-sm-inline", tooltip: true)
       author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "d-block d-sm-none")
@@ -188,7 +191,7 @@ def issuable_meta(issuable, project, text)
     output << content_tag(:span, (issuable.task_status if issuable.tasks?), id: "task_status", class: "d-none d-sm-none d-md-inline-block")
     output << content_tag(:span, (issuable.task_status_short if issuable.tasks?), id: "task_status_short", class: "d-md-none")
 
-    output.html_safe
+    output.join.html_safe
   end
 
   def issuable_todo(issuable)
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 0998fbf4deb11f433118f80a8dc2d502d5a0e1e3..ae896b45db1597677212ccc9ce01055b0ed96139 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -1,11 +1,13 @@
+# frozen_string_literal: true
+
 module IssuesHelper
   include EE::IssuesHelper
 
   def issue_css_classes(issue)
-    classes = "issue"
-    classes << " closed" if issue.closed?
-    classes << " today" if issue.today?
-    classes
+    classes = ["issue"]
+    classes << "closed" if issue.closed?
+    classes << "today" if issue.today?
+    classes.join(' ')
   end
 
   # Returns an OpenStruct object suitable for use by <tt>options_from_collection_for_select</tt>
@@ -107,8 +109,8 @@ def awards_sort(awards)
   end
 
   def link_to_discussions_to_resolve(merge_request, single_discussion = nil)
-    link_text = merge_request.to_reference
-    link_text += " (discussion #{single_discussion.first_note.id})" if single_discussion
+    link_text = [merge_request.to_reference]
+    link_text << "(discussion #{single_discussion.first_note.id})" if single_discussion
 
     path = if single_discussion
              Gitlab::UrlBuilder.build(single_discussion.first_note)
@@ -117,7 +119,7 @@ def link_to_discussions_to_resolve(merge_request, single_discussion = nil)
              project_merge_request_path(project, merge_request)
            end
 
-    link_to link_text, path
+    link_to link_text.join(' '), path
   end
 
   def show_new_issue_link?(project)
diff --git a/app/helpers/javascript_helper.rb b/app/helpers/javascript_helper.rb
index cd4075b340d77756071ba2a6d873a2dad84eea6e..7cb6da262365874b7d8ba9b736fa24e04878876a 100644
--- a/app/helpers/javascript_helper.rb
+++ b/app/helpers/javascript_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module JavascriptHelper
   def page_specific_javascript_tag(js)
     javascript_include_tag asset_path(js)
diff --git a/app/helpers/kerberos_spnego_helper.rb b/app/helpers/kerberos_spnego_helper.rb
index dbbc740a2c14f240d552abe96d832c819084ffc1..670d6b257187ca0a3791c30067df9b84df361d84 100644
--- a/app/helpers/kerberos_spnego_helper.rb
+++ b/app/helpers/kerberos_spnego_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module KerberosSpnegoHelper
   include ActionController::HttpAuthentication::Basic
 
diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb
index c7df25cecefe01b323366ec91c5537d947d5c1d4..6c51739ba1a548e7d2c264ddf6a7216ec0f871bd 100644
--- a/app/helpers/labels_helper.rb
+++ b/app/helpers/labels_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module LabelsHelper
   extend self
   include ActionView::Helpers::TagHelper
diff --git a/app/helpers/lazy_image_tag_helper.rb b/app/helpers/lazy_image_tag_helper.rb
index 603b9438e35ce1ac80d1ddc5ef0361f4f239bffa..ac987a04895f428c9911fdc2260c16036de42b50 100644
--- a/app/helpers/lazy_image_tag_helper.rb
+++ b/app/helpers/lazy_image_tag_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module LazyImageTagHelper
   def placeholder_image
     "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
@@ -11,9 +13,11 @@ def image_tag(source, options = {})
       options[:data] ||= {}
       options[:data][:src] = path_to_image(source)
 
-      options[:class] ||= ""
-      options[:class] << " lazy"
+      # options[:class] can be either String or Array.
+      klass_opts = Array.wrap(options[:class])
+      klass_opts << "lazy"
 
+      options[:class] = klass_opts.join(' ')
       source = placeholder_image
     end
 
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index 3adaa1366c079183b9531cd8bac41255f875563e..f2cd676bb1b8b701d464c0ecea3b2afd368402a4 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'nokogiri'
 
 module MarkupHelper
diff --git a/app/helpers/mattermost_helper.rb b/app/helpers/mattermost_helper.rb
index 27ff4051c8d2025f77f779b27533bd19d0e807d5..b211fe5076adbabad582fa55f139ff713855be24 100644
--- a/app/helpers/mattermost_helper.rb
+++ b/app/helpers/mattermost_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module MattermostHelper
   def mattermost_teams_options(teams)
     teams.map do |team|
diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb
index a3129cac2b169c10442139dbf60aa7e733a25b60..5a21403bc5ef2f987d5eafd7c724a4aecc1890d3 100644
--- a/app/helpers/members_helper.rb
+++ b/app/helpers/members_helper.rb
@@ -1,8 +1,10 @@
+# frozen_string_literal: true
+
 module MembersHelper
   def remove_member_message(member, user: nil)
     user = current_user if defined?(current_user)
+    text = 'Are you sure you want to'
 
-    text = 'Are you sure you want to '
     action =
       if member.request?
         if member.user == user
@@ -16,13 +18,12 @@ def remove_member_message(member, user: nil)
         "remove #{member.user.name} from"
       end
 
-    text << action << " the #{member.source.human_name} #{member.real_source_type.humanize(capitalize: false)}?"
+    "#{text} #{action} the #{member.source.human_name} #{member.real_source_type.humanize(capitalize: false)}?"
   end
 
   def remove_member_title(member)
-    text = " from #{member.real_source_type.humanize(capitalize: false)}"
-
-    text.prepend(member.request? ? 'Deny access request' : 'Remove user')
+    action = member.request? ? 'Deny access request' : 'Remove user'
+    "#{action} from #{member.real_source_type.humanize(capitalize: false)}"
   end
 
   def leave_confirmation_message(member_source)
@@ -32,9 +33,6 @@ def leave_confirmation_message(member_source)
 
   def filter_group_project_member_path(options = {})
     options = params.slice(:search, :sort).merge(options)
-
-    path = request.path
-    path << "?#{options.to_param}"
-    path
+    "#{request.path}?#{options.to_param}"
   end
 end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 399c8d9521bec8e0d24a3d1d3ca6cb59fcea4692..f984aed9803f3a286c95cb5dca893d627e4a9d5f 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module MergeRequestsHelper
   prepend EE::MergeRequestsHelper
 
@@ -21,10 +23,10 @@ def new_mr_from_push_event(event, target_project)
   end
 
   def mr_css_classes(mr)
-    classes = "merge-request"
-    classes << " closed" if mr.closed?
-    classes << " merged" if mr.merged?
-    classes
+    classes = ["merge-request"]
+    classes << "closed" if mr.closed?
+    classes << "merged" if mr.merged?
+    classes.join(' ')
   end
 
   def ci_build_details_path(merge_request)
diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb
index 37f05e64c67aa59b3d0fbe13f61e67a076d90d9b..8c431042b146a914f1c4fe9cc8d8e09273809c76 100644
--- a/app/helpers/milestones_helper.rb
+++ b/app/helpers/milestones_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module MilestonesHelper
   prepend EE::MilestonesHelper
   include EntityDateHelper
@@ -120,20 +122,18 @@ def milestone_time_for(date, date_type)
     title = date_type == :start ? "Start date" : "End date"
 
     if date
-      time_ago = time_ago_in_words(date)
-      time_ago.slice!("about ")
-
-      time_ago << if date.past?
-                    " ago"
-                  else
-                    " remaining"
-                  end
+      time_ago = time_ago_in_words(date).sub("about ", "")
+      state = if date.past?
+                "ago"
+              else
+                "remaining"
+              end
 
       content = [
         title,
         "<br />",
         date.to_s(:medium),
-        "(#{time_ago})"
+        "(#{time_ago} #{state})"
       ].join(" ")
 
       content.html_safe
diff --git a/app/helpers/milestones_routing_helper.rb b/app/helpers/milestones_routing_helper.rb
index a0b2616f22422d2f99baa09d4c0f4cc9c3e58564..a49b561533a63dc5fc3c5348902de2d5568ddc05 100644
--- a/app/helpers/milestones_routing_helper.rb
+++ b/app/helpers/milestones_routing_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module MilestonesRoutingHelper
   def milestone_path(milestone, *args)
     if milestone.group_milestone?
diff --git a/app/helpers/mirror_helper.rb b/app/helpers/mirror_helper.rb
index 93ed22513acbd8aa4d8388b949993101f5f6b865..a4025730397daa3be378b68069e5ce91eb0b7988 100644
--- a/app/helpers/mirror_helper.rb
+++ b/app/helpers/mirror_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module MirrorHelper
   def mirrors_form_data_attributes
     { project_mirror_endpoint: project_mirror_path(@project) }
diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb
index f1789c8896a0e2302d57d6b1e47b36187f27d7bf..6dfa23218d60dbc7fdd24f806a724e1438ddb11a 100644
--- a/app/helpers/namespaces_helper.rb
+++ b/app/helpers/namespaces_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module NamespacesHelper
   include EE::NamespacesHelper
 
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index 546753ecc8feef4e20177f9457339e10d6ac51a6..3403fdb646392d0049e54734c7ae37bbd353182f 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module NavHelper
   def header_links
     @header_links ||= get_header_links
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 69976ae345c3975041710ff9539e01dcb60a13d2..11b2b9aa312aa99284303a2a7974cf08e8855e1e 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module NotesHelper
   prepend EE::NotesHelper
 
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
index a185f2916d40d1d1882e133903ab257ebde5beba..5318ab4ddef8be91835c9b830104316915afd5d5 100644
--- a/app/helpers/notifications_helper.rb
+++ b/app/helpers/notifications_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module NotificationsHelper
   include IconsHelper
 
diff --git a/app/helpers/numbers_helper.rb b/app/helpers/numbers_helper.rb
index 45bd36060767fb4f7627105b8ef51a313dbdcc5a..f609b6c0cec929e5248c9befdb0c9dfb52341047 100644
--- a/app/helpers/numbers_helper.rb
+++ b/app/helpers/numbers_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module NumbersHelper
   def limited_counter_with_delimiter(resource, **options)
     limit = options.fetch(:limit, 1000).to_i
diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb
index 68d892393ef13ec6cb352f2a07a6e9a440f13253..b33c074d1afec07702746caf21c2f113cf03aa45 100644
--- a/app/helpers/page_layout_helper.rb
+++ b/app/helpers/page_layout_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module PageLayoutHelper
   def page_title(*titles)
     @page_title ||= []
@@ -65,14 +67,14 @@ def page_card_attributes(map = {})
   end
 
   def page_card_meta_tags
-    tags = ''
+    tags = []
 
     page_card_attributes.each_with_index do |pair, i|
       tags << tag(:meta, property: "twitter:label#{i + 1}", content: pair[0])
       tags << tag(:meta, property: "twitter:data#{i + 1}",  content: pair[1])
     end
 
-    tags.html_safe
+    tags.join.html_safe
   end
 
   def header_title(title = nil, title_url = nil)
@@ -115,16 +117,16 @@ def blank_container(enabled = false)
   end
 
   def container_class
-    css_class = "container-fluid"
+    css_class = ["container-fluid"]
 
     unless fluid_layout
-      css_class += " container-limited"
+      css_class << "container-limited"
     end
 
     if blank_container
-      css_class += " container-blank"
+      css_class << "container-blank"
     end
 
-    css_class
+    css_class.join(' ')
   end
 end
diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb
index 83dd76a01dd30322eaf112a6e67130b4c84b9489..d05153c9d4b8ad3a490dd2b32ec15294b35200ba 100644
--- a/app/helpers/pagination_helper.rb
+++ b/app/helpers/pagination_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module PaginationHelper
   def paginate_collection(collection, remote: nil)
     if collection.is_a?(Kaminari::PaginatableWithoutCount)
diff --git a/app/helpers/performance_bar_helper.rb b/app/helpers/performance_bar_helper.rb
index d24efe37f5f53efa51b179ac7f3684ec93bf0f21..7518cec160c0dd38f3e9aa60556acb7dfa219dcc 100644
--- a/app/helpers/performance_bar_helper.rb
+++ b/app/helpers/performance_bar_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module PerformanceBarHelper
   # This is a hack since using `alias_method :performance_bar_enabled?, :peek_enabled?`
   # in WithPerformanceBar breaks tests (but works in the browser).
diff --git a/app/helpers/pipeline_schedules_helper.rb b/app/helpers/pipeline_schedules_helper.rb
index 4b9f6bd2cafc619ae3d38e601e664f31e48ace5d..0e166106b324cdd2bbf936f8069237e8ace6fce9 100644
--- a/app/helpers/pipeline_schedules_helper.rb
+++ b/app/helpers/pipeline_schedules_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module PipelineSchedulesHelper
   def timezone_data
     ActiveSupport::TimeZone.all.map do |timezone|
diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb
index fb523cb865b960162ccd0f14f158b65e3eb5db77..ff9842d4cd9afc1ad1efda8bace490ad37e8a598 100644
--- a/app/helpers/preferences_helper.rb
+++ b/app/helpers/preferences_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 # Helper methods for per-User preferences
 module PreferencesHelper
   def layout_choices
diff --git a/app/helpers/profiles_helper.rb b/app/helpers/profiles_helper.rb
index e7aa92e6e5c66276d70778eafc5c693d4da1a27f..55674e37a34e8b5b91545677e348ccff30b54c04 100644
--- a/app/helpers/profiles_helper.rb
+++ b/app/helpers/profiles_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ProfilesHelper
   def attribute_provider_label(attribute)
     user_synced_attributes_metadata = current_user.user_synced_attributes_metadata
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index a01dc3113f93bcfe7eef29e8c0e6003bcebd1085..d6a9e8722ba78c80b4a66b4cd0e0d53f7835386a 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ProjectsHelper
   prepend ::EE::ProjectsHelper
 
@@ -52,7 +54,7 @@ def link_to_member(project, author, opts = {}, &block)
 
     return "(deleted)" unless author
 
-    author_html = ""
+    author_html = []
 
     # Build avatar image tag
     author_html << link_to_member_avatar(author, opts) if opts[:avatar]
@@ -62,7 +64,7 @@ def link_to_member(project, author, opts = {}, &block)
 
     author_html << capture(&block) if block
 
-    author_html = author_html.html_safe
+    author_html = author_html.join.html_safe
 
     if opts[:name]
       link_to(author_html, user_path(author), class: "author-link #{"#{opts[:extra_class]}" if opts[:extra_class]} #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}").html_safe
@@ -82,15 +84,8 @@ def project_title(project)
       end
 
     project_link = link_to project_path(project) do
-      output =
-        if project.avatar_url && !Rails.env.test?
-          project_icon(project, alt: project.name, class: 'avatar-tile', width: 15, height: 15)
-        else
-          ""
-        end
-
-      output << content_tag("span", simple_sanitize(project.name), class: "breadcrumb-item-text js-breadcrumb-item-text")
-      output.html_safe
+      icon = project_icon(project, alt: project.name, class: 'avatar-tile', width: 15, height: 15) if project.avatar_url && !Rails.env.test?
+      [icon, content_tag("span", simple_sanitize(project.name), class: "breadcrumb-item-text js-breadcrumb-item-text")].join.html_safe
     end
 
     namespace_link = breadcrumb_list_item(namespace_link) unless project.group
diff --git a/app/helpers/repository_languages_helper.rb b/app/helpers/repository_languages_helper.rb
index 9a842cf5ce01d173bd1cea8198ca067b22fdb0eb..c1505b528083f37a17cbc04e2ffaeb3ecff9f0d6 100644
--- a/app/helpers/repository_languages_helper.rb
+++ b/app/helpers/repository_languages_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module RepositoryLanguagesHelper
   def repository_languages_bar(languages)
     return if languages.none?
diff --git a/app/helpers/rss_helper.rb b/app/helpers/rss_helper.rb
index 7d4fa83a67a3619fa6e2bd7d7d86b0acd83a1993..67c7d244f11b5e4c249f15a3a83f040ddbda3647 100644
--- a/app/helpers/rss_helper.rb
+++ b/app/helpers/rss_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module RssHelper
   def rss_url_options
     { format: :atom, feed_token: current_user.try(:feed_token) }
diff --git a/app/helpers/runners_helper.rb b/app/helpers/runners_helper.rb
index 9fb42487a75e6a2ddcc7d44c04ce29d14f00bf0c..cb21f9224015046e060f2267a2a349fdae0dd087 100644
--- a/app/helpers/runners_helper.rb
+++ b/app/helpers/runners_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module RunnersHelper
   def runner_status_icon(runner)
     status = runner.status
diff --git a/app/helpers/safe_params_helper.rb b/app/helpers/safe_params_helper.rb
index b568e8810cce6973be7c5c6ecebc272b484bfbf8..72bf1377b024568d8e85a86127bd2f61dcd93af7 100644
--- a/app/helpers/safe_params_helper.rb
+++ b/app/helpers/safe_params_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module SafeParamsHelper
   # Rails 5.0 requires to permit `params` if they're used in url helpers.
   # Use this helper when generating links with `params.merge(...)`
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index e11f2681b2b9169e125725542aadfef0bcbded19..1ed80773439c24c3c771f55b8d40e5a2f269a35c 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module SearchHelper
   prepend EE::SearchHelper
 
diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb
index a265da32ffa621e860dd1555f14d1a3cd8e0d9a7..afe26a5cd97794db2c2c89a7e19dbb648b667e88 100644
--- a/app/helpers/selects_helper.rb
+++ b/app/helpers/selects_helper.rb
@@ -1,12 +1,14 @@
+# frozen_string_literal: true
+
 module SelectsHelper
   def users_select_tag(id, opts = {})
-    css_class = "ajax-users-select "
-    css_class << "multiselect " if opts[:multiple]
-    css_class << "skip_ldap " if opts[:skip_ldap]
+    css_class = ["ajax-users-select"]
+    css_class << "multiselect" if opts[:multiple]
+    css_class << "skip_ldap" if opts[:skip_ldap]
     css_class << (opts[:class] || '')
     value = opts[:selected] || ''
     html = {
-      class: css_class,
+      class: css_class.join(' '),
       data: users_select_data_attributes(opts)
     }
 
@@ -32,21 +34,22 @@ def ldap_server_select_options
   end
 
   def groups_select_tag(id, opts = {})
-    opts[:class] ||= ''
-    opts[:class] << ' ajax-groups-select'
-    opts[:class] << ' multiselect' if opts[:multiple]
+    classes = Array.wrap(opts[:class])
+    classes << 'ajax-groups-select'
+    classes << 'multiselect' if opts[:multiple]
+
+    opts[:class] = classes.join(' ')
+
     select2_tag(id, opts)
   end
 
   def namespace_select_tag(id, opts = {})
-    opts[:class] ||= ''
-    opts[:class] << ' ajax-namespace-select'
+    opts[:class] = [*opts[:class], 'ajax-namespace-select'].join(' ')
     select2_tag(id, opts)
   end
 
   def project_select_tag(id, opts = {})
-    opts[:class] ||= ''
-    opts[:class] << ' ajax-project-select'
+    opts[:class] = [*opts[:class], 'ajax-project-select'].join(' ')
 
     unless opts.delete(:scope) == :all
       if @group
@@ -66,18 +69,21 @@ def project_select_tag(id, opts = {})
   end
 
   def select2_tag(id, opts = {})
-    opts[:class] << ' multiselect' if opts[:multiple]
+    klass_opts = [opts[:class]]
+    klass_opts << 'multiselect' if opts[:multiple]
+
+    opts[:class] = klass_opts.join(' ')
     value = opts[:selected] || ''
     hidden_field_tag(id, value, opts)
   end
 
   def admin_email_select_tag(id, opts = {})
-    css_class = "ajax-admin-email-select "
-    css_class << "multiselect " if opts[:multiple]
-    css_class << (opts[:class] || '')
+    css_class = ["ajax-admin-email-select"]
+    css_class << "multiselect" if opts[:multiple]
+    css_class << opts[:class] if opts[:class]
     value = opts[:selected] || ''
 
-    hidden_field_tag(id, value, class: css_class)
+    hidden_field_tag(id, value, class: css_class.join(' '))
   end
 
   private
diff --git a/app/helpers/sentry_helper.rb b/app/helpers/sentry_helper.rb
index 3d255df66a0c39214ea4ea9d2b66e5d36b6a44ed..d53eaef99526cc88438c3876e4489341c908fc65 100644
--- a/app/helpers/sentry_helper.rb
+++ b/app/helpers/sentry_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module SentryHelper
   def sentry_enabled?
     Gitlab::Sentry.enabled?
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
index d8c7c17d3bbafeb200284193f40ae00c2d421abb..979c2bb4f7d61a141a7f9be785c98036729b19d1 100644
--- a/app/helpers/services_helper.rb
+++ b/app/helpers/services_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module ServicesHelper
   prepend EE::ServicesHelper
 
diff --git a/app/helpers/sidekiq_helper.rb b/app/helpers/sidekiq_helper.rb
index 50aeb7f4b825f9c71b278d6641bebbb9d954a078..32bf35265718781d26fa805ea86177e68eb0cd20 100644
--- a/app/helpers/sidekiq_helper.rb
+++ b/app/helpers/sidekiq_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module SidekiqHelper
   SIDEKIQ_PS_REGEXP = %r{\A
     (?<pid>\d+)\s+
diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb
index a05640773ad9981392c18ecdcb78e9d3432a3493..c7d31f3469d46315c3ff41d3de39228fb8cd5717 100644
--- a/app/helpers/snippets_helper.rb
+++ b/app/helpers/snippets_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module SnippetsHelper
   def reliable_snippet_path(snippet, opts = nil)
     if snippet.project_id?
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 96620ca812255124d59968d900460f7dbf9956cd..5f92070180d79df2da74d6d731d619131ec38a1f 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module SortingHelper
   prepend ::EE::SortingHelper
 
diff --git a/app/helpers/storage_health_helper.rb b/app/helpers/storage_health_helper.rb
index b76c122822087162748a91f8c0dd6e20427eafee..182e8e6641b649277c9a61ac56ea2db9c47970cc 100644
--- a/app/helpers/storage_health_helper.rb
+++ b/app/helpers/storage_health_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module StorageHealthHelper
   def failing_storage_health_message(storage_health)
     storage_name = content_tag(:strong, h(storage_health.storage_name))
diff --git a/app/helpers/storage_helper.rb b/app/helpers/storage_helper.rb
index e19c67a37ca0c46c38b076b2a05d1d648cdca618..be8761db5621e81558381a88a52bb4c2f3eee8d9 100644
--- a/app/helpers/storage_helper.rb
+++ b/app/helpers/storage_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module StorageHelper
   def storage_counter(size_in_bytes)
     precision = size_in_bytes < 1.megabyte ? 0 : 1
diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb
index ec2cf2b16c037398391bd839fc88f59cf3401549..164c69ca50bf56653774491a7ab94fca70529847 100644
--- a/app/helpers/submodule_helper.rb
+++ b/app/helpers/submodule_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module SubmoduleHelper
   extend self
 
diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb
index 05dffd639d142502ef5c90e845c0b9c20c8bcb62..08d94ff6d651bf20dbd7652aa522fceef31a32ed 100644
--- a/app/helpers/system_note_helper.rb
+++ b/app/helpers/system_note_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module SystemNoteHelper
   prepend EE::SystemNoteHelper
 
diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb
index 6e89f114c637aea7f33ee99f3a44d4a9ee9410ac..fb440c08bae66e0c69a1f42d6f89f5cc6e87e1b9 100644
--- a/app/helpers/tab_helper.rb
+++ b/app/helpers/tab_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module TabHelper
   # Navigation link helper
   #
@@ -47,9 +49,7 @@ def nav_link(options = {}, &block)
     # Add our custom class into the html_options, which may or may not exist
     # and which may or may not already have a :class key
     o = options.delete(:html_options) || {}
-    o[:class] ||= ''
-    o[:class] += ' ' + klass
-    o[:class].strip!
+    o[:class] = [*o[:class], klass].join(' ').strip
 
     if block_given?
       content_tag(:li, capture(&block), o)
diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb
index d000d6b1c0affe3073dd7055e028fadbc6d11c81..de0b92b6fd71c9bac34129267eb1fb861d39d527 100644
--- a/app/helpers/tags_helper.rb
+++ b/app/helpers/tags_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module TagsHelper
   def tag_path(tag)
     "/tags/#{tag}"
@@ -14,12 +16,13 @@ def filter_tags_path(options = {})
   end
 
   def tag_list(project)
-    html = ''
+    html = []
+
     project.tag_list.each do |tag|
       html << link_to(tag, tag_path(tag))
     end
 
-    html.html_safe
+    html.join.html_safe
   end
 
   def protected_tag?(project, tag)
diff --git a/app/helpers/time_helper.rb b/app/helpers/time_helper.rb
index 336385f679892ecb4e5e97d7a6de60c214f3aacb..94044d7b85ec0fbb74ef0990e5c4030d629d9304 100644
--- a/app/helpers/time_helper.rb
+++ b/app/helpers/time_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module TimeHelper
   def time_interval_in_words(interval_in_seconds)
     interval_in_seconds = interval_in_seconds.to_i
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 558e4456135d5a2303d0f57a0941a0d63a0fb8b8..54e9fdec96d132d09e7bd657d115a179c07a9b60 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module TodosHelper
   prepend EE::NotesHelper
 
@@ -96,9 +98,7 @@ def todos_filter_path(options = {})
       end
     end
 
-    path = request.path
-    path << "?#{options.to_param}"
-    path
+    "#{request.path}?#{options.to_param}"
   end
 
   def todo_actions_options
@@ -154,10 +154,11 @@ def todo_due_date(todo)
         ''
       end
 
-    html = "&middot; ".html_safe
-    html << content_tag(:span, class: css_class) do
+    content = content_tag(:span, class: css_class) do
       "Due #{is_due_today ? "today" : todo.target.due_date.to_s(:medium)}"
     end
+
+    "&middot; #{content}".html_safe
   end
 
   private
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index dc42caa70e5500695f213401eef008631e4a5c30..80f61a371fd35feaf6f81e5798d94035b7478f68 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module TreeHelper
   FILE_LIMIT = 1_000
 
@@ -8,7 +10,7 @@ module TreeHelper
   def render_tree(tree)
     # Sort submodules and folders together by name ahead of files
     folders, files, submodules = tree.trees, tree.blobs, tree.submodules
-    tree = ''
+    tree = []
     items = (folders + submodules).sort_by(&:name) + files
 
     if items.size > FILE_LIMIT
@@ -18,7 +20,7 @@ def render_tree(tree)
     end
 
     tree << render(partial: 'projects/tree/tree_row', collection: items) if items.present?
-    tree.html_safe
+    tree.join.html_safe
   end
 
   # Return an image icon depending on the file type and mode
diff --git a/app/helpers/triggers_helper.rb b/app/helpers/triggers_helper.rb
index ce435ca22413e492924e2d47ada45bd816cee74f..5cfdc0971f0d9a8067417df008dac0657e5a041a 100644
--- a/app/helpers/triggers_helper.rb
+++ b/app/helpers/triggers_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module TriggersHelper
   def builds_trigger_url(project_id, ref: nil)
     if ref.nil?
diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb
index 657a3227dd4b3d7baedcf354c2ccffb89fb626b0..bae01d476df25d2237d947ed7a8a1a2ec3724d0f 100644
--- a/app/helpers/user_callouts_helper.rb
+++ b/app/helpers/user_callouts_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module UserCalloutsHelper
   GKE_CLUSTER_INTEGRATION = 'gke_cluster_integration'.freeze
   GCP_SIGNUP_OFFER = 'gcp_signup_offer'.freeze
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index 2c0c4254a0c31af2ef2159305b842546bdec9889..bcd91f619c8a1a67267ccefbeed351fd833bbe5b 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module UsersHelper
   def user_link(user)
     link_to(user.name, user_path(user),
diff --git a/app/helpers/version_check_helper.rb b/app/helpers/version_check_helper.rb
index c20753ece7228b64778a7ed26a89e3a6f49d7819..fd00339623058a93a0250369ca7b3afc13cc1359 100644
--- a/app/helpers/version_check_helper.rb
+++ b/app/helpers/version_check_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module VersionCheckHelper
   def version_status_badge
     if Rails.env.production? && Gitlab::CurrentSettings.version_check_enabled
diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb
index 7b64869c9ea40a83b0df84ee7470ae7aded817c3..e690350a0d1f15311ac51719fd93c4c85d8d056e 100644
--- a/app/helpers/visibility_level_helper.rb
+++ b/app/helpers/visibility_level_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module VisibilityLevelHelper
   def visibility_level_color(level)
     case level
@@ -82,7 +84,7 @@ def disallowed_visibility_level_description(level, form_model)
   def disallowed_project_visibility_level_description(level, project)
     level_name = Gitlab::VisibilityLevel.level_name(level).downcase
     reasons = []
-    instructions = ''
+    instructions = []
 
     unless project.visibility_level_allowed_as_fork?(level)
       reasons << "the fork source project has lower visibility"
@@ -96,7 +98,7 @@ def disallowed_project_visibility_level_description(level, project)
     end
 
     reasons = reasons.any? ? ' because ' + reasons.to_sentence : ''
-    "This project cannot be #{level_name}#{reasons}.#{instructions}".html_safe
+    "This project cannot be #{level_name}#{reasons}.#{instructions.join}".html_safe
   end
 
   # Note: these messages closely mirror the form validation strings found in the group
@@ -104,7 +106,7 @@ def disallowed_project_visibility_level_description(level, project)
   def disallowed_group_visibility_level_description(level, group)
     level_name = Gitlab::VisibilityLevel.level_name(level).downcase
     reasons = []
-    instructions = ''
+    instructions = []
 
     unless group.visibility_level_allowed_by_projects?(level)
       reasons << "it contains projects with higher visibility"
@@ -122,7 +124,7 @@ def disallowed_group_visibility_level_description(level, group)
     end
 
     reasons = reasons.any? ? ' because ' + reasons.to_sentence : ''
-    "This group cannot be #{level_name}#{reasons}.#{instructions}".html_safe
+    "This group cannot be #{level_name}#{reasons}.#{instructions.join}".html_safe
   end
 
   def visibility_icon_description(form_model)
diff --git a/app/helpers/webpack_helper.rb b/app/helpers/webpack_helper.rb
index 72f6b3970469fd0bd1083db370aa8930dfe0c555..345ddcf023a4b7db2d7e2f45c75c6ff3bd251124 100644
--- a/app/helpers/webpack_helper.rb
+++ b/app/helpers/webpack_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module WebpackHelper
   def webpack_bundle_tag(bundle)
     javascript_include_tag(*webpack_entrypoint_paths(bundle))
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index 17940aeb900066bcb294c83d54d1b6be08193b0a..647f34e57ed34983480052d0fb7d607726f5a73a 100644
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module WikiHelper
   include API::Helpers::RelatedResourcesHelpers
 
diff --git a/app/helpers/workhorse_helper.rb b/app/helpers/workhorse_helper.rb
index fd1d78bd9b800a1a335f65564e746c8bd8bd6433..f19445fca1a95a0dffef83dec149042af9ed669f 100644
--- a/app/helpers/workhorse_helper.rb
+++ b/app/helpers/workhorse_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 # Helpers to send Git blobs, diffs, patches or archives through Workhorse.
 # Workhorse will also serve files when using `send_file`.
 module WorkhorseHelper
diff --git a/app/models/license_template.rb b/app/models/license_template.rb
index 0ad75b27827d635dfbd2e54cf800a27fab159b72..693a6a89fd2f9d6e1a8495d213f0d96b4ee3a496 100644
--- a/app/models/license_template.rb
+++ b/app/models/license_template.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class LicenseTemplate
   PROJECT_TEMPLATE_REGEX =
     %r{[\<\{\[]
diff --git a/changelogs/unreleased/frozen-string-enable-app-helpers.yml b/changelogs/unreleased/frozen-string-enable-app-helpers.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7f6805ccb5af1313d550a72e6323136c16973b3a
--- /dev/null
+++ b/changelogs/unreleased/frozen-string-enable-app-helpers.yml
@@ -0,0 +1,5 @@
+---
+title: Enable frozen string for app/helpers/**/*.rb
+merge_request:
+author: gfyoung
+type: performance