Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-05-12 15:10:25 +00:00
parent 71a67d17b0
commit 4a882000a9
43 changed files with 562 additions and 117 deletions

View File

@ -156,7 +156,7 @@ eslint-as-if-foss:
needs: []
script:
- *yarn-install
- run_timed_command "yarn run eslint"
- run_timed_command "yarn run lint:eslint:all"
.karma-base:
extends: .frontend-test-base

View File

@ -1 +1 @@
55f05e10c18669ba920243bfef46ae9bb5f53c72
1be74fe6af19847eec28665da39ef03865329acb

View File

@ -92,6 +92,7 @@ export default {
<template #cell(commit)="{ item }">
<gl-link
v-if="item.pipeline && item.pipeline.project"
:href="item.pipeline.project.commit_url"
class="gl-text-gray-500"
data-testid="commit-link"

View File

@ -237,11 +237,6 @@
line-height: 34px;
margin: 0;
> li + li::before {
padding: 0 3px;
color: $gray-300;
}
a {
color: $gl-text-color;
}

View File

@ -106,6 +106,10 @@ class ApplicationController < ActionController::Base
redirect_back(fallback_location: default, **options)
end
def check_if_gl_com_or_dev
render_404 unless ::Gitlab.dev_env_or_com?
end
def not_found
render_404
end

View File

@ -86,7 +86,18 @@ class InvitesController < ApplicationController
if user_sign_up?
set_session_invite_params
redirect_to new_user_registration_path(invite_email: member.invite_email), notice: _("To accept this invitation, create an account or sign in.")
experiment(:invite_signup_page_interaction, actor: member) do |experiment_instance|
set_originating_member_id if experiment_instance.enabled?
experiment_instance.use do
redirect_to new_user_registration_path(invite_email: member.invite_email), notice: _("To accept this invitation, create an account or sign in.")
end
experiment_instance.try do
redirect_to new_users_sign_up_invite_path(invite_email: member.invite_email)
end
experiment_instance.track(:view)
end
else
redirect_to new_user_session_path(sign_in_redirect_params), notice: sign_in_notice
end
@ -95,7 +106,11 @@ class InvitesController < ApplicationController
def set_session_invite_params
session[:invite_email] = member.invite_email
session[:originating_member_id] = member.id if Members::InviteEmailExperiment.initial_invite_email?(params[:invite_type])
set_originating_member_id if Members::InviteEmailExperiment.initial_invite_email?(params[:invite_type])
end
def set_originating_member_id
session[:originating_member_id] = member.id
end
def sign_in_redirect_params

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
module Registrations
class InvitesController < RegistrationsController
layout 'simple_registration'
before_action :check_if_gl_com_or_dev
end
end

View File

@ -199,6 +199,7 @@ class RegistrationsController < Devise::RegistrationsController
return unless member
experiment(:invite_signup_page_interaction, actor: member).track(:form_submission)
experiment('members/invite_email', actor: member).track(:accepted)
end
end

View File

@ -16,7 +16,7 @@ module AuthHelper
twitter
).freeze
LDAP_PROVIDER = /\Aldap/.freeze
TRIAL_REGISTRATION_PROVIDERS = %w(google_oauth2 github).freeze
POPULAR_PROVIDERS = %w(google_oauth2 github).freeze
def ldap_enabled?
Gitlab::Auth::Ldap::Config.enabled?
@ -116,19 +116,12 @@ module AuthHelper
providers = button_based_providers.map(&:to_s) - disabled_providers
providers.sort_by do |provider|
case provider
when 'google_oauth2'
0
when 'github'
1
else
2
end
POPULAR_PROVIDERS.index(provider) || POPULAR_PROVIDERS.length
end
end
def trial_enabled_button_based_providers
enabled_button_based_providers & TRIAL_REGISTRATION_PROVIDERS
def popular_enabled_button_based_providers
enabled_button_based_providers & POPULAR_PROVIDERS
end
def button_based_providers_enabled?

View File

@ -0,0 +1,12 @@
# frozen_string_literal: true
module RegistrationsHelper
def social_signin_enabled?
::Gitlab.dev_env_or_com? &&
omniauth_enabled? &&
devise_mapping.omniauthable? &&
button_based_providers_enabled?
end
end
RegistrationsHelper.prepend_mod_with('RegistrationsHelper')

View File

@ -1,3 +1,3 @@
= render 'devise/shared/signup_omniauth_provider_list', providers: trial_enabled_button_based_providers
= render 'devise/shared/signup_omniauth_provider_list', providers: popular_enabled_button_based_providers
.omniauth-divider.d-flex.align-items-center.text-center
= _("or")

