Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
75dbbc4a87
commit
72b735b5f2
|
|
@ -1 +1 @@
|
|||
18a6087f7e43e9219de607dbe363c54bb73101d8
|
||||
d1cf3491ba7c28ee609e87ba796218713077a297
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
afa804f189e2e143cbe807af1003e46dcb41eb6b
|
||||
22dc62058605bb04bb302295b79a1169649dcb14
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
fragment MergeRequestDashboardFragment on MergeRequest {
|
||||
id
|
||||
reference(full: true)
|
||||
titleHtml
|
||||
title
|
||||
webUrl
|
||||
author {
|
||||
...User
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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__(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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?('*') }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
3dbbfb2880123f915697fda46b5e4f10ccdc772862a2d22ef65bb5eb8a660c3f
|
||||
|
|
@ -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**.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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. |
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
module Gitlab
|
||||
module Audit
|
||||
class DeletedAuthor < Gitlab::Audit::NullAuthor
|
||||
def impersonated?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]) }
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
||||
|
|
|
|||
|
|
@ -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|
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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|
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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' }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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') }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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]) }
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)}") }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ export function createMockMergeRequest(mergeRequest = {}) {
|
|||
return {
|
||||
id: 1,
|
||||
reference: '!1',
|
||||
titleHtml: 'Title',
|
||||
title: 'Title',
|
||||
webUrl: '/',
|
||||
author: {
|
||||
id: 1,
|
||||
|
|
|
|||
|
|
@ -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 () => {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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=
|
||||
|
|
|
|||
Loading…
Reference in New Issue