summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Gemfile6
-rw-r--r--Gemfile.lock22
-rw-r--r--app/assets/stylesheets/pages/pipeline_schedules.scss7
-rw-r--r--app/assets/stylesheets/pages/reports.scss5
-rw-r--r--app/models/application_setting.rb4
-rw-r--r--app/models/concerns/group_descendant.rb4
-rw-r--r--app/models/concerns/token_authenticatable_strategies/base.rb2
-rw-r--r--app/models/concerns/token_authenticatable_strategies/encrypted.rb6
-rw-r--r--app/models/milestone.rb10
-rw-r--r--app/models/project.rb32
-rw-r--r--app/models/project_group_link.rb4
-rw-r--r--app/models/project_services/asana_service.rb8
-rw-r--r--app/models/project_services/bamboo_service.rb12
-rw-r--r--app/models/project_services/discord_service.rb4
-rw-r--r--app/models/project_services/emails_on_push_service.rb14
-rw-r--r--app/models/project_services/external_wiki_service.rb6
-rw-r--r--app/models/project_services/flowdock_service.rb4
-rw-r--r--app/models/project_services/jira_service.rb20
-rw-r--r--app/models/project_services/pipelines_email_service.rb6
-rw-r--r--app/models/project_services/pivotaltracker_service.rb8
-rw-r--r--app/models/project_services/pushover_service.rb26
-rw-r--r--app/models/u2f_registration.rb2
-rw-r--r--app/models/upload.rb6
-rw-r--r--app/models/user.rb22
-rw-r--r--app/models/wiki_page.rb4
-rw-r--r--app/services/clusters/applications/install_service.rb9
-rw-r--r--app/services/clusters/applications/patch_service.rb10
-rw-r--r--app/services/clusters/applications/upgrade_service.rb36
-rw-r--r--app/services/users/activity_service.rb2
-rw-r--r--app/views/projects/pipeline_schedules/_form.html.haml6
-rw-r--r--changelogs/unreleased/59921-pipeline-schedule.yml5
-rw-r--r--locale/gitlab.pot282
-rw-r--r--qa/Gemfile.lock2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb10
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb3
-rw-r--r--spec/features/u2f_spec.rb20
-rw-r--r--spec/models/wiki_page_spec.rb8
-rw-r--r--spec/services/clusters/applications/install_service_spec.rb6
-rw-r--r--spec/services/clusters/applications/patch_service_spec.rb6
-rw-r--r--spec/services/clusters/applications/upgrade_service_spec.rb6
-rw-r--r--spec/services/users/activity_service_spec.rb2
-rw-r--r--spec/support/shared_examples/features/master_manages_access_requests_shared_example.rb4
42 files changed, 466 insertions, 195 deletions
diff --git a/Gemfile b/Gemfile
index f2d24d79cb7..5f345f4329a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -345,9 +345,9 @@ group :development, :test do
# Generate Fake data
gem 'ffaker', '~> 2.10'
- gem 'capybara', '~> 2.16.1'
- gem 'capybara-screenshot', '~> 1.0.18'
- gem 'selenium-webdriver', '~> 3.12'
+ gem 'capybara', '~> 2.18.0'
+ gem 'capybara-screenshot', '~> 1.0.22'
+ gem 'selenium-webdriver', '~> 3.141'
gem 'spring', '~> 2.0.0'
gem 'spring-commands-rspec', '~> 1.0.4'
diff --git a/Gemfile.lock b/Gemfile.lock
index baa7be6258a..c1d1a50799f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -100,13 +100,13 @@ GEM
bundler (~> 1.2)
thor (~> 0.18)
byebug (9.1.0)
- capybara (2.16.1)
+ capybara (2.18.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
- xpath (~> 2.0)
+ xpath (>= 2.0, < 4.0)
capybara-screenshot (1.0.22)
capybara (>= 1.0, < 4)
launchy
@@ -488,7 +488,7 @@ GEM
net-ssh (5.0.1)
netrc (0.11.0)
nio4r (2.3.1)
- nokogiri (1.10.1)
+ nokogiri (1.10.2)
mini_portile2 (~> 2.4.0)
nokogumbo (1.5.0)
nokogiri
@@ -706,7 +706,7 @@ GEM
redis-store (>= 1.2, < 2)
redis-store (1.6.0)
redis (>= 2.2, < 5)
- regexp_parser (1.3.0)
+ regexp_parser (1.4.0)
regexp_property_values (0.3.4)
representable (3.0.4)
declarative (< 0.1.0)
@@ -815,9 +815,9 @@ GEM
seed-fu (2.3.7)
activerecord (>= 3.1)
activesupport (>= 3.1)
- selenium-webdriver (3.12.0)
+ selenium-webdriver (3.141.0)
childprocess (~> 0.5)
- rubyzip (~> 1.2)
+ rubyzip (~> 1.2, >= 1.2.2)
sentry-raven (2.9.0)
faraday (>= 0.7.6, < 1.0)
settingslogic (2.0.9)
@@ -943,8 +943,8 @@ GEM
rinku
with_env (1.1.0)
xml-simple (1.1.5)
- xpath (2.1.0)
- nokogiri (~> 1.3)
+ xpath (3.2.0)
+ nokogiri (~> 1.8)
PLATFORMS
ruby
@@ -974,8 +974,8 @@ DEPENDENCIES
browser (~> 2.5)
bullet (~> 5.5.0)
bundler-audit (~> 0.5.0)
- capybara (~> 2.16.1)
- capybara-screenshot (~> 1.0.18)
+ capybara (~> 2.18.0)
+ capybara-screenshot (~> 1.0.22)
carrierwave (~> 1.3)
charlock_holmes (~> 0.7.5)
chronic (~> 0.10.2)
@@ -1146,7 +1146,7 @@ DEPENDENCIES
sass-rails (~> 5.0.6)
scss_lint (~> 0.56.0)
seed-fu (~> 2.3.7)
- selenium-webdriver (~> 3.12)
+ selenium-webdriver (~> 3.141)
sentry-raven (~> 2.7)
settingslogic (~> 2.0.9)
sham_rack (~> 1.3.6)
diff --git a/app/assets/stylesheets/pages/pipeline_schedules.scss b/app/assets/stylesheets/pages/pipeline_schedules.scss
index 617b3db2fae..85c4902eee2 100644
--- a/app/assets/stylesheets/pages/pipeline_schedules.scss
+++ b/app/assets/stylesheets/pages/pipeline_schedules.scss
@@ -1,9 +1,4 @@
-.js-pipeline-schedule-form {
- .dropdown-select,
- .dropdown-menu-toggle {
- width: 100% !important;
- }
-
+.pipeline-schedule-form {
.gl-field-error {
margin: 10px 0 0;
}
diff --git a/app/assets/stylesheets/pages/reports.scss b/app/assets/stylesheets/pages/reports.scss
index f7619ccbd20..94da72622af 100644
--- a/app/assets/stylesheets/pages/reports.scss
+++ b/app/assets/stylesheets/pages/reports.scss
@@ -52,11 +52,6 @@
.report-block-list-icon .loading-container {
position: relative;
left: -2px;
- // needed to make the next element align with the
- // elements below that have a svg with 16px width
- .fa-spinner {
- width: 16px;
- }
}
}
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index eb6ddaac871..2f9b4c4eaa2 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -198,7 +198,7 @@ class ApplicationSetting < ApplicationRecord
validates_each :restricted_visibility_levels do |record, attr, value|
value&.each do |level|
unless Gitlab::VisibilityLevel.options.value?(level)
- record.errors.add(attr, "'#{level}' is not a valid visibility level")
+ record.errors.add(attr, _("'%{level}' is not a valid visibility level") % { level: level })
end
end
end
@@ -206,7 +206,7 @@ class ApplicationSetting < ApplicationRecord
validates_each :import_sources do |record, attr, value|
value&.each do |source|
unless Gitlab::ImportSources.options.value?(source)
- record.errors.add(attr, "'#{source}' is not a import source")
+ record.errors.add(attr, _("'%{source}' is not a import source") % { source: source })
end
end
end
diff --git a/app/models/concerns/group_descendant.rb b/app/models/concerns/group_descendant.rb
index 05cd4265133..cfffd845e43 100644
--- a/app/models/concerns/group_descendant.rb
+++ b/app/models/concerns/group_descendant.rb
@@ -22,7 +22,7 @@ module GroupDescendant
return [] if descendants.empty?
unless descendants.all? { |hierarchy| hierarchy.is_a?(GroupDescendant) }
- raise ArgumentError.new('element is not a hierarchy')
+ raise ArgumentError.new(_('element is not a hierarchy'))
end
all_hierarchies = descendants.map do |descendant|
@@ -56,7 +56,7 @@ module GroupDescendant
end
if parent.nil? && hierarchy_top.present?
- raise ArgumentError.new('specified top is not part of the tree')
+ raise ArgumentError.new(_('specified top is not part of the tree'))
end
if parent && parent != hierarchy_top
diff --git a/app/models/concerns/token_authenticatable_strategies/base.rb b/app/models/concerns/token_authenticatable_strategies/base.rb
index df14e6e4754..aafd0b538a3 100644
--- a/app/models/concerns/token_authenticatable_strategies/base.rb
+++ b/app/models/concerns/token_authenticatable_strategies/base.rb
@@ -41,7 +41,7 @@ module TokenAuthenticatableStrategies
def self.fabricate(model, field, options)
if options[:digest] && options[:encrypted]
- raise ArgumentError, 'Incompatible options set!'
+ raise ArgumentError, _('Incompatible options set!')
end
if options[:digest]
diff --git a/app/models/concerns/token_authenticatable_strategies/encrypted.rb b/app/models/concerns/token_authenticatable_strategies/encrypted.rb
index 2c7fa2c5b3c..4728cb658dc 100644
--- a/app/models/concerns/token_authenticatable_strategies/encrypted.rb
+++ b/app/models/concerns/token_authenticatable_strategies/encrypted.rb
@@ -13,7 +13,7 @@ module TokenAuthenticatableStrategies
elsif migrating?
find_by_plaintext_token(token, unscoped)
else
- raise ArgumentError, "Unknown encryption strategy: #{encrypted_strategy}!"
+ raise ArgumentError, _("Unknown encryption strategy: %{encrypted_strategy}!") % { encrypted_strategy: encrypted_strategy }
end
end
@@ -32,7 +32,7 @@ module TokenAuthenticatableStrategies
return super if instance.has_attribute?(encrypted_field)
if required?
- raise ArgumentError, 'Using required encryption strategy when encrypted field is missing!'
+ raise ArgumentError, _('Using required encryption strategy when encrypted field is missing!')
else
insecure_strategy.ensure_token(instance)
end
@@ -74,7 +74,7 @@ module TokenAuthenticatableStrategies
value = value.call if value.is_a?(Proc)
unless value.in?([:required, :optional, :migrating])
- raise ArgumentError, 'encrypted: needs to be a :required, :optional or :migrating!'
+ raise ArgumentError, _('encrypted: needs to be a :required, :optional or :migrating!')
end
value
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index b4aad9e512e..787600569fa 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -291,22 +291,22 @@ class Milestone < ApplicationRecord
end
title_exists = relation.find_by_title(title)
- errors.add(:title, "already being used for another group or project milestone.") if title_exists
+ errors.add(:title, _("already being used for another group or project milestone.")) if title_exists
end
# Milestone should be either a project milestone or a group milestone
def milestone_type_check
if group_id && project_id
field = project_id_changed? ? :project_id : :group_id
- errors.add(field, "milestone should belong either to a project or a group.")
+ errors.add(field, _("milestone should belong either to a project or a group."))
end
end
def milestone_format_reference(format = :iid)
- raise ArgumentError, 'Unknown format' unless [:iid, :name].include?(format)
+ raise ArgumentError, _('Unknown format') unless [:iid, :name].include?(format)
if group_milestone? && format == :iid
- raise ArgumentError, 'Cannot refer to a group milestone by an internal id!'
+ raise ArgumentError, _('Cannot refer to a group milestone by an internal id!')
end
if format == :name && !name.include?('"')
@@ -322,7 +322,7 @@ class Milestone < ApplicationRecord
def start_date_should_be_less_than_due_date
if due_date <= start_date
- errors.add(:due_date, "must be greater than start date")
+ errors.add(:due_date, _("must be greater than start date"))
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index c838df03c0d..2fb6f5cb6a7 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -313,7 +313,7 @@ class Project < ApplicationRecord
validates :description, length: { maximum: 2000 }, allow_blank: true
validates :ci_config_path,
format: { without: %r{(\.{2}|\A/)},
- message: 'cannot include leading slash or directory traversal.' },
+ message: _('cannot include leading slash or directory traversal.') },
length: { maximum: 255 },
allow_blank: true
validates :name,
@@ -420,13 +420,13 @@ class Project < ApplicationRecord
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
chronic_duration_attr :build_timeout_human_readable, :build_timeout,
- default: 3600, error_message: 'Maximum job timeout has a value which could not be accepted'
+ default: 3600, error_message: _('Maximum job timeout has a value which could not be accepted')
validates :build_timeout, allow_nil: true,
numericality: { greater_than_or_equal_to: 10.minutes,
less_than: 1.month,
only_integer: true,
- message: 'needs to be beetween 10 minutes and 1 month' }
+ message: _('needs to be beetween 10 minutes and 1 month') }
# Used by Projects::CleanupService to hold a map of rewritten object IDs
mount_uploader :bfg_object_map, AttachmentUploader
@@ -850,7 +850,7 @@ class Project < ApplicationRecord
def mark_stuck_remote_mirrors_as_failed!
remote_mirrors.stuck.update_all(
update_status: :failed,
- last_error: 'The remote mirror took to long to complete.',
+ last_error: _('The remote mirror took to long to complete.'),
last_update_at: Time.now
)
end
@@ -887,14 +887,14 @@ class Project < ApplicationRecord
level_name = Gitlab::VisibilityLevel.level_name(self.visibility_level).downcase
group_level_name = Gitlab::VisibilityLevel.level_name(self.group.visibility_level).downcase
- self.errors.add(:visibility_level, "#{level_name} is not allowed in a #{group_level_name} group.")
+ self.errors.add(:visibility_level, _("%{level_name} is not allowed in a %{group_level_name} group.") % { level_name: level_name, group_level_name: group_level_name })
end
def visibility_level_allowed_as_fork
return if visibility_level_allowed_as_fork?
level_name = Gitlab::VisibilityLevel.level_name(self.visibility_level).downcase
- self.errors.add(:visibility_level, "#{level_name} is not allowed since the fork source project has lower visibility.")
+ self.errors.add(:visibility_level, _("%{level_name} is not allowed since the fork source project has lower visibility.") % { level_name: level_name })
end
def check_wiki_path_conflict
@@ -903,7 +903,7 @@ class Project < ApplicationRecord
path_to_check = path.ends_with?('.wiki') ? path.chomp('.wiki') : "#{path}.wiki"
if Project.where(namespace_id: namespace_id, path: path_to_check).exists?
- errors.add(:name, 'has already been taken')
+ errors.add(:name, _('has already been taken'))
end
end
@@ -923,7 +923,7 @@ class Project < ApplicationRecord
return unless pages_https_only?
unless pages_domains.all?(&:https?)
- errors.add(:pages_https_only, "cannot be enabled unless all domains have TLS certificates")
+ errors.add(:pages_https_only, _("cannot be enabled unless all domains have TLS certificates"))
end
end
@@ -1203,7 +1203,7 @@ class Project < ApplicationRecord
def valid_repo?
repository.exists?
rescue
- errors.add(:path, 'Invalid repository path')
+ errors.add(:path, _('Invalid repository path'))
false
end
@@ -1294,7 +1294,7 @@ class Project < ApplicationRecord
# Check if repository with same path already exists on disk we can
# skip this for the hashed storage because the path does not change
if legacy_storage? && repository_with_same_path_already_exists?
- errors.add(:base, 'There is already a repository with that name on disk')
+ errors.add(:base, _('There is already a repository with that name on disk'))
return false
end
@@ -1316,7 +1316,7 @@ class Project < ApplicationRecord
repository.after_create
true
else
- errors.add(:base, 'Failed to create repository via gitlab-shell')
+ errors.add(:base, _('Failed to create repository via gitlab-shell'))
false
end
end
@@ -1392,7 +1392,7 @@ class Project < ApplicationRecord
ProjectCacheWorker.perform_async(self.id, [], [:commit_count])
reload_default_branch
else
- errors.add(:base, "Could not change HEAD: branch '#{branch}' does not exist")
+ errors.add(:base, _("Could not change HEAD: branch '%{branch}' does not exist") % { branch: branch })
false
end
end
@@ -1444,7 +1444,7 @@ class Project < ApplicationRecord
ProjectWiki.new(self, self.owner).wiki
true
rescue ProjectWiki::CouldNotCreateWikiError
- errors.add(:base, 'Failed create wiki')
+ errors.add(:base, _('Failed create wiki'))
false
end
@@ -1933,7 +1933,7 @@ class Project < ApplicationRecord
#
# @param [Symbol] feature that needs to be rolled out for the project (:repository, :attachments)
def hashed_storage?(feature)
- raise ArgumentError, "Invalid feature" unless HASHED_STORAGE_FEATURES.include?(feature)
+ raise ArgumentError, _("Invalid feature") unless HASHED_STORAGE_FEATURES.include?(feature)
self.storage_version && self.storage_version >= HASHED_STORAGE_FEATURES[feature]
end
@@ -2165,7 +2165,7 @@ class Project < ApplicationRecord
return if skip_disk_validation
if repository_storage.blank? || repository_with_same_path_already_exists?
- errors.add(:base, 'There is already a repository with that name on disk')
+ errors.add(:base, _('There is already a repository with that name on disk'))
throw :abort
end
end
@@ -2211,7 +2211,7 @@ class Project < ApplicationRecord
errors.delete(error)
end
- errors.add(:base, "The project is still being deleted. Please try again later.")
+ errors.add(:base, _("The project is still being deleted. Please try again later."))
end
def pending_delete_twin
diff --git a/app/models/project_group_link.rb b/app/models/project_group_link.rb
index 58b555c3581..feaf172d48d 100644
--- a/app/models/project_group_link.rb
+++ b/app/models/project_group_link.rb
@@ -14,7 +14,7 @@ class ProjectGroupLink < ApplicationRecord
validates :project_id, presence: true
validates :group, presence: true
- validates :group_id, uniqueness: { scope: [:project_id], message: "already shared with this group" }
+ validates :group_id, uniqueness: { scope: [:project_id], message: _("already shared with this group") }
validates :group_access, presence: true
validates :group_access, inclusion: { in: Gitlab::Access.values }, presence: true
validate :different_group
@@ -44,7 +44,7 @@ class ProjectGroupLink < ApplicationRecord
group_ids = project_group.ancestors.map(&:id).push(project_group.id)
if group_ids.include?(self.group.id)
- errors.add(:base, "Project cannot be shared with the group it is in or one of its ancestors.")
+ errors.add(:base, _("Project cannot be shared with the group it is in or one of its ancestors."))
end
end
diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb
index cc5f1207653..3e28dc23782 100644
--- a/app/models/project_services/asana_service.rb
+++ b/app/models/project_services/asana_service.rb
@@ -11,7 +11,7 @@ class AsanaService < Service
end
def description
- 'Asana - Teamwork without email'
+ s_('AsanaService|Asana - Teamwork without email')
end
def help
@@ -36,13 +36,13 @@ http://app.asana.com/-/account_api'
{
type: 'text',
name: 'api_key',
- placeholder: 'User Personal Access Token. User must have access to task, all comments will be attributed to this user.',
+ placeholder: s_('AsanaService|User Personal Access Token. User must have access to task, all comments will be attributed to this user.'),
required: true
},
{
type: 'text',
name: 'restrict_to_branch',
- placeholder: 'Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches.'
+ placeholder: s_('AsanaService|Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches.')
}
]
end
@@ -73,7 +73,7 @@ http://app.asana.com/-/account_api'
project_name = project.full_name
data[:commits].each do |commit|
- push_msg = "#{user} pushed to branch #{branch} of #{project_name} ( #{commit[:url]} ):"
+ push_msg = s_("AsanaService|%{user} pushed to branch %{branch} of %{project_name} ( %{commit_url} ):") % { user: user, branch: branch, project_name: project_name, commit_url: commit[:url] }
check_commit(commit[:message], push_msg)
end
end
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
index 71f5607dbdb..dfeb21680a9 100644
--- a/app/models/project_services/bamboo_service.rb
+++ b/app/models/project_services/bamboo_service.rb
@@ -31,15 +31,15 @@ class BambooService < CiService
end
def title
- 'Atlassian Bamboo CI'
+ s_('BambooService|Atlassian Bamboo CI')
end
def description
- 'A continuous integration and build server'
+ s_('BambooService|A continuous integration and build server')
end
def help
- 'You must set up automatic revision labeling and a repository trigger in Bamboo.'
+ s_('BambooService|You must set up automatic revision labeling and a repository trigger in Bamboo.')
end
def self.to_param
@@ -49,11 +49,11 @@ class BambooService < CiService
def fields
[
{ type: 'text', name: 'bamboo_url',
- placeholder: 'Bamboo root URL like https://bamboo.example.com', required: true },
+ placeholder: s_('BambooService|Bamboo root URL like https://bamboo.example.com'), required: true },
{ type: 'text', name: 'build_key',
- placeholder: 'Bamboo build plan key like KEY', required: true },
+ placeholder: s_('BambooService|Bamboo build plan key like KEY'), required: true },
{ type: 'text', name: 'username',
- placeholder: 'A user with API access, if applicable' },
+ placeholder: s_('BambooService|A user with API access, if applicable') },
{ type: 'password', name: 'password' }
]
end
diff --git a/app/models/project_services/discord_service.rb b/app/models/project_services/discord_service.rb
index 21afd14dbff..405676792de 100644
--- a/app/models/project_services/discord_service.rb
+++ b/app/models/project_services/discord_service.rb
@@ -4,11 +4,11 @@ require "discordrb/webhooks"
class DiscordService < ChatNotificationService
def title
- "Discord Notifications"
+ s_("DiscordService|Discord Notifications")
end
def description
- "Receive event notifications in Discord"
+ s_("DiscordService|Receive event notifications in Discord")
end
def self.to_param
diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb
index fb73d430fb1..45de64a9990 100644
--- a/app/models/project_services/emails_on_push_service.rb
+++ b/app/models/project_services/emails_on_push_service.rb
@@ -7,11 +7,11 @@ class EmailsOnPushService < Service
validates :recipients, presence: true, if: :valid_recipients?
def title
- 'Emails on push'
+ s_('EmailsOnPushService|Emails on push')
end
def description
- 'Email the commits and diff of each push to a list of recipients.'
+ s_('EmailsOnPushService|Email the commits and diff of each push to a list of recipients.')
end
def self.to_param
@@ -45,11 +45,11 @@ class EmailsOnPushService < Service
def fields
domains = Notify.allowed_email_domains.map { |domain| "user@#{domain}" }.join(", ")
[
- { type: 'checkbox', name: 'send_from_committer_email', title: "Send from committer",
- help: "Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. #{domains})." },
- { type: 'checkbox', name: 'disable_diffs', title: "Disable code diffs",
- help: "Don't include possibly sensitive code diffs in notification body." },
- { type: 'textarea', name: 'recipients', placeholder: 'Emails separated by whitespace' }
+ { type: 'checkbox', name: 'send_from_committer_email', title: s_("EmailsOnPushService|Send from committer"),
+ help: s_("EmailsOnPushService|Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. %{domains}).") % { domains: domains } },
+ { type: 'checkbox', name: 'disable_diffs', title: s_("EmailsOnPushService|Disable code diffs"),
+ help: s_("EmailsOnPushService|Don't include possibly sensitive code diffs in notification body.") },
+ { type: 'textarea', name: 'recipients', placeholder: s_('EmailsOnPushService|Emails separated by whitespace') }
]
end
end
diff --git a/app/models/project_services/external_wiki_service.rb b/app/models/project_services/external_wiki_service.rb
index d2835c6ac82..593ce69b0fd 100644
--- a/app/models/project_services/external_wiki_service.rb
+++ b/app/models/project_services/external_wiki_service.rb
@@ -6,11 +6,11 @@ class ExternalWikiService < Service
validates :external_wiki_url, presence: true, public_url: true, if: :activated?
def title
- 'External Wiki'
+ s_('ExternalWikiService|External Wiki')
end
def description
- 'Replaces the link to the internal wiki with a link to an external wiki.'
+ s_('ExternalWikiService|Replaces the link to the internal wiki with a link to an external wiki.')
end
def self.to_param
@@ -19,7 +19,7 @@ class ExternalWikiService < Service
def fields
[
- { type: 'text', name: 'external_wiki_url', placeholder: 'The URL of the external Wiki', required: true }
+ { type: 'text', name: 'external_wiki_url', placeholder: s_('ExternalWikiService|The URL of the external Wiki'), required: true }
]
end
diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb
index 76624263aab..094488cb431 100644
--- a/app/models/project_services/flowdock_service.rb
+++ b/app/models/project_services/flowdock_service.rb
@@ -9,7 +9,7 @@ class FlowdockService < Service
end
def description
- 'Flowdock is a collaboration web app for technical teams.'
+ s_('FlowdockService|Flowdock is a collaboration web app for technical teams.')
end
def self.to_param
@@ -18,7 +18,7 @@ class FlowdockService < Service
def fields
[
- { type: 'text', name: 'token', placeholder: 'Flowdock Git source token', required: true }
+ { type: 'text', name: 'token', placeholder: s_('FlowdockService|Flowdock Git source token'), required: true }
]
end
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index 81302c516c2..ebf28dc842c 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -11,7 +11,7 @@ class JiraService < IssueTrackerService
validates :password, presence: true, if: :activated?
validates :jira_issue_transition_id,
- format: { with: Gitlab::Regex.jira_transition_id_regex, message: "transition ids can have only numbers which can be split with , or ;" },
+ format: { with: Gitlab::Regex.jira_transition_id_regex, message: s_("JiraService|transition ids can have only numbers which can be split with , or ;") },
allow_blank: true
# JIRA cloud version is deprecating authentication via username and password.
@@ -86,7 +86,7 @@ class JiraService < IssueTrackerService
if self.properties && self.properties['description'].present?
self.properties['description']
else
- 'Jira issue tracker'
+ s_('JiraService|Jira issue tracker')
end
end
@@ -96,11 +96,11 @@ class JiraService < IssueTrackerService
def fields
[
- { type: 'text', name: 'url', title: 'Web URL', placeholder: 'https://jira.example.com', required: true },
- { type: 'text', name: 'api_url', title: 'JIRA API URL', placeholder: 'If different from Web URL' },
- { type: 'text', name: 'username', title: 'Username or Email', placeholder: 'Use a username for server version and an email for cloud version', required: true },
- { type: 'password', name: 'password', title: 'Password or API token', placeholder: 'Use a password for server version and an API token for cloud version', required: true },
- { type: 'text', name: 'jira_issue_transition_id', title: 'Transition ID(s)', placeholder: 'Use , or ; to separate multiple transition IDs' }
+ { type: 'text', name: 'url', title: s_('JiraService|Web URL'), placeholder: 'https://jira.example.com', required: true },
+ { type: 'text', name: 'api_url', title: s_('JiraService|JIRA API URL'), placeholder: s_('JiraService|If different from Web URL') },
+ { type: 'text', name: 'username', title: s_('JiraService|Username or Email'), placeholder: s_('JiraService|Use a username for server version and an email for cloud version'), required: true },
+ { type: 'password', name: 'password', title: s_('JiraService|Password or API token'), placeholder: s_('JiraService|Use a password for server version and an API token for cloud version'), required: true },
+ { type: 'text', name: 'jira_issue_transition_id', title: s_('JiraService|Transition ID(s)'), placeholder: s_('JiraService|Use , or ; to separate multiple transition IDs') }
]
end
@@ -139,7 +139,7 @@ class JiraService < IssueTrackerService
def create_cross_reference_note(mentioned, noteable, author)
unless can_cross_reference?(noteable)
- return "Events for #{noteable.model_name.plural.humanize(capitalize: false)} are disabled."
+ return s_("JiraService|Events for %{noteable_model_name} are disabled.") % { noteable_model_name: noteable.model_name.plural.humanize(capitalize: false) }
end
jira_issue = jira_request { client.Issue.find(mentioned.id) }
@@ -338,9 +338,9 @@ class JiraService < IssueTrackerService
def self.event_description(event)
case event
when "merge_request", "merge_request_events"
- "JIRA comments will be created when an issue gets referenced in a merge request."
+ s_("JiraService|JIRA comments will be created when an issue gets referenced in a merge request.")
when "commit", "commit_events"
- "JIRA comments will be created when an issue gets referenced in a commit."
+ s_("JiraService|JIRA comments will be created when an issue gets referenced in a commit.")
end
end
end
diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb
index d60a6a7efa3..7ba69370f14 100644
--- a/app/models/project_services/pipelines_email_service.rb
+++ b/app/models/project_services/pipelines_email_service.rb
@@ -10,11 +10,11 @@ class PipelinesEmailService < Service
end
def title
- 'Pipelines emails'
+ _('Pipelines emails')
end
def description
- 'Email the pipelines status to a list of recipients.'
+ _('Email the pipelines status to a list of recipients.')
end
def self.to_param
@@ -51,7 +51,7 @@ class PipelinesEmailService < Service
[
{ type: 'textarea',
name: 'recipients',
- placeholder: 'Emails separated by comma',
+ placeholder: _('Emails separated by comma'),
required: true },
{ type: 'checkbox',
name: 'notify_only_broken_pipelines' }
diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb
index 617e502b639..c15993bdc06 100644
--- a/app/models/project_services/pivotaltracker_service.rb
+++ b/app/models/project_services/pivotaltracker_service.rb
@@ -11,7 +11,7 @@ class PivotaltrackerService < Service
end
def description
- 'Project Management Software (Source Commits Endpoint)'
+ s_('PivotalTrackerService|Project Management Software (Source Commits Endpoint)')
end
def self.to_param
@@ -23,14 +23,14 @@ class PivotaltrackerService < Service
{
type: 'text',
name: 'token',
- placeholder: 'Pivotal Tracker API token.',
+ placeholder: s_('PivotalTrackerService|Pivotal Tracker API token.'),
required: true
},
{
type: 'text',
name: 'restrict_to_branch',
- placeholder: 'Comma-separated list of branches which will be ' \
- 'automatically inspected. Leave blank to include all branches.'
+ placeholder: s_('PivotalTrackerService|Comma-separated list of branches which will be ' \
+ 'automatically inspected. Leave blank to include all branches.')
}
]
end
diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb
index 4e48c348b45..0d35bab7f80 100644
--- a/app/models/project_services/pushover_service.rb
+++ b/app/models/project_services/pushover_service.rb
@@ -11,7 +11,7 @@ class PushoverService < Service
end
def description
- 'Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop.'
+ s_('PushoverService|Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop.')
end
def self.to_param
@@ -20,15 +20,15 @@ class PushoverService < Service
def fields
[
- { type: 'text', name: 'api_key', placeholder: 'Your application key', required: true },
- { type: 'text', name: 'user_key', placeholder: 'Your user key', required: true },
- { type: 'text', name: 'device', placeholder: 'Leave blank for all active devices' },
+ { type: 'text', name: 'api_key', placeholder: s_('PushoverService|Your application key'), required: true },
+ { type: 'text', name: 'user_key', placeholder: s_('PushoverService|Your user key'), required: true },
+ { type: 'text', name: 'device', placeholder: s_('PushoverService|Leave blank for all active devices') },
{ type: 'select', name: 'priority', required: true, choices:
[
- ['Lowest Priority', -2],
- ['Low Priority', -1],
- ['Normal Priority', 0],
- ['High Priority', 1]
+ [s_('PushoverService|Lowest Priority'), -2],
+ [s_('PushoverService|Low Priority'), -1],
+ [s_('PushoverService|Normal Priority'), 0],
+ [s_('PushoverService|High Priority'), 1]
],
default_choice: 0 },
{ type: 'select', name: 'sound', choices:
@@ -73,15 +73,15 @@ class PushoverService < Service
message =
if Gitlab::Git.blank_ref?(before)
- "#{data[:user_name]} pushed new branch \"#{ref}\"."
+ s_("PushoverService|%{user_name} pushed new branch \"%{ref}\".") % { user_name: data[:user_name], ref: ref }
elsif Gitlab::Git.blank_ref?(after)
- "#{data[:user_name]} deleted branch \"#{ref}\"."
+ s_("PushoverService|%{user_name} deleted branch \"%{ref}\".") % { user_name: data[:user_name], ref: ref }
else
- "#{data[:user_name]} push to branch \"#{ref}\"."
+ s_("PushoverService|%{user_name} push to branch \"%{ref}\".") % { user_name: data[:user_name], ref: ref }
end
if data[:total_commits_count] > 0
- message = [message, "Total commits count: #{data[:total_commits_count]}"].join("\n")
+ message = [message, s_("PushoverService|Total commits count: %{total_commits_count}") % { total_commits_count: data[:total_commits_count] }].join("\n")
end
pushover_data = {
@@ -92,7 +92,7 @@ class PushoverService < Service
title: "#{project.full_name}",
message: message,
url: data[:project][:web_url],
- url_title: "See project #{project.full_name}"
+ url_title: s_("PushoverService|See project %{project_full_name}") % { project_full_name: project.full_name }
}
# Sound parameter MUST NOT be sent to API if not selected
diff --git a/app/models/u2f_registration.rb b/app/models/u2f_registration.rb
index b4645462314..81415eb383b 100644
--- a/app/models/u2f_registration.rb
+++ b/app/models/u2f_registration.rb
@@ -19,7 +19,7 @@ class U2fRegistration < ApplicationRecord
user: user,
name: params[:name])
rescue JSON::ParserError, NoMethodError, ArgumentError
- registration.errors.add(:base, 'Your U2F device did not send a valid JSON response.')
+ registration.errors.add(:base, _('Your U2F device did not send a valid JSON response.'))
rescue U2F::Error => e
registration.errors.add(:base, e.message)
end
diff --git a/app/models/upload.rb b/app/models/upload.rb
index 9bffdcdb2e7..ca74f16b3b8 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -45,7 +45,7 @@ class Upload < ApplicationRecord
end
def absolute_path
- raise ObjectStorage::RemoteStoreError, "Remote object has no absolute path." unless local?
+ raise ObjectStorage::RemoteStoreError, _("Remote object has no absolute path.") unless local?
return path unless relative_path?
uploader_class.absolute_path(self)
@@ -71,10 +71,10 @@ class Upload < ApplicationRecord
# Help sysadmins find missing upload files
if persisted? && !exist
if Gitlab::Sentry.enabled?
- Raven.capture_message("Upload file does not exist", extra: self.attributes)
+ Raven.capture_message(_("Upload file does not exist"), extra: self.attributes)
end
- Gitlab::Metrics.counter(:upload_file_does_not_exist_total, 'The number of times an upload record could not find its file').increment
+ Gitlab::Metrics.counter(:upload_file_does_not_exist_total, _('The number of times an upload record could not find its file')).increment
end
exist
diff --git a/app/models/user.rb b/app/models/user.rb
index d3524bfd6ae..551eb58a4de 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -517,7 +517,7 @@ class User < ApplicationRecord
def ghost
email = 'ghost%s@example.com'
unique_internal(where(ghost: true), 'ghost', email) do |u|
- u.bio = 'This is a "Ghost User", created to hold all issues authored by users that have since been deleted. This user cannot be removed.'
+ u.bio = _('This is a "Ghost User", created to hold all issues authored by users that have since been deleted. This user cannot be removed.')
u.name = 'Ghost User'
end
end
@@ -537,20 +537,16 @@ class User < ApplicationRecord
username
end
- def self.internal_attributes
- [:ghost]
- end
-
def internal?
- self.class.internal_attributes.any? { |a| self[a] }
+ ghost?
end
def self.internal
- where(Hash[internal_attributes.zip([true] * internal_attributes.size)])
+ where(ghost: true)
end
def self.non_internal
- where(internal_attributes.map { |attr| "#{attr} IS NOT TRUE" }.join(" AND "))
+ where('ghost IS NOT TRUE')
end
#
@@ -626,32 +622,32 @@ class User < ApplicationRecord
def namespace_move_dir_allowed
if namespace&.any_project_has_container_registry_tags?
- errors.add(:username, 'cannot be changed if a personal project has container registry tags.')
+ errors.add(:username, _('cannot be changed if a personal project has container registry tags.'))
end
end
def unique_email
if !emails.exists?(email: email) && Email.exists?(email: email)
- errors.add(:email, 'has already been taken')
+ errors.add(:email, _('has already been taken'))
end
end
def owns_notification_email
return if temp_oauth_email?
- errors.add(:notification_email, "is not an email you own") unless all_emails.include?(notification_email)
+ errors.add(:notification_email, _("is not an email you own")) unless all_emails.include?(notification_email)
end
def owns_public_email
return if public_email.blank?
- errors.add(:public_email, "is not an email you own") unless all_emails.include?(public_email)
+ errors.add(:public_email, _("is not an email you own")) unless all_emails.include?(public_email)
end
def owns_commit_email
return if read_attribute(:commit_email).blank?
- errors.add(:commit_email, "is not an email you own") unless verified_emails.include?(commit_email)
+ errors.add(:commit_email, _("is not an email you own")) unless verified_emails.include?(commit_email)
end
# Define commit_email-related attribute methods explicitly instead of relying
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 909da4316d0..cd4c7895587 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -31,7 +31,9 @@ class WikiPage
pages.each_with_object([]) do |page, grouped_pages|
next grouped_pages << page unless page.directory.present?
- directory = grouped_pages.find { |dir| dir.slug == page.directory }
+ directory = grouped_pages.find do |obj|
+ obj.is_a?(WikiDirectory) && obj.slug == page.directory
+ end
next directory.pages << page if directory
diff --git a/app/services/clusters/applications/install_service.rb b/app/services/clusters/applications/install_service.rb
index 1f62b3eb4de..b37ac510ff4 100644
--- a/app/services/clusters/applications/install_service.rb
+++ b/app/services/clusters/applications/install_service.rb
@@ -7,6 +7,13 @@ module Clusters
return unless app.scheduled?
app.make_installing!
+
+ install
+ end
+
+ private
+
+ def install
log_event(:begin_install)
helm_api.install(install_command)
@@ -18,7 +25,7 @@ module Clusters
app.make_errored!("Kubernetes error: #{e.error_code}")
rescue StandardError => e
log_error(e)
- app.make_errored!("Can't start installation process.")
+ app.make_errored!('Failed to install.')
end
end
end
diff --git a/app/services/clusters/applications/patch_service.rb b/app/services/clusters/applications/patch_service.rb
index c3d317e226b..977a5e91041 100644
--- a/app/services/clusters/applications/patch_service.rb
+++ b/app/services/clusters/applications/patch_service.rb
@@ -8,6 +8,12 @@ module Clusters
app.make_updating!
+ patch
+ end
+
+ private
+
+ def patch
log_event(:begin_patch)
helm_api.update(update_command)
@@ -16,10 +22,10 @@ module Clusters
ClusterWaitForAppInstallationWorker::INTERVAL, app.name, app.id)
rescue Kubeclient::HttpError => e
log_error(e)
- app.make_update_errored!("Kubernetes error: #{e.error_code}")
+ app.make_errored!("Kubernetes error: #{e.error_code}")
rescue StandardError => e
log_error(e)
- app.make_update_errored!("Can't start update process.")
+ app.make_errored!('Failed to update.')
end
end
end
diff --git a/app/services/clusters/applications/upgrade_service.rb b/app/services/clusters/applications/upgrade_service.rb
index c34391bc8ad..813a9c4d071 100644
--- a/app/services/clusters/applications/upgrade_service.rb
+++ b/app/services/clusters/applications/upgrade_service.rb
@@ -6,24 +6,28 @@ module Clusters
def execute
return unless app.scheduled?
- begin
- app.make_updating!
+ app.make_updating!
- log_event(:begin_upgrade)
- # install_command works with upgrades too
- # as it basically does `helm upgrade --install`
- helm_api.update(install_command)
+ upgrade
+ end
+
+ private
+
+ def upgrade
+ # install_command works with upgrades too
+ # as it basically does `helm upgrade --install`
+ log_event(:begin_upgrade)
+ helm_api.update(install_command)
- log_event(:schedule_wait_for_upgrade)
- ClusterWaitForAppInstallationWorker.perform_in(
- ClusterWaitForAppInstallationWorker::INTERVAL, app.name, app.id)
- rescue Kubeclient::HttpError => e
- log_error(e)
- app.make_update_errored!("Kubernetes error: #{e.error_code}")
- rescue StandardError => e
- log_error(e)
- app.make_update_errored!("Can't start upgrade process.")
- end
+ log_event(:schedule_wait_for_upgrade)
+ ClusterWaitForAppInstallationWorker.perform_in(
+ ClusterWaitForAppInstallationWorker::INTERVAL, app.name, app.id)
+ rescue Kubeclient::HttpError => e
+ log_error(e)
+ app.make_errored!("Kubernetes error: #{e.error_code}")
+ rescue StandardError => e
+ log_error(e)
+ app.make_errored!('Failed to upgrade.')
end
end
end
diff --git a/app/services/users/activity_service.rb b/app/services/users/activity_service.rb
index e50840a9158..33444c2a7dc 100644
--- a/app/services/users/activity_service.rb
+++ b/app/services/users/activity_service.rb
@@ -30,7 +30,7 @@ module Users
return if @user.last_activity_on == today
- lease = Gitlab::ExclusiveLease.new("acitvity_service:#{@user.id}",
+ lease = Gitlab::ExclusiveLease.new("activity_service:#{@user.id}",
timeout: LEASE_TIMEOUT)
return unless lease.try_obtain
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
index 1121cf06b5c..396e5da87bc 100644
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ b/app/views/projects/pipeline_schedules/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for [@project.namespace.becomes(Namespace), @project, @schedule], as: :schedule, html: { id: "new-pipeline-schedule-form", class: "js-pipeline-schedule-form" } do |f|
+= form_for [@project.namespace.becomes(Namespace), @project, @schedule], as: :schedule, html: { id: "new-pipeline-schedule-form", class: "js-pipeline-schedule-form pipeline-schedule-form" } do |f|
= form_errors(@schedule)
.form-group.row
.col-md-9
@@ -11,12 +11,12 @@
.form-group.row
.col-md-9
= f.label :cron_timezone, _('Cron Timezone'), class: 'label-bold'
- = dropdown_tag(_("Select a timezone"), options: { toggle_class: 'btn js-timezone-dropdown', title: _("Select a timezone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } )
+ = dropdown_tag(_("Select a timezone"), options: { toggle_class: 'btn js-timezone-dropdown w-100', dropdown_class: 'w-100', title: _("Select a timezone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } )
= f.text_field :cron_timezone, value: @schedule.cron_timezone, id: 'schedule_cron_timezone', class: 'hidden', name: 'schedule[cron_timezone]', required: true
.form-group.row
.col-md-9
= f.label :ref, _('Target Branch'), class: 'label-bold'
- = dropdown_tag(_("Select target branch"), options: { toggle_class: 'btn js-target-branch-dropdown', dropdown_class: 'git-revision-dropdown', title: _("Select target branch"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: @project.repository.branch_names, default_branch: @project.default_branch } } )
+ = dropdown_tag(_("Select target branch"), options: { toggle_class: 'btn js-target-branch-dropdown w-100', dropdown_class: 'git-revision-dropdown w-100', title: _("Select target branch"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: @project.repository.branch_names, default_branch: @project.default_branch } } )
= f.text_field :ref, value: @schedule.ref, id: 'schedule_ref', class: 'hidden', name: 'schedule[ref]', required: true
.form-group.row.js-ci-variable-list-section
.col-md-9
diff --git a/changelogs/unreleased/59921-pipeline-schedule.yml b/changelogs/unreleased/59921-pipeline-schedule.yml
new file mode 100644
index 00000000000..4227a047913
--- /dev/null
+++ b/changelogs/unreleased/59921-pipeline-schedule.yml
@@ -0,0 +1,5 @@
+---
+title: Replaces CSS with BS4 utility class for pipeline schedules
+merge_request:
+author:
+type: other
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index cfd630ae8e2..4f401acccf9 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -132,6 +132,12 @@ msgstr ""
msgid "%{label_for_message} unavailable"
msgstr ""
+msgid "%{level_name} is not allowed in a %{group_level_name} group."
+msgstr ""
+
+msgid "%{level_name} is not allowed since the fork source project has lower visibility."
+msgstr ""
+
msgid "%{level_name} visibility has been restricted by the administrator."
msgstr ""
@@ -203,6 +209,12 @@ msgstr ""
msgid "%{user_name} profile page"
msgstr ""
+msgid "'%{level}' is not a valid visibility level"
+msgstr ""
+
+msgid "'%{source}' is not a import source"
+msgstr ""
+
msgid "(external source)"
msgstr ""
@@ -978,6 +990,18 @@ msgstr ""
msgid "Artifacts"
msgstr ""
+msgid "AsanaService|%{user} pushed to branch %{branch} of %{project_name} ( %{commit_url} ):"
+msgstr ""
+
+msgid "AsanaService|Asana - Teamwork without email"
+msgstr ""
+
+msgid "AsanaService|Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches."
+msgstr ""
+
+msgid "AsanaService|User Personal Access Token. User must have access to task, all comments will be attributed to this user."
+msgstr ""
+
msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
@@ -1221,6 +1245,24 @@ msgstr ""
msgid "Badges|e.g. %{exampleUrl}"
msgstr ""
+msgid "BambooService|A continuous integration and build server"
+msgstr ""
+
+msgid "BambooService|A user with API access, if applicable"
+msgstr ""
+
+msgid "BambooService|Atlassian Bamboo CI"
+msgstr ""
+
+msgid "BambooService|Bamboo build plan key like KEY"
+msgstr ""
+
+msgid "BambooService|Bamboo root URL like https://bamboo.example.com"
+msgstr ""
+
+msgid "BambooService|You must set up automatic revision labeling and a repository trigger in Bamboo."
+msgstr ""
+
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr ""
@@ -1515,6 +1557,9 @@ msgstr ""
msgid "Cannot modify managed Kubernetes cluster"
msgstr ""
+msgid "Cannot refer to a group milestone by an internal id!"
+msgstr ""
+
msgid "Cannot render the image. Maximum character count (%{charLimit}) has been exceeded."
msgstr ""
@@ -2600,6 +2645,9 @@ msgstr ""
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
+msgid "Could not change HEAD: branch '%{branch}' does not exist"
+msgstr ""
+
msgid "Could not connect to FogBugz, check your URL"
msgstr ""
@@ -3109,6 +3157,12 @@ msgstr ""
msgid "Discard draft"
msgstr ""
+msgid "DiscordService|Discord Notifications"
+msgstr ""
+
+msgid "DiscordService|Receive event notifications in Discord"
+msgstr ""
+
msgid "Discover projects, groups and snippets. Share your projects with others"
msgstr ""
@@ -3235,6 +3289,9 @@ msgstr ""
msgid "Email patch"
msgstr ""
+msgid "Email the pipelines status to a list of recipients."
+msgstr ""
+
msgid "EmailError|It appears that the email is blank. Make sure your reply is at the top of the email, we can't process inline replies."
msgstr ""
@@ -3262,6 +3319,30 @@ msgstr ""
msgid "Emails"
msgstr ""
+msgid "Emails separated by comma"
+msgstr ""
+
+msgid "EmailsOnPushService|Disable code diffs"
+msgstr ""
+
+msgid "EmailsOnPushService|Don't include possibly sensitive code diffs in notification body."
+msgstr ""
+
+msgid "EmailsOnPushService|Email the commits and diff of each push to a list of recipients."
+msgstr ""
+
+msgid "EmailsOnPushService|Emails on push"
+msgstr ""
+
+msgid "EmailsOnPushService|Emails separated by whitespace"
+msgstr ""
+
+msgid "EmailsOnPushService|Send from committer"
+msgstr ""
+
+msgid "EmailsOnPushService|Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. %{domains})."
+msgstr ""
+
msgid "Embed"
msgstr ""
@@ -3751,6 +3832,15 @@ msgstr ""
msgid "ExternalAuthorizationService|When no classification label is set the default label `%{default_label}` will be used."
msgstr ""
+msgid "ExternalWikiService|External Wiki"
+msgstr ""
+
+msgid "ExternalWikiService|Replaces the link to the internal wiki with a link to an external wiki."
+msgstr ""
+
+msgid "ExternalWikiService|The URL of the external Wiki"
+msgstr ""
+
msgid "Facebook"
msgstr ""
@@ -3760,12 +3850,18 @@ msgstr ""
msgid "Failed Jobs"
msgstr ""
+msgid "Failed create wiki"
+msgstr ""
+
msgid "Failed to change the owner"
msgstr ""
msgid "Failed to check related branches."
msgstr ""
+msgid "Failed to create repository via gitlab-shell"
+msgstr ""
+
msgid "Failed to create resources"
msgstr ""
@@ -3921,6 +4017,12 @@ msgstr ""
msgid "FirstPushedBy|pushed by"
msgstr ""
+msgid "FlowdockService|Flowdock Git source token"
+msgstr ""
+
+msgid "FlowdockService|Flowdock is a collaboration web app for technical teams."
+msgstr ""
+
msgid "FogBugz Email"
msgstr ""
@@ -4607,6 +4709,9 @@ msgstr ""
msgid "Incompatible Project"
msgstr ""
+msgid "Incompatible options set!"
+msgstr ""
+
msgid "Indicates whether this runner can pick jobs without tags"
msgstr ""
@@ -4682,6 +4787,9 @@ msgstr ""
msgid "Invalid Login or password"
msgstr ""
+msgid "Invalid feature"
+msgstr ""
+
msgid "Invalid file."
msgstr ""
@@ -4691,6 +4799,9 @@ msgstr ""
msgid "Invalid pin code"
msgstr ""
+msgid "Invalid repository path"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
@@ -4751,6 +4862,48 @@ msgstr ""
msgid "January"
msgstr ""
+msgid "JiraService|Events for %{noteable_model_name} are disabled."
+msgstr ""
+
+msgid "JiraService|If different from Web URL"
+msgstr ""
+
+msgid "JiraService|JIRA API URL"
+msgstr ""
+
+msgid "JiraService|JIRA comments will be created when an issue gets referenced in a commit."
+msgstr ""
+
+msgid "JiraService|JIRA comments will be created when an issue gets referenced in a merge request."
+msgstr ""
+
+msgid "JiraService|Jira issue tracker"
+msgstr ""
+
+msgid "JiraService|Password or API token"
+msgstr ""
+
+msgid "JiraService|Transition ID(s)"
+msgstr ""
+
+msgid "JiraService|Use , or ; to separate multiple transition IDs"
+msgstr ""
+
+msgid "JiraService|Use a password for server version and an API token for cloud version"
+msgstr ""
+
+msgid "JiraService|Use a username for server version and an email for cloud version"
+msgstr ""
+
+msgid "JiraService|Username or Email"
+msgstr ""
+
+msgid "JiraService|Web URL"
+msgstr ""
+
+msgid "JiraService|transition ids can have only numbers which can be split with , or ;"
+msgstr ""
+
msgid "Job"
msgstr ""
@@ -5187,6 +5340,9 @@ msgstr ""
msgid "Maximum job timeout"
msgstr ""
+msgid "Maximum job timeout has a value which could not be accepted"
+msgstr ""
+
msgid "Maximum push size (MB)"
msgstr ""
@@ -6133,6 +6289,9 @@ msgstr ""
msgid "Pipelines charts"
msgstr ""
+msgid "Pipelines emails"
+msgstr ""
+
msgid "Pipelines for last month"
msgstr ""
@@ -6256,6 +6415,15 @@ msgstr ""
msgid "Pipeline|with stages"
msgstr ""
+msgid "PivotalTrackerService|Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches."
+msgstr ""
+
+msgid "PivotalTrackerService|Pivotal Tracker API token."
+msgstr ""
+
+msgid "PivotalTrackerService|Project Management Software (Source Commits Endpoint)"
+msgstr ""
+
msgid "Plain diff"
msgstr ""
@@ -6667,6 +6835,9 @@ msgstr ""
msgid "Project avatar"
msgstr ""
+msgid "Project cannot be shared with the group it is in or one of its ancestors."
+msgstr ""
+
msgid "Project configuration, including services"
msgstr ""
@@ -6928,6 +7099,45 @@ msgstr ""
msgid "Push to create a project"
msgstr ""
+msgid "PushoverService|%{user_name} deleted branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|%{user_name} push to branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|%{user_name} pushed new branch \"%{ref}\"."
+msgstr ""
+
+msgid "PushoverService|High Priority"
+msgstr ""
+
+msgid "PushoverService|Leave blank for all active devices"
+msgstr ""
+
+msgid "PushoverService|Low Priority"
+msgstr ""
+
+msgid "PushoverService|Lowest Priority"
+msgstr ""
+
+msgid "PushoverService|Normal Priority"
+msgstr ""
+
+msgid "PushoverService|Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop."
+msgstr ""
+
+msgid "PushoverService|See project %{project_full_name}"
+msgstr ""
+
+msgid "PushoverService|Total commits count: %{total_commits_count}"
+msgstr ""
+
+msgid "PushoverService|Your application key"
+msgstr ""
+
+msgid "PushoverService|Your user key"
+msgstr ""
+
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
@@ -7014,6 +7224,9 @@ msgstr ""
msgid "Remind later"
msgstr ""
+msgid "Remote object has no absolute path."
+msgstr ""
+
msgid "Remove"
msgstr ""
@@ -8427,6 +8640,9 @@ msgstr ""
msgid "The name %{entryName} is already taken in this directory."
msgstr ""
+msgid "The number of times an upload record could not find its file"
+msgstr ""
+
msgid "The passphrase required to decrypt the private key. This is optional and the value is encrypted at rest."
msgstr ""
@@ -8454,12 +8670,18 @@ msgstr ""
msgid "The project can be accessed without any authentication."
msgstr ""
+msgid "The project is still being deleted. Please try again later."
+msgstr ""
+
msgid "The project was successfully forked."
msgstr ""
msgid "The project was successfully imported."
msgstr ""
+msgid "The remote mirror took to long to complete."
+msgstr ""
+
msgid "The remote repository is being updated..."
msgstr ""
@@ -8559,6 +8781,9 @@ msgstr ""
msgid "There are no unstaged changes"
msgstr ""
+msgid "There is already a repository with that name on disk"
+msgstr ""
+
msgid "There was an error loading users activity calendar."
msgstr ""
@@ -8655,6 +8880,9 @@ msgstr ""
msgid "This group does not provide any group Runners yet."
msgstr ""
+msgid "This is a \"Ghost User\", created to hold all issues authored by users that have since been deleted. This user cannot be removed."
+msgstr ""
+
msgid "This is a confidential issue."
msgstr ""
@@ -9196,6 +9424,12 @@ msgstr ""
msgid "Unfortunately, your email message to GitLab could not be processed."
msgstr ""
+msgid "Unknown encryption strategy: %{encrypted_strategy}!"
+msgstr ""
+
+msgid "Unknown format"
+msgstr ""
+
msgid "Unlock"
msgstr ""
@@ -9292,6 +9526,9 @@ msgstr ""
msgid "Upload file"
msgstr ""
+msgid "Upload file does not exist"
+msgstr ""
+
msgid "Upload object map"
msgstr ""
@@ -9457,6 +9694,9 @@ msgstr ""
msgid "Users were successfully added."
msgstr ""
+msgid "Using required encryption strategy when encrypted field is missing!"
+msgstr ""
+
msgid "Validate"
msgstr ""
@@ -10038,6 +10278,9 @@ msgstr ""
msgid "Your Todos"
msgstr ""
+msgid "Your U2F device did not send a valid JSON response."
+msgstr ""
+
msgid "Your U2F device needs to be set up. Plug it in (if not already) and click the button on the left."
msgstr ""
@@ -10119,6 +10362,12 @@ msgstr ""
msgid "allowed to fail"
msgstr ""
+msgid "already being used for another group or project milestone."
+msgstr ""
+
+msgid "already shared with this group"
+msgstr ""
+
msgid "among other things"
msgstr ""
@@ -10131,6 +10380,15 @@ msgstr ""
msgid "branch name"
msgstr ""
+msgid "cannot be changed if a personal project has container registry tags."
+msgstr ""
+
+msgid "cannot be enabled unless all domains have TLS certificates"
+msgstr ""
+
+msgid "cannot include leading slash or directory traversal."
+msgstr ""
+
msgid "commented on %{link_to_project}"
msgstr ""
@@ -10174,9 +10432,15 @@ msgstr[1] ""
msgid "done"
msgstr ""
+msgid "element is not a hierarchy"
+msgstr ""
+
msgid "enabled"
msgstr ""
+msgid "encrypted: needs to be a :required, :optional or :migrating!"
+msgstr ""
+
msgid "error"
msgstr ""
@@ -10210,6 +10474,9 @@ msgstr ""
msgid "group"
msgstr ""
+msgid "has already been taken"
+msgstr ""
+
msgid "here"
msgstr ""
@@ -10237,6 +10504,9 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
+msgid "is not an email you own"
+msgstr ""
+
msgid "issue boards"
msgstr ""
@@ -10269,6 +10539,9 @@ msgid_plural "merge requests"
msgstr[0] ""
msgstr[1] ""
+msgid "milestone should belong either to a project or a group."
+msgstr ""
+
msgid "missing"
msgstr ""
@@ -10476,9 +10749,15 @@ msgstr ""
msgid "mrWidget|to be merged automatically when the pipeline succeeds"
msgstr ""
+msgid "must be greater than start date"
+msgstr ""
+
msgid "n/a"
msgstr ""
+msgid "needs to be beetween 10 minutes and 1 month"
+msgstr ""
+
msgid "new merge request"
msgstr ""
@@ -10566,6 +10845,9 @@ msgstr ""
msgid "source diff"
msgstr ""
+msgid "specified top is not part of the tree"
+msgstr ""
+
msgid "spendCommand|%{slash_command} will update the sum of the time spent."
msgstr ""
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index c9b0db6a272..9d3d42fb6ae 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -49,7 +49,7 @@ GEM
mini_portile2 (2.4.0)
minitest (5.11.1)
netrc (0.11.0)
- nokogiri (1.10.1)
+ nokogiri (1.10.2)
mini_portile2 (~> 2.4.0)
pry (0.11.3)
coderay (~> 1.1.0)
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 25ed3bdc88e..ce780789f5a 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -73,22 +73,26 @@ describe 'Admin::Hooks' do
end
describe 'Remove existing hook', :js do
+ let(:hook_url) { generate(:url) }
+
before do
- create(:system_hook)
+ create(:system_hook, url: hook_url)
end
context 'removes existing hook' do
it 'from hooks list page' do
visit admin_hooks_path
- expect { accept_confirm { find(:link, 'Remove').send_keys(:return) } }.to change(SystemHook, :count).by(-1)
+ accept_confirm { click_link 'Remove' }
+ expect(page).not_to have_content(hook_url)
end
it 'from hook edit page' do
visit admin_hooks_path
click_link 'Edit'
- expect { accept_confirm { find(:link, 'Remove').send_keys(:return) } }.to change(SystemHook, :count).by(-1)
+ accept_confirm { click_link 'Remove' }
+ expect(page).not_to have_content(hook_url)
end
end
end
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 50ba67f0ffc..f26941ab567 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -62,8 +62,9 @@ describe 'Projects > Members > User requests access', :js do
accept_confirm { click_link 'Withdraw Access Request' }
- expect(project.requesters.exists?(user_id: user)).to be_falsey
expect(page).to have_content 'Your access request to the project has been withdrawn.'
+ expect(page).not_to have_content 'Withdraw Access Request'
+ expect(page).to have_content 'Request Access'
end
def open_project_settings_menu
diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb
index ae9b65d1a39..ea02f36d9d0 100644
--- a/spec/features/u2f_spec.rb
+++ b/spec/features/u2f_spec.rb
@@ -246,26 +246,6 @@ describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
end
end
end
-
- describe "when two-factor authentication is disabled" do
- let(:user) { create(:user) }
-
- before do
- user = gitlab_sign_in(:user)
- user.update_attribute(:otp_required_for_login, true)
- visit profile_account_path
- manage_two_factor_authentication
- expect(page).to have_content("Your U2F device needs to be set up.")
- register_u2f_device
- end
-
- it "deletes u2f registrations" do
- visit profile_two_factor_auth_path
- expect do
- accept_confirm { click_on "Disable" }
- end.to change { U2fRegistration.count }.by(-1)
- end
- end
end
describe 'fallback code authentication' do
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index cacdb0e0595..d5c85c11195 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -22,6 +22,7 @@ describe WikiPage do
create_page('dir_1/dir_1_1/page_3', 'content')
create_page('page_1', 'content')
create_page('dir_1/page_2', 'content')
+ create_page('dir_2', 'page with dir name')
create_page('dir_2/page_5', 'content')
create_page('page_6', 'content')
create_page('dir_2/page_4', 'content')
@@ -29,6 +30,7 @@ describe WikiPage do
let(:page_1) { wiki.find_page('page_1') }
let(:page_6) { wiki.find_page('page_6') }
+ let(:page_dir_2) { wiki.find_page('dir_2') }
let(:dir_1) do
WikiDirectory.new('dir_1', [wiki.find_page('dir_1/page_2')])
@@ -44,7 +46,7 @@ describe WikiPage do
context 'sort by title' do
let(:grouped_entries) { described_class.group_by_directory(wiki.pages) }
- let(:expected_grouped_entries) { [dir_1_1, dir_1, dir_2, page_1, page_6] }
+ let(:expected_grouped_entries) { [dir_1_1, dir_1, page_dir_2, dir_2, page_1, page_6] }
it 'returns an array with pages and directories' do
grouped_entries.each_with_index do |page_or_dir, i|
@@ -59,7 +61,7 @@ describe WikiPage do
context 'sort by created_at' do
let(:grouped_entries) { described_class.group_by_directory(wiki.pages(sort: 'created_at')) }
- let(:expected_grouped_entries) { [dir_1_1, page_1, dir_1, dir_2, page_6] }
+ let(:expected_grouped_entries) { [dir_1_1, page_1, dir_1, page_dir_2, dir_2, page_6] }
it 'returns an array with pages and directories' do
grouped_entries.each_with_index do |page_or_dir, i|
@@ -73,7 +75,7 @@ describe WikiPage do
end
it 'returns an array with retained order with directories at the top' do
- expected_order = ['dir_1/dir_1_1/page_3', 'dir_1/page_2', 'dir_2/page_4', 'dir_2/page_5', 'page_1', 'page_6']
+ expected_order = ['dir_1/dir_1_1/page_3', 'dir_1/page_2', 'dir_2', 'dir_2/page_4', 'dir_2/page_5', 'page_1', 'page_6']
grouped_entries = described_class.group_by_directory(wiki.pages)
diff --git a/spec/services/clusters/applications/install_service_spec.rb b/spec/services/clusters/applications/install_service_spec.rb
index db0c33a95b2..14739ff9e7c 100644
--- a/spec/services/clusters/applications/install_service_spec.rb
+++ b/spec/services/clusters/applications/install_service_spec.rb
@@ -58,7 +58,7 @@ describe Clusters::Applications::InstallService do
let(:error) { StandardError.new('something bad happened') }
before do
- expect(application).to receive(:make_installing!).once.and_raise(error)
+ expect(helm_client).to receive(:install).with(install_command).and_raise(error)
end
include_examples 'logs kubernetes errors' do
@@ -68,12 +68,10 @@ describe Clusters::Applications::InstallService do
end
it 'make the application errored' do
- expect(helm_client).not_to receive(:install)
-
service.execute
expect(application).to be_errored
- expect(application.status_reason).to eq("Can't start installation process.")
+ expect(application.status_reason).to eq('Failed to install.')
end
end
end
diff --git a/spec/services/clusters/applications/patch_service_spec.rb b/spec/services/clusters/applications/patch_service_spec.rb
index 10b1379a127..3ebe0540837 100644
--- a/spec/services/clusters/applications/patch_service_spec.rb
+++ b/spec/services/clusters/applications/patch_service_spec.rb
@@ -66,16 +66,14 @@ describe Clusters::Applications::PatchService do
end
before do
- expect(application).to receive(:make_updating!).once.and_raise(error)
+ expect(helm_client).to receive(:update).with(update_command).and_raise(error)
end
it 'make the application errored' do
- expect(helm_client).not_to receive(:update)
-
service.execute
expect(application).to be_update_errored
- expect(application.status_reason).to eq("Can't start update process.")
+ expect(application.status_reason).to eq('Failed to update.')
end
end
end
diff --git a/spec/services/clusters/applications/upgrade_service_spec.rb b/spec/services/clusters/applications/upgrade_service_spec.rb
index dd2e6e94e4f..a80b1d9127c 100644
--- a/spec/services/clusters/applications/upgrade_service_spec.rb
+++ b/spec/services/clusters/applications/upgrade_service_spec.rb
@@ -60,7 +60,7 @@ describe Clusters::Applications::UpgradeService do
let(:error) { StandardError.new('something bad happened') }
before do
- expect(application).to receive(:make_updating!).once.and_raise(error)
+ expect(helm_client).to receive(:update).with(install_command).and_raise(error)
end
include_examples 'logs kubernetes errors' do
@@ -70,12 +70,10 @@ describe Clusters::Applications::UpgradeService do
end
it 'make the application errored' do
- expect(helm_client).not_to receive(:update)
-
service.execute
expect(application).to be_update_errored
- expect(application.status_reason).to eq("Can't start upgrade process.")
+ expect(application.status_reason).to eq('Failed to upgrade.')
end
end
end
diff --git a/spec/services/users/activity_service_spec.rb b/spec/services/users/activity_service_spec.rb
index 3c0a4ac8e18..7b11d9e06e9 100644
--- a/spec/services/users/activity_service_spec.rb
+++ b/spec/services/users/activity_service_spec.rb
@@ -76,7 +76,7 @@ describe Users::ActivityService do
let(:last_activity_on) { nil }
it 'does not update last_activity_on' do
- stub_exclusive_lease_taken("acitvity_service:#{user.id}", timeout: 1.minute.to_i)
+ stub_exclusive_lease_taken("activity_service:#{user.id}", timeout: 1.minute.to_i)
expect { subject.execute }.not_to change(user, :last_activity_on)
end
diff --git a/spec/support/shared_examples/features/master_manages_access_requests_shared_example.rb b/spec/support/shared_examples/features/master_manages_access_requests_shared_example.rb
index 75ad948e42c..d87e5fcaa88 100644
--- a/spec/support/shared_examples/features/master_manages_access_requests_shared_example.rb
+++ b/spec/support/shared_examples/features/master_manages_access_requests_shared_example.rb
@@ -19,7 +19,7 @@ RSpec.shared_examples 'Maintainer manages access requests' do
expect_visible_access_request(entity, user)
- accept_confirm { click_on 'Grant access' }
+ click_on 'Grant access'
expect_no_visible_access_request(entity, user)
@@ -40,13 +40,11 @@ RSpec.shared_examples 'Maintainer manages access requests' do
end
def expect_visible_access_request(entity, user)
- expect(entity.requesters.exists?(user_id: user)).to be_truthy
expect(page).to have_content "Users requesting access to #{entity.name} 1"
expect(page).to have_content user.name
end
def expect_no_visible_access_request(entity, user)
- expect(entity.requesters.exists?(user_id: user)).to be_falsy
expect(page).not_to have_content "Users requesting access to #{entity.name}"
end
end