View File

@ -6,10 +6,8 @@
%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
.form-group.gl-mb-3
.form-check
= f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'form-check-input', data: { qa_selector: 'lfs_checkbox' }
= f.label :lfs_enabled, class: 'form-check-label' do
%span
= _('Allow projects within this group to use Git LFS')
%br/
%span.text-muted= _('This setting can be overridden in each project.')
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'custom-control-input', data: { qa_selector: 'lfs_checkbox' }
= f.label :lfs_enabled, class: 'custom-control-label' do
= _('Allow projects within this group to use Git LFS')
%p.help-text= _('This setting can be overridden in each project.')

View File

@ -7,17 +7,17 @@
%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
.form-group
.form-check
= f.check_box :require_two_factor_authentication, class: 'form-check-input', data: { qa_selector: 'require_2fa_checkbox' }
= f.label :require_two_factor_authentication, class: 'form-check-label' do
%span= _('Require all users in this group to setup two-factor authentication')
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :require_two_factor_authentication, class: 'custom-control-input', data: { qa_selector: 'require_2fa_checkbox' }
= f.label :require_two_factor_authentication, class: 'custom-control-label' do
= _('Require all users in this group to setup two-factor authentication')
.form-group
= f.label :two_factor_grace_period, _('Time before enforced'), class: 'label-bold'
= f.text_field :two_factor_grace_period, class: 'form-control form-control-sm w-auto'
.form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication')
- unless group.has_parent?
.form-group
.form-check
= f.check_box :allow_mfa_for_subgroups, class: 'form-check-input', checked: group.namespace_settings&.allow_mfa_for_subgroups
= f.label :allow_mfa_for_subgroups, class: 'form-check-label' do
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :allow_mfa_for_subgroups, class: 'custom-control-input', checked: group.namespace_settings&.allow_mfa_for_subgroups
= f.label :allow_mfa_for_subgroups, class: 'custom-control-label' do
= _('Allow subgroups to set up their own two-factor authentication rules')

View File

@ -0,0 +1,10 @@
!!! 5
%html{ lang: "en" }
= render "layouts/head"
%body.login-page.application.navless{ class: user_application_theme, data: { page: body_data_page } }
= render "layouts/header/logo_with_title"
= render "layouts/broadcast"
.container.navless-container.pt-0
.content.mw-460.mx-auto
= render "layouts/flash"
= yield

View File

@ -0,0 +1,18 @@
- page_title _('Join your team')
- add_page_specific_style 'page_bundles/signup'
- content_for :page_specific_javascripts do
= render "layouts/google_tag_manager_head"
= render "layouts/google_tag_manager_body"
%h2.center.pt-6.pb-3.gl-mb-0
= _('Join your team')
%p.gl-text-center= _('Create your own profile to collaborate with your teammates in issues, merge requests, and more.')
.signup-page
= render 'devise/shared/signup_box',
url: users_sign_up_invites_path,
button_text: _('Continue'),
show_omniauth_providers: social_signin_enabled?,
omniauth_providers_placement: :top,
suggestion_path: nil
= render 'devise/shared/sign_in_link'

View File

@ -1,6 +1,6 @@
- label_class = local_assigns.fetch(:bold_label, false) ? 'font-weight-bold' : ''
.form-check
= form.check_box :request_access_enabled, class: 'form-check-input', data: { qa_selector: 'request_access_checkbox' }
= form.label :request_access_enabled, class: 'form-check-label' do
.gl-form-checkbox.custom-control.custom-checkbox
= form.check_box :request_access_enabled, class: 'custom-control-input', data: { qa_selector: 'request_access_checkbox' }
= form.label :request_access_enabled, class: 'custom-control-label' do
%span{ class: label_class }= _('Allow users to request access (if visibility is public or internal)')

View File

@ -2786,7 +2786,7 @@
:tags: []
- :name: service_desk_email_receiver
:worker_name: ServiceDeskEmailReceiverWorker
:feature_category: :issue_tracking
:feature_category: :service_desk
:has_external_dependencies:
:urgency: :low
:resource_boundary: :unknown

View File

@ -3,6 +3,7 @@
class ServiceDeskEmailReceiverWorker < EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
feature_category :service_desk
sidekiq_options retry: 3
def should_perform?

View File

@ -0,0 +1,6 @@
---
title: Update checkbox styles in "Group" -> "Settings" -> "General" -> "Permissions,
LFS, 2FA"
merge_request: 61294
author:
type: other

View File

