Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-10-14 18:16:04 +00:00
parent 75dbbc4a87
commit 72b735b5f2
81 changed files with 610 additions and 494 deletions

View File

@ -1 +1 @@
18a6087f7e43e9219de607dbe363c54bb73101d8
d1cf3491ba7c28ee609e87ba796218713077a297

View File

@ -1 +1 @@
afa804f189e2e143cbe807af1003e46dcb41eb6b
22dc62058605bb04bb302295b79a1169649dcb14

View File

@ -71,11 +71,9 @@ export default {
</td>
<td class="gl-px-3 gl-py-4 gl-align-top">
<h4 class="gl-mb-0 gl-mt-0 gl-text-base">
<gl-link
v-safe-html="mergeRequest.titleHtml"
:href="mergeRequest.webUrl"
class="gl-text-primary hover:gl-text-gray-900"
/>
<gl-link :href="mergeRequest.webUrl" class="gl-text-primary hover:gl-text-gray-900">
{{ mergeRequest.title }}
</gl-link>
</h4>
<div class="gl-mb-2 gl-mt-2 gl-text-sm gl-text-secondary">
<gl-sprintf

View File

@ -6,7 +6,7 @@
fragment MergeRequestDashboardFragment on MergeRequest {
id
reference(full: true)
titleHtml
title
webUrl
author {
...User

View File

@ -17,7 +17,6 @@ import {
I18N_HELP_TEXT,
I18N_SEND_TO_SECONDARY_EMAIL_BUTTON_TEXT,
I18N_SEND_TO_SECONDARY_EMAIL_GUIDE,
I18N_CHECK_SUPPORT_PAGE_TEXT,
SUPPORT_URL,
VERIFICATION_CODE_REGEX,
SUCCESS_RESPONSE,
@ -172,7 +171,6 @@ export default {
helpText: I18N_HELP_TEXT,
sendToSecondaryEmailButtonText: I18N_SEND_TO_SECONDARY_EMAIL_BUTTON_TEXT,
sendToSecondaryEmailGuide: I18N_SEND_TO_SECONDARY_EMAIL_GUIDE,
checkSupportPageText: I18N_CHECK_SUPPORT_PAGE_TEXT,
supportUrl: SUPPORT_URL,
},
forms: {
@ -236,10 +234,7 @@ export default {
>
</section>
<p class="gl-mt-3 gl-text-secondary">
<gl-sprintf
v-if="glFeatures.sendVerificationCodeToSecondaryEmail"
:message="$options.i18n.helpText"
>
<gl-sprintf :message="$options.i18n.helpText">
<template #sendToSecondaryEmailButton>
<gl-button
class="gl-align-baseline"
@ -252,11 +247,6 @@ export default {
<gl-link :href="$options.i18n.supportUrl" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
<gl-sprintf v-else :message="$options.i18n.checkSupportPageText">
<template #supportLink="{ content }">
<gl-link :href="$options.i18n.supportUrl" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
</gl-form>
</div>

View File

@ -29,9 +29,6 @@ export const I18N_HELP_TEXT = s__(
export const I18N_SEND_TO_SECONDARY_EMAIL_GUIDE = s__(
'IdentityVerification|Enter a verified email address associated with this account. A new code will be sent to this address.',
);
export const I18N_CHECK_SUPPORT_PAGE_TEXT = s__(
"IdentityVerification|If you've lost access to the email associated to this account or having trouble with the code, %{supportLinkStart}here are some other steps you can take.%{supportLinkEnd}",
);
export const I18N_CANCEL = __('Cancel');
export const I18N_EMAIL_INVALID = s__('IdentityVerification|Please enter a valid email address.');
export const I18N_UPDATE_EMAIL_SUCCESS = s__(

View File

@ -40,8 +40,10 @@ export default {
};
},
mounted() {
this.isNarrowScreen = isNarrowScreen(this.$refs?.buttonRoot);
isNarrowScreenAddListener(this.$refs?.buttonRoot, this.handleNarrowScreenChange);
if (this.$refs?.buttonRoot) {
this.isNarrowScreen = isNarrowScreen(this.$refs.buttonRoot);
isNarrowScreenAddListener(this.$refs.buttonRoot, this.handleNarrowScreenChange);
}
},
beforeDestroy() {
isNarrowScreenRemoveListener(this.$refs.buttonRoot, this.handleNarrowScreenChange);

View File

@ -22,8 +22,6 @@ module VerifiesWithEmail
# when the password is correct, which could be a giveaway when brute-forced.
return render_sign_in_rate_limited if check_rate_limit!(:user_sign_in, scope: user) { true }
push_frontend_feature_flag(:send_verification_code_to_secondary_email, user)
# Verify the email if the user has logged in successfully.
verify_email(user) if user.valid_password?(user_params[:password])
end
@ -41,8 +39,7 @@ module VerifiesWithEmail
else
secondary_email = user_secondary_email(user, email_params[:email])
if Feature.enabled?(:send_verification_code_to_secondary_email, user) &&
email_params[:email].present? && secondary_email.present?
if email_params[:email].present? && secondary_email.present?
send_verification_instructions(user, secondary_email: secondary_email)
elsif email_params[:email].blank?
send_verification_instructions(user)

View File

@ -47,7 +47,7 @@ module Mutations
required: false,
description: 'Full path of the project the work item is associated with.',
deprecated: {
reason: 'Please use namespace_path instead. That will cover for both projects and groups',
reason: 'Please use namespacePath instead. That will cover for both projects and groups',
milestone: '15.10'
}
argument :title,

View File

@ -882,8 +882,13 @@ class MergeRequestDiff < ApplicationRecord
end
def keep_around_commits
# The merge head keeps track of what an actual merge might look like. The
# referenced merge is temporary and so is kept alive with
# MergeRequest#merge_ref_path which is updated as required.
return if merge_head?
[repository, merge_request.source_project.repository].uniq.each do |repo|
repo.keep_around(start_commit_sha, head_commit_sha, base_commit_sha, source: self.class.name)
repo.keep_around(start_commit_sha, head_commit_sha, source: self.class.name)
end
end

View File

@ -329,6 +329,7 @@ module Auth
def repository_path_push_protected?
return false if Feature.disabled?(:container_registry_protected_containers, project&.root_ancestor)
return false if current_user&.can_admin_all_resources?
push_scopes = scopes.select { |scope| scope[:actions].include?('push') || scope[:actions].include?('*') }

View File

@ -1,9 +0,0 @@
---
name: send_verification_code_to_secondary_email
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/416451
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165313
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/484893
milestone: '17.5'
group: group::anti-abuse
type: gitlab_com_derisk
default_enabled: false

View File

@ -537,6 +537,8 @@
- 1
- - merge_requests_process_auto_merge_from_event
- 1
- - merge_requests_process_merge_audit_event
- 1
- - merge_requests_remove_user_approval_rules
- 1
- - merge_requests_resolve_todos

View File

@ -5,4 +5,4 @@ feature_category: portfolio_management
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153678
milestone: '17.1'
queued_migration_version: 20240521093524
finalized_by: # version of the migration that finalized this BBM
finalized_by: '20241010232133'

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
class FinalizeBackfillBoardsEpicListsGroupId < Gitlab::Database::Migration[2.2]
milestone '17.5'
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
def up
ensure_batched_background_migration_is_finished(
job_class_name: 'BackfillBoardsEpicListsGroupId',
table_name: :boards_epic_lists,
column_name: :id,
job_arguments: [:group_id, :boards_epic_boards, :group_id, :epic_board_id],
finalize: true
)
end
def down; end
end

View File

@ -0,0 +1 @@
3dbbfb2880123f915697fda46b5e4f10ccdc772862a2d22ef65bb5eb8a660c3f

View File

@ -0,0 +1,91 @@
---
stage: Verify
group: Pipeline Execution
description: Calculations, quotas, purchase information.
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Compute minutes administration
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** Self-managed, GitLab Dedicated
> - [Renamed](https://gitlab.com/groups/gitlab-com/-/epics/2150) from "CI/CD minutes" to "compute quota" or "compute minutes" in GitLab 16.1.
Administrators can limit the amount of time that projects can use to run jobs on
[instance runners](../../ci/runners/runners_scope.md#instance-runners) each month. This limit
is tracked with a [compute minutes quota](../../ci/pipelines/compute_minutes.md).
[Project runners](../../ci/runners/runners_scope.md#project-runners) are not subject to the compute quota.
On self-managed GitLab instances:
- Compute quotas are disabled by default.
- Administrators can [assign more compute minutes](#set-the-compute-quota-for-a-group)
if a namespace uses all its monthly quota.
- The [cost factors](../../ci/pipelines/compute_minutes.md#cost-factor) are:
- `0` for public projects, so they do not consume compute minutes.
- `1` for internal and private projects.
[Trigger jobs](../../ci/yaml/index.md#trigger) do not execute on runners, so they do not
consume compute minutes, even when using [`strategy:depend`](../../ci/yaml/index.md#triggerstrategy)
to wait for the [downstream pipeline](../../ci/pipelines/downstream_pipelines.md) status.
The triggered downstream pipeline consumes compute minutes the same as other pipelines.
GitLab.com administrators can add a namespace to the [reduced cost factor](../../ci/pipelines/compute_minutes.md#reduce-compute-quota-usage)
with the `ci_minimal_cost_factor_for_gitlab_namespaces` [feature flag](../../administration/feature_flags.md).
## Set the compute quota for all namespaces
By default, GitLab instances do not have a compute quota. The default value for the quota is `0`,
which is unlimited.
Prerequisites:
- You must be a GitLab administrator.
To change the default quota that applies to all namespaces:
1. On the left sidebar, at the bottom, select **Admin**.
1. Select **Settings > CI/CD**.
1. Expand **Continuous Integration and Deployment**.
1. In the **Compute quota** box, enter a limit.
1. Select **Save changes**.
If a quota is already defined for a specific namespace, this value does not change that quota.
## Set the compute quota for a group
You can override the global value and set a compute quota for a group.
Prerequisites:
- You must be a GitLab administrator.
- The group must be a top-level group, not a subgroup.
To set a compute quota for a group or namespace:
1. On the left sidebar, at the bottom, select **Admin**.
1. Select **Overview > Groups**.
1. For the group you want to update, select **Edit**.
1. In the **Compute quota** box, enter the maximum number of compute minutes.
1. Select **Save changes**.
You can also use the [update group API](../../api/groups.md#update-group) or the
[update user API](../../api/users.md#modify-a-user) instead.
## Reset compute usage
An administrator can reset the compute usage for a namespace for the current month.
### Reset usage for a personal namespace
1. Find the [user in the **Admin** area](../admin_area.md#administering-users).
1. Select **Edit**.
1. In **Limits**, select **Reset compute usage**.
### Reset usage for a group namespace
1. Find the [group in the **Admin** area](../admin_area.md#administering-groups).
1. Select **Edit**.
1. In **Permissions and group features**, select **Reset compute usage**.

View File

@ -74,6 +74,7 @@ this method only supports replies, and not the other features of [incoming email
> - Accepting `Cc` headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348572) in GitLab 16.5.
> - Accepting `X-Original-To` headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/149874) in GitLab 17.0.
> - Accepting `X-Forwarded-To` headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168716) in GitLab 17.6.
Email is processed correctly when a configured email address is present in one of the following headers
(sorted in the order they are checked):
@ -83,6 +84,7 @@ Email is processed correctly when a configured email address is present in one o
- `Envelope-To` or `X-Envelope-To`
- `Received`
- `X-Original-To`
- `X-Forwarded-To`
- `Cc`
The `References` header is also accepted, however it is used specifically to relate email responses to existing discussion threads. It is not used for creating issues by email.

View File

@ -10840,7 +10840,7 @@ Input type: `WorkItemCreateInput`
| <a id="mutationworkitemcreatelinkeditemswidget"></a>`linkedItemsWidget` | [`WorkItemWidgetLinkedItemsCreateInput`](#workitemwidgetlinkeditemscreateinput) | Input for linked items widget. |
| <a id="mutationworkitemcreatemilestonewidget"></a>`milestoneWidget` | [`WorkItemWidgetMilestoneInput`](#workitemwidgetmilestoneinput) | Input for milestone widget. |
| <a id="mutationworkitemcreatenamespacepath"></a>`namespacePath` | [`ID`](#id) | Full path of the namespace(project or group) the work item is created in. |
| <a id="mutationworkitemcreateprojectpath"></a>`projectPath` **{warning-solid}** | [`ID`](#id) | **Deprecated:** Please use namespace_path instead. That will cover for both projects and groups. Deprecated in GitLab 15.10. |
| <a id="mutationworkitemcreateprojectpath"></a>`projectPath` **{warning-solid}** | [`ID`](#id) | **Deprecated:** Please use namespacePath instead. That will cover for both projects and groups. Deprecated in GitLab 15.10. |
| <a id="mutationworkitemcreaterolledupdateswidget"></a>`rolledupDatesWidget` **{warning-solid}** | [`WorkItemWidgetRolledupDatesInput`](#workitemwidgetrolledupdatesinput) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 16.9. |
| <a id="mutationworkitemcreatetitle"></a>`title` | [`String!`](#string) | Title of the work item. |
| <a id="mutationworkitemcreateweightwidget"></a>`weightWidget` | [`WorkItemWidgetWeightInput`](#workitemwidgetweightinput) | Input for weight widget. |

View File

@ -8,23 +8,18 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Compute minutes
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** GitLab.com, Self-managed
**Tier:** Free, Premium, Ultimate
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
> - [Renamed](https://gitlab.com/groups/gitlab-com/-/epics/2150) from "CI/CD minutes" to "compute quota" or "compute minutes" in GitLab 16.1.
NOTE:
The term `CI/CD minutes` is being renamed to `compute minutes`. During this transition, you might see references in the UI and documentation to `CI/CD minutes`, `CI minutes`, `pipeline minutes`, `CI pipeline minutes`, `pipeline minutes quota`, `compute credits`, `compute units`, and `compute minutes`. For more information, see [epic 2150](https://gitlab.com/groups/gitlab-com/-/epics/2150).
The amount of time that projects can use to run jobs on [instance runners](../runners/runners_scope.md#instance-runners)
on GitLab.com is limited. This limit is tracked with a compute quota. [Project runners](../runners/runners_scope.md#project-runners)
are not subject to the compute quota.
Administrators can limit the amount of time that projects can use to run jobs on
[instance runners](../runners/runners_scope.md#instance-runners) each month. This limit
is tracked with a compute quota.
By default, one minute of execution time by a single job uses
one compute minute. The total execution time for a pipeline is
[the sum of all its jobs' durations](#how-compute-usage-is-calculated).
Jobs can run concurrently, so the total usage can be higher than the
end-to-end duration of a pipeline.
By default, one minute of execution time by a single job uses one compute minute.
The total compute usage for a pipeline is calculated using [the sum of all its jobs' durations](#compute-usage-calculation).
Jobs can run concurrently, so the total usage can be higher than the end-to-end duration of a pipeline.
On GitLab.com:
@ -32,75 +27,22 @@ On GitLab.com:
projects [consume compute minutes at a slower rate](#cost-factor).
- The base monthly compute quota for a GitLab.com [namespace](../../user/namespace/index.md)
is determined by its [license tier](https://about.gitlab.com/pricing/).
- You can [purchase additional compute minutes](#purchase-additional-compute-minutes)
- You can [purchase additional compute minutes](../../subscriptions/gitlab_com/compute_minutes.md)
if you need more than the amount of compute in your monthly quota.
On self-managed GitLab instances:
- Compute quotas are disabled by default.
- When enabled, compute quotas apply to private projects only.
- Administrators can [assign more compute minutes](#set-the-compute-quota-for-a-specific-namespace)
if a namespace uses all its monthly quota.
[Trigger jobs](../../ci/yaml/index.md#trigger) do not execute on runners, so they do not
consume compute minutes, even when using [`strategy:depend`](../yaml/index.md#triggerstrategy)
to wait for the [downstream pipeline](../pipelines/downstream_pipelines.md) status.
The triggered downstream pipeline consumes compute minutes the same as other pipelines.
[Project runners](../runners/runners_scope.md#project-runners) are not subject to a compute quota.
## Set the compute quota for all namespaces
By default, GitLab instances do not have a compute quota.
The default value for the quota is `0`, which is unlimited.
However, you can change this default value.
Prerequisites:
- You must be a GitLab administrator.
To change the default quota that applies to all namespaces:
1. On the left sidebar, at the bottom, select **Admin**.
1. Select **Settings > CI/CD**.
1. Expand **Continuous Integration and Deployment**.
1. In the **Compute quota** box, enter a limit.
1. Select **Save changes**.
If a quota is already defined for a specific namespace, this value does not change that quota.
## Set the compute quota for a specific namespace
You can override the global value and set a compute quota
for a specific namespace.
Prerequisites:
- You must be a GitLab administrator.
To set a compute quota for a namespace:
1. On the left sidebar, at the bottom, select **Admin**.
1. Select **Overview > Groups**.
1. For the group you want to update, select **Edit**.
1. In the **Compute quota** box, enter the maximum number of compute minutes.
1. Select **Save changes**.
You can also use the [update group API](../../api/groups.md#update-group) or the
[update user API](../../api/users.md#modify-a-user) instead.
NOTE:
You can set a compute quota for only top-level groups or user namespaces.
If you set a quota for a subgroup, it is not used.
Compute quotas [are disabled by default on self-managed instances](../../administration/cicd/compute_minutes.md).
## View compute usage
Prerequisites:
You can view the compute usage for a group or personal namespace to understand
compute usage trends and how many compute minutes remain.
- You must have access to the build to view the total usage and quota summary for a namespace associated with a build.
- Access to **Usage Quotas** page is based on your role for the associated namespace or group.
In some cases, the quota limit is replaced by one of the following labels:
### View Usage Quota Reports for a group
- **Unlimited**: For namespaces with unlimited compute quota.
- **Not supported**: For namespaces where active instance runners are not enabled.
### View usage quota reports for a group
> - Displaying instance runners duration per project [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/355666) in GitLab 15.0.
@ -119,130 +61,42 @@ The projects list shows projects with compute usage or instance runners usage
in the current month only. The list includes all projects in the namespace and its
subgroups, sorted in descending order of compute usage.
### View Usage Quota reports for a personal namespace
### View usage quota reports for a personal namespace
> - Displaying instance runners duration [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345795) in GitLab 15.0.
Prerequisites:
- The namespace must be your personal namespace.
You can view the compute usage for a personal namespace:
You can view the compute usage for your personal namespace:
1. On the left sidebar, select your avatar.
1. Select **Edit profile**.
1. On the left sidebar, select **Usage Quotas**.
The projects list shows [personal projects](../../user/project/working_with_projects.md#view-personal-projects)
with compute usage or instance runners usage in the current month only. The list
is sorted in descending order of compute usage.
with compute usage or instance runners usage in the current month only.
## Purchase additional compute minutes
### Exceeding the quota
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** GitLab.com
On GitLab.com an in-app banner is displayed and an email notification sent to the
namespace owners when the remaining compute minutes is:
If you're using GitLab.com, you can purchase additional packs of compute minutes.
These additional compute minutes:
- Less than 30% of the quota.
- Less than 5% of the quota.
- Completely used (zero minutes remaining).
- Are used only after the monthly quota included in your subscription runs out.
- Are carried over to the next month, if any remain at the end of the month.
- Are valid for 12 months from date of purchase or until all compute minutes are consumed, whichever comes first. Expiry of compute minutes is not enforced.
When the compute quota is used for the current month, instance runners stop processing new jobs.
In pipelines that have already started:
For example, with a GitLab.com Premium license:
- Any pending job (not yet started) or retried job that must be processed by instance runners is dropped.
- Jobs running on instance runners can continue to run until the overall namespace usage goes over-quota
by 1,000 compute minutes. After the 1,000 compute minute grace period, any remaining running jobs
are also dropped.
- You have `10,000` monthly compute minutes.
- You purchase an additional `5,000` compute minutes.
- Your total limit is `15,000` compute minutes.
If you're using GitLab.com, you can [purchase additional packs of compute minutes](../../subscriptions/gitlab_com/index.md)
to continue running CI/CD pipelines on instance runners.
If you use `13,000` compute minutes during the month, the next month your additional compute minutes become
`2,000`. If you use `9,000` compute minutes during the month, your additional compute minutes remain the same.
Project runners are not affected by the compute quota and continue processing jobs.
Additional compute minutes bought on a trial subscription are available after the trial ends or upgrading to a paid plan.
You can find pricing for additional compute minutes on the
[GitLab Pricing page](https://about.gitlab.com/pricing/).
### Purchase compute minutes for a group
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** GitLab.com
Prerequisites:
- You must have the Owner role for the group.
You can purchase additional compute minutes for your group.
You cannot transfer purchased compute minutes from one group to another,
so be sure to select the correct group.
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Settings > Usage Quotas**.
1. Select **Pipelines**.
1. Select **Buy additional compute minutes**. You are taken to the Customers Portal.
1. Enter the desired quantity of compute minute packs.
1. In the **Customer information** section, verify your address.
1. In the **Billing information** section, select a payment method from the dropdown list.
1. Select the **Privacy Statement** and **Terms of Service** checkboxes.
1. Select **Buy compute minutes**.
After your payment is processed, the additional compute minutes are added to your group
namespace.
### Purchase compute minutes for a personal namespace
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** GitLab.com
Prerequisites:
- The namespace must be your personal namespace.
To purchase additional compute minutes for your personal namespace:
1. On the left sidebar, select your avatar.
1. Select **Edit profile**.
1. On the left sidebar, select **Usage Quotas**.
1. Select **Buy additional compute minutes**. You are taken to the Customers Portal.
1. In the **Subscription details** section, select the name of the user from the dropdown list.
1. Enter the desired quantity of compute minute packs.
1. In the **Customer information** section, verify your address.
1. In the **Billing information** section, select a payment method from the dropdown list.
1. Select the **Privacy Statement** and **Terms of Service** checkboxes.
1. Select **Buy compute minutes**.
After your payment is processed, the additional compute minutes are added to your personal
namespace.
### Troubleshooting
#### Error: `Last name can't be blank`
You might get an error "Last name can't be blank" when purchasing compute minutes. This issue occurs when a last name is missing from the **Full name** field of your profile.
To resolve the issue:
1. Ensure that your user profile has a last name filled in:
- On the left sidebar, select your avatar.
- Select **Edit profile**.
- Update the **Full name** field to have both first name and last name, save the changes.
1. Clear your browser cache and cookies, then try the purchase process again.
1. If the error persists, try using a different web browser or an incognito/private browsing window.
#### Error: `Attempt_Exceed_Limitation - Attempt exceed the limitation, refresh page to try again`
You might get the error `Attempt_Exceed_Limitation - Attempt exceed the limitation, refresh page to try again.` when purchasing compute minutes.
This issue occurs when the credit card form is re-submitted too quickly within a specific time frame (three submissions within one minute or six submissions within one hour).
To resolve this issue, wait a few minutes and try the purchase process again.
## How compute usage is calculated
## Compute usage calculation
GitLab uses this formula to calculate the compute usage of a job:
@ -250,46 +104,53 @@ GitLab uses this formula to calculate the compute usage of a job:
Job duration * Cost factor
```
- **Job duration**: The time, in seconds, that a job took to run on a instance runner,
- **Job duration**: The time, in seconds, that a job took to run on an instance runner,
not including time spent in the `created` or `pending` statuses.
- [**Cost factor**](#cost-factor): A number based on project visibility.
- [**Cost factor**](#cost-factor): A number based on the project type.
The value is transformed into compute minutes and added to the count of used units
The value is converted into compute minutes and added to the count of used units
in the job's top-level namespace.
For example, if a user `alice` runs a pipeline:
- Under the `gitlab-org` namespace, the compute minutes used by each job in the pipeline are
- In a project in the `gitlab-org` namespace, the compute minutes used by each job in the pipeline are
added to the overall consumption for the `gitlab-org` namespace, not the `alice` namespace.
- For one of the personal projects in their namespace, the compute minutes are added
to the overall consumption for the `alice` namespace.
- In a personal projects in their `alice` namespace, the compute minutes are added
to the overall consumption for their namespace.
The compute used by one pipeline is the total compute minutes used by all the jobs
that ran in the pipeline. Jobs can run concurrently, so the total compute usage
can be higher than the end-to-end duration of a pipeline.
[Trigger jobs](../../ci/yaml/index.md#trigger) do not execute on runners, so they do not
consume compute minutes, even when using [`strategy:depend`](../yaml/index.md#triggerstrategy)
to wait for the [downstream pipeline](../pipelines/downstream_pipelines.md) status.
The triggered downstream pipeline consumes compute minutes the same as other pipelines.
### Cost factor
The cost factors for jobs running on instance runners on GitLab.com are:
The default cost factors for jobs running on instance runners on GitLab.com are:
- `1` for internal, public, and private projects.
- Exceptions for public projects:
- `0.5` for projects in the [GitLab for Open Source program](../../subscriptions/community_programs.md#gitlab-for-open-source).
- `0.008` for forks of projects in the [GitLab for Open Source program](../../subscriptions/community_programs.md#gitlab-for-open-source). For every 125 minutes of job execution time,
you use 1 compute minute.
- Discounted dynamically for [community contributions to GitLab projects](#cost-factor-for-community-contributions-to-gitlab-projects).
For every 1 minute of job execution time, you use 1 compute minute.
- `0.5` for public projects in the [GitLab for Open Source program](../../subscriptions/community_programs.md#gitlab-for-open-source).
For every 2 minutes of job execution time, you use 1 compute minute.
- `0.008` for public forks of projects in the [GitLab for Open Source program](../../subscriptions/community_programs.md#gitlab-for-open-source).
For every 125 minutes of job execution time, you use 1 compute minute.
- Discounted dynamically for [community contributions to GitLab projects](#community-contributions-to-gitlab-projects).
- Increased if you use [different types of instance runners](#gitlab-hosted-runner-cost-factors).
The cost factors on self-managed instances are:
The cost factors on self-managed instances [are different](../../administration/cicd/compute_minutes.md).
- `0` for public projects, so they do not consume compute minutes.
- `1` for internal and private projects.
#### Cost factor for community contributions to GitLab projects
#### Community contributions to GitLab projects
Community contributors can use up to 300,000 minutes on instance runners when contributing to open source projects
maintained by GitLab. The maximum of 300,000 minutes would only be possible if contributing exclusively to projects [part of the GitLab product](https://handbook.gitlab.com/handbook/engineering/metrics/#projects-that-are-part-of-the-product). The total number of minutes available on instance runners
is reduced by the compute minutes used by pipelines from other projects.
The 300,000 minutes applies to all SaaS tiers, and the cost factor calculation is:
maintained by GitLab. The maximum of 300,000 minutes would only be possible if contributing exclusively to projects
[part of the GitLab product](https://handbook.gitlab.com/handbook/engineering/metrics/#projects-that-are-part-of-the-product).
The total number of minutes available on instance runners is reduced by the compute minutes used by pipelines from
other projects. The 300,000 minutes applies to all GitLab.com tiers.
The cost factor calculation is:
- `Monthly compute quota / 300,000 job duration minutes = Cost factor`
@ -305,82 +166,37 @@ For this reduced cost factor:
- The merge request target project must be the fork's parent project.
- The pipeline must be a merge request, merged results, or merge train pipeline.
GitLab administrators can add a namespace to the reduced cost factor
[with a flag](../../administration/feature_flags.md) named `ci_minimal_cost_factor_for_gitlab_namespaces`.
#### GitLab-hosted runner cost factors
### GitLab-hosted runner costs
GitLab-hosted runners have different cost factors, depending on the runner type (Linux, Windows, macOS) and the virtual machine configuration.
GitLab-hosted runners have different cost factors depending on the runner type
(Linux, Windows, macOS) and the virtual machine configuration:
| GitLab-hosted runner type | Machine Size | Cost factor |
|:---------------------------|:-----------------------|:------------|
| Linux x86-64 | `small` | 1 |
| Linux x86-64 | `medium` | 2 |
| Linux x86-64 | `large` | 3 |
| Linux x86-64 | `xlarge` | 6 |
| Linux x86-64 | `2xlarge` | 12 |
| Linux x86-64 + GPU-enabled | `medium`, GPU standard | 7 |
| Linux Arm64 | `medium` | 2 |
| Linux Arm64 | `large` | 3 |
| macOS M1 | `medium` | 6 (**Status:** Beta) |
| Windows | `medium` | 1 (**Status:** Beta) |
| Linux x86-64 (default) | `small` | `1` |
| Linux x86-64 | `medium` | `2` |
| Linux x86-64 | `large` | `3` |
| Linux x86-64 | `xlarge` | `6` |
| Linux x86-64 | `2xlarge` | `12` |
| Linux x86-64 + GPU-enabled | `medium`, GPU standard | `7` |
| Linux Arm64 | `medium` | `2` |
| Linux Arm64 | `large` | `3` |
| macOS M1 | `medium` | `6` (**Status:** Beta) |
| Windows | `medium` | `1` (**Status:** Beta) |
### Monthly reset of compute usage
On the first day of each calendar month, the accumulated compute usage is reset to `0`
for all namespaces that use instance runners. This means your full quota is available, and
calculations start again from `0`.
for all namespaces.
For example, if you have a monthly quota of `10,000` compute minutes:
For example, if you have a monthly quota of 10,000 compute minutes:
- On **1st April**, you have `10,000` compute minutes.
- During April, you use only `6,000` of the `10,000` compute minutes.
- On **1st May**, the accumulated compute usage resets to `0`, and you have `10,000` compute minutes to use again
during May.
1. On April 1 you have 10,000 compute minutes available.
1. During April, you use 6,000 of the 10,000 compute minutes.
1. On May 1, the accumulated compute usage resets to 0, and you have 10,000
compute minutes available for May.
Usage data for the previous month is kept to show historical view of the consumption over time.
### Monthly rollover of purchased compute minutes
If you purchase additional compute minutes and don't use the full amount, the remaining amount rolls over to
the next month.
For example:
- On **April 1**, you purchase `5,000` additional compute minutes.
- During April, you use only `3,000` of the `5,000` additional compute minutes.
- On **May 1**, the unused compute minutes roll over, so you have `2,000` additional compute minutes available for May.
Additional compute minutes are a one-time purchase and do not renew or refresh each month.
## What happens when you exceed the quota
When the compute quota is used for the current month, GitLab stops
processing new jobs.
- Any non-running job that should be picked by instance runners is automatically dropped.
- Any job being retried is automatically dropped.
- Any running job can be dropped at any point if the overall namespace usage goes over-quota
by a grace period.
The grace period for running jobs is `1,000` compute minutes.
Jobs on project runners are not affected by the compute quota.
### GitLab.com usage notifications
On GitLab.com an in-app banner is displayed and an email notification sent to the namespace owners when:
- The remaining compute minutes is below 30% of the quota.
- The remaining compute minutes is below 5% of the quota.
- All the compute quota has been used.
### Special quota limits
In some cases, the quota limit is replaced by one of the following labels:
- **Unlimited**: For namespaces with unlimited compute quota.
- **Not supported**: For namespaces where active instance runners are not enabled.
Usage data for the previous month is kept to show a historical view of the consumption over time.
## Reduce compute quota usage
@ -402,24 +218,4 @@ use to reduce your usage:
If you manage an open source project, these improvements can also reduce compute quota
consumption for contributor fork projects, enabling more contributions.
See our [pipeline efficiency guide](pipeline_efficiency.md) for more details.
## Reset compute usage
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** Self-managed, GitLab Dedicated
An administrator can reset the compute usage for a namespace for the current month.
### Reset usage for a personal namespace
1. Find the [user in the **Admin** area](../../administration/admin_area.md#administering-users).
1. Select **Edit**.
1. In **Limits**, select **Reset compute usage**.
### Reset usage for a group namespace
1. Find the [group in the **Admin** area](../../administration/admin_area.md#administering-groups).
1. Select **Edit**.
1. In **Permissions and group features**, select **Reset compute usage**.
See the [pipeline efficiency guide](pipeline_efficiency.md) for more details.

View File

@ -87,9 +87,9 @@ For more information about how caching works, see [Architecture diagram of hoste
### Pricing of hosted runners for GitLab.com
Jobs that run on hosted runners for GitLab.com consume [compute minutes](../pipelines/compute_minutes.md) allocated to your namespace.
The number of minutes you can use on these runners depends on the included compute minutes in your [subscription plan](https://about.gitlab.com/pricing/) or [additionally purchased compute minutes](../pipelines/compute_minutes.md#purchase-additional-compute-minutes).
The number of minutes you can use on these runners depends on the included compute minutes in your [subscription plan](https://about.gitlab.com/pricing/) or [additionally purchased compute minutes](../../subscriptions/gitlab_com/compute_minutes.md#purchase-additional-compute-minutes).
For more information about the cost factor applied to the machine type based on size, see [cost factor](../../ci/pipelines/compute_minutes.md#gitlab-hosted-runner-costs).
For more information about the cost factor applied to the machine type based on size, see [cost factor](../../ci/pipelines/compute_minutes.md#gitlab-hosted-runner-cost-factors).
### SLO & Release cycle for hosted runners for GitLab.com

View File

@ -28,7 +28,7 @@ multiple projects.
If you are using a self-managed instance of GitLab, administrators can:
- [Install GitLab Runner](https://docs.gitlab.com/runner/install/index.html) and register an instance runner.
- Configure a maximum number of instance runner [compute minutes for each group](../pipelines/compute_minutes.md#set-the-compute-quota-for-a-specific-namespace).
- Configure a maximum number of instance runner [compute minutes for each group](../../administration/cicd/compute_minutes.md#set-the-compute-quota-for-a-group).
If you are using GitLab.com:

View File

@ -0,0 +1,108 @@
---
stage: Verify
group: Pipeline Execution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Purchase additional compute minutes
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** GitLab.com
[Compute minutes](../../ci/pipelines/compute_minutes.md) is the resource consumed
when running [CI/CD pipelines](../../ci/index.md) on GitLab instance runners. You can find
pricing for additional compute minutes on the [GitLab Pricing page](https://about.gitlab.com/pricing/).
Additional compute minutes:
- Are valid for 12 months from date of purchase or until all compute minutes are consumed,
whichever comes first. Expiry of compute minutes is not enforced.
- Are used only after the monthly quota included in your subscription runs out.
- Are [carried over to the next month](#monthly-rollover-of-purchased-compute-minutes),
if any remain at the end of the month.
- Bought on a trial subscription are available after the trial ends or upgrading to a paid plan.
## Purchase compute minutes for a group
Prerequisites:
- You must have the Owner role for the group.
You can purchase additional compute minutes for your group.
You cannot transfer purchased compute minutes from one group to another,
so be sure to select the correct group.
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Settings > Usage Quotas**.
1. Select **Pipelines**.
1. Select **Buy additional compute minutes**. You are taken to the Customers Portal.
1. Enter the desired quantity of compute minute packs.
1. In the **Customer information** section, verify your address.
1. In the **Billing information** section, select a payment method from the dropdown list.
1. Select the **Privacy Statement** and **Terms of Service** checkboxes.
1. Select **Buy compute minutes**.
After your payment is processed, the additional compute minutes are added to your group
namespace.
## Purchase compute minutes for a personal namespace
To purchase additional compute minutes for your personal namespace:
1. On the left sidebar, select your avatar.
1. Select **Edit profile**.
1. On the left sidebar, select **Usage Quotas**.
1. Select **Buy additional compute minutes**. You are taken to the Customers Portal.
1. In the **Subscription details** section, select the name of the user from the dropdown list.
1. Enter the desired quantity of compute minute packs.
1. In the **Customer information** section, verify your address.
1. In the **Billing information** section, select a payment method from the dropdown list.
1. Select the **Privacy Statement** and **Terms of Service** checkboxes.
1. Select **Buy compute minutes**.
After your payment is processed, the additional compute minutes are added to your personal
namespace.
## Monthly rollover of purchased compute minutes
If you purchase additional compute minutes and don't use the full amount, the remaining amount
rolls over to the next month. Additional compute minutes are a one-time purchase and
do not renew or refresh each month.
For example, if you have a monthly quota of 10,000 compute minutes:
- On April 1, you purchase 5,000 additional compute minutes, so you have 15,000 minutes
available for April.
- During April, you use 13,000 minutes, so you used 3,000 of the 5,000 additional compute minutes.
- On May 1, [the monthly quota resets](../../ci/pipelines/compute_minutes.md#monthly-reset-of-compute-usage)
and the unused compute minutes roll over. So you have 2,000 additional compute minutes remaining
and a total of 12,000 available for May.
## Troubleshooting
### Error: `Last name can't be blank`
You might get an error "Last name can't be blank" when purchasing compute minutes.
This issue occurs when a last name is missing from the **Full name** field of your profile.
To resolve the issue:
- Ensure that your user profile has a last name filled in:
1. On the left sidebar, select your avatar.
1. Select **Edit profile**.
1. Update the **Full name** field to have both first name and last name, then save the changes.
- Clear your browser cache and cookies, then try the purchase process again.
- If the error persists, try using a different web browser or an incognito/private browsing window.
### Error: `Attempt_Exceed_Limitation - Attempt exceed the limitation, refresh page to try again`
You might get the error `Attempt_Exceed_Limitation - Attempt exceed the limitation, refresh page to try again.`
when purchasing compute minutes.
This issue occurs when the credit card form is re-submitted too quickly
(three submissions in one minute or six submissions in one hour).
To resolve this issue, wait a few minutes and try the purchase process again.

View File

@ -375,11 +375,9 @@ You cannot transfer:
## Compute minutes
Compute is the resource consumed when running [pipelines](../../ci/pipelines/index.md)
on GitLab instance runners.
You can [purchase additional compute minutes](../../ci/pipelines/compute_minutes.md#purchase-additional-compute-minutes)
for your personal or group namespace.
Compute minutes are a **one-time purchase**, so they do not renew.
[Compute minutes](../../ci/pipelines/compute_minutes.md) is the resource consumed when running
[CI/CD pipelines](../../ci/index.md) on GitLab instance runners. If you run out of compute minutes,
you can [purchase additional compute minutes](compute_minutes.md).
## Enterprise Agile Planning

View File

@ -170,7 +170,7 @@ Google Cloud infrastructure.
- docker:24.0.5-dind
image: docker:git
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG --build-arg="name=Cloud Run" .
- docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG
@ -182,13 +182,13 @@ Google Cloud infrastructure.
source: $CI_REGISTRY_IMAGE:$IMAGE_TAG
target: $AR_IMAGE:$IMAGE_TAG
- component: gitlab.com/google-gitlab-components/cloud-run/deploy-cloud-run@0.1.0
inputs:
stage: deploy
image: $AR_IMAGE:$IMAGE_TAG
project_id: PROJECT
region: LOCATION
service: python-service
- component: gitlab.com/google-gitlab-components/cloud-run/deploy-cloud-run@0.1.0
inputs:
stage: deploy
image: $AR_IMAGE:$IMAGE_TAG
project_id: PROJECT
region: LOCATION
service: python-service
```

View File

@ -156,6 +156,7 @@ Audit event types belong to the following product categories.
| [`member_destroyed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109711) | Triggered when a membership is destroyed | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/374112) | Group, Project |
| [`member_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109711) | Triggered when a membership is updated | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/374112) | Group, Project |
| [`merge_request_create`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90911) | Triggered when a merge request is created | **{dotted-circle}** No | **{check-circle}** Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/367239) | Project |
| [`merge_request_merged`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164846) | When a merge request is merged | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.5](https://gitlab.com/gitlab-org/gitlab/-/issues/442279) | Project |
| [`omniauth_login_failed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123080) | Triggered when an OmniAuth login fails | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.3](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User |
| [`password_reset_requested`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114548) | Triggered when a user requests a password reset using a registered email address | **{check-circle}** Yes | **{dotted-circle}** No | GitLab [15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/374107) | User |
| [`personal_access_token_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108952) | Triggered when a user creates a personal access token | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.9](https://gitlab.com/gitlab-org/gitlab/-/issues/374113) | User |

View File

@ -3,6 +3,9 @@
module Gitlab
module Audit
class DeletedAuthor < Gitlab::Audit::NullAuthor
def impersonated?
false
end
end
end
end

View File

@ -49,6 +49,7 @@ module Gitlab
envelope_to: envelope_to.map(&:value),
x_envelope_to: x_envelope_to.map(&:value),
x_original_to: x_original_to.map(&:value),
x_forwarded_to: x_forwarded_to.map(&:value),
cc_address: cc,
# reduced down to what looks like an email in the received headers
received_recipients: recipients_from_received_headers,
@ -112,6 +113,7 @@ module Gitlab
find_first_key_from(x_envelope_to) ||
find_first_key_from(recipients_from_received_headers) ||
find_first_key_from(x_original_to) ||
find_first_key_from(x_forwarded_to) ||
find_first_key_from(cc)
end
@ -167,6 +169,10 @@ module Gitlab
Array(mail[:x_original_to])
end
def x_forwarded_to
Array(mail[:x_forwarded_to])
end
def recipients_from_received_headers
received.filter_map { |header| header.value[RECEIVED_HEADER_REGEX, 1] }
end

View File

@ -58,12 +58,11 @@ namespace :gitlab do
merge_requests = MergeRequest.from_and_to_forks(project)
merge_request_diffs = MergeRequestDiff
.joins(:merge_request).merge(merge_requests)
.select(:id, :start_commit_sha, :head_commit_sha, :base_commit_sha)
.select(:id, :start_commit_sha, :head_commit_sha)
merge_request_diffs.find_each do |diff|
merge_request_diffs.where.not(diff_type: :merge_head).find_each do |diff|
add_match(csv, diff.start_commit_sha)
add_match(csv, diff.head_commit_sha)
add_match(csv, diff.base_commit_sha)
end
end

View File

@ -27844,9 +27844,6 @@ msgstr ""
msgid "IdentityVerification|If you have not recently tried to sign into GitLab, we recommend changing your password (%{password_link}) and setting up Two-Factor Authentication (%{two_fa_link}) to keep your account safe."
msgstr ""
msgid "IdentityVerification|If you've lost access to the email associated to this account or having trouble with the code, %{supportLinkStart}here are some other steps you can take.%{supportLinkEnd}"
msgstr ""
msgid "IdentityVerification|Maximum login attempts exceeded. Wait %{interval} and try again."
msgstr ""

View File

@ -1,9 +1,14 @@
# frozen_string_literal: true
require "socket"
module QA
module Service
module DockerRun
class Webgoat < Base
DEFAULT_SERVER_PORT = 8080
DEFAULT_ADMIN_PORT = 9090
def initialize
@image = 'registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256:' \
'bc09fe2e0721dfaeee79364115aeedf2174cce0947b9ae5fe7c33312ee019a4e'
@ -11,32 +16,84 @@ module QA
super
end
# We should be on the same network as the runner
def register!
shell <<~CMD.tr("\n", ' ')
docker run -d --rm
--network #{network}
--name #{name}
--hostname #{host_name}
--publish 8080:8080
--publish 9090:9090
#{image}
CMD
return if running?
command = %W[docker run -d --rm --network #{network} --name #{name} --hostname #{host_name}]
command.push("-e", "WEBGOAT_PORT=#{host_network? ? server_port : DEFAULT_SERVER_PORT}")
command.push("-e", "WEBGOAT_SSRF_PORT=#{host_network? ? admin_port : DEFAULT_ADMIN_PORT}")
command.push("-p", DEFAULT_SERVER_PORT, "-p", WEBGOAT_SSRF_PORT) unless host_network?
command.push(image)
shell command.join(" ")
end
# DAST/ZAP DIND needs to reference the Webgoat container by IP address
def ip_address
ip_address = `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' #{name}`
.strip
ip_address = `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' #{name}`.strip
return host_name if ip_address.empty?
ip_address
end
def public_port
@public_port ||= if host_network?
server_port
elsif docker_network?
DEFAULT_SERVER_PORT
else
fetch_published_port(DEFAULT_SERVER_PORT)
end
end
def admin_port
@admin_port ||= if host_network?
admin_port_random
elsif docker_network?
DEFAULT_ADMIN_PORT
else
fetch_published_port(DEFAULT_ADMIN_PORT)
end
end
private
attr_reader :name, :image
def server_port
@server_port ||= random_port
end
def admin_port_random
@admin_port_random ||= random_port
end
def host_network?
network == "host"
end
def docker_network?
host_name == "#{name}.#{network}"
end
def fetch_published_port(container_port)
port = published_ports.split("\n").find { |line| line.start_with?(container_port.to_s) }.split(':').last
raise("Could not find published #{container_port} port for container #{name}") unless port
port.to_i
end
def published_ports
@published_ports ||= shell("docker port #{name}").presence || raise(
"Unable to fetch published ports for webgoat container #{name}"
)
end
def random_port
server = TCPServer.new('127.0.0.1', 0)
port = server.addr[1]
server.close
port
end
end
end
end

View File

@ -26,7 +26,7 @@ module QA
RSpec.describe 'Manage', :orchestrated, :runner, :requires_admin, :smtp, product_group: :import_and_integrate do
describe 'Pipeline status emails' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:executor) { "qa-runner-#{SecureRandom.hex(6)}" }
let(:emails) { %w[foo@bar.com baz@buzz.com] }
let(:project) { create(:project, name: 'pipeline-status-project') }
let!(:runner) { create(:project_runner, project: project, name: executor, tags: [executor]) }

View File

@ -5,9 +5,7 @@ module QA
describe 'Email Notification' do
include Support::API
let!(:user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let!(:user) { create(:user) }
let(:project) { create(:project, name: 'email-notification-test') }
@ -15,6 +13,10 @@ module QA
Flow::Login.sign_in
end
after do
user.remove_via_api!
end
it 'is received by a user for project invitation', :blocking, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347961' do
project.visit!

View File

@ -3,9 +3,7 @@
module QA
RSpec.describe 'Plan', :smoke, product_group: :project_management do
describe 'mention' do
let(:user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let(:user) { create(:user) }
let(:project) do
Resource::Project.fabricate_via_api_unless_fips! do |project|
@ -40,6 +38,10 @@ module QA
end
end
after do
user.remove_via_api!
end
it 'mentions another user in an issue',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347988' do
Page::Project::Issue::Show.perform do |show|

View File

@ -3,8 +3,8 @@
module QA
RSpec.describe 'Plan', product_group: :project_management do
describe 'Assignees' do
let(:user1) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
let(:user2) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2) }
let(:user1) { create(:user) }
let(:user2) { create(:user) }
let(:project) { create(:project, name: 'project-to-test-assignees') }
before do
@ -14,6 +14,11 @@ module QA
project.add_member(user2)
end
after do
user1.remove_via_api!
user2.remove_via_api!
end
it 'update without refresh', :blocking, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347941' do
issue = create(:issue, project: project, assignee_ids: [user1.id])
issue.visit!

View File

@ -3,9 +3,7 @@
module QA
RSpec.describe 'Plan', :transient, product_group: :project_management do
describe 'Discussion comments transient bugs' do
let(:user1) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let(:user1) { create(:user) }
let(:my_first_reply) { 'This is my first reply' }
let(:my_second_reply) { "@#{Runtime::Env.gitlab_qa_username_1}" }
@ -16,6 +14,10 @@ module QA
Flow::Login.sign_in
end
after do
user1.remove_via_api!
end
it 'comments with mention on a discussion in an issue', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347940' do
Runtime::Env.transient_trials.times do |i|
QA::Runtime::Logger.info("Transient bug test action - Trial #{i}")

View File

@ -14,9 +14,7 @@ module QA
))
end
let(:dev_user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let(:dev_user) { create(:user) }
before do
project.add_member(dev_user)
@ -38,6 +36,10 @@ module QA
merge_request.visit!
end
after do
dev_user.remove_via_api!
end
it 'applies multiple suggestions', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347682' do
Page::MergeRequest::Show.perform do |merge_request|
merge_request.click_diffs_tab

View File

@ -15,9 +15,7 @@ module QA
))
end
let(:dev_user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let(:dev_user) { create(:user) }
before do
project.add_member(dev_user)
@ -34,6 +32,10 @@ module QA
merge_request.visit!
end
after do
dev_user.remove_via_api!
end
it 'applies a single suggestion with a custom message',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347711' do
Page::MergeRequest::Show.perform do |merge_request|

View File

@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create', :orchestrated, :repository_storage, :requires_admin, product_group: :source_code do
describe 'Gitaly repository storage' do
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
let(:user) { create(:user) }
let(:parent_project) { create(:project, :with_readme, name: 'parent-project') }
let(:fork_project) { create(:fork, user: user, upstream: parent_project).project }
@ -11,6 +11,10 @@ module QA
parent_project.add_member(user)
end
after do
user.remove_via_api!
end
it 'creates a 2nd fork after moving the parent project',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347787',
quarantine: {

View File

@ -8,13 +8,9 @@ module QA
only: { job: /gdk-qa-.*/ }
} do
let(:project) { create(:project, :with_readme, name: 'project-for-tags') }
let(:developer_user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let(:developer_user) { create(:user) }
let(:maintainer_user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2)
end
let(:maintainer_user) { create(:user) }
let(:tag_name) { 'v0.0.1' }
let(:tag_message) { 'Version 0.0.1' }

View File

@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create', product_group: :source_code do
describe 'Adding comments on snippets', :blocking do
let(:comment_author) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
let(:comment_author) { create(:user) }
let(:comment_content) { 'Comment 123' }
let(:edited_comment_content) { 'Nice snippet!' }
@ -23,6 +23,10 @@ module QA
Flow::Login.sign_in
end
after do
comment_author.remove_via_api!
end
shared_examples 'comments on snippets' do |snippet_type, testcase|
it "adds, edits, and deletes a comment on a #{snippet_type}", testcase: testcase do
send(snippet_type)

View File

@ -3,7 +3,7 @@
module QA
RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'Pipeline with customizable variable' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:executor) { "qa-runner-#{SecureRandom.hex(6)}" }
let(:pipeline_job_name) { 'customizable-variable' }
let(:variable_custom_value) { 'Custom Foo' }
let(:project) { create(:project, name: 'project-with-customizable-variable-pipeline') }

View File

@ -22,13 +22,9 @@ module QA
])
end
let(:developer) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let(:developer) { create(:user) }
let(:maintainer) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2)
end
let(:maintainer) { create(:user) }
before do
Flow::Login.sign_in
@ -39,6 +35,8 @@ module QA
end
after do
developer.remove_via_api!
maintainer.remove_via_api!
runner.remove_via_api!
end

View File

@ -3,7 +3,7 @@
module QA
RSpec.describe 'Verify', :runner do
describe 'Pipeline with raw variables in YAML', product_group: :pipeline_authoring do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:executor) { "qa-runner-#{SecureRandom.hex(6)}" }
let(:pipeline_job_name) { 'rspec' }
let(:project) { create(:project, name: 'project-with-raw-variable-pipeline') }
let!(:runner) { create(:project_runner, project: project, name: executor, tags: [executor]) }

View File

@ -3,7 +3,7 @@
module QA
RSpec.describe 'Verify', :runner, product_group: :runner do
describe 'Runner fleet management' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:executor) { "qa-runner-#{SecureRandom.hex(6)}" }
let!(:runner) { create(:group_runner, name: executor) }

View File

@ -3,7 +3,7 @@
module QA
RSpec.describe 'Verify', :runner, product_group: :runner do
describe 'Runner fleet management' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:executor) { "qa-runner-#{SecureRandom.hex(6)}" }
let!(:runner) { create(:group_runner, name: executor) }

View File

@ -3,7 +3,7 @@
module QA
RSpec.describe 'Verify', :runner, product_group: :runner do
describe 'Group runner registration' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:executor) { "qa-runner-#{SecureRandom.hex(6)}" }
let!(:runner) { create(:group_runner, name: executor) }
after do

View File

@ -3,7 +3,7 @@
module QA
RSpec.describe 'Verify', :runner, product_group: :runner do
describe 'Runner registration' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:executor) { "qa-runner-#{SecureRandom.hex(6)}" }
let!(:runner) { create(:project_runner, name: executor, tags: ['e2e-test']) }
after do

View File

@ -21,7 +21,7 @@ module QA
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -9,7 +9,7 @@ module QA
let(:project) { create(:project, :private, name: 'dependency-proxy-project') }
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -22,7 +22,7 @@ module QA
let(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
runner.name = "qa-runner-#{SecureRandom.hex(6)}"
runner.tags = ["runner-for-#{imported_project.name}"]
runner.executor = :docker
runner.project = imported_project

View File

@ -10,7 +10,7 @@ module QA
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -18,7 +18,7 @@ module QA
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -10,7 +10,7 @@ module QA
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -21,7 +21,7 @@ module QA
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{package_project.name}"],
executor: :docker,
project: package_project)

View File

@ -20,7 +20,7 @@ module QA
let(:project) { create(:project, :private, :with_readme, name: "#{package_type}_project") }
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -30,7 +30,7 @@ module QA
let!(:another_project) { create(:project, name: 'npm-group-level-install', group: project.group) }
let!(:runner) do
create(:group_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.group.name}"],
executor: :docker,
group: project.group)

View File

@ -30,7 +30,7 @@ module QA
let!(:another_project) { create(:project, name: 'npm-instance-level-install', group: project.group) }
let!(:runner) do
create(:group_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.group.name}"],
executor: :docker,
group: project.group)

View File

@ -29,7 +29,7 @@ module QA
let!(:project) { create(:project, :private, name: 'npm-project-level') }
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -49,7 +49,7 @@ module QA
let!(:runner) do
create(:group_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.group.name}"],
executor: :docker,
group: project.group)

View File

@ -26,7 +26,7 @@ module QA
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -11,7 +11,7 @@ module QA
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -11,7 +11,7 @@ module QA
let!(:runner) do
create(:project_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{project.name}"],
executor: :docker,
project: project)

View File

@ -30,9 +30,7 @@ module QA
end
end
let(:user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let(:user) { create(:user) }
before do
Flow::Login.sign_in
@ -40,6 +38,10 @@ module QA
project.visit!
end
after do
user.remove_via_api!
end
context 'with a personal namespace project',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349223' do
let(:group) { create(:group, path: "group-for-personal-project-#{SecureRandom.hex(8)}") }

View File

@ -3,15 +3,11 @@
module QA
RSpec.describe 'Data Stores' do
describe 'Project owner permissions', :smoke, product_group: :tenant_scale do
let!(:owner) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
let!(:owner) { create(:user) }
let!(:owner_api_client) { Runtime::API::Client.new(:gitlab, user: owner) }
let!(:maintainer) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2)
end
let!(:maintainer) { create(:user) }
shared_examples 'adds user as owner' do |project_type, testcase|
let!(:issue) do

View File

@ -30,7 +30,7 @@ module QA
let!(:runner) do
create(:group_runner,
name: "qa-runner-#{Time.now.to_i}",
name: "qa-runner-#{SecureRandom.hex(6)}",
tags: ["runner-for-#{package_project.group.name}"],
executor: :docker,
group: package_project.group)

View File

@ -134,7 +134,7 @@ module QA
if response.code == HTTP_STATUS_TOO_MANY_REQUESTS
wait_seconds = response.headers[:retry_after].to_i
QA::Runtime::Logger.debug("Received 429 - Too many requests. Waiting for #{wait_seconds} seconds.")
QA::Runtime::Logger.warn("Received 429 - Too many requests. Waiting for #{wait_seconds} seconds.")
sleep wait_seconds
end

View File

@ -18,7 +18,7 @@ describe('Merge request dashboard merge request component', () => {
propsData: {
mergeRequest: {
reference: '!123456',
titleHtml: 'Merge request title',
title: 'Merge request title',
author: {
name: 'John Smith',
webUrl: 'https://gitlab.com/root',

View File

@ -32,7 +32,7 @@ describe('Merge requests query component', () => {
startCursor: null,
endCursor: null,
},
nodes: [createMockMergeRequest({ titleHtml: 'reviewer' })],
nodes: [createMockMergeRequest({ title: 'reviewer' })],
},
},
},
@ -49,7 +49,7 @@ describe('Merge requests query component', () => {
endCursor: null,
__typename: 'PageInfo',
},
nodes: [createMockMergeRequest({ titleHtml: 'assignee' })],
nodes: [createMockMergeRequest({ title: 'assignee' })],
},
},
},
@ -107,7 +107,7 @@ describe('Merge requests query component', () => {
it.each([
['reviewRequestedMergeRequests', 'reviewer'],
['assignedMergeRequests', 'assignee'],
])('sets merge request prop for %p', async (query, titleHtml) => {
])('sets merge request prop for %p', async (query, title) => {
createComponent({ query, variables: { state: 'opened' } });
await waitForPromises();
@ -116,7 +116,7 @@ describe('Merge requests query component', () => {
expect.objectContaining({
mergeRequests: expect.arrayContaining([
expect.objectContaining({
titleHtml,
title,
}),
]),
}),

View File

@ -2,7 +2,7 @@ export function createMockMergeRequest(mergeRequest = {}) {
return {
id: 1,
reference: '!1',
titleHtml: 'Title',
title: 'Title',
webUrl: '/',
author: {
id: 1,

View File

@ -76,36 +76,18 @@ describe('EmailVerification', () => {
expect(wrapper.text()).toContain(`You are signed in as ${defaultPropsData.username}`);
});
it('contains help text linking the user to support page', () => {
expect(wrapper.text()).toContain(
"If you've lost access to the email associated to this account or having trouble with the code, here are some other steps you can take.",
it('contains help text describing option to verification code to secondary email and a link to support page', () => {
expect(wrapper.text()).toMatch(
/If you don't have access to the primary email address, you can.*send a code to another address associated with this account, or you can try to verify another way./,
);
});
it('does not render the link to show secondary email form', () => {
expect(findShowSecondaryEmailFormLink().exists()).toBe(false);
it('renders the link to show secondary email form', () => {
expect(findShowSecondaryEmailFormLink().exists()).toBe(true);
});
describe('when sendVerificationCodeToSecondaryEmail feature flag is enabled', () => {
beforeEach(() => {
createComponent({
provide: { glFeatures: { sendVerificationCodeToSecondaryEmail: true } },
});
});
it('contains help text describing option to verification code to secondary email and a link to support page', () => {
expect(wrapper.text()).toMatch(
/If you don't have access to the primary email address, you can.*send a code to another address associated with this account, or you can try to verify another way./,
);
});
it('renders the link to show secondary email form', () => {
expect(findShowSecondaryEmailFormLink().exists()).toBe(true);
});
it('does not render EmailForm for sending code to secondary email initially', () => {
expect(findSecondaryEmailForm().exists()).toBe(false);
});
it('does not render EmailForm for sending code to secondary email initially', () => {
expect(findSecondaryEmailForm().exists()).toBe(false);
});
});
@ -238,9 +220,7 @@ describe('EmailVerification', () => {
${'the request failed'} | ${HTTP_STATUS_NOT_FOUND} | ${null} | ${genericAlertObject}
`(`displayed alert message when $scenario`, ({ statusCode, response, alertObject }) => {
beforeEach(() => {
createComponent({
provide: { glFeatures: { sendVerificationCodeToSecondaryEmail: true } },
});
createComponent();
enterCode('xxx');
});
@ -319,9 +299,7 @@ describe('EmailVerification', () => {
describe('secondary email form', () => {
beforeEach(() => {
createComponent({
provide: { glFeatures: { sendVerificationCodeToSecondaryEmail: true } },
});
createComponent();
});
it('is shown when the show link is clicked', async () => {

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
require 'fast_spec_helper'
RSpec.describe Gitlab::Audit::DeletedAuthor, feature_category: :compliance_management do
subject(:deleted_author) { described_class.new id: 0, name: 'delete this' }
describe '#impersonated?' do
it 'returns false' do
expect(deleted_author.impersonated?).to be false
end
end
end

View File

@ -46,8 +46,8 @@ RSpec.describe Gitlab::BackgroundMigration::FixPickUpAtCiDeletedObject, schema:
.to not_change { deleted_object1.reload.pick_up_at }
.and not_change { deleted_object2.reload.pick_up_at }
expect(deleted_object3.reload.pick_up_at).to be_within(2.seconds).of(1.hour.from_now)
expect(deleted_object4.reload.pick_up_at).to be_within(2.seconds).of(1.hour.from_now)
expect(deleted_object3.reload.pick_up_at).to be_within(10.seconds).of(1.hour.from_now)
expect(deleted_object4.reload.pick_up_at).to be_within(10.seconds).of(1.hour.from_now)
end
end
end

View File

@ -34,7 +34,7 @@ RSpec.describe Gitlab::Email::Receiver, feature_category: :shared do
metadata = receiver.mail_metadata
expect(metadata.keys).to match_array(%i[mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta received_recipients cc_address x_original_to])
expect(metadata.keys).to match_array(%i[mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta received_recipients cc_address x_original_to x_forwarded_to])
expect(metadata[:meta]).to include(client_id: client_id, project: project.full_path)
expect(metadata[meta_key]).to eq(meta_value)
end
@ -151,6 +151,23 @@ RSpec.describe Gitlab::Email::Receiver, feature_category: :shared do
it_behaves_like 'successful receive'
end
context 'when in a X-Forwarded-To header' do
let(:email_raw) do
<<~EMAIL
From: jake@example.com
To: to@example.com
X-Forwarded-To: #{incoming_email}
Subject: Issue titile
Issue description
EMAIL
end
let(:meta_key) { :x_forwarded_to }
it_behaves_like 'successful receive'
end
context 'for Service Desk custom email' do
let_it_be_with_refind(:setting) { create(:service_desk_setting, project: project, add_external_participants_from_cc: true) }

View File

@ -66,6 +66,21 @@ RSpec.describe Gitlab::Email::ServiceDeskReceiver, feature_category: :service_de
it_behaves_like 'received successfully'
end
context 'when in a X-Forwarded-To header' do
let(:email) do
<<~EMAIL
From: from@example.com
To: to@example.com
X-Forwarded-To: #{service_desk_email}
Subject: Issue titile
Issue description
EMAIL
end
it_behaves_like 'received successfully'
end
context 'when in a Cc header' do
let(:email) do
<<~EMAIL

View File

@ -44,6 +44,10 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
describe 'create new record' do
subject { diff_with_commits }
before do
allow(Gitlab::Git::KeepAround).to receive(:execute).and_call_original
end
it { expect(subject).to be_valid }
it { expect(subject).to be_persisted }
it { expect(subject.commits.count).to eq(29) }
@ -61,10 +65,20 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
merge_request.create_merge_request_diff
end
context 'when diff_type is merge_head' do
let_it_be(:merge_request) { create(:merge_request) }
it 'creates hidden refs' do
hidden_refs = subject.project.repository.raw.list_refs(["refs/#{Repository::REF_MERGE_REQUEST}/", "refs/#{Repository::REF_KEEP_AROUND}/"])
let_it_be(:merge_head) do
expect(hidden_refs).to match_array([
Gitaly::ListRefsResponse::Reference.new(name: subject.merge_request.ref_path, target: subject.head_commit_sha),
Gitaly::ListRefsResponse::Reference.new(name: "refs/#{Repository::REF_KEEP_AROUND}/#{subject.head_commit_sha}", target: subject.head_commit_sha),
Gitaly::ListRefsResponse::Reference.new(name: "refs/#{Repository::REF_KEEP_AROUND}/#{subject.start_commit_sha}", target: subject.start_commit_sha)
])
end
context 'when diff_type is merge_head' do
let(:merge_request) { create(:merge_request) }
let!(:merge_head) do
MergeRequests::MergeToRefService
.new(project: merge_request.project, current_user: merge_request.author)
.execute(merge_request)
@ -79,6 +93,17 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
it { expect(merge_head.head_commit_sha).to eq(merge_request.merge_ref_head.diff_refs.head_sha) }
it { expect(merge_head.base_commit_sha).to eq(merge_request.merge_ref_head.diff_refs.base_sha) }
it { expect(merge_head.start_commit_sha).to eq(merge_request.target_branch_sha) }
it 'creates hidden refs' do
hidden_refs = merge_request.project.repository.raw.list_refs(["refs/#{Repository::REF_MERGE_REQUEST}/", "refs/#{Repository::REF_KEEP_AROUND}/"])
expect(hidden_refs).to match_array([
Gitaly::ListRefsResponse::Reference.new(name: merge_request.ref_path, target: merge_request.source_branch_sha),
Gitaly::ListRefsResponse::Reference.new(name: merge_request.merge_ref_path, target: merge_head.head_commit_sha),
Gitaly::ListRefsResponse::Reference.new(name: "refs/#{Repository::REF_KEEP_AROUND}/#{merge_head.start_commit_sha}", target: merge_head.start_commit_sha),
Gitaly::ListRefsResponse::Reference.new(name: "refs/#{Repository::REF_KEEP_AROUND}/#{merge_request.source_branch_sha}", target: merge_request.source_branch_sha)
])
end
end
end

View File

@ -54,7 +54,6 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
expect(request.session[:verification_user_id]).to eq(user.id)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template('devise/sessions/email_verification')
expect(response.body).to have_pushed_frontend_feature_flags(sendVerificationCodeToSecondaryEmail: true)
end
end
@ -323,11 +322,8 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
end
context 'when a verification_user_id session variable exists' do
let(:send_verification_code_to_secondary_email) { true }
before do
stub_session(session_data: { verification_user_id: user.id })
stub_feature_flags(send_verification_code_to_secondary_email: send_verification_code_to_secondary_email)
perform_enqueued_jobs do
post(users_resend_verification_code_path, params: params)
@ -350,15 +346,6 @@ RSpec.describe 'VerifiesWithEmail', :clean_gitlab_redis_sessions, :clean_gitlab_
it_behaves_like 'locks the user and sends verification instructions' do
let(:recipient_email) { secondary_email.email }
end
context 'when send_verification_code_to_secondary_email feature flag is disabled' do
let(:send_verification_code_to_secondary_email) { false }
it 'does not send verification instructions to email address specified by email param' do
sent_email = ActionMailer::Base.deliveries.find { |d| d.to.include?(secondary_email.email) }
expect(sent_email).to be_nil
end
end
end
context 'when email param matches one of the user\'s unverified secondary emails' do

View File

@ -34,7 +34,7 @@ RSpec.shared_examples 'policy editor' do
it "can create a policy when a policy project exists" do
visit(path_to_policy_editor)
page.within(".gl-card:nth-child(1)") do
click_button _('Select policy')
click_link _('Select policy')
end
fill_in _('Name'), with: 'Prevent vulnerabilities'
click_button _('Select scan type')

View File

@ -1424,7 +1424,6 @@ RSpec.shared_examples 'a container registry auth service' do
let_it_be(:current_project) { create(:project) }
let_it_be(:project) { current_project }
let_it_be(:current_user) { create(:user) }
let_it_be(:container_repository_path) { current_project.full_path }
let_it_be(:container_repository_path_pattern_no_match) { "#{container_repository_path}_no_match" }
@ -1437,6 +1436,7 @@ RSpec.shared_examples 'a container registry auth service' do
let_it_be(:project_developer) { create(:user, developer_of: current_project) }
let_it_be(:project_maintainer) { create(:user, maintainer_of: current_project) }
let_it_be(:project_owner) { current_project.owner }
let_it_be(:instance_admin) { create(:admin) }
let(:current_params) { { scopes: ["repository:#{container_repository_path}:push"] } }
@ -1449,13 +1449,16 @@ RSpec.shared_examples 'a container registry auth service' do
end
end
context 'for different repository_path_patterns and current user roles' do
context 'for different repository_path_patterns and current user roles', :enable_admin_mode do
# rubocop:disable Layout/LineLength -- Avoid formatting to keep one-line table layout
where(:repository_path_pattern, :minimum_access_level_for_push, :current_user, :shared_examples_name) do
ref(:container_repository_path) | :maintainer | ref(:project_developer) | 'a protected container repository'
ref(:container_repository_path) | :maintainer | ref(:project_owner) | 'a pushable'
ref(:container_repository_path) | :owner | ref(:project_maintainer) | 'a protected container repository'
ref(:container_repository_path) | :owner | ref(:project_owner) | 'a pushable'
ref(:container_repository_path) | :owner | ref(:instance_admin) | 'a pushable'
ref(:container_repository_path) | :admin | ref(:project_owner) | 'a protected container repository'
ref(:container_repository_path) | :admin | ref(:instance_admin) | 'a pushable'
ref(:container_repository_path_pattern_no_match) | :maintainer | ref(:project_developer) | 'a pushable'
ref(:container_repository_path_pattern_no_match) | :admin | ref(:project_owner) | 'a pushable'
end

View File

@ -30,7 +30,7 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0
gitlab.com/gitlab-org/gitaly/v16 v16.11.10
gitlab.com/gitlab-org/labkit v1.21.0
gitlab.com/gitlab-org/labkit v1.21.2
go.uber.org/goleak v1.3.0
gocloud.dev v0.39.0
golang.org/x/image v0.20.0
@ -79,7 +79,6 @@ require (
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/client9/reopen v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
@ -126,6 +125,7 @@ require (
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
gitlab.com/gitlab-org/go/reopen v1.0.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect

View File

@ -163,8 +163,6 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws=
github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ=
github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CSfmHMw=
github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@ -487,8 +485,10 @@ github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPR
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
gitlab.com/gitlab-org/gitaly/v16 v16.11.10 h1:AuOHkrj0qLvHA6mnbrxIc5X9iwqRgRm9IM37gR+3n1s=
gitlab.com/gitlab-org/gitaly/v16 v16.11.10/go.mod h1:lJizRUtXRd1SBHjNbbbL9OsGN4TiugvfRBd8bIsdWI0=
gitlab.com/gitlab-org/labkit v1.21.0 h1:hLmdBDtXjD1yOmZ+uJOac3a5Tlo83QaezwhES4IYik4=
gitlab.com/gitlab-org/labkit v1.21.0/go.mod h1:zeATDAaSBelPcPLbTTq8J3ZJEHyPTLVBM1q3nva+/W4=
gitlab.com/gitlab-org/go/reopen v1.0.0 h1:6BujZ0lkkjGIejTUJdNO1w56mN1SI10qcVQyQlOPM+8=
gitlab.com/gitlab-org/go/reopen v1.0.0/go.mod h1:D6OID8YJDzEVZNYW02R/Pkj0v8gYFSIhXFTArAsBQw8=
gitlab.com/gitlab-org/labkit v1.21.2 h1:GlFHh8OdkrIMH3Qi0ByOzva0fGYXMICsuahGpJe4KNQ=
gitlab.com/gitlab-org/labkit v1.21.2/go.mod h1:Q++SWyCH/abH2pytnX2SU/3mrCX6aK/xKz/WpM1hLbA=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=