diff --git a/app/assets/stylesheets/page_bundles/experimental_separate_sign_up.scss b/app/assets/stylesheets/page_bundles/signup.scss
similarity index 76%
rename from app/assets/stylesheets/page_bundles/experimental_separate_sign_up.scss
rename to app/assets/stylesheets/page_bundles/signup.scss
index 337b5b001fe..9ed48b693b9 100644
--- a/app/assets/stylesheets/page_bundles/experimental_separate_sign_up.scss
+++ b/app/assets/stylesheets/page_bundles/signup.scss
@@ -1,27 +1,6 @@
@import 'mixins_and_variables_and_functions';
.signup-page {
- .page-wrap {
- background-color: var(--gray-10, $gray-10);
- }
-
- .signup-box-container {
- max-width: 960px;
- }
-
- .signup-box {
- background-color: var(--white, $white);
- box-shadow: 0 0 0 1px var(--border-color, $border-color);
- border-radius: $border-radius;
- }
-
- .form-control {
- &:active,
- &:focus {
- background-color: var(--white, $white);
- }
- }
-
.devise-errors {
h2 {
font-size: $gl-font-size;
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 7fce61516dc..55683e3c23c 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -14,15 +14,12 @@ class RegistrationsController < Devise::RegistrationsController
prepend_before_action :check_captcha, only: :create
before_action :whitelist_query_limiting, :ensure_destroy_prerequisites_met, only: [:destroy]
before_action :load_recaptcha, only: :new
+ before_action :set_invite_params, only: :new
feature_category :authentication_and_authorization
def new
- if experiment_enabled?(:signup_flow)
- @resource = build_resource
- else
- redirect_to new_user_session_path(anchor: 'register-pane')
- end
+ @resource = build_resource
end
def create
@@ -206,8 +203,8 @@ class RegistrationsController < Devise::RegistrationsController
# Part of an experiment to build a new sign up flow. Will be resolved
# with https://gitlab.com/gitlab-org/growth/engineering/issues/64
def choose_layout
- if %w(welcome update_registration).include?(action_name) || experiment_enabled?(:signup_flow)
- 'devise_experimental_separate_sign_up_flow'
+ if %w(welcome update_registration).include?(action_name)
+ 'welcome'
else
'devise'
end
@@ -225,6 +222,10 @@ class RegistrationsController < Devise::RegistrationsController
resource.state = BLOCKED_PENDING_APPROVAL_STATE
end
+
+ def set_invite_params
+ @invite_email = ActionController::Base.helpers.sanitize(params[:invite_email])
+ end
end
RegistrationsController.prepend_if_ee('EE::RegistrationsController')
diff --git a/app/models/project.rb b/app/models/project.rb
index 7e4ec6c7036..d002d7edeb5 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -571,6 +571,7 @@ class Project < ApplicationRecord
scope :imported_from, -> (type) { where(import_type: type) }
scope :with_tracing_enabled, -> { joins(:tracing_setting) }
+ scope :with_enabled_error_tracking, -> { joins(:error_tracking_setting).where(project_error_tracking_settings: { enabled: true }) }
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
diff --git a/app/services/jira_connect/sync_service.rb b/app/services/jira_connect/sync_service.rb
index 07a648bb8c9..f8855fb6deb 100644
--- a/app/services/jira_connect/sync_service.rb
+++ b/app/services/jira_connect/sync_service.rb
@@ -6,11 +6,11 @@ module JiraConnect
self.project = project
end
- def execute(commits: nil, branches: nil, merge_requests: nil)
+ def execute(commits: nil, branches: nil, merge_requests: nil, update_sequence_id: nil)
JiraConnectInstallation.for_project(project).each do |installation|
client = Atlassian::JiraConnect::Client.new(installation.base_url, installation.shared_secret)
- response = client.store_dev_info(project: project, commits: commits, branches: branches, merge_requests: merge_requests)
+ response = client.store_dev_info(project: project, commits: commits, branches: branches, merge_requests: merge_requests, update_sequence_id: update_sequence_id)
log_response(response)
end
diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml
index 2f75203ac62..a1e6e701c79 100644
--- a/app/views/devise/registrations/new.html.haml
+++ b/app/views/devise/registrations/new.html.haml
@@ -1,16 +1,6 @@
- page_title _("Sign up")
-- if experiment_enabled?(:signup_flow)
- .row
- .col-lg-7
- %h1.mb-3.font-weight-bold.text-6.mt-0
- = html_escape(_("Speed up your DevOps%{br_tag}with GitLab")) % { br_tag: '
'.html_safe }
- %p.text-3
- = _("GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring, and security.")
- .col-lg-5.order-12
- .text-center.mb-3
- %h2.font-weight-bold= _('Register for GitLab')
- = render 'devise/shared/experimental_separate_sign_up_flow_box'
- = render 'devise/shared/sign_in_link'
-- else
+- add_page_specific_style 'page_bundles/signup'
+
+.signup-page
= render 'devise/shared/signup_box'
= render 'devise/shared/sign_in_link'
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index c466d2ce936..e57220a8b14 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -2,23 +2,21 @@
#signin-container
- if any_form_based_providers_enabled?
- = render 'devise/shared/tabs_ldap'
- - else
- - unless experiment_enabled?(:signup_flow)
- = render 'devise/shared/tabs_normal'
+ = render 'devise/shared/tabs_ldap', render_signup_link: false
.tab-content
- if password_authentication_enabled_for_web? || ldap_sign_in_enabled? || crowd_enabled?
= render 'devise/shared/signin_box'
- -# Signup only makes sense if you can also sign-in
- - if allow_signup?
- = render 'devise/shared/signup_box'
-
-# Show a message if none of the mechanisms above are enabled
- if !password_authentication_enabled_for_web? && !ldap_sign_in_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
%div
No authentication methods configured.
+ - if allow_signup?
+ %p.gl-mt-3
+ = _("Don't have an account yet?")
+ = link_to _("Register now"), new_registration_path(:user, invite_email: @invite_email), data: { qa_selector: 'register_link' }
+
- if omniauth_enabled? && devise_mapping.omniauthable? && button_based_providers_enabled?
.clearfix
= render 'devise/shared/omniauth_box'
diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
deleted file mode 100644
index 1ad9e7c82b6..00000000000
--- a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml
+++ /dev/null
@@ -1,38 +0,0 @@
-- max_first_name_length = max_last_name_length = 127
-- max_username_length = 255
-- min_username_length = 2
-.signup-box.p-3.mb-2
- .signup-body
- = form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
- .devise-errors.mt-0
- = render "devise/shared/error_messages", resource: resource
- - if Feature.enabled?(:invisible_captcha)
- = invisible_captcha
- .name.form-row
- .col.form-group
- = f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold'
- = f.text_field :first_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :max_length_message => _("First name is too long (maximum is %{max_length} characters).") % { max_length: max_first_name_length }, :qa_selector => 'new_user_firstname_field' }, required: true, title: _("This field is required.")
- .col.form-group
- = f.label :last_name, _('Last name'), for: 'new_user_last_name', class: 'label-bold'
- = f.text_field :last_name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_last_name_length, :max_length_message => _("Last name is too long (maximum is %{max_length} characters).") % { max_length: max_last_name_length }, :qa_selector => 'new_user_lastname_field' }, required: true, title: _("This field is required.")
- .username.form-group
- = f.label :username, class: 'label-bold'
- = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :min_length => min_username_length, :min_length_message => s_("SignUp|Username is too short (minimum is %{min_length} characters).") % { min_length: min_username_length }, :max_length => max_username_length, :max_length_message => _("Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
- %p.validation-error.gl-field-error-ignore.field-validation.mt-1.hide.cred= _('Username is already taken.')
- %p.validation-success.gl-field-error-ignore.field-validation.mt-1.hide.cgreen= _('Username is available.')
- %p.validation-pending.gl-field-error-ignore.field-validation.mt-1.hide= _('Checking username availability...')
- .form-group
- = f.label :email, class: 'label-bold'
- = f.email_field :email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.")
- .form-group.append-bottom-20#password-strength
- = f.label :password, class: 'label-bold'
- = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
- %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
- %div
- - if show_recaptcha_sign_up?
- = recaptcha_tags
- .submit-container.mt-3
- = f.submit _("Register"), class: "btn-register gl-button btn btn-block btn-success mb-0 p-2", data: { qa_selector: 'new_user_register_button' }
- = render 'devise/shared/terms_of_service_notice'
- - if omniauth_enabled? && button_based_providers_enabled?
- = render 'devise/shared/experimental_separate_sign_up_flow_omniauth_box'
diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml
index d217b47527a..ff93449194a 100644
--- a/app/views/devise/shared/_signin_box.html.haml
+++ b/app/views/devise/shared/_signin_box.html.haml
@@ -22,8 +22,3 @@
.login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' }
.login-body
= render 'devise/sessions/new_base'
-
-- if experiment_enabled?(:signup_flow)
- %p.light.mt-2
- = _("Don't have an account yet?")
- = link_to _("Register now"), new_registration_path(:user)
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index 4543fb8ec92..b5c2adb0b9a 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -1,36 +1,38 @@
- max_first_name_length = max_last_name_length = 127
- max_username_length = 255
- min_username_length = 2
-#register-pane.tab-pane.login-box{ role: 'tabpanel' }
- .login-body
- = form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
- .devise-errors
- = render "devise/shared/error_messages", resource: resource
- - if Feature.enabled?(:invisible_captcha)
- = invisible_captcha
- .name.form-row
- .col.form-group
- = f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold'
- = f.text_field :first_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :max_length_message => _("First name is too long (maximum is %{max_length} characters).") % { max_length: max_first_name_length }, :qa_selector => 'new_user_first_name_field' }, required: true, title: _("This field is required.")
- .col.form-group
- = f.label :last_name, _('Last name'), for: 'new_user_last_name', class: 'label-bold'
- = f.text_field :last_name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_last_name_length, :max_length_message => _("Last name is too long (maximum is %{max_length} characters).") % { max_length: max_last_name_length }, :qa_selector => 'new_user_last_name_field' }, required: true, title: _("This field is required.")
- .username.form-group
- = f.label :username, class: 'label-bold'
- = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :min_length => min_username_length, :min_length_message => s_("SignUp|Username is too short (minimum is %{min_length} characters).") % { min_length: min_username_length }, :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
- %p.validation-error.gl-field-error-ignore.field-validation.hide= _('Username is already taken.')
- %p.validation-success.gl-field-error-ignore.field-validation.hide= _('Username is available.')
- %p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking username availability...')
- .form-group
- = f.label :email, class: 'label-bold'
- = f.email_field :email, value: @invite_email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.")
- .form-group.append-bottom-20#password-strength
- = f.label :password, class: 'label-bold'
- = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
- %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
- %div
- - if show_recaptcha_sign_up?
- = recaptcha_tags
- .submit-container
- = f.submit _("Register"), class: "btn-register btn", data: { qa_selector: 'new_user_register_button' }
- = render 'devise/shared/terms_of_service_notice'
+.gl-mb-3.gl-p-4.gl-border-gray-100.gl-border-1.gl-border-solid.gl-rounded-base
+ = form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f|
+ .devise-errors
+ = render "devise/shared/error_messages", resource: resource
+ - if Feature.enabled?(:invisible_captcha)
+ = invisible_captcha
+ .name.form-row
+ .col.form-group
+ = f.label :first_name, _('First name'), for: 'new_user_first_name', class: 'label-bold'
+ = f.text_field :first_name, class: 'form-control top js-block-emoji js-validate-length', :data => { :max_length => max_first_name_length, :max_length_message => _("First name is too long (maximum is %{max_length} characters).") % { max_length: max_first_name_length }, :qa_selector => 'new_user_first_name_field' }, required: true, title: _("This field is required.")
+ .col.form-group
+ = f.label :last_name, _('Last name'), for: 'new_user_last_name', class: 'label-bold'
+ = f.text_field :last_name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_last_name_length, :max_length_message => _("Last name is too long (maximum is %{max_length} characters).") % { max_length: max_last_name_length }, :qa_selector => 'new_user_last_name_field' }, required: true, title: _("This field is required.")
+ .username.form-group
+ = f.label :username, class: 'label-bold'
+ = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :min_length => min_username_length, :min_length_message => s_("SignUp|Username is too short (minimum is %{min_length} characters).") % { min_length: min_username_length }, :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
+ %p.validation-error.gl-text-red-500.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is already taken.')
+ %p.validation-success.gl-text-green-600.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is available.')
+ %p.validation-pending.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Checking username availability...')
+ .form-group
+ = f.label :email, class: 'label-bold'
+ = f.email_field :email, value: @invite_email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.")
+ .form-group.append-bottom-20#password-strength
+ = f.label :password, class: 'label-bold'
+ = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length }
+ %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length }
+ %div
+ - if show_recaptcha_sign_up?
+ = recaptcha_tags
+ .submit-container
+ = f.submit _("Register"), class: "btn gl-button btn-success", data: { qa_selector: 'new_user_register_button' }
+ = render 'devise/shared/terms_of_service_notice'
+ - if omniauth_enabled? && button_based_providers_enabled?
+ = render 'devise/shared/signup_omniauth_providers'
+
diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml b/app/views/devise/shared/_signup_omniauth_providers.haml
similarity index 100%
rename from app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml
rename to app/views/devise/shared/_signup_omniauth_providers.haml
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 9d0c3ad5787..1d12b30c58c 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -1,17 +1,4 @@
- page_description brand_title unless page_description
-
--# Needs a redirect on the client side since it's using an anchor to distinguish
--# between sign in and registration. We need to inline the JS to not render
--# anything from this page beforehand.
--# Part of an experiment to build a new sign up flow. Will be removed again with
--# https://gitlab.com/gitlab-org/growth/engineering/issues/64
-- if experiment_enabled?(:signup_flow) && current_path?("sessions#new")
- = javascript_tag nonce: true do
- :plain
- if (window.location.hash === '#register-pane') {
- window.location.replace("/users/sign_up")
- }
-
- site_name = "GitLab"
%head{ prefix: "og: http://ogp.me/ns#" }
%meta{ charset: "utf-8" }
diff --git a/app/views/layouts/devise_experimental_onboarding_issues.html.haml b/app/views/layouts/devise_experimental_onboarding_issues.html.haml
index ec9867f9e1f..f768fba84ca 100644
--- a/app/views/layouts/devise_experimental_onboarding_issues.html.haml
+++ b/app/views/layouts/devise_experimental_onboarding_issues.html.haml
@@ -1,6 +1,6 @@
!!! 5
%html.devise-layout-html.navless{ class: system_message_class }
- - add_page_specific_style 'page_bundles/experimental_separate_sign_up'
+ - add_page_specific_style 'page_bundles/signup'
= render "layouts/head"
%body.ui-indigo.signup-page{ class: "#{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } }
= render "layouts/header/logo_with_title"
diff --git a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml
deleted file mode 100644
index 6be62645768..00000000000
--- a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml
+++ /dev/null
@@ -1,20 +0,0 @@
-!!! 5
-%html.devise-layout-html.navless{ class: system_message_class }
- - add_page_specific_style 'page_bundles/experimental_separate_sign_up'
- = render "layouts/head"
- %body.ui-indigo.signup-page{ class: "#{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } }
- = render "layouts/header/logo_with_title"
- = render "layouts/init_client_detection_flags"
- .page-wrap
- .container.signup-box-container.navless-container
- = render "layouts/broadcast"
- .content
- = render "layouts/flash"
- = yield
- %hr.footer-fixed
- .footer-container
- .container
- .footer-links
- = link_to _("Help"), help_path
- = link_to _("About GitLab"), "https://about.gitlab.com/"
- = footer_message
diff --git a/app/views/layouts/welcome.html.haml b/app/views/layouts/welcome.html.haml
new file mode 100644
index 00000000000..48921e9ff89
--- /dev/null
+++ b/app/views/layouts/welcome.html.haml
@@ -0,0 +1,8 @@
+!!! 5
+%html.subscriptions-layout-html{ lang: 'en' }
+ = render 'layouts/head'
+ %body.ui-indigo.d-flex.vh-100.gl-bg-gray-10
+ = render "layouts/header/logo_with_title"
+ = render "layouts/broadcast"
+ .container.d-flex.flex-grow-1.m-0
+ = yield
diff --git a/app/views/registrations/welcome.html.haml b/app/views/registrations/welcome.html.haml
index bebcc2152af..dfb2d508f3a 100644
--- a/app/views/registrations/welcome.html.haml
+++ b/app/views/registrations/welcome.html.haml
@@ -1,6 +1,6 @@
- page_title _('Your profile')
-.row.gl-flex-grow-1.gl-bg-gray-10
+.row.gl-flex-grow-1
.d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-p-5
.edit-profile.login-page.d-flex.flex-column.gl-align-items-center.pt-lg-3
= render_if_exists "registrations/welcome/progress_bar"
diff --git a/app/views/shared/notes/_notes_with_form.html.haml b/app/views/shared/notes/_notes_with_form.html.haml
index 9baa340376b..1b03225d48d 100644
--- a/app/views/shared/notes/_notes_with_form.html.haml
+++ b/app/views/shared/notes/_notes_with_form.html.haml
@@ -19,7 +19,7 @@
= render "shared/notes/form", view: diff_view, supports_autocomplete: autocomplete
- elsif !current_user
.disabled-comment.text-center.gl-mt-3
- - link_to_register = link_to(_("register"), new_session_path(:user, redirect_to_referer: 'yes', anchor: 'register-pane'), class: 'js-register-link')
+ - link_to_register = link_to(_("register"), new_user_registration_path(redirect_to_referer: 'yes'), class: 'js-register-link')
- link_to_sign_in = link_to(_("sign in"), new_session_path(:user, redirect_to_referer: 'yes'), class: 'js-sign-in-link')
= _("Please %{link_to_register} or %{link_to_sign_in} to comment").html_safe % { link_to_register: link_to_register, link_to_sign_in: link_to_sign_in }
- elsif discussion_locked
diff --git a/app/workers/jira_connect/sync_branch_worker.rb b/app/workers/jira_connect/sync_branch_worker.rb
index 8c3416478fd..4c1c987353d 100644
--- a/app/workers/jira_connect/sync_branch_worker.rb
+++ b/app/workers/jira_connect/sync_branch_worker.rb
@@ -8,7 +8,7 @@ module JiraConnect
feature_category :integrations
loggable_arguments 1, 2
- def perform(project_id, branch_name, commit_shas)
+ def perform(project_id, branch_name, commit_shas, update_sequence_id = nil)
project = Project.find_by_id(project_id)
return unless project
@@ -16,7 +16,7 @@ module JiraConnect
branches = [project.repository.find_branch(branch_name)] if branch_name.present?
commits = project.commits_by(oids: commit_shas) if commit_shas.present?
- JiraConnect::SyncService.new(project).execute(commits: commits, branches: branches)
+ JiraConnect::SyncService.new(project).execute(commits: commits, branches: branches, update_sequence_id: update_sequence_id)
end
end
end
diff --git a/app/workers/jira_connect/sync_merge_request_worker.rb b/app/workers/jira_connect/sync_merge_request_worker.rb
index b78bb8dfe16..f45ab38f35d 100644
--- a/app/workers/jira_connect/sync_merge_request_worker.rb
+++ b/app/workers/jira_connect/sync_merge_request_worker.rb
@@ -7,12 +7,12 @@ module JiraConnect
queue_namespace :jira_connect
feature_category :integrations
- def perform(merge_request_id)
+ def perform(merge_request_id, update_sequence_id = nil)
merge_request = MergeRequest.find_by_id(merge_request_id)
return unless merge_request && merge_request.project
- JiraConnect::SyncService.new(merge_request.project).execute(merge_requests: [merge_request])
+ JiraConnect::SyncService.new(merge_request.project).execute(merge_requests: [merge_request], update_sequence_id: update_sequence_id)
end
end
end
diff --git a/changelogs/unreleased/250323-move-projects_with_error_tracking_enabled-to-core.yml b/changelogs/unreleased/250323-move-projects_with_error_tracking_enabled-to-core.yml
new file mode 100644
index 00000000000..8a602a858bd
--- /dev/null
+++ b/changelogs/unreleased/250323-move-projects_with_error_tracking_enabled-to-core.yml
@@ -0,0 +1,5 @@
+---
+title: Moves projects_with_error_tracking_enabled ping usage to Core
+merge_request: 46556
+author:
+type: changed
diff --git a/changelogs/unreleased/nicolasdular-split-signin-and-signup.yml b/changelogs/unreleased/nicolasdular-split-signin-and-signup.yml
new file mode 100644
index 00000000000..f4fdf10acad
--- /dev/null
+++ b/changelogs/unreleased/nicolasdular-split-signin-and-signup.yml
@@ -0,0 +1,5 @@
+---
+title: Split sign in and sign up pages
+merge_request: 42592
+author:
+type: changed
diff --git a/config/application.rb b/config/application.rb
index 0f550f40ea9..b01bd92e5e1 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -183,7 +183,7 @@ module Gitlab
config.assets.precompile << "page_bundles/environments.css"
config.assets.precompile << "page_bundles/error_tracking_details.css"
config.assets.precompile << "page_bundles/error_tracking_index.css"
- config.assets.precompile << "page_bundles/experimental_separate_sign_up.css"
+ config.assets.precompile << "page_bundles/signup.css"
config.assets.precompile << "page_bundles/ide.css"
config.assets.precompile << "page_bundles/issues_list.css"
config.assets.precompile << "page_bundles/jira_connect.css"
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index d073ed81afa..f5627cef621 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -262,6 +262,7 @@ Here are the valid connection parameters for GCS:
| `google_project` | GCP project name | `gcp-project-12345` |
| `google_client_email` | The email address of the service account | `foo@gcp-project-12345.iam.gserviceaccount.com` |
| `google_json_key_location` | The JSON key path | `/path/to/gcp-project-12345-abcde.json` |
+| `google_application_default` | Set to `true` to use [Google Cloud Application Default Credentials](https://cloud.google.com/docs/authentication/production#automatically) to locate service account credentials. |
NOTE: **Note:**
The service account must have permission to access the bucket.
@@ -280,6 +281,33 @@ gitlab_rails['object_store']['connection'] = {
}
```
+##### Google example with ADC (consolidated form)
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275979) in GitLab 13.6.
+
+Google Cloud Application Default Credentials (ADC) are typically
+used with GitLab to use the default service account. This eliminates the
+need to supply credentials for the instance. For example:
+
+```ruby
+gitlab_rails['object_store']['connection'] = {
+ 'provider' => 'Google',
+ 'google_project' => '',
+ 'google_application_default' => true
+}
+```
+
+If you use ADC, be sure that:
+
+- The service account that you use has the
+[`iam.serviceAccounts.signBlob` permission](https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob).
+ Typically this is done by granting the `Service Account Token Creator` role to the service account.
+- Your virtual machines have the [correct access scopes to access Google Cloud APIs](https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes). If the machines do not have the right scope, the error logs may show:
+
+ ```markdown
+ Google::Apis::ClientError (insufficientPermissions: Request had insufficient authentication scopes.)
+ ```
+
#### Azure Blob storage
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25877) in GitLab 13.4.
diff --git a/doc/raketasks/generate_sample_prometheus_data.md b/doc/raketasks/generate_sample_prometheus_data.md
index ef2376da0a9..f37aa95c63b 100644
--- a/doc/raketasks/generate_sample_prometheus_data.md
+++ b/doc/raketasks/generate_sample_prometheus_data.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Monitor
+group: Health
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
diff --git a/doc/subscriptions/gitlab_com/index.md b/doc/subscriptions/gitlab_com/index.md
index 948fee9230c..a03c8e758de 100644
--- a/doc/subscriptions/gitlab_com/index.md
+++ b/doc/subscriptions/gitlab_com/index.md
@@ -57,7 +57,7 @@ To subscribe to GitLab.com:
- **For individuals**:
1. Create a user account for yourself using our
- [sign up page](https://gitlab.com/users/sign_in#register-pane).
+ [sign up page](https://gitlab.com/users/sign_up).
1. Visit the [billing page](https://gitlab.com/profile/billings)
under your profile.
1. Select the **Bronze**, **Silver**, or **Gold** GitLab.com plan through the
@@ -70,7 +70,7 @@ To subscribe to GitLab.com:
1. Proceed to checkout.
- **For groups**:
1. Create a user account for yourself using our
- [sign up page](https://gitlab.com/users/sign_in#register-pane).
+ [sign up page](https://gitlab.com/users/sign_up).
1. Create a [group](../../user/group/index.md). GitLab groups help assemble related
projects together allowing you to grant members access to several projects
at once. A group is not required if you plan on having projects inside a personal
diff --git a/doc/user/profile/account/create_accounts.md b/doc/user/profile/account/create_accounts.md
index 09bfa7afc9e..cf5e4591a50 100644
--- a/doc/user/profile/account/create_accounts.md
+++ b/doc/user/profile/account/create_accounts.md
@@ -14,9 +14,9 @@ You can create users:
## Create users on sign in page
-If you have [sign-up enabled](../../admin_area/settings/sign_up_restrictions.md), users can create their own accounts using the **Register** tab on the sign in page.
+If you have [sign-up enabled](../../admin_area/settings/sign_up_restrictions.md), users can create their own accounts by selecting "Register now" on the sign-in page, or navigate to `https://gitlab.example.com/users/sign_up`.
-
+
## Create users in Admin Area
diff --git a/doc/user/profile/account/img/register_tab.png b/doc/user/profile/account/img/register_tab.png
deleted file mode 100644
index 4bbb4e62687..00000000000
Binary files a/doc/user/profile/account/img/register_tab.png and /dev/null differ
diff --git a/doc/user/profile/account/img/register_v13_6.png b/doc/user/profile/account/img/register_v13_6.png
new file mode 100644
index 00000000000..7c6eb04de79
Binary files /dev/null and b/doc/user/profile/account/img/register_v13_6.png differ
diff --git a/lib/atlassian/jira_connect/client.rb b/lib/atlassian/jira_connect/client.rb
index 0b578c03782..d548251b602 100644
--- a/lib/atlassian/jira_connect/client.rb
+++ b/lib/atlassian/jira_connect/client.rb
@@ -3,19 +3,24 @@
module Atlassian
module JiraConnect
class Client < Gitlab::HTTP
+ def self.generate_update_sequence_id
+ Gitlab::Metrics::System.monotonic_time.to_i
+ end
+
def initialize(base_uri, shared_secret)
@base_uri = base_uri
@shared_secret = shared_secret
end
- def store_dev_info(project:, commits: nil, branches: nil, merge_requests: nil)
+ def store_dev_info(project:, commits: nil, branches: nil, merge_requests: nil, update_sequence_id: nil)
dev_info_json = {
repositories: [
Serializers::RepositoryEntity.represent(
project,
commits: commits,
branches: branches,
- merge_requests: merge_requests
+ merge_requests: merge_requests,
+ update_sequence_id: update_sequence_id
)
]
}.to_json
diff --git a/lib/atlassian/jira_connect/serializers/base_entity.rb b/lib/atlassian/jira_connect/serializers/base_entity.rb
index c5490aa3f54..94deb174a45 100644
--- a/lib/atlassian/jira_connect/serializers/base_entity.rb
+++ b/lib/atlassian/jira_connect/serializers/base_entity.rb
@@ -9,12 +9,12 @@ module Atlassian
format_with(:string) { |value| value.to_s }
- expose :monotonic_time, as: :updateSequenceId
+ expose :update_sequence_id, as: :updateSequenceId
private
- def monotonic_time
- Gitlab::Metrics::System.monotonic_time.to_i
+ def update_sequence_id
+ options[:update_sequence_id] || Client.generate_update_sequence_id
end
end
end
diff --git a/lib/atlassian/jira_connect/serializers/repository_entity.rb b/lib/atlassian/jira_connect/serializers/repository_entity.rb
index 819ca2b62e0..9ae88ea21d1 100644
--- a/lib/atlassian/jira_connect/serializers/repository_entity.rb
+++ b/lib/atlassian/jira_connect/serializers/repository_entity.rb
@@ -15,13 +15,13 @@ module Atlassian
end
expose :commits do |project, options|
- JiraConnect::Serializers::CommitEntity.represent options[:commits], project: project
+ JiraConnect::Serializers::CommitEntity.represent options[:commits], project: project, update_sequence_id: options[:update_sequence_id]
end
expose :branches do |project, options|
- JiraConnect::Serializers::BranchEntity.represent options[:branches], project: project
+ JiraConnect::Serializers::BranchEntity.represent options[:branches], project: project, update_sequence_id: options[:update_sequence_id]
end
expose :pullRequests do |project, options|
- JiraConnect::Serializers::PullRequestEntity.represent options[:merge_requests], project: project
+ JiraConnect::Serializers::PullRequestEntity.represent options[:merge_requests], project: project, update_sequence_id: options[:update_sequence_id]
end
end
end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index ab49c3e6829..c4c372b0806 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -617,7 +617,8 @@ module Gitlab
operations_dashboard_default_dashboard: count(::User.active.with_dashboard('operations').where(time_period),
start: user_minimum_id,
finish: user_maximum_id),
- projects_with_tracing_enabled: distinct_count(::Project.with_tracing_enabled.where(time_period), :creator_id)
+ projects_with_tracing_enabled: distinct_count(::Project.with_tracing_enabled.where(time_period), :creator_id),
+ projects_with_error_tracking_enabled: distinct_count(::Project.with_enabled_error_tracking.where(time_period), :creator_id)
}
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 6bf07db03c7..11367498406 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -22016,9 +22016,6 @@ msgstr ""
msgid "Register device"
msgstr ""
-msgid "Register for GitLab"
-msgstr ""
-
msgid "Register now"
msgstr ""
@@ -25305,9 +25302,6 @@ msgstr ""
msgid "Specify the following URL during the Runner setup:"
msgstr ""
-msgid "Speed up your DevOps%{br_tag}with GitLab"
-msgstr ""
-
msgid "Squash commit message"
msgstr ""
@@ -29246,9 +29240,6 @@ msgstr ""
msgid "Username is available."
msgstr ""
-msgid "Username is too long (maximum is %{max_length} characters)."
-msgstr ""
-
msgid "Username or email"
msgstr ""
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 8eb28eb53e7..265e2b7573c 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -125,9 +125,9 @@ module QA
click_element :sign_in_tab
end
- def switch_to_register_tab
+ def switch_to_register_page
set_initial_password_if_present
- click_element :register_tab
+ click_element :register_link
end
def switch_to_ldap_tab
diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb
index 5cd4147e154..ca30ff12480 100644
--- a/qa/qa/resource/user.rb
+++ b/qa/qa/resource/user.rb
@@ -75,7 +75,7 @@ module QA
end
else
Page::Main::Login.perform do |login|
- login.switch_to_register_tab
+ login.switch_to_register_page
end
Page::Main::SignUp.perform do |signup|
signup.sign_up!(self)
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 31eaf3c83a5..cc7b469b3b8 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -12,30 +12,10 @@ RSpec.describe RegistrationsController do
describe '#new' do
subject { get :new }
- context 'with the experimental signup flow enabled and the user is part of the experimental group' do
- before do
- stub_experiment(signup_flow: true)
- stub_experiment_for_user(signup_flow: true)
- end
-
- it 'renders new template and sets the resource variable' do
- expect(subject).to render_template(:new)
- expect(response).to have_gitlab_http_status(:ok)
- expect(assigns(:resource)).to be_a(User)
- end
- end
-
- context 'with the experimental signup flow enabled and the user is part of the control group' do
- before do
- stub_experiment(signup_flow: true)
- stub_experiment_for_user(signup_flow: false)
- end
-
- it 'renders new template and sets the resource variable' do
- subject
- expect(response).to have_gitlab_http_status(:found)
- expect(response).to redirect_to(new_user_session_path(anchor: 'register-pane'))
- end
+ it 'renders new template and sets the resource variable' do
+ expect(subject).to render_template(:new)
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(assigns(:resource)).to be_a(User)
end
end
@@ -426,12 +406,10 @@ RSpec.describe RegistrationsController do
describe '#welcome' do
subject { get :welcome }
- it 'renders the devise_experimental_separate_sign_up_flow layout' do
+ it 'renders the welcome layout' do
sign_in(create(:user))
- expected_layout = Gitlab.ee? ? :checkout : :devise_experimental_separate_sign_up_flow
-
- expect(subject).to render_template(expected_layout)
+ expect(subject).to render_template(:welcome)
end
context '2FA is required from group' do
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index 8ccaf82536a..d1520a5a53a 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -58,6 +58,8 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'pre-fills the Email field on the sign up box with the invite_email from the invite' do
+ click_link 'Register now'
+
expect(find_field('Email').value).to eq(group_invite.invite_email)
end
@@ -92,6 +94,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
before do
stub_application_setting(send_user_confirmation_email: send_email_confirmation)
visit invite_path(group_invite.raw_invite_token)
+ click_link 'Register now'
end
context 'email confirmation disabled' do
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index f56c6f28f9d..0761c1871d3 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -26,7 +26,6 @@ RSpec.describe 'Login' do
user.reload
expect(user.reset_password_token).not_to be_nil
- find('a[href="#login-pane"]').click
gitlab_sign_in(user)
expect(current_path).to eq root_path
@@ -593,10 +592,16 @@ RSpec.describe 'Login' do
describe 'UI tabs and panes' do
context 'when no defaults are changed' do
- it 'correctly renders tabs and panes' do
+ it 'does not render any tabs' do
visit new_user_session_path
- ensure_tab_pane_correctness(['Sign in', 'Register'])
+ ensure_no_tabs
+ end
+
+ it 'renders link to sign up path' do
+ visit new_user_session_path
+
+ expect(page.body).to have_link('Register now', href: new_user_registration_path)
end
end
@@ -607,8 +612,14 @@ RSpec.describe 'Login' do
visit new_user_session_path
end
- it 'correctly renders tabs and panes' do
- ensure_tab_pane_correctness(['Sign in'])
+ it 'does not render any tabs' do
+ ensure_no_tabs
+ end
+
+ it 'does not render link to sign up path' do
+ visit new_user_session_path
+
+ expect(page.body).not_to have_link('Register now', href: new_user_registration_path)
end
end
@@ -644,7 +655,11 @@ RSpec.describe 'Login' do
end
it 'correctly renders tabs and panes' do
- ensure_tab_pane_correctness(['Main LDAP', 'Standard', 'Register'])
+ ensure_tab_pane_correctness(['Main LDAP', 'Standard'])
+ end
+
+ it 'renders link to sign up path' do
+ expect(page.body).to have_link('Register now', href: new_user_registration_path)
end
end
@@ -665,7 +680,7 @@ RSpec.describe 'Login' do
end
it 'correctly renders tabs and panes' do
- ensure_tab_pane_correctness(%w(Crowd Standard Register))
+ ensure_tab_pane_correctness(%w(Crowd Standard))
end
end
end
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index c59121626f0..bb2b465a69a 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -2,7 +2,45 @@
require 'spec_helper'
-RSpec.shared_examples 'Signup' do
+RSpec.shared_examples 'Signup name validation' do |field, max_length, label|
+ before do
+ visit new_user_registration_path
+ end
+
+ describe "#{field} validation", :js do
+ it "does not show an error border if the user's fullname length is not longer than #{max_length} characters" do
+ fill_in field, with: 'u' * max_length
+
+ expect(find('.name')).not_to have_css '.gl-field-error-outline'
+ end
+
+ it 'shows an error border if the user\'s fullname contains an emoji' do
+ simulate_input("##{field}", 'Ehsan 🦋')
+
+ expect(find('.name')).to have_css '.gl-field-error-outline'
+ end
+
+ it "shows an error border if the user\'s fullname is longer than #{max_length} characters" do
+ fill_in field, with: 'n' * (max_length + 1)
+
+ expect(find('.name')).to have_css '.gl-field-error-outline'
+ end
+
+ it "shows an error message if the user\'s #{label} is longer than #{max_length} characters" do
+ fill_in field, with: 'n' * (max_length + 1)
+
+ expect(page).to have_content("#{label} is too long (maximum is #{max_length} characters).")
+ end
+
+ it 'shows an error message if the username contains emojis' do
+ simulate_input("##{field}", 'Ehsan 🦋')
+
+ expect(page).to have_content("Invalid input, please avoid emojis")
+ end
+ end
+end
+
+RSpec.describe 'Signup' do
include TermsHelper
let(:new_user) { build_stubbed(:user) }
@@ -295,64 +333,7 @@ RSpec.shared_examples 'Signup' do
expect(created_user.setup_for_company).to be_nil
expect(page).to have_current_path(new_project_path)
end
-end
-RSpec.shared_examples 'Signup name validation' do |field, max_length, label|
- before do
- visit new_user_registration_path
- end
-
- describe "#{field} validation", :js do
- it "does not show an error border if the user's fullname length is not longer than #{max_length} characters" do
- fill_in field, with: 'u' * max_length
-
- expect(find('.name')).not_to have_css '.gl-field-error-outline'
- end
-
- it 'shows an error border if the user\'s fullname contains an emoji' do
- simulate_input("##{field}", 'Ehsan 🦋')
-
- expect(find('.name')).to have_css '.gl-field-error-outline'
- end
-
- it "shows an error border if the user\'s fullname is longer than #{max_length} characters" do
- fill_in field, with: 'n' * (max_length + 1)
-
- expect(find('.name')).to have_css '.gl-field-error-outline'
- end
-
- it "shows an error message if the user\'s #{label} is longer than #{max_length} characters" do
- fill_in field, with: 'n' * (max_length + 1)
-
- expect(page).to have_content("#{label} is too long (maximum is #{max_length} characters).")
- end
-
- it 'shows an error message if the username contains emojis' do
- simulate_input("##{field}", 'Ehsan 🦋')
-
- expect(page).to have_content("Invalid input, please avoid emojis")
- end
- end
-end
-
-RSpec.describe 'With original flow' do
- before do
- stub_experiment(signup_flow: false)
- stub_experiment_for_user(signup_flow: false)
- end
-
- it_behaves_like 'Signup'
- it_behaves_like 'Signup name validation', 'new_user_first_name', 127, 'First name'
- it_behaves_like 'Signup name validation', 'new_user_last_name', 127, 'Last name'
-end
-
-RSpec.describe 'With experimental flow' do
- before do
- stub_experiment(signup_flow: true)
- stub_experiment_for_user(signup_flow: true)
- end
-
- it_behaves_like 'Signup'
it_behaves_like 'Signup name validation', 'new_user_first_name', 127, 'First name'
it_behaves_like 'Signup name validation', 'new_user_last_name', 127, 'Last name'
end
diff --git a/spec/frontend/fixtures/static/signin_tabs.html b/spec/frontend/fixtures/static/signin_tabs.html
index 247a6b03054..7e66ab9394b 100644
--- a/spec/frontend/fixtures/static/signin_tabs.html
+++ b/spec/frontend/fixtures/static/signin_tabs.html
@@ -5,7 +5,4 @@
Standard
-
-Register
-
diff --git a/spec/frontend/notes/mock_data.js b/spec/frontend/notes/mock_data.js
index 4ff64abe4cc..7661d51aadf 100644
--- a/spec/frontend/notes/mock_data.js
+++ b/spec/frontend/notes/mock_data.js
@@ -7,7 +7,7 @@ export const notesDataMock = {
newSessionPath: '/users/sign_in?redirect_to_referer=yes',
notesPath: '/gitlab-org/gitlab-foss/noteable/issue/98/notes',
quickActionsDocsPath: '/help/user/project/quick_actions',
- registerPath: '/users/sign_in?redirect_to_referer=yes#register-pane',
+ registerPath: '/users/sign_up?redirect_to_referer=yes',
prerenderedNotesCount: 1,
closePath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=close',
reopenPath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=reopen',
diff --git a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
index 0d9af0cb856..4b50342bf84 100644
--- a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
+++ b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js
@@ -14,18 +14,16 @@ describe('preserve_url_fragment', () => {
loadFixtures('sessions/new.html');
});
- it('adds the url fragment to all login and sign up form actions', () => {
+ it('adds the url fragment to the login form actions', () => {
preserveUrlFragment('#L65');
expect($('#new_user').attr('action')).toBe('http://test.host/users/sign_in#L65');
- expect($('#new_new_user').attr('action')).toBe('http://test.host/users#L65');
});
- it('does not add an empty url fragment to login and sign up form actions', () => {
+ it('does not add an empty url fragment to the login form actions', () => {
preserveUrlFragment();
expect($('#new_user').attr('action')).toBe('http://test.host/users/sign_in');
- expect($('#new_new_user').attr('action')).toBe('http://test.host/users');
});
it('does not add an empty query parameter to OmniAuth login buttons', () => {
diff --git a/spec/lib/atlassian/jira_connect/client_spec.rb b/spec/lib/atlassian/jira_connect/client_spec.rb
index 40ffec21b26..2fd2fe66173 100644
--- a/spec/lib/atlassian/jira_connect/client_spec.rb
+++ b/spec/lib/atlassian/jira_connect/client_spec.rb
@@ -11,6 +11,14 @@ RSpec.describe Atlassian::JiraConnect::Client do
Timecop.freeze { example.run }
end
+ describe '.generate_update_sequence_id' do
+ it 'returns monotonic_time converted it to integer' do
+ allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(1.0)
+
+ expect(described_class.generate_update_sequence_id).to eq(1)
+ end
+ end
+
describe '#store_dev_info' do
it "calls the API with auth headers" do
expected_jwt = Atlassian::Jwt.encode(
diff --git a/spec/lib/atlassian/jira_connect/serializers/base_entity_spec.rb b/spec/lib/atlassian/jira_connect/serializers/base_entity_spec.rb
new file mode 100644
index 00000000000..d7672c0baf1
--- /dev/null
+++ b/spec/lib/atlassian/jira_connect/serializers/base_entity_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Atlassian::JiraConnect::Serializers::BaseEntity do
+ let(:update_sequence_id) { nil }
+
+ subject do
+ described_class.represent(
+ anything,
+ update_sequence_id: update_sequence_id
+ )
+ end
+
+ it 'generates the update_sequence_id' do
+ allow(Atlassian::JiraConnect::Client).to receive(:generate_update_sequence_id).and_return(1)
+
+ expect(subject.value_for(:updateSequenceId)).to eq(1)
+ end
+
+ context 'with update_sequence_id option' do
+ let(:update_sequence_id) { 123 }
+
+ it 'uses the custom update_sequence_id' do
+ expect(subject.value_for(:updateSequenceId)).to eq(123)
+ end
+ end
+end
diff --git a/spec/lib/atlassian/jira_connect/serializers/repository_entity_spec.rb b/spec/lib/atlassian/jira_connect/serializers/repository_entity_spec.rb
index 23ba1770827..9100398ecc5 100644
--- a/spec/lib/atlassian/jira_connect/serializers/repository_entity_spec.rb
+++ b/spec/lib/atlassian/jira_connect/serializers/repository_entity_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Atlassian::JiraConnect::Serializers::RepositoryEntity do
+ let(:update_sequence_id) { nil }
+
subject do
project = create(:project, :repository)
commits = [project.commit]
@@ -13,9 +15,23 @@ RSpec.describe Atlassian::JiraConnect::Serializers::RepositoryEntity do
project,
commits: commits,
branches: branches,
- merge_requests: merge_requests
+ merge_requests: merge_requests,
+ update_sequence_id: update_sequence_id
).to_json
end
it { is_expected.to match_schema('jira_connect/repository') }
+
+ context 'with custom update_sequence_id' do
+ let(:update_sequence_id) { 1.0 }
+
+ it 'passes the update_sequence_id on to the nested entities', :aggregate_failures do
+ parsed_subject = Gitlab::Json.parse(subject)
+
+ expect(parsed_subject['updateSequenceId']).to eq(update_sequence_id)
+ expect(parsed_subject['commits'].first['updateSequenceId']).to eq(update_sequence_id)
+ expect(parsed_subject['branches'].first['updateSequenceId']).to eq(update_sequence_id)
+ expect(parsed_subject['pullRequests'].first['updateSequenceId']).to eq(update_sequence_id)
+ end
+ end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 63a050e4f56..243da628204 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -294,19 +294,22 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
create(:project, creator: user)
create(:clusters_applications_prometheus, :installed, cluster: cluster)
create(:project_tracing_setting)
+ create(:project_error_tracking_setting)
end
expect(described_class.usage_activity_by_stage_monitor({})).to include(
clusters: 2,
clusters_applications_prometheus: 2,
operations_dashboard_default_dashboard: 2,
- projects_with_tracing_enabled: 2
+ projects_with_tracing_enabled: 2,
+ projects_with_error_tracking_enabled: 2
)
expect(described_class.usage_activity_by_stage_monitor(described_class.last_28_days_time_period)).to include(
clusters: 1,
clusters_applications_prometheus: 1,
operations_dashboard_default_dashboard: 1,
- projects_with_tracing_enabled: 1
+ projects_with_tracing_enabled: 1,
+ projects_with_error_tracking_enabled: 1
)
end
end
diff --git a/spec/services/jira_connect/sync_service_spec.rb b/spec/services/jira_connect/sync_service_spec.rb
index e26ca30d0e1..83088bb2e79 100644
--- a/spec/services/jira_connect/sync_service_spec.rb
+++ b/spec/services/jira_connect/sync_service_spec.rb
@@ -23,7 +23,8 @@ RSpec.describe JiraConnect::SyncService do
project: project,
commits: commits,
branches: [instance_of(Gitlab::Git::Branch)],
- merge_requests: merge_requests
+ merge_requests: merge_requests,
+ update_sequence_id: anything
).and_return(return_value)
end
end
diff --git a/spec/support/helpers/user_login_helper.rb b/spec/support/helpers/user_login_helper.rb
index 925576119bb..47e858cb68c 100644
--- a/spec/support/helpers/user_login_helper.rb
+++ b/spec/support/helpers/user_login_helper.rb
@@ -8,6 +8,10 @@ module UserLoginHelper
ensure_one_active_pane
end
+ def ensure_no_tabs
+ expect(page.all('[role="tab"]').size).to eq(0)
+ end
+
def ensure_tab_labels(tab_names)
tab_labels = page.all('[role="tab"]').map(&:text)
diff --git a/spec/workers/jira_connect/sync_branch_worker_spec.rb b/spec/workers/jira_connect/sync_branch_worker_spec.rb
index 2da3ea9d256..4aa2f89de7b 100644
--- a/spec/workers/jira_connect/sync_branch_worker_spec.rb
+++ b/spec/workers/jira_connect/sync_branch_worker_spec.rb
@@ -4,7 +4,10 @@ require 'spec_helper'
RSpec.describe JiraConnect::SyncBranchWorker do
describe '#perform' do
- let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :repository, group: group) }
+ let_it_be(:subscription) { create(:jira_connect_subscription, installation: create(:jira_connect_installation), namespace: group) }
+
let(:project_id) { project.id }
let(:branch_name) { 'master' }
let(:commit_shas) { %w(b83d6e3 5a62481) }
@@ -13,7 +16,7 @@ RSpec.describe JiraConnect::SyncBranchWorker do
def expect_jira_sync_service_execute(args)
expect_next_instance_of(JiraConnect::SyncService) do |instance|
- expect(instance).to receive(:execute).with(args)
+ expect(instance).to receive(:execute).with(args.merge(update_sequence_id: nil))
end
end
@@ -61,5 +64,31 @@ RSpec.describe JiraConnect::SyncBranchWorker do
subject
end
end
+
+ context 'with update_sequence_id' do
+ let(:update_sequence_id) { 1 }
+ let(:request_url) { 'https://sample.atlassian.net/rest/devinfo/0.10/bulk' }
+ let(:request_body) do
+ {
+ repositories: [
+ Atlassian::JiraConnect::Serializers::RepositoryEntity.represent(
+ project,
+ commits: project.commits_by(oids: commit_shas),
+ branches: [project.repository.find_branch(branch_name)],
+ update_sequence_id: update_sequence_id
+ )
+ ]
+ }.to_json
+ end
+
+ subject { described_class.new.perform(project_id, branch_name, commit_shas, update_sequence_id) }
+
+ it 'sends the reqeust with custom update_sequence_id' do
+ expect(Atlassian::JiraConnect::Client).to receive(:post)
+ .with(URI(request_url), headers: anything, body: request_body)
+
+ subject
+ end
+ end
end
end
diff --git a/spec/workers/jira_connect/sync_merge_request_worker_spec.rb b/spec/workers/jira_connect/sync_merge_request_worker_spec.rb
index 764201e750a..b3c0db4f260 100644
--- a/spec/workers/jira_connect/sync_merge_request_worker_spec.rb
+++ b/spec/workers/jira_connect/sync_merge_request_worker_spec.rb
@@ -4,14 +4,18 @@ require 'spec_helper'
RSpec.describe JiraConnect::SyncMergeRequestWorker do
describe '#perform' do
- let(:merge_request) { create(:merge_request) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :repository, group: group) }
+ let_it_be(:subscription) { create(:jira_connect_subscription, installation: create(:jira_connect_installation), namespace: group) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project) }
+
let(:merge_request_id) { merge_request.id }
subject { described_class.new.perform(merge_request_id) }
it 'calls JiraConnect::SyncService#execute' do
expect_next_instance_of(JiraConnect::SyncService) do |service|
- expect(service).to receive(:execute).with(merge_requests: [merge_request])
+ expect(service).to receive(:execute).with(merge_requests: [merge_request], update_sequence_id: nil)
end
subject
@@ -26,5 +30,30 @@ RSpec.describe JiraConnect::SyncMergeRequestWorker do
subject
end
end
+
+ context 'with update_sequence_id' do
+ let(:update_sequence_id) { 1 }
+ let(:request_url) { 'https://sample.atlassian.net/rest/devinfo/0.10/bulk' }
+ let(:request_body) do
+ {
+ repositories: [
+ Atlassian::JiraConnect::Serializers::RepositoryEntity.represent(
+ project,
+ merge_requests: [merge_request],
+ update_sequence_id: update_sequence_id
+ )
+ ]
+ }.to_json
+ end
+
+ subject { described_class.new.perform(merge_request_id, update_sequence_id) }
+
+ it 'sends the request with custom update_sequence_id' do
+ expect(Atlassian::JiraConnect::Client).to receive(:post)
+ .with(URI(request_url), headers: anything, body: request_body)
+
+ subject
+ end
+ end
end
end