@ -0,0 +1,5 @@
---
title: Hide commit msg for package files without pipeline
merge_request: 61571
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Allow disabling build stage for Auto Devops
merge_request: 48638
author: Shane Davidson @shanekdavidson
type: added

View File

@ -0,0 +1,8 @@
---
name: api_caching_branches
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61157
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330371
milestone: '13.12'
type: development
group: group::source code
default_enabled: false

View File

@ -0,0 +1,8 @@
---
name: invite_signup_page_interaction
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60939
rollout_issue_url: https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/379
milestone: '13.12'
type: experiment
group: group::expansion
default_enabled: false

View File

@ -56,6 +56,7 @@ Rails.application.routes.draw do
end
resource :experience_level, only: [:show, :update]
resources :invites, only: [:new, :create]
Gitlab.ee do
resources :groups, only: [:new, :create]

View File

@ -853,9 +853,9 @@ Parameters for all comments:
| `position[start_sha]` | string | yes | SHA referencing commit in target branch |
| `position[head_sha]` | string | yes | SHA referencing HEAD of this merge request |
| `position[position_type]` | string | yes | Type of the position reference', allowed values: `text` or `image` |
| `position[new_path]` | string | no | File path after change |
| `position[new_path]` | string | yes (if the position type is `text`) | File path after change |
| `position[new_line]` | integer | no | Line number after change (for `text` diff notes) |
| `position[old_path]` | string | no | File path before change |
| `position[old_path]` | string | yes (if the position type is `text`) | File path before change |
| `position[old_line]` | integer | no | Line number before change (for `text` diff notes) |
| `position[line_range]` | hash | no | Line range for a multi-line diff note |
| `position[width]` | integer | no | Width of the image (for `image` diff notes) |
@ -863,10 +863,63 @@ Parameters for all comments:
| `position[x]` | float | no | X coordinate (for `image` diff notes) |
| `position[y]` | float | no | Y coordinate (for `image` diff notes) |
#### Create a new thread on the overview page
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions?body=comment"
```
#### Create a new thread in the merge request diff
- Both `position[old_path]` and `position[new_path]` are required and must refer to the file path before and after the change.
- To create a thread on an added line (highlighted in green in the merge request diff), use `position[new_line]` and don't include `position[old_line]`.
- To create a thread on a removed line (highlighted in red in the merge request diff), use `position[old_line]` and don't include `position[new_line]`.
- To create a thread on an unchanged line, include both `position[new_line]` and `position[old_line]` for the line. These positions might not be the same if earlier changes in the file changed the line number. This is a bug that we plan to fix in [GraphQL `createDiffNote` forces clients to compute redundant information (#325161)](https://gitlab.com/gitlab-org/gitlab/-/issues/325161).
- If you specify incorrect `base`/`head`/`start` `SHA` parameters, you might run into the following bug: [Merge request comments receive "download" link instead of inline code (#296829)](https://gitlab.com/gitlab-org/gitlab/-/issues/296829).
To create a new thread:
1. [Get the latest merge request version](merge_requests.md#get-mr-diff-versions):
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/versions"
````
1. Note the details of the latest version, which is listed first in the response array.
```json
[
{
"id": 164560414,
"head_commit_sha": "f9ce7e16e56c162edbc9e480108041cf6b0291fe",
"base_commit_sha": "5e6dffa282c5129aa67cd227a0429be21bfdaf80",
"start_commit_sha": "5e6dffa282c5129aa67cd227a0429be21bfdaf80",
"created_at": "2021-03-30T09:18:27.351Z",
"merge_request_id": 93958054,
"state": "collected",
"real_size": "2"
},
"previous versions are here"
]
```
1. Create a new diff thread. This example creates a thread on an added line:
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
--form 'position[position_type]=text'\
--form 'position[base_sha]=<use base_commit_sha from the versions response>'\
--form 'position[head_sha]=<use head_commit_sha from the versions response>'\
--form 'position[start_sha]=<use start_commit_sha from the versions response>'\
--form 'position[new_path]=file.js'\
--form 'position[old_path]=file.js'\
--form 'position[new_line]=18'\
--form 'body=test comment body'\
"https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions"
```
#### Parameters for multiline comments
Parameters for multiline comments only:
| Attribute | Type | Required | Description |

View File

