Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-04-29 18:08:18 +00:00
parent 44b15934c7
commit 888564d614
43 changed files with 331 additions and 133 deletions

View File

@ -26,6 +26,7 @@ import {
AWS_TIP_DISMISSED_COOKIE_NAME,
AWS_TIP_MESSAGE,
CONTAINS_VARIABLE_REFERENCE_MESSAGE,
ENVIRONMENT_SCOPE_LINK_TITLE,
EVENT_LABEL,
EVENT_ACTION,
} from '../constants';
@ -40,6 +41,7 @@ export default {
tokenList: awsTokenList,
awsTipMessage: AWS_TIP_MESSAGE,
containsVariableReferenceMessage: CONTAINS_VARIABLE_REFERENCE_MESSAGE,
environmentScopeLinkTitle: ENVIRONMENT_SCOPE_LINK_TITLE,
components: {
CiEnvironmentsDropdown,
GlAlert,
@ -81,6 +83,7 @@ export default {
'containsVariableReferenceLink',
'protectedEnvironmentVariablesLink',
'maskedEnvironmentVariablesLink',
'environmentScopeLink',
]),
...mapComputed(
[
@ -278,12 +281,18 @@ export default {
<gl-form-select id="ci-variable-type" v-model="variable_type" :options="typeOptions" />
</gl-form-group>
<gl-form-group
:label="__('Environment scope')"
label-for="ci-variable-env"
class="w-50"
data-testid="environment-scope"
>
<gl-form-group label-for="ci-variable-env" class="w-50" data-testid="environment-scope">
<template #label>
{{ __('Environment scope') }}
<gl-link
:title="$options.environmentScopeLinkTitle"
:href="environmentScopeLink"
target="_blank"
data-testid="environment-scope-link"
>
<gl-icon name="question" :size="12" />
</gl-link>
</template>
<ci-environments-dropdown
v-if="scopedVariablesAvailable"
class="w-100"

View File

@ -31,3 +31,5 @@ export const AWS_TOKEN_CONSTANTS = [AWS_ACCESS_KEY_ID, AWS_DEFAULT_REGION, AWS_S
export const CONTAINS_VARIABLE_REFERENCE_MESSAGE = __(
'Values that contain the %{codeStart}$%{codeEnd} character can be considered a variable reference and expanded. %{docsLinkStart}Learn more.%{docsLinkEnd}',
);
export const ENVIRONMENT_SCOPE_LINK_TITLE = __('Learn more');

View File

@ -17,6 +17,7 @@ const mountCiVariableListApp = (containerEl) => {
containsVariableReferenceLink,
protectedEnvironmentVariablesLink,
maskedEnvironmentVariablesLink,
environmentScopeLink,
} = containerEl.dataset;
const isGroup = parseBoolean(group);
const isProtectedByDefault = parseBoolean(protectedByDefault);
@ -34,6 +35,7 @@ const mountCiVariableListApp = (containerEl) => {
containsVariableReferenceLink,
protectedEnvironmentVariablesLink,
maskedEnvironmentVariablesLink,
environmentScopeLink,
});
return new Vue({

View File

@ -43,6 +43,10 @@ module Mutations
required: false,
description: 'Description of or notes for the contact.'
argument :active, GraphQL::Types::Boolean,
required: false,
description: 'State of the contact.'
def resolve(args)
contact = ::Gitlab::Graphql::Lazy.force(GitlabSchema.object_from_id(args.delete(:id), expected_type: ::CustomerRelations::Contact))
raise_resource_not_available_error! unless contact

View File

@ -34,6 +34,10 @@ module Mutations
required: false,
description: 'Description of or notes for the organization.'
argument :active, GraphQL::Types::Boolean,
required: false,
description: 'State of the organization.'
def resolve(args)
organization = ::Gitlab::Graphql::Lazy.force(GitlabSchema.object_from_id(args.delete(:id), expected_type: ::CustomerRelations::Organization))
raise_resource_not_available_error! unless organization

View File

@ -50,6 +50,11 @@ module Types
Types::TimeType,
null: false,
description: 'Timestamp the contact was last updated.'
field :active,
GraphQL::Types::Boolean,
null: false,
description: 'State of the contact.', method: :active?
end
end
end

View File

@ -36,6 +36,11 @@ module Types
Types::TimeType,
null: false,
description: 'Timestamp the organization was last updated.'
field :active,
GraphQL::Types::Boolean,
null: false,
description: 'State of the organization.', method: :active?
end
end
end

View File

@ -1294,10 +1294,11 @@ module Ci
def security_reports(report_types: [])
reports_scope = report_types.empty? ? ::Ci::JobArtifact.security_reports : ::Ci::JobArtifact.security_reports(file_types: report_types)
types_to_collect = report_types.empty? ? ::Ci::JobArtifact::SECURITY_REPORT_FILE_TYPES : report_types
::Gitlab::Ci::Reports::Security::Reports.new(self).tap do |security_reports|
latest_report_builds(reports_scope).each do |build|
build.collect_security_reports!(security_reports)
build.collect_security_reports!(security_reports, report_types: types_to_collect)
end
end
end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
# Base class for CI services
# List methods you need to implement to get your CI service
# Base class for CI integrations
# List methods you need to implement to get your CI integration
# working with GitLab merge requests
module Integrations
class BaseCi < Integration
@ -12,7 +12,7 @@ module Integrations
end
def self.supported_events
%w(push)
%w[push]
end
# Return complete url to build page
@ -30,10 +30,10 @@ module Integrations
#
#
# Ex.
# @service.commit_status('13be4ac', 'master')
# @integration.commit_status('13be4ac', 'master')
# # => 'success'
#
# @service.commit_status('2abe4ac', 'dev')
# @integration.commit_status('2abe4ac', 'dev')
# # => 'running'
#
#

View File

@ -15,7 +15,6 @@ module Integrations
validates :project_name, presence: true, if: :activated?
validates :username, presence: true, if: ->(service) { service.activated? && service.password_touched? && service.password.present? }
default_value_for :push_events, true
default_value_for :merge_requests_events, false
default_value_for :tag_push_events, false

View File

@ -10,9 +10,6 @@ module Integrations
validates :username, presence: true, if: :activated?
validates :token, presence: true, if: :activated?
default_value_for :push_events, true
default_value_for :tag_push_events, true
def title
'Packagist'
end

View File

@ -134,7 +134,6 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
rule { has_access }.enable :read_namespace
rule { developer }.policy do
enable :admin_milestone
enable :create_metrics_dashboard_annotation
enable :delete_metrics_dashboard_annotation
enable :update_metrics_dashboard_annotation
@ -152,6 +151,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :read_container_image
enable :admin_issue_board
enable :admin_label
enable :admin_milestone
enable :admin_issue_board_list
enable :admin_issue
enable :read_metrics_dashboard_annotation

View File

@ -285,6 +285,7 @@ class ProjectPolicy < BasePolicy
enable :reopen_issue
enable :admin_issue
enable :admin_label
enable :admin_milestone
enable :admin_issue_board_list
enable :admin_issue_link
enable :read_commit_status
@ -370,7 +371,6 @@ class ProjectPolicy < BasePolicy
enable :create_package
enable :admin_issue_board
enable :admin_merge_request
enable :admin_milestone
enable :update_merge_request
enable :reopen_merge_request
enable :create_commit_status

View File

@ -5,6 +5,8 @@ module CustomerRelations
class UpdateService < BaseService
def execute(contact)
return error_no_permissions unless allowed?
handle_active_param
return error_updating(contact) unless contact.update(params)
ServiceResponse.success(payload: contact)
@ -12,6 +14,13 @@ module CustomerRelations
private
def handle_active_param
return if params[:active].nil?
active = params.delete(:active)
params[:state] = active ? 'active' : 'inactive'
end
def error_no_permissions
error('You have insufficient permissions to update a contact for this group')
end

View File

@ -5,6 +5,8 @@ module CustomerRelations
class UpdateService < BaseService
def execute(organization)
return error_no_permissions unless allowed?
handle_active_param
return error_updating(organization) unless organization.update(params)
ServiceResponse.success(payload: organization)
@ -12,6 +14,13 @@ module CustomerRelations
private
def handle_active_param
return if params[:active].nil?
active = params.delete(:active)
params[:state] = active ? 'active' : 'inactive'
end
def error_no_permissions
error('You have insufficient permissions to update an organization for this group')
end

View File

@ -19,7 +19,7 @@
contains_variable_reference_link: help_page_path('ci/variables/index', anchor: 'use-variables-in-other-variables'),
protected_environment_variables_link: help_page_path('ci/variables/index', anchor: 'protect-a-cicd-variable'),
masked_environment_variables_link: help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'),
} }
environment_scope_link: help_page_path('ci/environments/index', anchor: 'scope-environments-with-specs') } }
- if !@group && @project.group
.settings-header.border-top.gl-mt-6

View File

@ -30,6 +30,10 @@ class Gitlab::Seeder::TriageOps
puts "Setting up webhooks"
ensure_webhook_for('gitlab-com')
ensure_webhook_for('gitlab-org')
puts "Ensuring work type labels"
ensure_work_type_labels_for('gitlab-com')
ensure_work_type_labels_for('gitlab-org')
end
end
@ -83,6 +87,38 @@ class Gitlab::Seeder::TriageOps
puts "Hook with url '#{hook.url}' and token '#{hook.token}' for '#{group_path}' is present now."
end
def ensure_work_type_labels_for(group_path)
label_titles = [
'bug::availability',
'bug::mobile',
'bug::performance',
'bug::vulnerability',
'feature::addition',
'feature::consolidation',
'feature::enhancement',
'feature::removal',
'maintenance::dependency',
'maintenance::pipelines',
'maintenance::refactor',
'maintenance::test-gap',
'maintenance::usability',
'maintenance::workflow',
'type::bug',
'type::feature',
'type::maintenance',
]
group = Group.find_by_full_path(group_path)
label_titles.each do |label_title|
color = Digest::MD5.hexdigest(label_title[/[^:]+/])[0..5]
Labels::CreateService
.new(title: label_title, color: "##{color}")
.execute(group: group)
end
end
def ensure_group(full_path)
group = Group.find_by_full_path(full_path)

View File

@ -637,9 +637,9 @@ to start again from scratch, there are a few steps that can help you:
1. Reset the Tracking Database.
```shell
gitlab-rake db:drop:geo # on a secondary app node
gitlab-ctl reconfigure # on the tracking database node
gitlab-rake db:setup:geo # on a secondary app node
gitlab-rake db:drop:geo # on a secondary app node
gitlab-ctl reconfigure # on the tracking database node
gitlab-rake db:migrate:geo # on a secondary app node
```
1. Restart previously stopped services.

View File

@ -157,7 +157,7 @@ table.test-coverage th {
</tr>
<tr>
<th scope="row">1k</th>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/1k">Daily</a> (to be moved to Weekly)</td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/1k">Weekly</a></td>
<td></td>
<td></td>
<td></td>
@ -165,7 +165,7 @@ table.test-coverage th {
</tr>
<tr>
<th scope="row">2k</th>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k">Daily</a> (to be moved to Weekly)</td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k">Weekly</a></td>
<td></td>
<td></td>
<td></td>
@ -176,7 +176,7 @@ table.test-coverage th {
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/3k">Weekly</a></td>
<td></td>
<td></td>
<td></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/3k_hybrid_aws_services">Weekly</a></td>
<td></td>
</tr>
<tr>
@ -190,9 +190,9 @@ table.test-coverage th {
<tr>
<th scope="row">10k</th>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k">Daily</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k-Cloud-Native-Hybrid">Ad-Hoc</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k">Ad-Hoc (inc Cloud Services)</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k-Cloud-Native-Hybrid">Ad-Hoc</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k_hybrid">Weekly</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k_aws">Weekly</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k_hybrid_aws_services">Weekly</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k">Ad-Hoc</a></td>
</tr>
<tr>
@ -215,6 +215,8 @@ table.test-coverage th {
## Cost to run
The following table details the cost to run the different reference architectures across GCP, AWS, and Azure. Bare-metal costs are not included here as it varies widely depending on each customer configuration.
<table class="test-coverage">
<col>
<colgroup span="2"></colgroup>

View File

@ -1589,6 +1589,7 @@ Input type: `CustomerRelationsContactUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationcustomerrelationscontactupdateactive"></a>`active` | [`Boolean`](#boolean) | State of the contact. |
| <a id="mutationcustomerrelationscontactupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcustomerrelationscontactupdatedescription"></a>`description` | [`String`](#string) | Description of or notes for the contact. |
| <a id="mutationcustomerrelationscontactupdateemail"></a>`email` | [`String`](#string) | Email address of the contact. |
@ -1636,6 +1637,7 @@ Input type: `CustomerRelationsOrganizationUpdateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationcustomerrelationsorganizationupdateactive"></a>`active` | [`Boolean`](#boolean) | State of the organization. |
| <a id="mutationcustomerrelationsorganizationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcustomerrelationsorganizationupdatedefaultrate"></a>`defaultRate` | [`Float`](#float) | Standard billing rate for the organization. |
| <a id="mutationcustomerrelationsorganizationupdatedescription"></a>`description` | [`String`](#string) | Description of or notes for the organization. |
@ -9954,6 +9956,7 @@ A custom emoji uploaded by user.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="customerrelationscontactactive"></a>`active` | [`Boolean!`](#boolean) | State of the contact. |
| <a id="customerrelationscontactcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp the contact was created. |
| <a id="customerrelationscontactdescription"></a>`description` | [`String`](#string) | Description of or notes for the contact. |
| <a id="customerrelationscontactemail"></a>`email` | [`String`](#string) | Email address of the contact. |
@ -9970,6 +9973,7 @@ A custom emoji uploaded by user.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="customerrelationsorganizationactive"></a>`active` | [`Boolean!`](#boolean) | State of the organization. |
| <a id="customerrelationsorganizationcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp the organization was created. |
| <a id="customerrelationsorganizationdefaultrate"></a>`defaultRate` | [`Float`](#float) | Standard billing rate for the organization. |
| <a id="customerrelationsorganizationdescription"></a>`description` | [`String`](#string) | Description of or notes for the organization. |

View File

@ -113,7 +113,9 @@ Parameters:
## Delete project milestone
Only for users with the Developer role in the project.
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
Only for users with at least the Reporter role in the project.
```plaintext
DELETE /projects/:id/milestones/:milestone_id
@ -158,9 +160,9 @@ Parameters:
## Promote project milestone to a group milestone
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53861) in GitLab 11.9
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
Only for users with the Developer role in the group.
Only for users with at least the Reporter role in the group.
```plaintext
POST /projects/:id/milestones/:milestone_id/promote

View File

@ -1200,7 +1200,14 @@ The site profile is created.
#### Edit a site profile
To edit an existing site profile:
If a site profile is linked to a security policy, a user cannot edit the profile from this page. See
[Scan execution policies](../policies/scan-execution-policies.md)
for more information.
When a validated site profile's file, header, or meta tag is edited, the site's
[validation status](#site-profile-validation) is revoked.
To edit a site profile:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. In the **DAST Profiles** row select **Manage**.
@ -1208,42 +1215,37 @@ To edit an existing site profile:
1. In the profile's row select the **More actions** (**{ellipsis_v}**) menu, then select **Edit**.
1. Edit the fields then select **Save profile**.
If a site profile is linked to a security policy, a user cannot edit the profile from this page. See
[Scan execution policies](../policies/scan-execution-policies.md)
for more information.
#### Delete a site profile
To delete an existing site profile:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. In the **DAST Profiles** row select **Manage**.
1. Select the **Site Profiles** tab.
1. In the profile's row select the **More actions** (**{ellipsis_v}**) menu, then select **Delete**.
1. Select **Delete** to confirm the deletion.
If a site profile is linked to a security policy, a user cannot delete the profile from this page.
See [Scan execution policies](../policies/scan-execution-policies.md)
for more information.
To delete a site profile:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. In the **DAST Profiles** row select **Manage**.
1. Select the **Site Profiles** tab.
1. In the profile's row, select the **More actions** (**{ellipsis_v}**) menu, then select **Delete**.
1. Select **Delete** to confirm the deletion.
#### Validate a site profile
Prerequisites:
- A site profile.
Validating a site is required to run an active scan.
To validate a site profile:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. In the **Dynamic Application Security Testing (DAST)** section, select **Manage scans**.
1. In the **Dynamic Application Security Testing (DAST)** section, select **Manage profiles**.
1. Select the **Site Profiles** tab.
1. In the profile's row select **Validate** or **Retry validation**.
1. In the profile's row, select **Validate**.
1. Select the validation method.
1. For **Text file validation**:
1. Download the validation file listed in **Step 2**.
1. Upload the validation file to the host. Upload the file to the location in
**Step 3** or any location you prefer.
1. Upload the validation file to the host, to the location in **Step 3** or any location you
prefer.
1. If required, edit the file location in **Step 3**.
1. Select **Validate**.
1. For **Header validation**:
1. Select the clipboard icon in **Step 2**.
@ -1256,9 +1258,8 @@ To validate a site profile:
1. Select the input field in **Step 3** and enter the location of the meta tag.
1. Select **Validate**.
The site is validated and an active scan can run against it.
If a validated site profile's target URL is edited, the site's validation status is revoked.
The site is validated and an active scan can run against it. A site profile's validation status is
revoked only when it's revoked manually, or its file, header, or meta tag is edited.
#### Retry a failed validation
@ -1266,22 +1267,28 @@ If a validated site profile's target URL is edited, the site's validation status
> - [Deployed behind the `dast_failed_site_validations` flag](../../../administration/feature_flags.md), enabled by default.
> - [Feature flag `dast_failed_site_validations` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323961) in GitLab 14.4.
If a site profile's validation fails, you can retry it by selecting the **Retry validation** button
in the profiles list.
Failed site validation attempts are listed on the **Site profiles** tab of the **Manage profiles**
page.
When loading the DAST profiles library, past failed validations are listed above the profiles
list. You can also retry the validation from there by selecting the **Retry validation** link in
the alert. You can also dismiss the alert to revoke failed validations.
To retry a site profile's failed validation:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. In the **Dynamic Application Security Testing (DAST)** section, select **Manage profiles**.
1. Select the **Site Profiles** tab.
1. In the profile's row, select **Retry validation**.
#### Revoke a site profile's validation status
Note that all site profiles with the same URL have their validation status revoked.
WARNING:
When a site profile's validation status is revoked, all site profiles that share the same URL also
have their validation status revoked.
To revoke a site profile's validation status:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. In the **DAST Profiles** row select **Manage**.
1. Select **Revoke validation** beside the validated profile.
1. Beside the validated profile, select **Revoke validation**.
The site profile's validation status is revoked.
@ -1349,40 +1356,40 @@ A scanner profile defines the scanner settings used to run an on-demand scan:
To create a scanner profile:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. In the **DAST Profiles** row select **Manage**.
1. In the **DAST Profiles** row, select **Manage**.
1. Select **New > Scanner Profile**.
1. Complete the form. For details of each field, see [Scanner profile](#scanner-profile).
1. Click **Save profile**.
1. Select **Save profile**.
#### Edit a scanner profile
To edit a scanner profile:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. Click **Manage** in the **DAST Profiles** row.
1. Select the **Scanner Profiles** tab.
1. In the scanner's row select the **More actions** (**{ellipsis_v}**) menu, then select **Edit**.
1. Edit the form.
1. Select **Save profile**.
If a scanner profile is linked to a security policy, a user cannot edit the profile from this page.
See [Scan execution policies](../policies/scan-execution-policies.md)
for more information.
#### Delete a scanner profile
To delete a scanner profile:
To edit a scanner profile:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. Click **Manage** in the **DAST Profiles** row.
1. In the **DAST Profiles** row, select **Manage**.
1. Select the **Scanner Profiles** tab.
1. In the scanner's row select the **More actions** (**{ellipsis_v}**) menu, then select **Delete**.
1. Select **Delete**.
1. In the scanner's row, select the **More actions** (**{ellipsis_v}**) menu, then select **Edit**.
1. Edit the form.
1. Select **Save profile**.
#### Delete a scanner profile
If a scanner profile is linked to a security policy, a user cannot delete the profile from this
page. See [Scan execution policies](../policies/scan-execution-policies.md)
for more information.
To delete a scanner profile:
1. From your project's home page, go to **Security & Compliance > Configuration**.
1. In the **DAST Profiles** row, select **Manage**.
1. Select the **Scanner Profiles** tab.
1. In the scanner's row, select the **More actions** (**{ellipsis_v}**) menu, then select **Delete**.
1. Select **Delete**.
## Auditing
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217872) in GitLab 14.1.

View File

@ -41,7 +41,8 @@ From there you can create a new iteration or select an iteration to get a more d
## Create an iteration
> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069) in GitLab 14.10.
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069) in GitLab 14.10.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
WARNING:
Manual iteration management is in its end-of-life process. Creating an iteration is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069)
@ -49,7 +50,7 @@ in GitLab 14.10, and is planned for removal in GitLab 16.0.
Prerequisites:
- You must have at least the Developer role for a group.
- You must have at least the Reporter role for a group.
To create an iteration:
@ -63,6 +64,7 @@ To create an iteration:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218277) in GitLab 13.2.
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069) in GitLab 14.10.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
WARNING:
Editing all attributes, with the exception of `description` is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069)
@ -71,7 +73,7 @@ In the future only editing an iteration's `description` will be allowed.
Prerequisites:
- You must have at least the Developer role for a group.
- You must have at least the Reporter role for a group.
To edit an iteration, select the three-dot menu (**{ellipsis_v}**) > **Edit**.
@ -79,6 +81,7 @@ To edit an iteration, select the three-dot menu (**{ellipsis_v}**) > **Edit**.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292268) in GitLab 14.3.
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069) in GitLab 14.10.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
WARNING:
Manual iteration management is in its end-of-life process. Deleting an iteration is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/356069)
@ -86,7 +89,7 @@ in GitLab 14.10, and is planned for removal in GitLab 16.0.
Prerequisites:
- You must have at least the Developer role for a group.
- You must have at least the Reporter role for a group.
To delete an iteration, select the three-dot menu (**{ellipsis_v}**) > **Delete**.
@ -184,9 +187,11 @@ configure iteration cadences to automatically roll over incomplete issues to the
### Create an iteration cadence
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
Prerequisites:
- You must have at least the Developer role for a group.
- You must have at least the Reporter role for a group.
To create an iteration cadence:
@ -197,9 +202,11 @@ To create an iteration cadence:
### Delete an iteration cadence
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
Prerequisites:
- You must have at least the Developer role for a group.
- You must have at least the Reporter role for a group.
Deleting an iteration cadence also deletes all iterations within that cadence.

View File

@ -37,7 +37,8 @@ For a list of planned additions, view the
To enable or turn off the Dependency Proxy for a group:
1. Go to your group's **Settings > Packages & Registries**.
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Settings > Packages & Registries**.
1. Expand the **Dependency Proxy** section.
1. To enable the proxy, turn on **Enable Proxy**. To turn it off, turn the toggle off.
@ -49,7 +50,8 @@ for the entire GitLab instance.
To view the Dependency Proxy:
- Go to your group's **Packages & Registries > Dependency Proxy**.
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Packages & Registries > Dependency Proxy**.
The Dependency Proxy is not available for projects.
@ -182,8 +184,9 @@ You can also use [custom CI/CD variables](../../../ci/variables/index.md#custom-
To store a Docker image in Dependency Proxy storage:
1. Go to your group's **Packages & Registries > Dependency Proxy**.
1. Copy the **Dependency Proxy URL**.
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Packages & Registries > Dependency Proxy**.
1. Copy the **Dependency Proxy image prefix**.
1. Use one of these commands. In these examples, the image is `alpine:latest`.
1. You can also pull images by digest to specify exactly which version of an image to pull.

View File

@ -144,7 +144,7 @@ The following table lists project permissions available for each role:
| [Projects](project/index.md):<br>Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Manage labels | | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>View [project traffic statistics](../api/project_statistics.md) | | ✓ | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*12*) | ✓ (*12*) | ✓ (*12*) |
| [Projects](project/index.md):<br>Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
| [Projects](project/index.md):<br>Enable [Review Apps](../ci/review_apps/index.md) | | | ✓ | ✓ | ✓ |
@ -398,8 +398,8 @@ The following table lists group permissions available for each role:
| View [Productivity analytics](analytics/productivity_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
| Create and edit [group wiki](project/wiki/group.md) pages | | | ✓ | ✓ | ✓ |
| Create project in group | | | ✓ (3)(5) | ✓ (3) | ✓ (3) |
| Create/edit/delete group milestones | | | ✓ | ✓ | ✓ |
| Create/edit/delete iterations | | | ✓ | ✓ | ✓ |
| Create/edit/delete group milestones | | | ✓ | ✓ | ✓ |
| Create/edit/delete iterations | | | ✓ | ✓ | ✓ |
| Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
| Enable/disable a dependency proxy | | | ✓ | ✓ | ✓ |
| Purge the dependency proxy for a group | | | | | ✓ |

View File

@ -53,10 +53,14 @@ If you're in a project and select **Issues > Milestones**, GitLab displays only
## Creating milestones
Users with at least the Developer role can create milestones.
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
Milestones can be created either at project or group level.
Prerequisites:
- You must have at least the Reporter role for a group.
To create a milestone:
1. On the top bar, select **Menu > Projects** and find your project or **Menu > Groups** and find your group.
@ -69,7 +73,13 @@ To create a milestone:
## Editing milestones
Users with at least the Developer role can edit milestones.
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/343889) the minimum user role from Developer to Reporter in GitLab 15.0.
Users with at least the Reporter role can edit milestones.
Prerequisites:
- You must have at least the Reporter role for a group.
To edit a milestone:

View File

@ -28,7 +28,7 @@ module Gitlab
private
def connection
ActiveRecord::Base.connection
ApplicationRecord.connection
end
def relation_scoped_to_range(source_table, source_key_column, start_id, stop_id)

View File

@ -1,5 +1,7 @@
# frozen_string_literal: true
require 'securerandom'
module Gitlab
module I18n
class PoLinter
@ -245,16 +247,24 @@ module Gitlab
[]
elsif variables.any? { |variable| unnamed_variable?(variable) }
variables.map do |variable|
variable == '%d' ? Random.rand(1000) : Gitlab::Utils.random_string
variable == '%d' ? random_number : random_string
end
else
variables.each_with_object({}) do |variable, hash|
variable_name = variable[/\w+/]
hash[variable_name] = Gitlab::Utils.random_string
hash[variable_name] = random_string
end
end
end
def random_number
Random.rand(1000)
end
def random_string
SecureRandom.alphanumeric(64)
end
def validate_unnamed_variables(errors, variables)
unnamed_variables, named_variables = variables.partition { |name| unnamed_variable?(name) }

View File

@ -128,10 +128,6 @@ module Gitlab
end
end
def random_string
Random.rand(Float::MAX.to_i).to_s(36)
end
# Behaves like `which` on Linux machines: given PATH, try to resolve the given
# executable name to an absolute path, or return nil.
#

View File

@ -16588,6 +16588,9 @@ msgstr ""
msgid "Geo|Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
msgid "Geo|Configure various settings for your %{siteType} site. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "Geo|Connection timeout"
msgstr ""
@ -16657,6 +16660,12 @@ msgstr ""
msgid "Geo|Geo Status"
msgstr ""
msgid "Geo|Geo allows you to choose specific groups or storage shards to replicate."
msgstr ""
msgid "Geo|Geo can replicate objects stored in Object Storage (AWS S3, or other compatible object storage)."
msgstr ""
msgid "Geo|Geo sites"
msgstr ""
@ -16672,7 +16681,7 @@ msgstr ""
msgid "Geo|Healthy"
msgstr ""
msgid "Geo|If enabled, GitLab will handle Object Storage replication using Geo. %{linkStart}Learn more%{linkEnd}"
msgid "Geo|If enabled, GitLab will handle Object Storage replication using Geo."
msgstr ""
msgid "Geo|If you want to make changes, you must visit the primary site."
@ -16726,7 +16735,7 @@ msgstr ""
msgid "Geo|Must match with the %{codeStart}external_url%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
msgid "Geo|Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgid "Geo|Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}."
msgstr ""
msgid "Geo|Never"
@ -16936,10 +16945,10 @@ msgstr ""
msgid "Geo|Synchronization status"
msgstr ""
msgid "Geo|The URL of the primary site that is used internally by the secondary sites. %{linkStart}Learn more.%{linkEnd}"
msgid "Geo|The URL of the primary site that is used internally by the secondary sites."
msgstr ""
msgid "Geo|The URL of the secondary site that is used internally by the primary site. %{linkStart}Learn more.%{linkEnd}"
msgid "Geo|The URL of the secondary site that is used internally by the primary site."
msgstr ""
msgid "Geo|The database is currently %{db_lag} behind the primary site."

View File

@ -5,7 +5,12 @@ import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper';
import CiEnvironmentsDropdown from '~/ci_variable_list/components/ci_environments_dropdown.vue';
import CiVariableModal from '~/ci_variable_list/components/ci_variable_modal.vue';
import { AWS_ACCESS_KEY_ID, EVENT_LABEL, EVENT_ACTION } from '~/ci_variable_list/constants';
import {
AWS_ACCESS_KEY_ID,
EVENT_LABEL,
EVENT_ACTION,
ENVIRONMENT_SCOPE_LINK_TITLE,
} from '~/ci_variable_list/constants';
import createStore from '~/ci_variable_list/store';
import mockData from '../services/mock_data';
import ModalStub from '../stubs';
@ -20,7 +25,11 @@ describe('Ci variable modal', () => {
const maskableRegex = '^[a-zA-Z0-9_+=/@:.~-]{8,}$';
const createComponent = (method, options = {}) => {
store = createStore({ maskableRegex, isGroup: options.isGroup });
store = createStore({
maskableRegex,
isGroup: options.isGroup,
environmentScopeLink: '/help/environments',
});
wrapper = method(CiVariableModal, {
attachTo: document.body,
stubs: {
@ -213,6 +222,15 @@ describe('Ci variable modal', () => {
});
});
});
it('renders a link to documentation on scopes', () => {
createComponent(mount);
const link = wrapper.find('[data-testid="environment-scope-link"]');
expect(link.attributes('title')).toBe(ENVIRONMENT_SCOPE_LINK_TITLE);
expect(link.attributes('href')).toBe('/help/environments');
});
});
describe('Validations', () => {

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['CustomerRelationsContact'] do
let(:fields) { %i[id organization first_name last_name phone email description created_at updated_at] }
let(:fields) { %i[id organization first_name last_name phone email description active created_at updated_at] }
it { expect(described_class.graphql_name).to eq('CustomerRelationsContact') }
it { expect(described_class).to have_graphql_fields(fields) }

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['CustomerRelationsOrganization'] do
let(:fields) { %i[id name default_rate description created_at updated_at] }
let(:fields) { %i[id name default_rate description active created_at updated_at] }
it { expect(described_class.graphql_name).to eq('CustomerRelationsOrganization') }
it { expect(described_class).to have_graphql_fields(fields) }

View File

@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Utils do
using RSpec::Parameterized::TableSyntax
delegate :to_boolean, :boolean_to_yes_no, :slugify, :random_string, :which,
delegate :to_boolean, :boolean_to_yes_no, :slugify, :which,
:ensure_array_from_string, :to_exclusive_sentence, :bytes_to_megabytes,
:append_path, :check_path_traversal!, :allowlisted?, :check_allowed_absolute_path!, :decode_path, :ms_to_round_sec, :check_allowed_absolute_path_and_path_traversal!, to: :described_class
@ -311,12 +311,6 @@ RSpec.describe Gitlab::Utils do
end
end
describe '.random_string' do
it 'generates a string' do
expect(random_string).to be_kind_of(String)
end
end
describe '.which' do
before do
stub_env('PATH', '/sbin:/usr/bin:/home/joe/bin')

View File

@ -4,11 +4,12 @@ require 'spec_helper'
RSpec.describe Integrations::Jenkins do
let(:project) { create(:project) }
let(:jenkins_integration) { described_class.new(jenkins_params) }
let(:jenkins_url) { 'http://jenkins.example.com/' }
let(:jenkins_hook_url) { jenkins_url + 'project/my_project' }
let(:jenkins_username) { 'u$er name%2520' }
let(:jenkins_password) { 'pas$ word' }
let(:jenkins_authorization) { 'Basic ' + ::Base64.strict_encode64(jenkins_username + ':' + jenkins_password) }
let(:jenkins_params) do
{
active: true,
@ -22,17 +23,21 @@ RSpec.describe Integrations::Jenkins do
}
end
let(:jenkins_authorization) { "Basic " + ::Base64.strict_encode64(jenkins_username + ':' + jenkins_password) }
include_context Integrations::EnableSslVerification do
let(:integration) { described_class.new(jenkins_params) }
let(:integration) { jenkins_integration }
end
it_behaves_like Integrations::HasWebHook do
let(:integration) { described_class.new(jenkins_params) }
let(:integration) { jenkins_integration }
let(:hook_url) { "http://#{ERB::Util.url_encode jenkins_username}:#{ERB::Util.url_encode jenkins_password}@jenkins.example.com/project/my_project" }
end
it 'sets the default values', :aggregate_failures do
expect(jenkins_integration.push_events).to eq(true)
expect(jenkins_integration.merge_requests_events).to eq(false)
expect(jenkins_integration.tag_push_events).to eq(false)
end
describe 'username validation' do
let(:jenkins_integration) do
described_class.create!(

View File

@ -70,6 +70,9 @@ RSpec.describe Admin::BackgroundMigrationsController, :enable_admin_mode do
end
it 'returns CI database records' do
# If we only have one DB we'll see both migrations
skip_if_multiple_databases_not_setup
ci_database_migration = Gitlab::Database::SharedModel.using_connection(ci_model.connection) { create(:batched_background_migration, :active) }
get admin_background_migrations_path, params: { database: 'ci' }

View File

@ -85,7 +85,7 @@ RSpec.describe API::GroupMilestones do
def setup_for_group
context_group.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
context_group.add_developer(user)
context_group.add_reporter(user)
public_project.update!(namespace: context_group)
context_group.reload
end

View File

@ -9,8 +9,8 @@ RSpec.describe API::ProjectMilestones do
let_it_be(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') }
let_it_be(:route) { "/projects/#{project.id}/milestones" }
before do
project.add_developer(user)
before_all do
project.add_reporter(user)
end
it_behaves_like 'group and project milestones', "/projects/:id/milestones"

View File

@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe CustomerRelations::Contacts::UpdateService do
let_it_be(:user) { create(:user) }
let(:contact) { create(:contact, first_name: 'Mark', group: group) }
let(:contact) { create(:contact, first_name: 'Mark', group: group, state: 'active') }
subject(:update) { described_class.new(group: group, current_user: user, params: params).execute(contact) }
@ -41,6 +41,29 @@ RSpec.describe CustomerRelations::Contacts::UpdateService do
end
end
context 'when activating' do
let(:contact) { create(:contact, state: 'inactive') }
let(:params) { { active: true } }
it 'updates the contact' do
response = update
expect(response).to be_success
expect(response.payload.active?).to be_truthy
end
end
context 'when deactivating' do
let(:params) { { active: false } }
it 'updates the contact' do
response = update
expect(response).to be_success
expect(response.payload.active?).to be_falsy
end
end
context 'when the contact is invalid' do
let(:params) { { first_name: nil } }

View File

@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe CustomerRelations::Organizations::UpdateService do
let_it_be(:user) { create(:user) }
let(:organization) { create(:organization, name: 'Test', group: group) }
let(:organization) { create(:organization, name: 'Test', group: group, state: 'active') }
subject(:update) { described_class.new(group: group, current_user: user, params: params).execute(organization) }
@ -41,6 +41,29 @@ RSpec.describe CustomerRelations::Organizations::UpdateService do
end
end
context 'when activating' do
let(:organization) { create(:organization, state: 'inactive') }
let(:params) { { active: true } }
it 'updates the contact' do
response = update
expect(response).to be_success
expect(response.payload.active?).to be_truthy
end
end
context 'when deactivating' do
let(:params) { { active: false } }
it 'updates the organization' do
response = update
expect(response).to be_success
expect(response.payload.active?).to be_falsy
end
end
context 'when the organization is invalid' do
let(:params) { { name: nil } }

View File

@ -28,6 +28,7 @@ RSpec.shared_context 'GroupPolicy context' do
let(:reporter_permissions) do
%i[
admin_label
admin_milestone
admin_issue_board
read_container_image
read_metrics_dashboard_annotation
@ -40,7 +41,6 @@ RSpec.shared_context 'GroupPolicy context' do
let(:developer_permissions) do
%i[
admin_milestone
create_metrics_dashboard_annotation
delete_metrics_dashboard_annotation
update_metrics_dashboard_annotation

View File

@ -25,7 +25,7 @@ RSpec.shared_context 'ProjectPolicy context' do
let(:base_reporter_permissions) do
%i[
admin_issue admin_issue_link admin_label admin_issue_board_list
admin_issue admin_issue_link admin_label admin_milestone admin_issue_board_list
create_snippet create_incident daily_statistics create_merge_request_in download_code
download_wiki_code fork_project metrics_dashboard read_build
read_commit_status read_confidential_issues read_container_image
@ -41,7 +41,7 @@ RSpec.shared_context 'ProjectPolicy context' do
let(:developer_permissions) do
%i[
admin_merge_request admin_milestone admin_tag create_build
admin_merge_request admin_tag create_build
create_commit_status create_container_image create_deployment
create_environment create_merge_request_from
create_metrics_dashboard_annotation create_pipeline create_release

View File

@ -203,16 +203,16 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
end
describe "DELETE #{route_definition}/:milestone_id" do
it "rejects a member with reporter access from deleting a milestone" do
reporter = create(:user)
milestone.resource_parent.add_reporter(reporter)
it "rejects a member with guest access from deleting a milestone" do
guest = create(:user)
milestone.resource_parent.add_guest(guest)
delete api(resource_route, reporter)
delete api(resource_route, guest)
expect(response).to have_gitlab_http_status(:forbidden)
end
it 'deletes the milestone when the user has developer access to the project' do
it 'deletes the milestone when the user has reporter access to the project' do
delete api(resource_route, user)
expect(project.milestones.find_by_id(milestone.id)).to be_nil