@ -27,7 +27,7 @@ When requested across groups or projects, it's expected to be the same as the `f
## List issues
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
> Moved `weight` to GitLab Premium in 13.9.
Get all issues the authenticated user has access to. By default it
returns only issues created by the current user. To get all issues,
@ -233,7 +233,7 @@ that closed the issue still exists.
## List group issues
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
> Moved `weight` to GitLab Premium in 13.9.
Get a list of a group's issues.
@ -437,7 +437,7 @@ the issue still exists.
## List project issues
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
> Moved `weight` to GitLab Premium in 13.9.
Get a list of a project's issues.
@ -972,7 +972,7 @@ the issue still exists.
## New issue
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
> Moved `weight` to GitLab Premium in 13.9.
Creates a new project issue.
@ -1127,7 +1127,7 @@ See [Issues rate limits](../user/admin_area/settings/rate_limit_on_issues_creati
## Edit issue
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
> Moved `weight` to GitLab Premium in 13.9.
Updates an existing project issue. This call is also used to mark an issue as
closed.

View File

@ -387,6 +387,8 @@ The following table lists variables used to disable jobs.
|----------------------------------------|---------------------------------|-----------------------|-----------------|
| `.fuzz_base` | `COVFUZZ_DISABLED` | [From GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34984) | [Read more](../../user/application_security/coverage_fuzzing/) about how `.fuzz_base` provide capability for your own jobs. If the variable is present, your jobs aren't created. |
| `apifuzzer_fuzz` | `API_FUZZING_DISABLED` | [From GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39135) | If the variable is present, the job isn't created. |
| `build` | `BUILD_DISABLED` | | If the variable is present, the job isn't created. |
| `build_artifact` | `BUILD_DISABLED` | | If the variable is present, the job isn't created. |
| `bandit-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `brakeman-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `bundler-audit-dependency_scanning` | `DEPENDENCY_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |

View File

@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
---
# Contribution Analytics **(PREMIUM)**
> - Introduced in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3090) for subgroups in GitLab 12.2.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3090) in GitLab 12.2 for subgroups.
With Contribution Analytics you can get an overview of the following activity in your
group:
@ -16,8 +15,7 @@ group:
- Merge requests
- Push events
To view the Contribution Analytics, go to your group's **Analytics > Contribution Analytics**
page.
To view the Contribution Analytics, go to your group and select **Analytics > Contribution**.
## Use cases

View File

@ -6,9 +6,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Group DevOps Adoption **(ULTIMATE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321083) as a [Beta feature](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta) in GitLab 13.11.
> - [Deployed behind a feature flag](../../../user/feature_flags.md), enabled by default.
> - Not recommended for production use.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321083) in GitLab 13.11 as a [Beta feature](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta).
> - [Deployed behind a feature flag](../../../user/feature_flags.md), disabled by default.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/323159) in GitLab 13.12.
> - Enabled on GitLab.com.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-group-devops-adoption). **(ULTIMATE SELF)**
This in-development feature might not be available for your use. There can be
[risks when enabling features still in development](../../feature_flags.md#risks-when-enabling-features-still-in-development).
@ -41,7 +43,65 @@ With DevOps Adoption you can:
![DevOps Report](img/group_devops_adoption_v13_11.png)
## Enable or disable Group DevOps Adoption **(ULTIMATE)**
## Enable data processing
Group DevOps Adoption relies on data that has been gathered by a weekly data processing task.
This task is disabled by default.
To begin using Group DevOps Adoption, access the feature for the first time. GitLab automatically
enables the data processing for that group. The group data doesn't appear immediately, because
GitLab requires around a minute to process it.
## What is displayed
DevOps Adoption displays feature adoption data for the given group
and any added sub-groups for the current calendar month.
Each group appears as a separate row in the table.
For each row, a feature is considered "adopted" if it has been used in a project in the given group
during the time period (including projects in any sub-groups of the given group).
You should expect adoption to be lower at the beginning of the month,
before you have had an opportunity to use all the features listed in the table.
In the future [we plan to implement](https://gitlab.com/gitlab-org/gitlab/-/issues/329708)
a rolling 30-day perspective instead.
## When is a feature considered adopted
A feature is considered "adopted" if it has been used anywhere in the group in the specified time.
For example, if an issue was created in one project in a group, the group is considered to have
"adopted" issues in that time.
## No penalties for common adoption patterns
DevOps Adoption is designed not to penalize for any circumstances or practices that are common in DevOps.
Following this guideline, GitLab doesn't penalize for:
1. Having dormant projects. It's common for groups to have a mix of active and dormant projects,
so we should not consider adoption to be low if there are relatively many dormant projects.
This means we should not measure adoption by how many projects in the group have used a feature,
only by whether a feature was used anywhere in the group.
1. GitLab adding new features over time. It's common for group feature usage to be consistent
over time, so we should not consider adoption to have decreased if GitLab adds features.
This means we should not measure adoption by percentages, only total counts.
## Add a sub-group
DevOps Adoption can also display data for sub-groups within the given group,
to show you differences in adoption across the group.
To add a sub-group to your Group DevOps Adoption report:
1. Select **Add/remove sub-groups**.
1. Select the sub-group you want to add and select **Save changes**.
The sub-group data might not appear immediately, because GitLab requires around a minute to collect
the data.
Please note that the sub-group data might not appear immediately,
because GitLab requires a few moments to collect the data.
Generally the data will be visible in less than one minute.
## Enable or disable Group DevOps Adoption **(ULTIMATE SELF)**
Group DevOps Adoption is under development and not ready for production use. It is
deployed behind a feature flag that is **enabled by default**.

View File

@ -47,13 +47,25 @@ module API
merged_branch_names = repository.merged_branch_names(branches.map(&:name))
present(
branches,
with: Entities::Branch,
current_user: current_user,
project: user_project,
merged_branch_names: merged_branch_names
)
if Feature.enabled?(:api_caching_branches, user_project, type: :development, default_enabled: :yaml)
present_cached(
branches,
with: Entities::Branch,
current_user: current_user,
project: user_project,
merged_branch_names: merged_branch_names,
expires_in: 10.minutes,
cache_context: -> (branch) { [current_user&.cache_key, merged_branch_names.include?(branch.name)] }
)
else
present(
branches,
with: Entities::Branch,
current_user: current_user,
project: user_project,
merged_branch_names: merged_branch_names
)
end
end
resource ':id/repository/branches/:branch', requirements: BRANCH_ENDPOINT_REQUIREMENTS do

View File

@ -16,6 +16,8 @@ build:
fi
- /build/build.sh
rules:
- if: '$BUILD_DISABLED'
when: never
- if: '$AUTO_DEVOPS_PLATFORM_TARGET == "EC2"'
when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
@ -26,4 +28,6 @@ build_artifact:
- printf "To build your project, please create a build_artifact job into your .gitlab-ci.yml file.\nMore information at https://docs.gitlab.com/ee/ci/cloud_deployment\n"
- exit 1
rules:
- if: '$BUILD_DISABLED'
when: never
- if: '$AUTO_DEVOPS_PLATFORM_TARGET == "EC2"'

View File

@ -28,6 +28,10 @@ module Gitlab
def state
active? ? :active : :stale
end
def cache_key
"branch:" + Digest::SHA1.hexdigest([name, target, dereferenced_target&.sha].join(':'))
end
end
end
end

View File

@ -1520,9 +1520,15 @@ msgstr ""
msgid "APIFuzzing|$VariableWithUsername"
msgstr ""
msgid "APIFuzzing|/folder/example_file.har"
msgstr ""
msgid "APIFuzzing|/folder/example_file.json"
msgstr ""
msgid "APIFuzzing|/folder/example_file.postman_collection.json"
msgstr ""
msgid "APIFuzzing|API Fuzzing Configuration"
msgstr ""
@ -1562,19 +1568,16 @@ msgstr ""
msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
msgstr ""
msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz"
msgstr ""
msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz.har"
msgid "APIFuzzing|File path containing APIs to be tested. For example, /folder/example_file.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
msgstr ""
msgid "APIFuzzing|File path containing APIs to be tested. For example, /folder/example_file.json."
msgstr ""
msgid "APIFuzzing|Generate code snippet"
msgid "APIFuzzing|File path containing requests to be tested. For example, /folder/example_file.postman_collection.json."
msgstr ""
msgid "APIFuzzing|HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
msgid "APIFuzzing|Generate code snippet"
msgstr ""
msgid "APIFuzzing|Make sure your credentials are secured"
@ -1583,9 +1586,6 @@ msgstr ""
msgid "APIFuzzing|Password for basic authentication"
msgstr ""
msgid "APIFuzzing|Postman collections are a group of saved requests you can organize into folders."
msgstr ""
msgid "APIFuzzing|Predefined profiles"
msgstr ""
@ -9427,6 +9427,9 @@ msgstr ""
msgid "Create your group"
msgstr ""
msgid "Create your own profile to collaborate with your teammates in issues, merge requests, and more."
msgstr ""
msgid "Create/import your first project"
msgstr ""
@ -18384,6 +18387,9 @@ msgstr ""
msgid "Iterations|Duration"
msgstr ""
msgid "Iterations|Error loading iteration cadences."
msgstr ""
msgid "Iterations|Future iterations"
msgstr ""
@ -18393,6 +18399,9 @@ msgstr ""
msgid "Iterations|New iteration cadence"
msgstr ""
msgid "Iterations|No iteration cadences to show."
msgstr ""
msgid "Iterations|Number of future iterations you would like to have scheduled"
msgstr ""
@ -18807,6 +18816,9 @@ msgstr ""
msgid "Join Zoom meeting"
msgstr ""
msgid "Join your team"
msgstr ""
msgid "Joined %{time_ago}"
msgstr ""

View File

@ -59,37 +59,37 @@ module QA
def set_lfs_enabled
expand_content(:permission_lfs_2fa_content)
check_element(:lfs_checkbox)
check_element(:lfs_checkbox, true)
click_element(:save_permissions_changes_button)
end
def set_lfs_disabled
expand_content(:permission_lfs_2fa_content)
uncheck_element(:lfs_checkbox)
uncheck_element(:lfs_checkbox, true)
click_element(:save_permissions_changes_button)
end
def set_request_access_enabled
expand_content(:permission_lfs_2fa_content)
check_element(:request_access_checkbox)
check_element(:request_access_checkbox, true)
click_element(:save_permissions_changes_button)
end
def set_request_access_disabled
expand_content(:permission_lfs_2fa_content)
uncheck_element(:request_access_checkbox)
uncheck_element(:request_access_checkbox, true)
click_element(:save_permissions_changes_button)
end
def set_require_2fa_enabled
expand_content(:permission_lfs_2fa_content)
check_element(:require_2fa_checkbox)
check_element(:require_2fa_checkbox, true)
click_element(:save_permissions_changes_button)
end
def set_require_2fa_disabled
expand_content(:permission_lfs_2fa_content)
uncheck_element(:require_2fa_checkbox)
uncheck_element(:require_2fa_checkbox, true)
click_element(:save_permissions_changes_button)
end
@ -102,10 +102,10 @@ module QA
def toggle_request_access
expand_content(:permission_lfs_2fa_content)
if find_element(:request_access_checkbox).checked?
uncheck_element(:request_access_checkbox)
if find_element(:request_access_checkbox, visible: false).checked?
uncheck_element(:request_access_checkbox, true)
else
check_element(:request_access_checkbox)
check_element(:request_access_checkbox, true)
end
click_element(:save_permissions_changes_button)

View File

@ -127,10 +127,38 @@ RSpec.describe InvitesController do
expect(flash[:notice]).to include('create an account or sign in')
end
it 'is redirected to a new registration with invite email param' do
request
context 'when it is part of our invite email experiment', :experiment, :aggregate_failures do
let(:experience) { :control }
expect(response).to redirect_to(new_user_registration_path(invite_email: member.invite_email))
before do
stub_experiments(invite_signup_page_interaction: experience)
end
it 'sets originating_member_id session key' do
request
expect(session[:originating_member_id]).to eq(member.id)
end
context 'with control experience' do
it 'is redirected to a new registration with invite email param and flash message' do
request
expect(response).to redirect_to(new_user_registration_path(invite_email: member.invite_email))
expect(flash[:notice]).to eq 'To accept this invitation, create an account or sign in.'
end
end
context 'with candidate experience' do
let(:experience) { :candidate }
it 'is redirected to a new invite registration with invite email param and no flash message' do
request
expect(response).to redirect_to(new_users_sign_up_invite_path(invite_email: member.invite_email))
expect(flash[:notice]).to be_nil
end
end
end
it 'sets session keys for auto email confirmation on sign up' do

View File

@ -187,6 +187,38 @@ RSpec.describe RegistrationsController do
end
end
context 'when it is part of our invite_signup_page_interaction experiment', :experiment do
let_it_be(:member) { create(:project_member, :invited, invite_email: user_params.dig(:user, :email)) }
let(:originating_member_id) { member.id }
let(:session_params) do
{
invite_email: user_params.dig(:user, :email),
originating_member_id: originating_member_id
}
end
context 'when member exists from the session key value' do
it 'tracks the experiment' do
expect(experiment(:invite_signup_page_interaction)).to track(:form_submission)
.with_context(actor: member)
.on_next_instance
subject
end
end
context 'when member does not exist from the session key value' do
let(:originating_member_id) { -1 }
it 'tracks the experiment' do
expect(experiment(:invite_signup_page_interaction)).not_to track(:form_submission)
subject
end
end
end
context 'when invite email matches email used on registration' do
let(:session_params) { { invite_email: user_params.dig(:user, :email) } }

View File

@ -24,13 +24,13 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
visit user_confirmation_path(confirmation_token: new_user_token)
end
def fill_in_sign_up_form(new_user)
def fill_in_sign_up_form(new_user, submit_button_text = 'Register')
fill_in 'new_user_first_name', with: new_user.first_name
fill_in 'new_user_last_name', with: new_user.last_name
fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: new_user.email
fill_in 'new_user_password', with: new_user.password
click_button 'Register'
click_button submit_button_text
end
def fill_in_sign_in_form(user)
@ -50,7 +50,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
visit invite_path(group_invite.raw_invite_token)
end
it 'renders sign in page with sign in notice' do
it 'renders sign up page with sign up notice' do
expect(current_path).to eq(new_user_registration_path)
expect(page).to have_content('To accept this invitation, create an account or sign in')
end
@ -149,30 +149,11 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
end
context 'when soft email confirmation is not enabled' do
before do
allow(User).to receive(:allow_unconfirmed_access_for).and_return 0
end
it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
expect(current_path).to eq(activity_group_path(group))
end
end
context 'when soft email confirmation is enabled' do
before do
allow(User).to receive(:allow_unconfirmed_access_for).and_return 2.days
end
it 'signs up and redirects to to the group activity page with all the project/groups invitation automatically accepted' do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
expect(current_path).to eq(activity_group_path(group))
end
expect(current_path).to eq(activity_group_path(group))
end
context 'the user sign-up using a different email address' do
@ -211,6 +192,57 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
end
context 'with invite_signup_page_interaction experiment on', :experiment do
context 'with control experience' do
before do
stub_experiments(invite_signup_page_interaction: :control)
end
it 'lands on invite sign up page and tracks the accepted invite' do
expect(experiment(:invite_signup_page_interaction)).to track(:view)
.with_context(actor: group_invite)
.on_next_instance
visit invite_path(group_invite.raw_invite_token)
expect(current_path).to eq(new_user_registration_path)
expect(experiment(:invite_signup_page_interaction)).to track(:form_submission)
.with_context(actor: group_invite)
.on_next_instance
fill_in_sign_up_form(new_user, 'Register')
expect(current_path).to eq(users_sign_up_welcome_path)
end
end
context 'with candidate experience on .com' do
before do
allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
stub_experiments(invite_signup_page_interaction: :candidate)
end
it 'lands on invite sign up page and tracks the accepted invite' do
expect(experiment(:invite_signup_page_interaction)).to track(:view)
.with_context(actor: group_invite)
.on_next_instance
visit invite_path(group_invite.raw_invite_token)
expect(current_path).to eq(new_users_sign_up_invite_path)
expect(experiment(:invite_signup_page_interaction)).to track(:form_submission)
.with_context(actor: group_invite)
.on_next_instance
fill_in_sign_up_form(new_user, 'Continue')
expect(current_path).to eq(users_sign_up_welcome_path)
end
end
end
context 'when declining the invitation' do
context 'as an existing user' do
let(:group_invite) { create(:group_member, user: user, group: group, created_by: owner) }

View File

@ -11,8 +11,10 @@ describe('Package Files', () => {
const findAllRows = () => wrapper.findAll('[data-testid="file-row"');
const findFirstRow = () => findAllRows().at(0);
const findSecondRow = () => findAllRows().at(1);
const findFirstRowDownloadLink = () => findFirstRow().find('[data-testid="download-link"');
const findFirstRowCommitLink = () => findFirstRow().find('[data-testid="commit-link"');
const findSecondRowCommitLink = () => findSecondRow().find('[data-testid="commit-link"');
const findFirstRowFileIcon = () => findFirstRow().find(FileIcon);
const findFirstRowCreatedAt = () => findFirstRow().find(TimeAgoTooltip);
@ -126,5 +128,14 @@ describe('Package Files', () => {
expect(findFirstRowCommitLink().exists()).toBe(false);
});
});
describe('when only one file lacks an associated pipeline', () => {
it('renders the commit when it exists and not otherwise', () => {
createComponent([npmFiles[0], mavenFiles[0]]);
expect(findFirstRowCommitLink().exists()).toBe(true);
expect(findSecondRowCommitLink().exists()).toBe(false);
});
});
});
});

View File

@ -77,8 +77,8 @@ RSpec.describe AuthHelper do
end
context 'all providers are enabled to sign in' do
it 'returns all the enabled providers from settings' do
expect(helper.enabled_button_based_providers).to include('twitter', 'github', 'google_oauth2', 'openid_connect')
it 'returns all the enabled providers from settings in expected order' do
expect(helper.enabled_button_based_providers).to match(%w[google_oauth2 github twitter openid_connect])
end
it 'puts google and github in the beginning' do
@ -99,19 +99,19 @@ RSpec.describe AuthHelper do
end
end
describe 'trial_enabled_button_based_providers' do
it 'returns the intersection set of github & google_oauth2 with enabled providers' do
describe 'popular_enabled_button_based_providers' do
it 'returns the intersection set of popular & enabled providers', :aggregate_failures do
allow(helper).to receive(:enabled_button_based_providers) { %w(twitter github google_oauth2) }
expect(helper.trial_enabled_button_based_providers).to eq(%w(github google_oauth2))
expect(helper.popular_enabled_button_based_providers).to eq(%w(github google_oauth2))
allow(helper).to receive(:enabled_button_based_providers) { %w(google_oauth2 bitbucket) }
expect(helper.trial_enabled_button_based_providers).to eq(%w(google_oauth2))
expect(helper.popular_enabled_button_based_providers).to eq(%w(google_oauth2))
allow(helper).to receive(:enabled_button_based_providers) { %w(bitbucket) }
expect(helper.trial_enabled_button_based_providers).to be_empty
expect(helper.popular_enabled_button_based_providers).to be_empty
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe RegistrationsHelper do
using RSpec::Parameterized::TableSyntax
describe '#social_signin_enabled?' do
before do
allow(::Gitlab).to receive(:dev_env_or_com?).and_return(com)
allow(view).to receive(:omniauth_enabled?).and_return(omniauth_enabled)
allow(view).to receive(:button_based_providers_enabled?).and_return(button_based_providers_enabled)
allow(view).to receive(:devise_mapping).and_return(double(omniauthable?: omniauthable))
end
subject { helper.social_signin_enabled? }
where com: [true, false],
omniauth_enabled: [true, false],
omniauthable: [true, false],
button_based_providers_enabled: [true, false]
with_them do
let(:result) { com && omniauth_enabled && button_based_providers_enabled && omniauthable }
it { is_expected.to eq(result) }
end
end
end

View File

@ -44,6 +44,16 @@ RSpec.describe Gitlab::Git::Branch, :seed_helper do
end
end
describe "#cache_key" do
subject { repository.branches.first }
it "returns a cache key that changes based on changeable values" do
digest = Digest::SHA1.hexdigest([subject.name, subject.target, subject.dereferenced_target.sha].join(":"))
expect(subject.cache_key).to eq("branch:#{digest}")
end
end
describe '#size' do
subject { super().size }

View File

@ -53,7 +53,7 @@ RSpec.describe API::Branches do
end
it 'determines only a limited number of merged branch names' do
expect(API::Entities::Branch).to receive(:represent).with(anything, has_up_to_merged_branch_names_count(2)).and_call_original
expect(API::Entities::Branch).to receive(:represent).with(anything, has_up_to_merged_branch_names_count(2)).at_least(:once).and_call_original
get api(route, current_user), params: base_params.merge(per_page: 2)
@ -111,7 +111,7 @@ RSpec.describe API::Branches do
end
it 'determines only a limited number of merged branch names' do
expect(API::Entities::Branch).to receive(:represent).with(anything, has_up_to_merged_branch_names_count(2)).and_call_original
expect(API::Entities::Branch).to receive(:represent).with(anything, has_up_to_merged_branch_names_count(2)).at_least(:once).and_call_original
get api(route, current_user), params: base_params.merge(per_page: 2)

View File

@ -0,0 +1,68 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Registering from an invite' do
let(:com) { true }
before do
allow(Gitlab).to receive(:dev_env_or_com?).and_return(com)
end
describe 'GET /users/sign_up/invites/new' do
subject(:request) { get '/users/sign_up/invites/new' }
context 'when on .com' do
it 'renders the template with expected text', :aggregate_failures do
request
expect(response).to render_template('layouts/simple_registration')
expect(response).to render_template(:new)
expect(response.body).to include('Join your team')
end
end
context 'when not on .com' do
let(:com) { false }
it 'returns not found' do
request
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe 'POST /users/sign_up/invites' do
subject(:request) do
post '/users/sign_up/invites',
params: {
user: {
first_name: 'first',
last_name: 'last',
username: 'new_username',
email: 'new@user.com',
password: 'Any_password'
}
}
end
context 'when on .com' do
it 'creates a user' do
expect { request }.to change(User, :count).by(1)
expect(response).to have_gitlab_http_status(:found)
end
end
context 'when not on .com' do
let(:com) { false }
it 'returns not found' do
request
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end