Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-23 15:09:32 +00:00
parent f46d20e508
commit cd81aadde2
43 changed files with 701 additions and 209 deletions

View File

@ -95,7 +95,7 @@ export default {
}, },
projectSelectLabelId: 'project-select', projectSelectLabelId: 'project-select',
modalId: uniqueId('import-a-project-modal-'), modalId: uniqueId('import-a-project-modal-'),
formClasses: 'gl-mt-3 gl-sm-w-auto gl-w-full', formClasses: 'gl-md-w-auto gl-w-full',
buttonClasses: 'gl-w-full', buttonClasses: 'gl-w-full',
}; };
</script> </script>

View File

@ -154,6 +154,8 @@ class Integration < ApplicationRecord
else else
raise ArgumentError, "Unknown field storage: #{storage}" raise ArgumentError, "Unknown field storage: #{storage}"
end end
boolean_accessor(name) if attrs[:type] == 'checkbox'
end end
# :nocov: # :nocov:

View File

@ -4,14 +4,16 @@ module Integrations
class Field class Field
SECRET_NAME = %r/token|key|password|passphrase|secret/.freeze SECRET_NAME = %r/token|key|password|passphrase|secret/.freeze
BOOLEAN_ATTRIBUTES = %i[required api_only exposes_secrets].freeze
ATTRIBUTES = %i[ ATTRIBUTES = %i[
section type placeholder required choices value checkbox_label section type placeholder choices value checkbox_label
title help title help
non_empty_password_help non_empty_password_help
non_empty_password_title non_empty_password_title
api_only ].concat(BOOLEAN_ATTRIBUTES).freeze
exposes_secrets
].freeze TYPES = %w[text textarea password checkbox select].freeze
attr_reader :name, :integration_class attr_reader :name, :integration_class
@ -22,6 +24,13 @@ module Integrations
attributes[:type] = SECRET_NAME.match?(@name) ? 'password' : type attributes[:type] = SECRET_NAME.match?(@name) ? 'password' : type
attributes[:api_only] = api_only attributes[:api_only] = api_only
@attributes = attributes.freeze @attributes = attributes.freeze
invalid_attributes = attributes.keys - ATTRIBUTES
if invalid_attributes.present?
raise ArgumentError, "Invalid attributes #{invalid_attributes.inspect}"
elsif !TYPES.include?(self[:type])
raise ArgumentError, "Invalid type #{self[:type].inspect}"
end
end end
def [](key) def [](key)
@ -34,11 +43,19 @@ module Integrations
end end
def secret? def secret?
@attributes[:type] == 'password' self[:type] == 'password'
end end
ATTRIBUTES.each do |name| ATTRIBUTES.each do |name|
define_method(name) { self[name] } define_method(name) { self[name] }
end end
BOOLEAN_ATTRIBUTES.each do |name|
define_method("#{name}?") { !!self[name] }
end
TYPES.each do |type|
define_method("#{type}?") { self[:type] == type }
end
end end
end end

View File

@ -7,18 +7,16 @@
.col-lg-12 .col-lg-12
.gl-display-flex.gl-flex-wrap .gl-display-flex.gl-flex-wrap
- if can_admin_group_member?(@group) - if can_admin_group_member?(@group)
.gl-w-half.gl-xs-w-full %h4
%h4 = _('Group members')
= _('Group members') %p.gl-w-full.order-md-1
%p = group_member_header_subtext(@group)
= group_member_header_subtext(@group) .gl-display-flex.gl-flex-wrap.gl-align-items-flex-start.gl-ml-auto.gl-md-w-auto.gl-w-full.gl-mt-3
.gl-w-half.gl-xs-w-full .js-invite-group-trigger{ data: { classes: 'gl-md-w-auto gl-w-full', display_text: _('Invite a group') } }
.gl-display-flex.gl-flex-wrap.gl-justify-content-end.gl-mb-3 .js-invite-members-trigger{ data: { variant: 'confirm',
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } } classes: 'gl-md-w-auto gl-w-full gl-md-ml-3 gl-md-mt-0 gl-mt-3',
.js-invite-members-trigger{ data: { variant: 'confirm', trigger_source: 'group-members-page',
classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } }
trigger_source: 'group-members-page',
display_text: _('Invite members') } }
= render 'groups/invite_groups_modal', group: @group = render 'groups/invite_groups_modal', group: @group
= render 'groups/invite_members_modal', group: @group = render 'groups/invite_members_modal', group: @group

View File

@ -6,39 +6,36 @@
.row.gl-mt-3 .row.gl-mt-3
.col-lg-12 .col-lg-12
- if can_invite_members_for_project?(@project) .gl-display-flex.gl-flex-wrap
.row - if can_invite_members_for_project?(@project)
.col-md-12.col-lg-6.gl-display-flex
.gl-flex-direction-column.gl-flex-wrap.align-items-baseline
%h4
= _("Project members")
.gl-justify-content-bottom.gl-display-flex.align-items-center
%p
= project_member_header_subtext(@project)
.col-md-12.col-lg-6
.gl-display-flex.gl-flex-wrap.gl-justify-content-end
- if can_admin_project_member?(@project)
.js-import-a-project-modal{ data: { project_id: @project.id, project_name: @project.name } }
- if @project.allowed_to_share_with_group?
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } }
= render 'projects/invite_groups_modal', project: @project
- if can_admin_project_member?(@project)
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3',
trigger_source: 'project-members-page',
display_text: _('Invite members') } }
= render 'projects/invite_members_modal', project: @project
- else
- if project_can_be_shared?
%h4 %h4
= _("Project members") = _("Project members")
- if can?(current_user, :admin_project_member, @project) %p.gl-w-full.order-md-1
%p = project_member_header_subtext(@project)
= project_member_header_subtext(@project) .gl-display-flex.gl-flex-wrap.gl-align-items-flex-start.gl-ml-auto.gl-md-w-auto.gl-w-full.gl-mt-3
- else - invite_group_top_margin = ''
%p - if can_admin_project_member?(@project)
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe } .js-import-a-project-modal{ data: { project_id: @project.id, project_name: @project.name } }
- invite_group_top_margin = 'gl-md-mt-0 gl-mt-3'
- if @project.allowed_to_share_with_group?
.js-invite-group-trigger{ data: { classes: "gl-md-w-auto gl-w-full gl-md-ml-3 #{invite_group_top_margin}", display_text: _('Invite a group') } }
= render 'projects/invite_groups_modal', project: @project
- if can_admin_project_member?(@project)
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-md-w-auto gl-w-full gl-md-ml-3 gl-md-mt-0 gl-mt-3',
trigger_source: 'project-members-page',
display_text: _('Invite members') } }
= render 'projects/invite_members_modal', project: @project
- else
- if project_can_be_shared?
%h4
= _("Project members")
- if can?(current_user, :admin_project_member, @project)
%p.gl-w-full
= project_member_header_subtext(@project)
- else
%p.gl-w-full
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe }
.js-project-members-list-app{ data: { members_data: project_members_app_data_json(@project, .js-project-members-list-app{ data: { members_data: project_members_app_data_json(@project,
members: @project_members, members: @project_members,

View File

@ -0,0 +1,8 @@
---
name: ci_value_change_for_processable_and_rules_entry
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90238
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/365876
milestone: '15.2'
type: development
group: group::pipeline authoring
default_enabled: false

View File

@ -0,0 +1,8 @@
---
name: delay_for_repository_update_mirror
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90749
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/365948
milestone: '15.2'
type: development
group: group::source code
default_enabled: false

View File

@ -1,8 +0,0 @@
---
name: use_status_for_repository_update_mirror
introduced_by_url:
rollout_issue_url:
milestone: '15.1'
type: development
group: group::source code
default_enabled: false

View File

@ -16,6 +16,7 @@ options:
- g_edit_by_web_ide - g_edit_by_web_ide
- g_edit_by_sfe - g_edit_by_sfe
- g_edit_by_snippet_ide - g_edit_by_snippet_ide
- g_edit_by_live_preview
distribution: distribution:
- ce - ce
- ee - ee

View File

@ -16,6 +16,7 @@ options:
- g_edit_by_web_ide - g_edit_by_web_ide
- g_edit_by_sfe - g_edit_by_sfe
- g_edit_by_snippet_ide - g_edit_by_snippet_ide
- g_edit_by_live_preview
distribution: distribution:
- ce - ce
- ee - ee

View File

@ -363,8 +363,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get 'work_items/*work_items_path' => 'work_items#index', as: :work_items get 'work_items/*work_items_path' => 'work_items#index', as: :work_items
resource :tracing, only: [:show]
post 'incidents/integrations/pagerduty', to: 'incident_management/pager_duty_incidents#create' post 'incidents/integrations/pagerduty', to: 'incident_management/pager_duty_incidents#create'
resources :incidents, only: [:index] resources :incidents, only: [:index]
@ -624,7 +622,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
:commits, :commit, :find_file, :files, :compare, :commits, :commit, :find_file, :files, :compare,
:cycle_analytics, :mattermost, :variables, :triggers, :cycle_analytics, :mattermost, :variables, :triggers,
:environments, :protected_environments, :error_tracking, :alert_management, :environments, :protected_environments, :error_tracking, :alert_management,
:tracing,
:serverless, :clusters, :audit_events, :wikis, :merge_requests, :serverless, :clusters, :audit_events, :wikis, :merge_requests,
:vulnerability_feedback, :security, :dependencies, :issues, :vulnerability_feedback, :security, :dependencies, :issues,
:pipelines, :pipeline_schedules, :runners, :snippets) :pipelines, :pipeline_schedules, :runners, :snippets)

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
class FinalizeOrphanedRoutesCleanup < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
MIGRATION = 'CleanupOrphanedRoutes'
def up
ensure_batched_background_migration_is_finished(
job_class_name: MIGRATION,
table_name: :routes,
column_name: :id,
job_arguments: []
)
end
def down
# noop
end
end

View File

@ -0,0 +1 @@
29b2e0496736ae09f7d2b6a971a7a9a946379469de0f5488a3ff16efd896e306

View File

@ -97,7 +97,7 @@ If you have a large GitLab installation or cannot tolerate downtime, consider
Doing so reduces both the length of the maintenance window, and the risk of data Doing so reduces both the length of the maintenance window, and the risk of data
loss as a result of a poorly executed planned failover. loss as a result of a poorly executed planned failover.
In GitLab 12.4, you can optionally allow GitLab to manage replication of Object Storage for In GitLab 15.1, you can optionally allow GitLab to manage replication of Object Storage for
**secondary** sites. For more information, see [Object Storage replication](../replication/object_storage.md). **secondary** sites. For more information, see [Object Storage replication](../replication/object_storage.md).
### Review the configuration of each **secondary** site ### Review the configuration of each **secondary** site

View File

@ -182,36 +182,29 @@ replicating data from those features causes the data to be **lost**.
To use those features on a **secondary** site, or to execute a failover To use those features on a **secondary** site, or to execute a failover
successfully, you must replicate their data using some other means. successfully, you must replicate their data using some other means.
|Feature | Replicated (added in GitLab version) | Verified (added in GitLab version) | Object Storage replication (see [Geo with Object Storage](object_storage.md)) | Notes | |Feature | Replicated (added in GitLab version) | Verified (added in GitLab version) | GitLab-managed object storage replication (added in GitLab version) | GitLab-managed object storage verification (added in GitLab version) | Notes |
|:--------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------|:---------------------------------------------------------------------------|:------------------------------------------------------------------------------|:------| |:--------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------|:---------------------------------------------------------------------------|:--------------------------------------------------------------------|:----------------------------------------------------------------|:------|
|[Application data in PostgreSQL](../../postgresql/index.md) | **Yes** (10.2) | **Yes** (10.2) | No | | |[Application data in PostgreSQL](../../postgresql/index.md) | **Yes** (10.2) | **Yes** (10.2) | N/A | N/A | |
|[Project repository](../../../user/project/repository/) | **Yes** (10.2) | **Yes** (10.7) | No | | |[Project repository](../../../user/project/repository/) | **Yes** (10.2) | **Yes** (10.7) | N/A | N/A | |
|[Project wiki repository](../../../user/project/wiki/) | **Yes** (10.2) | **Yes** (10.7) | No | | |[Project wiki repository](../../../user/project/wiki/) | **Yes** (10.2) | **Yes** (10.7) | N/A | N/A | |
|[Group wiki repository](../../../user/project/wiki/group.md) | [**Yes** (13.10)](https://gitlab.com/gitlab-org/gitlab/-/issues/208147) | No | No | Behind feature flag `geo_group_wiki_repository_replication`, enabled by default. | |[Group wiki repository](../../../user/project/wiki/group.md) | [**Yes** (13.10)](https://gitlab.com/gitlab-org/gitlab/-/issues/208147) | No | N/A | N/A | Behind feature flag `geo_group_wiki_repository_replication`, enabled by default. |
|[Uploads](../../uploads.md) | **Yes** (10.2) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_upload_replication`, enabled by default. Verification was behind the feature flag `geo_upload_verification`, removed in 14.8. | |[Uploads](../../uploads.md) | **Yes** (10.2) | **Yes** (14.6) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | Replication is behind the feature flag `geo_upload_replication`, enabled by default. Verification was behind the feature flag `geo_upload_verification`, removed in 14.8. |
|[LFS objects](../../lfs/index.md) | **Yes** (10.2) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).<br /><br />Replication is behind the feature flag `geo_lfs_object_replication`, enabled by default. Verification was behind the feature flag `geo_lfs_object_verification`, removed in 14.7. | |[LFS objects](../../lfs/index.md) | **Yes** (10.2) | **Yes** (14.6) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).<br /><br />Replication is behind the feature flag `geo_lfs_object_replication`, enabled by default. Verification was behind the feature flag `geo_lfs_object_verification`, removed in 14.7. |
|[Personal snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | | |[Personal snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | N/A | N/A | |
|[Project snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | | |[Project snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | N/A | N/A | |
|[CI job artifacts](../../../ci/pipelines/job_artifacts.md) | **Yes** (10.4) | **Yes** (14.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Verification is behind the feature flag `geo_job_artifact_replication`, enabled by default in 14.10. | |[CI job artifacts](../../../ci/pipelines/job_artifacts.md) | **Yes** (10.4) | **Yes** (14.10) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | Verification is behind the feature flag `geo_job_artifact_replication`, enabled by default in 14.10. |
|[CI Pipeline Artifacts](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/ci/pipeline_artifact.rb) | [**Yes** (13.11)](https://gitlab.com/gitlab-org/gitlab/-/issues/238464) | [**Yes** (13.11)](https://gitlab.com/gitlab-org/gitlab/-/issues/238464) | Via Object Storage provider if supported. Native Geo support (Beta). | Persists additional artifacts after a pipeline completes. | |[CI Pipeline Artifacts](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/ci/pipeline_artifact.rb) | [**Yes** (13.11)](https://gitlab.com/gitlab-org/gitlab/-/issues/238464) | [**Yes** (13.11)](https://gitlab.com/gitlab-org/gitlab/-/issues/238464) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | Persists additional artifacts after a pipeline completes. |
|[Container Registry](../../packages/container_registry.md) | **Yes** (12.3) | No | No | Disabled by default. See [instructions](docker_registry.md) to enable. | |[Container Registry](../../packages/container_registry.md) | **Yes** (12.3) | No | No | No | Disabled by default. See [instructions](docker_registry.md) to enable. |
|[Content in object storage (beta)](object_storage.md) | **Yes** (12.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/13845) | No | | |[Infrastructure Registry](../../../user/packages/infrastructure_registry/index.md) | **Yes** (14.0) | **Yes** (14.0) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | Behind feature flag `geo_package_file_replication`, enabled by default. |
|[Infrastructure Registry](../../../user/packages/infrastructure_registry/index.md) | **Yes** (14.0) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (14.0) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | |[Project designs repository](../../../user/project/issues/design_management.md) | **Yes** (12.7) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/32467) | N/A | N/A | Designs also require replication of LFS objects and Uploads. |
|[Project designs repository](../../../user/project/issues/design_management.md) | **Yes** (12.7) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/32467) | No | Designs also require replication of LFS objects and Uploads. | |[Package Registry](../../../user/packages/package_registry/index.md) | **Yes** (13.2) | **Yes** (13.10) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | Behind feature flag `geo_package_file_replication`, enabled by default. |
|[Package Registry](../../../user/packages/package_registry/index.md) | **Yes** (13.2) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | |[Versioned Terraform State](../../terraform_state.md) | **Yes** (13.5) | **Yes** (13.12) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | Replication is behind the feature flag `geo_terraform_state_version_replication`, enabled by default. Verification was behind the feature flag `geo_terraform_state_version_verification`, which was removed in 14.0. |
|[Versioned Terraform State](../../terraform_state.md) | **Yes** (13.5) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (13.12) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_terraform_state_version_replication`, enabled by default. Verification was behind the feature flag `geo_terraform_state_version_verification`, which was removed in 14.0. | |[External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | **Yes** (14.6) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | Replication is behind the feature flag `geo_merge_request_diff_replication`, enabled by default. Verification was behind the feature flag `geo_merge_request_diff_verification`, removed in 14.7.|
|[External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_merge_request_diff_replication`, enabled by default. Verification was behind the feature flag `geo_merge_request_diff_verification`, removed in 14.7.| |[Versioned snippets](../../../user/snippets.md#versioned-snippets) | [**Yes** (13.7)](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [**Yes** (14.2)](https://gitlab.com/groups/gitlab-org/-/epics/2810) | N/A | N/A | Verification was implemented behind the feature flag `geo_snippet_repository_verification` in 13.11, and the feature flag was removed in 14.2. |
|[Versioned snippets](../../../user/snippets.md#versioned-snippets) | [**Yes** (13.7)](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [**Yes** (14.2)](https://gitlab.com/groups/gitlab-org/-/epics/2810) | No | Verification was implemented behind the feature flag `geo_snippet_repository_verification` in 13.11, and the feature flag was removed in 14.2. | |[GitLab Pages](../../pages/index.md) | [**Yes** (14.3)](https://gitlab.com/groups/gitlab-org/-/epics/589) | **Yes** (14.6) | [**Yes** (15.1)](https://gitlab.com/groups/gitlab-org/-/epics/5551) | [No](object_storage.md#verification-of-files-in-object-storage) | Behind feature flag `geo_pages_deployment_replication`, enabled by default. Verification was behind the feature flag `geo_pages_deployment_verification`, removed in 14.7. |
|[GitLab Pages](../../pages/index.md) | [**Yes** (14.3)](https://gitlab.com/groups/gitlab-org/-/epics/589) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_pages_deployment_replication`, enabled by default. Verification was behind the feature flag `geo_pages_deployment_verification`, removed in 14.7. | |[Incident Metric Images](../../../operations/incident_management/incidents.md#metrics) | [Planned](https://gitlab.com/gitlab-org/gitlab/-/issues/352326) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/362561) | No | No | |
|[Incident Metric Images](../../../operations/incident_management/incidents.md#metrics) | [Planned](https://gitlab.com/gitlab-org/gitlab/-/issues/352326) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/362561) | No | | |[Alert Metric Images](../../../operations/incident_management/alerts.md#metrics-tab) | [Planned](https://gitlab.com/gitlab-org/gitlab/-/issues/352326) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/362561) | No | No | |
|[Alert Metric Images](../../../operations/incident_management/alerts.md#metrics-tab) | [Planned](https://gitlab.com/gitlab-org/gitlab/-/issues/352326) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/362561) | No | | |[Server-side Git hooks](../../server_hooks.md) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/1867) | No | N/A | N/A | Not planned because of current implementation complexity, low customer interest, and availability of alternatives to hooks. |
|[Server-side Git hooks](../../server_hooks.md) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/1867) | No | No | Not planned because of current implementation complexity, low customer interest, and availability of alternatives to hooks. | |[Elasticsearch integration](../../../integration/elasticsearch.md) | [Not planned](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | No | No | Not planned because further product discovery is required and Elasticsearch (ES) clusters can be rebuilt. Secondaries use the same ES cluster as the primary. |
|[Elasticsearch integration](../../../integration/advanced_search/elasticsearch.md) | [Not planned](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | No | Not planned because further product discovery is required and Elasticsearch (ES) clusters can be rebuilt. Secondaries use the same ES cluster as the primary. | |[Dependency proxy images](../../../user/packages/dependency_proxy/index.md) | [Not planned](https://gitlab.com/gitlab-org/gitlab/-/issues/259694) | No | No | No | Blocked by [Geo: Secondary Mimicry](https://gitlab.com/groups/gitlab-org/-/epics/1528). Replication of this cache is not needed for disaster recovery purposes because it can be recreated from external sources. |
|[Dependency proxy images](../../../user/packages/dependency_proxy/index.md) | [Not planned](https://gitlab.com/gitlab-org/gitlab/-/issues/259694) | No | No | Blocked by [Geo: Secondary Mimicry](https://gitlab.com/groups/gitlab-org/-/epics/1528). Replication of this cache is not needed for disaster recovery purposes because it can be recreated from external sources. | |[Vulnerability Export](../../../user/application_security/vulnerability_report/#export-vulnerability-details) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/3111) | No | No | No | Not planned because they are ephemeral and sensitive information. They can be regenerated on demand. |
|[Vulnerability Export](../../../user/application_security/vulnerability_report/#export-vulnerability-details) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/3111) | No | No | Not planned because they are ephemeral and sensitive information. They can be regenerated on demand. |
#### Limitation of verification for files in Object Storage
GitLab managed Object Storage replication support [is in beta](object_storage.md#enabling-gitlab-managed-object-storage-replication).
Locally stored files are verified but remote stored files are not.

View File

@ -181,7 +181,7 @@ The following are PostgreSQL upgrade validation tests we performed.
- [Geo multi-node upgrade from 12.0.9 to 12.1.9 does not upgrade PostgreSQL](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4705). - [Geo multi-node upgrade from 12.0.9 to 12.1.9 does not upgrade PostgreSQL](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4705).
- [Refresh foreign tables fails on app server in multi-node setup after upgrade to 12.1.9](https://gitlab.com/gitlab-org/gitlab/-/issues/32119). - [Refresh foreign tables fails on app server in multi-node setup after upgrade to 12.1.9](https://gitlab.com/gitlab-org/gitlab/-/issues/32119).
## Other tests ## Object storage replication tests
The following are additional validation tests we performed. The following are additional validation tests we performed.
@ -194,13 +194,6 @@ The following are additional validation tests we performed.
- Follow up issues: - Follow up issues:
- [Geo: Failing to replicate initial Monitoring project](https://gitlab.com/gitlab-org/gitlab/-/issues/330485) - [Geo: Failing to replicate initial Monitoring project](https://gitlab.com/gitlab-org/gitlab/-/issues/330485)
### August 2020
[Test Gitaly Cluster on a Geo Deployment](https://gitlab.com/gitlab-org/gitlab/-/issues/223210):
- Description: Tested a Geo deployment with Gitaly clusters configured on both the primary and secondary Geo sites. Triggered automatic Gitaly cluster failover on the primary Geo site, and ran end-to-end Geo tests. Then triggered Gitaly cluster failover on the secondary Geo site, and re-ran the end-to-end Geo tests.
- Outcome: Successful end-to-end tests before and after Gitaly cluster failover on the primary site, and before and after Gitaly cluster failover on the secondary site.
### January 2022 ### January 2022
[Validate Object storage replication using Azure based object storage](https://gitlab.com/gitlab-org/gitlab/-/issues/348804#note_821294631): [Validate Object storage replication using Azure based object storage](https://gitlab.com/gitlab-org/gitlab/-/issues/348804#note_821294631):
@ -221,3 +214,12 @@ The following are additional validation tests we performed.
- Description: Tested the average time it takes for a single image to replicate from the primary object storage location to the secondary when using GCP based object storage replication and [GitLab based object storage replication](object_storage.md#enabling-gitlab-managed-object-storage-replication). This was tested by uploading a 1mb image to a project on the primary site every second for 60 seconds. The time was then measured until a image was available on the secondary site. This was achieved using a [Ruby Script](https://gitlab.com/gitlab-org/quality/geo-replication-tester). - Description: Tested the average time it takes for a single image to replicate from the primary object storage location to the secondary when using GCP based object storage replication and [GitLab based object storage replication](object_storage.md#enabling-gitlab-managed-object-storage-replication). This was tested by uploading a 1mb image to a project on the primary site every second for 60 seconds. The time was then measured until a image was available on the secondary site. This was achieved using a [Ruby Script](https://gitlab.com/gitlab-org/quality/geo-replication-tester).
- Outcome: GCP handles replication differently than other Cloud Providers. In GCP, the process is to a create single bucket that is either multi, dual or single region based. This means that the bucket will automatically store replicas in a region based on the option chosen. Even when using multi region, this will still only replicate within a single continent, the options being America, Europe, or Asia. At current there doesn't seem to be any way to replicate objects between continents using GCP based replication. For Geo managed replication the average time when replicating within the same region was 6 seconds, and when replicating cross region this rose to just 9 seconds. - Outcome: GCP handles replication differently than other Cloud Providers. In GCP, the process is to a create single bucket that is either multi, dual or single region based. This means that the bucket will automatically store replicas in a region based on the option chosen. Even when using multi region, this will still only replicate within a single continent, the options being America, Europe, or Asia. At current there doesn't seem to be any way to replicate objects between continents using GCP based replication. For Geo managed replication the average time when replicating within the same region was 6 seconds, and when replicating cross region this rose to just 9 seconds.
## Other tests
### August 2020
[Test Gitaly Cluster on a Geo Deployment](https://gitlab.com/gitlab-org/gitlab/-/issues/223210):
- Description: Tested a Geo deployment with Gitaly clusters configured on both the primary and secondary Geo sites. Triggered automatic Gitaly cluster failover on the primary Geo site, and ran end-to-end Geo tests. Then triggered Gitaly cluster failover on the secondary Geo site, and re-ran the end-to-end Geo tests.
- Outcome: Successful end-to-end tests before and after Gitaly cluster failover on the primary site, and before and after Gitaly cluster failover on the secondary site.

View File

@ -28,14 +28,14 @@ To have:
- GitLab manage replication, follow [Enabling GitLab replication](#enabling-gitlab-managed-object-storage-replication). - GitLab manage replication, follow [Enabling GitLab replication](#enabling-gitlab-managed-object-storage-replication).
- Third-party services manage replication, follow [Third-party replication services](#third-party-replication-services). - Third-party services manage replication, follow [Third-party replication services](#third-party-replication-services).
See [Object storage replication tests](geo_validation_tests.md#object-storage-replication-tests) for comparisons between GitLab-managed replication and third-party replication.
[Read more about using object storage with GitLab](../../object_storage.md). [Read more about using object storage with GitLab](../../object_storage.md).
## Enabling GitLab-managed object storage replication ## Enabling GitLab-managed object storage replication
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10586) in GitLab 12.4. > The beta feature was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10586) in GitLab 12.4.
> The feature was made [generally available] in GitLab 15.1.
WARNING:
This is a [**Beta** feature](../../../policy/alpha-beta-support.md#beta-features) and is not ready yet for production use at any scale. The main limitations are a lack of testing at scale and no verification of any replicated data.
**Secondary** sites can replicate files stored on the **primary** site regardless of **Secondary** sites can replicate files stored on the **primary** site regardless of
whether they are stored on the local file system or in object storage. whether they are stored on the local file system or in object storage.
@ -86,3 +86,7 @@ For manual synchronization, or scheduled by `cron`, see:
- [`s3cmd sync`](https://s3tools.org/s3cmd-sync) - [`s3cmd sync`](https://s3tools.org/s3cmd-sync)
- [`gsutil rsync`](https://cloud.google.com/storage/docs/gsutil/commands/rsync) - [`gsutil rsync`](https://cloud.google.com/storage/docs/gsutil/commands/rsync)
## Verification of files in object storage
[Files stored in object storage are not verified.](https://gitlab.com/groups/gitlab-org/-/epics/8056)

View File

@ -244,8 +244,6 @@ background migration.
```ruby ```ruby
class QueueBackfillRoutesNamespaceId < Gitlab::Database::Migration[2.0] class QueueBackfillRoutesNamespaceId < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
MIGRATION = 'BackfillRouteNamespaceId' MIGRATION = 'BackfillRouteNamespaceId'
DELAY_INTERVAL = 2.minutes DELAY_INTERVAL = 2.minutes

View File

@ -8,15 +8,20 @@ info: To determine the technical writer assigned to the Stage/Group associated w
[HAML](https://haml.info/) is the [Ruby on Rails](https://rubyonrails.org/) template language that GitLab uses. [HAML](https://haml.info/) is the [Ruby on Rails](https://rubyonrails.org/) template language that GitLab uses.
## GitLab UI form builder ## HAML and our Pajamas Design System
[GitLab UI](https://gitlab-org.gitlab.io/gitlab-ui/) is a Vue component library that conforms [GitLab UI](https://gitlab-org.gitlab.io/gitlab-ui/) is a Vue component library that conforms
to the [Pajamas design system](https://design.gitlab.com/). Most of these components to the [Pajamas design system](https://design.gitlab.com/). Many of these components
rely on JavaScript and therefore can only be used in Vue. rely on JavaScript and therefore can only be used in Vue.
However, some of the simpler components (checkboxes, radio buttons, form inputs) can be However, some of the simpler components (such as buttons, checkboxes, or form inputs) can be
used in HAML by applying the correct CSS classes to the elements. A custom used in HAML:
[Ruby on Rails form builder](https://gitlab.com/gitlab-org/gitlab/-/blob/7c108df101e86d8a27d69df2b5b1ff1fc24133c5/lib/gitlab/form_builders/gitlab_ui_form_builder.rb) exists to help use GitLab UI components in HAML.
- Some of the Pajamas components are available as a [ViewComponent](view_component.md#pajamas-components). Use these when possible.
- If no ViewComponent exists, why not go ahead and create it? Talk to the Foundations team if you need help.
- As a fallback, this can be done by applying the correct CSS classes to the elements.
- A custom
[Ruby on Rails form builder](https://gitlab.com/gitlab-org/gitlab/-/blob/7c108df101e86d8a27d69df2b5b1ff1fc24133c5/lib/gitlab/form_builders/gitlab_ui_form_builder.rb) exists to help use GitLab UI components in HAML forms.
### Use the GitLab UI form builder ### Use the GitLab UI form builder
@ -100,7 +105,7 @@ Currently only the listed components are available but more components are plann
This component supports [ViewComponent slots](https://viewcomponent.org/guide/slots.html). This component supports [ViewComponent slots](https://viewcomponent.org/guide/slots.html).
| Slot | Description | Slot | Description
|---|---| |---|---|
| `label` | Checkbox label content. This slot can be used instead of the `label` argument. | | `label` | Checkbox label content. This slot can be used instead of the `label` argument. |
| `help_text` | Help text content displayed below the checkbox. This slot can be used instead of the `help_text` argument. | | `help_text` | Help text content displayed below the checkbox. This slot can be used instead of the `help_text` argument. |
@ -128,7 +133,7 @@ This component supports [ViewComponent slots](https://viewcomponent.org/guide/sl
This component supports [ViewComponent slots](https://viewcomponent.org/guide/slots.html). This component supports [ViewComponent slots](https://viewcomponent.org/guide/slots.html).
| Slot | Description | Slot | Description
|---|---| |---|---|
| `label` | Checkbox label content. This slot can be used instead of the `label` argument. | | `label` | Checkbox label content. This slot can be used instead of the `label` argument. |
| `help_text` | Help text content displayed below the radio button. This slot can be used instead of the `help_text` argument. | | `help_text` | Help text content displayed below the radio button. This slot can be used instead of the `help_text` argument. |

View File

@ -89,6 +89,10 @@ How to use [GraphQL](graphql.md).
How to use [HAML](haml.md). How to use [HAML](haml.md).
## ViewComponent
How we use [ViewComponent](view_component.md).
## Icons and Illustrations ## Icons and Illustrations
How we use SVG for our [Icons and Illustrations](icons.md). How we use SVG for our [Icons and Illustrations](icons.md).

View File

@ -0,0 +1,174 @@
---
stage: Ecosystem
group: Foundations
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# ViewComponent
ViewComponent is a framework for creating reusable, testable & encapsulated view
components with Ruby on Rails, without the need for a JavaScript framework like Vue.
They are rendered server-side and can be seamlessly used with template languages like [Haml](haml.md).
Refer to the official [documentation](https://viewcomponent.org/) to learn more or
watch this [introduction video](https://youtu.be/akRhUbvtnmo).
## Pajamas components
Some of the components of our [Pajamas](https://design.gitlab.com) design system are
available as a ViewComponent in `app/components/pajamas`.
NOTE:
We have a small but growing number of Pajamas components. Reach out to the
[Foundations team](https://about.gitlab.com/handbook/engineering/development/dev/ecosystem/foundations/)
if the component you are looking for is not yet available.
### Available components
#### Alert
The `Pajamas::AlertComponent` follows the [Pajamas Alert](https://design.gitlab.com/components/alert) specification.
**Examples:**
By default this creates a dismissible info alert with icon:
```haml
= render Pajamas::AlertComponent.new(title: "Almost done!")
```
You can set variant, hide the icons and more:
```haml
= render Pajamas::AlertComponent.new(title: "All done!",
variant: :success,
dismissible: :false,
show_icon: false)
```
For the full list of options, see its
[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/components/pajamas/alert_component.rb).
#### Banner
The `Pajamas::BannerComponent` follows the [Pajamas Banner](https://design.gitlab.com/components/banner) specification.
**Examples:**
In its simplest form the banner component looks like this:
```haml
= render Pajamas::BannerComponent.new(button_text: 'Learn more', button_link: example_path,
svg_path: 'illustrations/example.svg') do |c|
- c.title { 'Hello world!' }
%p Content of your banner goes here...
```
If you have a need for more control, you can also use the `illustration` slot
instead of `svg_path` and the `primary_action` slot instead of `button_text` and `button_link`:
```haml
= render Pajamas::BannerComponent.new do |c|
- c.illustration do
= custom_icon('my_inline_svg')
- c.title do
Hello world!
- c.primary_action do
= render 'my_button_in_a_partial'
```
For the full list of options, see its
[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/components/pajamas/banner_component.rb).
#### Button
The `Pajamas::ButtonComponent` follows the [Pajamas Button](https://design.gitlab.com/components/button) specification.
**Examples:**
The button component has a lot of options but all of them have good defaults,
so the simplest button looks like this:
```haml
= render Pajamas::ButtonComponent.new do |c|
= _('Button text goes here')
```
The following example shows most of the available options:
```haml
= render Pajamas::ButtonComponent.new(category: :secondary,
variant: :danger,
size: :small,
type: :submit,
disabled: true,
loading: false,
block: true) do |c|
Button text goes here
```
You can also create button-like looking `<a>` tags, like this:
```haml
= render Pajamas::ButtonComponent.new(href: root_path) do |c|
Go home
```
For the full list of options, see its
[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/components/pajamas/button_component.rb).
#### Card
The `Pajamas::CardComponent` follows the [Pajamas Card](https://design.gitlab.com/components/card) specification.
**Examples:**
The card has one mandatory `body` slot and optional `header` and `footer` slots:
```haml
= render Pajamas::CardComponent.new do |c|
- c.header do
I'm the header.
- c.body do
%p Multiple line
%p body content.
- c.footer do
Footer goes here.
```
If you want to add custom attributes to any of these or the card itself, use the following options:
```haml
= render Pajamas::CardComponent.new(card_options: {id: "my-id"}, body_options: {data: { count: 1 }})
```
`header_options` and `footer_options` are available, too.
For the full list of options, see its
[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/components/pajamas/card_component.rb).
#### Toggle
The `Pajamas::ToggleComponent` follows the [Pajamas Toggle](https://design.gitlab.com/components/toggle) specification.
```haml
= render Pajamas::ToggleComponent.new(classes: 'js-force-push-toggle',
label: s_("ProtectedBranch|Toggle allowed to force push"),
is_checked: protected_branch.allow_force_push,
label_position: :hidden)
Leverage this block to render a rich help text. To render a plain text help text, prefer the `help` parameter.
```
NOTE:
**The toggle ViewComponent is special as it depends on the Vue.js component.**
To actually initialize this component, make sure to call the `initToggle` helper from `~/toggles`.
For the full list of options, see its
[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/components/pajamas/toggle_component.rb).
### Best practices
- If you are about to create a new view in Haml, use the available components
over creating plain Haml tags with CSS classes.
- If you are making changes to an existing Haml view and see, for example, a
button that is still implemented with plain Haml, consider migrating it to use a ViewComponent.

View File

@ -488,6 +488,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
[check you have a PostgreSQL bug fix](#postgresql-segmentation-fault-issue) [check you have a PostgreSQL bug fix](#postgresql-segmentation-fault-issue)
to avoid the database crashing. to avoid the database crashing.
- The use of encrypted S3 buckets with storage-specific configuration is no longer supported after [removing support for using `background_upload`](removals.md#background-upload-for-object-storage). - The use of encrypted S3 buckets with storage-specific configuration is no longer supported after [removing support for using `background_upload`](removals.md#background-upload-for-object-storage).
- The [certificate-based Kubernetes integration (DEPRECATED)](../user/infrastructure/clusters/index.md#certificate-based-kubernetes-integration-deprecated) is disabled by default, but you can be re-enable it through the [`certificate_based_clusters` feature flag](../administration/feature_flags.md#how-to-enable-and-disable-features-behind-flags) until GitLab 16.0.
### 14.10.0 ### 14.10.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -81,7 +81,7 @@ status), and create and edit deployed policies:
1. On the top bar, select **Menu > Projects** and find your project. 1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Policies**. 1. On the left sidebar, select **Security & Compliance > Policies**.
![Policies List Page](img/policies_list_v15_0.png) ![Policies List Page](img/policies_list_v15_1.png)
## Policy editor ## Policy editor

View File

@ -6,10 +6,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Scan execution policies **(ULTIMATE)** # Scan execution policies **(ULTIMATE)**
Project owners can use scan execution policies to require that security scans run on a specified > - Group-level security policies were [introduced](https://gitlab.com/groups/gitlab-org/-/epics/4425) in GitLab 15.2 [with a flag](../../../administration/feature_flags.md) named `group_level_security_policies`. Disabled by default.
schedule or with the project pipeline. Required scans are injected into the CI pipeline as new jobs
Group, sub-group, or project owners can use scan execution policies to require that security scans run on a specified
schedule or with the project (or multiple projects if the policy is defined at a group or sub-group level) pipeline. Required scans are injected into the CI pipeline as new jobs
with a long, random job name. In the unlikely event of a job name collision, the security policy job overwrites with a long, random job name. In the unlikely event of a job name collision, the security policy job overwrites
any pre-existing job in the pipeline. any pre-existing job in the pipeline. If a policy is created at the group-level, it will apply to every child
project or sub-group. A group-level policy cannot be edited from a child project or sub-group.
This feature has some overlap with [compliance framework pipelines](../../project/settings/#compliance-pipeline-configuration), This feature has some overlap with [compliance framework pipelines](../../project/settings/#compliance-pipeline-configuration),
as we have not [unified the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312). as we have not [unified the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312).
@ -25,7 +28,7 @@ an error appears that states `chosen stage does not exist`.
## Scan execution policy editor ## Scan execution policy editor
NOTE: NOTE:
Only project Owners have the [permissions](../../permissions.md#project-members-permissions) Only group, sub-group, or project Owners have the [permissions](../../permissions.md#project-members-permissions)
to select Security Policy Project. to select Security Policy Project.
Once your policy is complete, save it by selecting **Create via merge request** Once your policy is complete, save it by selecting **Create via merge request**

View File

@ -7,8 +7,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Value stream analytics for groups **(PREMIUM)** # Value stream analytics for groups **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196455) in GitLab 12.9 for groups.
Value stream analytics provides metrics about each stage of your software development process. Value stream analytics provides metrics about each stage of your software development process.
A **value stream** is the entire work process that delivers value to customers. For example, A **value stream** is the entire work process that delivers value to customers. For example,
@ -20,14 +18,13 @@ Use value stream analytics to identify:
- The amount of time it takes to go from an idea to production. - The amount of time it takes to go from an idea to production.
- The velocity of a given project. - The velocity of a given project.
- Bottlenecks in the development process. - Bottlenecks in the development process.
- Detecting long-running issues or merge requests. - Long-running issues or merge requests.
- Factors that cause your software development lifecycle to slow down. - Factors that cause your software development lifecycle to slow down.
Value stream analytics is also available for [projects](../../analytics/value_stream_analytics.md). Value stream analytics is also available for [projects](../../analytics/value_stream_analytics.md).
## View value stream analytics ## View value stream analytics
> - Date range filter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13216) in GitLab 12.4
> - Filtering [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13216) in GitLab 13.3 > - Filtering [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13216) in GitLab 13.3
> - Horizontal stage path [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12196) in 13.0 and [feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323982) in 13.12 > - Horizontal stage path [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12196) in 13.0 and [feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323982) in 13.12
@ -68,7 +65,11 @@ The table shows a list of related workflow items for the selected stage. Based o
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210315) in GitLab 13.0. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210315) in GitLab 13.0.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323982) in GitLab 13.12. > - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323982) in GitLab 13.12.
The **Overview** dashboard in value stream analytics shows key metrics and DORA metrics of group performance. Based on the filter you select, the dashboard automatically aggregates DORA metrics and displays the current status of the value stream. The **Overview** dashboard in value stream analytics shows key metrics and DORA metrics of group performance. Based on the filter you select,
the dashboard automatically aggregates DORA metrics and displays the current status of the value stream.
To view deployment metrics, you must have a
[production environment configured](../../../ci/environments/index.md#deployment-tier-of-environments).
To view the DORA metrics and key metrics: To view the DORA metrics and key metrics:
@ -83,14 +84,14 @@ To view the DORA metrics and key metrics:
- In the **To** field, select an end date. - In the **To** field, select an end date.
Key metrics and DORA metrics display below the **Filter results** text box. Key metrics and DORA metrics display below the **Filter results** text box.
<iframe width="560" height="315" src="https://www.youtube.com/embed/wQU-mWvNSiI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
### Key metrics in the value stream ### Key metrics in the value stream
The **Overview** dashboard shows the following key metrics that measure team performance: The **Overview** dashboard shows the following key metrics that measure team performance:
- Lead time: Median time from when the issue was created to when it was closed. - Lead time: Median time from when the issue was created to when it was closed.
- Cycle time: Median time from first commit to issue closed. GitLab measures cycle time from the earliest commit of a [linked issue's merge request](../../project/issues/crosslinking_issues.md#from-commit-messages) to when that issue is closed. The cycle time approach underestimates the lead time because merge request creation is always later than commit time. - Cycle time: Median time from first commit to issue closed. GitLab measures cycle time from the earliest commit of a
[linked issue's merge request](../../project/issues/crosslinking_issues.md#from-commit-messages) to when that issue is closed.
The cycle time approach underestimates the lead time because merge request creation is always later than commit time.
- New issues: Number of new issues created. - New issues: Number of new issues created.
- Deploys: Total number of deployments to production. - Deploys: Total number of deployments to production.
@ -102,21 +103,25 @@ The **Overview** dashboard shows the following key metrics that measure team per
The value stream analytics **Overview** dashboard displays the following [DORA](../../../user/analytics/index.md) metrics: The value stream analytics **Overview** dashboard displays the following [DORA](../../../user/analytics/index.md) metrics:
These [four DORA metrics](../../../user/analytics/index.md) are: Deployment Frequency, Lead time for changes, Time to restore service and Change failure rate. - Deployment Frequency.
- Lead time for changes.
- Time to restore service.
- Change failure rate.
DORA metrics are calculated based on data from the DORA metrics are calculated based on data from the
[DORA API](../../../api/dora/metrics.md#devops-research-and-assessment-dora-key-metrics-api). [DORA API](../../../api/dora/metrics.md#devops-research-and-assessment-dora-key-metrics-api).
To view deployment metrics, you must have a
[production environment configured](../../../ci/environments/index.md#deployment-tier-of-environments).
NOTE:
The date range selector filters items by the event time. This is the time when the currently
selected stage finished for the given item.
NOTE: NOTE:
In GitLab 13.9 and later, deployment frequency metrics are calculated based on when the deployment was finished. In GitLab 13.9 and later, deployment frequency metrics are calculated based on when the deployment was finished.
In GitLab 13.8 and earlier, deployment frequency metrics are calculated based on when the deployment was created. In GitLab 13.8 and earlier, deployment frequency metrics are calculated based on when the deployment was created.
<div class="video-fallback">
See the video: <a href="https://www.youtube.com/embed/wQU-mWvNSiI">DORA metrics and value stream analytics</a>.
</div>
<figure class="video-container">
<iframe src="https://www.youtube.com/embed/wQU-mWvNSiI" frameborder="0" allowfullscreen="true"> </iframe>
</figure>
### How value stream analytics aggregates data ### How value stream analytics aggregates data
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335391) in GitLab 14.5 [with a flag](../../../administration/feature_flags.md) named `use_vsa_aggregated_tables`. Disabled by default. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335391) in GitLab 14.5 [with a flag](../../../administration/feature_flags.md) named `use_vsa_aggregated_tables`. Disabled by default.
@ -159,6 +164,10 @@ To view the median time spent in each stage by a group:
- In the **To** field, select an end date. - In the **To** field, select an end date.
1. To view the metrics for each stage, above the **Filter results** text box, hover over a stage. 1. To view the metrics for each stage, above the **Filter results** text box, hover over a stage.
NOTE:
The date range selector filters items by the event time. The event time is when the
selected stage finished for the given item.
## How value stream analytics measures stages ## How value stream analytics measures stages
Value stream analytics measures each stage from its start event to its end event. Value stream analytics measures each stage from its start event to its end event.
@ -320,7 +329,6 @@ To delete a custom value stream:
## View number of days for a cycle to complete ## View number of days for a cycle to complete
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21631) in GitLab 12.6.
> - Chart median line [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/235455) in GitLab 13.4. > - Chart median line [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/235455) in GitLab 13.4.
> - Totals [replaced](https://gitlab.com/gitlab-org/gitlab/-/issues/262070) with averages in GitLab 13.12. > - Totals [replaced](https://gitlab.com/gitlab-org/gitlab/-/issues/262070) with averages in GitLab 13.12.
@ -342,8 +350,6 @@ The chart shows data for the last 500 workflow items.
## Tasks by type chart ## Tasks by type chart
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32421) in GitLab 12.10.
This chart shows a cumulative count of issues and merge requests per day. This chart shows a cumulative count of issues and merge requests per day.
This chart uses the global page filters for displaying data based on the selected This chart uses the global page filters for displaying data based on the selected

View File

@ -8,7 +8,7 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/repository_mirroring.htm
# Repository mirroring **(FREE)** # Repository mirroring **(FREE)**
You can _mirror_ a repository to and from external sources. You can select which repository You can _mirror_ a repository to and from external sources. You can select which repository
serves as the source. Branches, tags, and commits can be mirrored. serves as the source. Branches, tags, and commits are synced automatically.
NOTE: NOTE:
SCP-style URLs are **not** supported. However, the work for implementing SCP-style URLs is tracked SCP-style URLs are **not** supported. However, the work for implementing SCP-style URLs is tracked

View File

@ -97,6 +97,24 @@ module API
present presenter, with: ::API::Entities::Terraform::ModuleVersions present presenter, with: ::API::Entities::Terraform::ModuleVersions
end end
get 'download' do
latest_version = packages.order_version.last&.version
render_api_error!({ error: "No version found for #{params[:module_name]} module" }, :not_found) if latest_version.nil?
download_path = api_v4_packages_terraform_modules_v1_module_version_download_path(
{
module_namespace: params[:module_namespace],
module_name: params[:module_name],
module_system: params[:module_system],
module_version: latest_version
},
true
)
redirect(download_path)
end
params do params do
includes :module_version includes :module_version
end end

View File

@ -71,9 +71,9 @@ module Gitlab
end end
def compose!(deps = nil) def compose!(deps = nil)
super do has_workflow_rules = deps&.workflow_entry&.has_rules?
has_workflow_rules = deps&.workflow_entry&.has_rules?
super do
# If workflow:rules: or rules: are used # If workflow:rules: or rules: are used
# they are considered not compatible # they are considered not compatible
# with `only/except` defaults # with `only/except` defaults
@ -86,12 +86,16 @@ module Gitlab
@entries.delete(:except) unless except_defined? # rubocop:disable Gitlab/ModuleWithInstanceVariables @entries.delete(:except) unless except_defined? # rubocop:disable Gitlab/ModuleWithInstanceVariables
end end
unless has_workflow_rules unless ::Feature.enabled?(:ci_value_change_for_processable_and_rules_entry)
validate_against_warnings validate_against_warnings unless has_workflow_rules
end end
yield if block_given? yield if block_given?
end end
if ::Feature.enabled?(:ci_value_change_for_processable_and_rules_entry)
validate_against_warnings unless has_workflow_rules
end
end end
def validate_against_warnings def validate_against_warnings

View File

@ -13,7 +13,12 @@ module Gitlab
end end
def value def value
[@config].flatten if ::Feature.enabled?(:ci_value_change_for_processable_and_rules_entry)
# `flatten` is needed to make it work with nested `!reference`
[super].flatten
else
[@config].flatten
end
end end
def composable_class def composable_class

View File

@ -17,14 +17,11 @@ module Gitlab
end end
def check_runner_upgrade_status(runner_version) def check_runner_upgrade_status(runner_version)
return :invalid unless runner_version
releases = RunnerReleases.instance.releases
orig_runner_version = runner_version
runner_version = ::Gitlab::VersionInfo.parse(runner_version) unless runner_version.is_a?(::Gitlab::VersionInfo) runner_version = ::Gitlab::VersionInfo.parse(runner_version) unless runner_version.is_a?(::Gitlab::VersionInfo)
raise ArgumentError, "'#{orig_runner_version}' is not a valid version" unless runner_version.valid? return :invalid unless runner_version.valid?
releases = RunnerReleases.instance.releases
gitlab_minor_version = @gitlab_version.without_patch gitlab_minor_version = @gitlab_version.without_patch
available_releases = releases available_releases = releases

View File

@ -72,12 +72,6 @@ module Gitlab
) )
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_dml_mode! Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_dml_mode!
if transaction_open?
raise 'The `queue_batched_background_migration` cannot be run inside a transaction. ' \
'You can disable transactions by calling `disable_ddl_transaction!` in the body of ' \
'your migration class.'
end
gitlab_schema ||= gitlab_schema_from_context gitlab_schema ||= gitlab_schema_from_context
Gitlab::Database::BackgroundMigration::BatchedMigration.reset_column_information Gitlab::Database::BackgroundMigration::BatchedMigration.reset_column_information
@ -182,12 +176,6 @@ module Gitlab
def delete_batched_background_migration(job_class_name, table_name, column_name, job_arguments) def delete_batched_background_migration(job_class_name, table_name, column_name, job_arguments)
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_dml_mode! Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_dml_mode!
if transaction_open?
raise 'The `#delete_batched_background_migration` cannot be run inside a transaction. ' \
'You can disable transactions by calling `disable_ddl_transaction!` in the body of ' \
'your migration class.'
end
Gitlab::Database::BackgroundMigration::BatchedMigration.reset_column_information Gitlab::Database::BackgroundMigration::BatchedMigration.reset_column_information
Gitlab::Database::BackgroundMigration::BatchedMigration Gitlab::Database::BackgroundMigration::BatchedMigration

View File

@ -39,6 +39,7 @@ module Gitlab
CATEGORIES_COLLECTED_FROM_METRICS_DEFINITIONS = %w[ CATEGORIES_COLLECTED_FROM_METRICS_DEFINITIONS = %w[
error_tracking error_tracking
ide_edit
].freeze ].freeze
# Track event on entity_id # Track event on entity_id

View File

@ -278,8 +278,13 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do
context 'when workflow rules is not used' do context 'when workflow rules is not used' do
let(:workflow) { double('workflow', 'has_rules?' => false) } let(:workflow) { double('workflow', 'has_rules?' => false) }
let(:ci_value_change_for_processable_and_rules_entry) { true }
before do before do
stub_feature_flags(
ci_value_change_for_processable_and_rules_entry: ci_value_change_for_processable_and_rules_entry
)
entry.compose!(deps) entry.compose!(deps)
end end
@ -303,6 +308,14 @@ RSpec.describe Gitlab::Ci::Config::Entry::Processable do
it 'raises a warning' do it 'raises a warning' do
expect(entry.warnings).to contain_exactly(/may allow multiple pipelines/) expect(entry.warnings).to contain_exactly(/may allow multiple pipelines/)
end end
context 'when the FF ci_value_change_for_processable_and_rules_entry is disabled' do
let(:ci_value_change_for_processable_and_rules_entry) { false }
it 'raises a warning' do
expect(entry.warnings).to contain_exactly(/may allow multiple pipelines/)
end
end
end end
context 'and its value is `never`' do context 'and its value is `never`' do

View File

@ -1,10 +1,13 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'fast_spec_helper' require 'fast_spec_helper'
require 'support/helpers/stubbed_feature'
require 'support/helpers/stub_feature_flags' require 'support/helpers/stub_feature_flags'
require_dependency 'active_model' require_dependency 'active_model'
RSpec.describe Gitlab::Ci::Config::Entry::Rules do RSpec.describe Gitlab::Ci::Config::Entry::Rules do
include StubFeatureFlags
let(:factory) do let(:factory) do
Gitlab::Config::Entry::Factory.new(described_class) Gitlab::Config::Entry::Factory.new(described_class)
.metadata(metadata) .metadata(metadata)
@ -12,13 +15,12 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules do
end end
let(:metadata) { { allowed_when: %w[always never] } } let(:metadata) { { allowed_when: %w[always never] } }
let(:entry) { factory.create! }
subject(:entry) { factory.create! }
describe '.new' do describe '.new' do
subject { entry }
before do before do
subject.compose! entry.compose!
end end
context 'with a list of rule rule' do context 'with a list of rule rule' do
@ -73,7 +75,11 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules do
end end
describe '#value' do describe '#value' do
subject { entry.value } subject(:value) { entry.value }
before do
entry.compose!
end
context 'with a list of rule rule' do context 'with a list of rule rule' do
let(:config) do let(:config) do
@ -99,7 +105,15 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules do
{ if: '$SKIP', when: 'never' } { if: '$SKIP', when: 'never' }
end end
it { is_expected.to eq([config]) } it { is_expected.to eq([]) }
context 'when the FF ci_value_change_for_processable_and_rules_entry is disabled' do
before do
stub_feature_flags(ci_value_change_for_processable_and_rules_entry: false)
end
it { is_expected.to eq([config]) }
end
end end
context 'with nested rules' do context 'with nested rules' do

View File

@ -30,8 +30,8 @@ RSpec.describe Gitlab::Ci::RunnerUpgradeCheck do
context 'with invalid runner_version' do context 'with invalid runner_version' do
let(:runner_version) { 'junk' } let(:runner_version) { 'junk' }
it 'raises ArgumentError' do it 'returns :invalid' do
expect { subject }.to raise_error(ArgumentError) is_expected.to eq(:invalid)
end end
end end

View File

@ -173,17 +173,6 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers d
expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to be_finished expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to be_finished
end end
context 'when within transaction' do
before do
allow(migration).to receive(:transaction_open?).and_return(true)
end
it 'does raise an exception' do
expect { migration.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: 5.minutes)}
.to raise_error /`queue_batched_background_migration` cannot be run inside a transaction./
end
end
end end
end end
@ -301,12 +290,8 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers d
end end
describe '#delete_batched_background_migration' do describe '#delete_batched_background_migration' do
let(:transaction_open) { false }
before do before do
expect(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas).to receive(:require_dml_mode!) expect(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas).to receive(:require_dml_mode!)
allow(migration).to receive(:transaction_open?).and_return(transaction_open)
end end
context 'when migration exists' do context 'when migration exists' do
@ -360,15 +345,6 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers d
end.not_to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count } end.not_to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count }
end end
end end
context 'when within transaction' do
let(:transaction_open) { true }
it 'raises an exception' do
expect { migration.delete_batched_background_migration('MyJobClass', :projects, :id, [[:id], [:id_convert_to_bigint]]) }
.to raise_error /`#delete_batched_background_migration` cannot be run inside a transaction./
end
end
end end
describe '#gitlab_schema_from_context' do describe '#gitlab_schema_from_context' do

View File

@ -0,0 +1,72 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe FinalizeOrphanedRoutesCleanup, :migration do
let(:batched_migrations) { table(:batched_background_migrations) }
let_it_be(:migration) { described_class::MIGRATION }
describe '#up' do
shared_examples 'finalizes the migration' do
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
expect(runner).to receive(:finalize).with('CleanupOrphanedRoutes', :projects, :id, [])
end
end
end
context 'when migration is missing' do
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
migrate!
end
end
context 'with migration present' do
let!(:project_namespace_backfill) do
batched_migrations.create!(
job_class_name: 'CleanupOrphanedRoutes',
table_name: :routes,
column_name: :id,
job_arguments: [],
interval: 2.minutes,
min_value: 1,
max_value: 2,
batch_size: 1000,
sub_batch_size: 200,
gitlab_schema: :gitlab_main,
status: 3 # finished
)
end
context 'when migration finished successfully' do
it 'does not raise exception' do
expect { migrate! }.not_to raise_error
end
end
context 'with different migration statuses' do
using RSpec::Parameterized::TableSyntax
where(:status, :description) do
0 | 'paused'
1 | 'active'
4 | 'failed'
5 | 'finalizing'
end
with_them do
before do
project_namespace_backfill.update!(status: status)
end
it_behaves_like 'finalizes the migration'
end
end
end
end
end

View File

@ -824,7 +824,7 @@ RSpec.describe Integration do
{ name: 'safe_field' }, { name: 'safe_field' },
{ name: 'url' }, { name: 'url' },
{ name: 'trojan_horse', type: 'password' }, { name: 'trojan_horse', type: 'password' },
{ name: 'trojan_gift', type: 'gift' } { name: 'trojan_gift', type: 'text' }
].shuffle ].shuffle
end end
end end
@ -849,7 +849,7 @@ RSpec.describe Integration do
field :safe_field field :safe_field
field :url field :url
field :trojan_horse, type: 'password' field :trojan_horse, type: 'password'
field :trojan_gift, type: 'gift' field :trojan_gift, type: 'text'
end end
end end
@ -1051,11 +1051,9 @@ RSpec.describe Integration do
field :bar, type: 'password' field :bar, type: 'password'
field :password field :password
field :with_help, field :with_help, help: -> { 'help' }
help: -> { 'help' } field :select, type: 'select'
field :boolean, type: 'checkbox'
field :a_number,
type: 'number'
end end
end end
@ -1084,6 +1082,19 @@ RSpec.describe Integration do
expect(integration).to be_foo_p_changed expect(integration).to be_foo_p_changed
end end
it 'provides boolean accessors for checkbox fields' do
integration.boolean = 'yes'
expect(integration.boolean?).to be(true)
integration.boolean = nil
expect(integration.boolean?).to be(false)
expect(integration).not_to respond_to(:foo?)
expect(integration).not_to respond_to(:bar?)
expect(integration).not_to respond_to(:password?)
expect(integration).not_to respond_to(:select?)
end
it 'provides data fields' do it 'provides data fields' do
integration.foo_dt = 3 integration.foo_dt = 3
expect(integration.foo_dt).to eq 3 expect(integration.foo_dt).to eq 3
@ -1093,21 +1104,24 @@ RSpec.describe Integration do
it 'registers fields in the fields list' do it 'registers fields in the fields list' do
expect(integration.fields.pluck(:name)).to match_array %w[ expect(integration.fields.pluck(:name)).to match_array %w[
foo foo_p foo_dt bar password with_help a_number foo foo_p foo_dt bar password with_help select boolean
] ]
expect(integration.api_field_names).to match_array %w[ expect(integration.api_field_names).to match_array %w[
foo foo_p foo_dt with_help a_number foo foo_p foo_dt with_help select boolean
] ]
end end
specify 'fields have expected attributes' do specify 'fields have expected attributes' do
expect(integration.fields).to include( expect(integration.fields).to include(
have_attributes(name: 'foo', type: 'text'), have_attributes(name: 'foo', type: 'text'),
have_attributes(name: 'foo_p', type: 'text'),
have_attributes(name: 'foo_dt', type: 'text'),
have_attributes(name: 'bar', type: 'password'), have_attributes(name: 'bar', type: 'password'),
have_attributes(name: 'password', type: 'password'), have_attributes(name: 'password', type: 'password'),
have_attributes(name: 'a_number', type: 'number'), have_attributes(name: 'with_help', help: 'help'),
have_attributes(name: 'with_help', help: 'help') have_attributes(name: 'select', type: 'select'),
have_attributes(name: 'boolean', type: 'checkbox')
) )
end end
end end

View File

@ -14,6 +14,37 @@ RSpec.describe ::Integrations::Field do
end end
end end
describe '#initialize' do
it 'sets type password for secret names' do
attrs[:name] = 'token'
attrs[:type] = 'text'
expect(field[:type]).to eq('password')
end
it 'uses the given type for other names' do
attrs[:name] = 'field'
attrs[:type] = 'select'
expect(field[:type]).to eq('select')
end
it 'raises an error if an invalid attribute is given' do
attrs[:foo] = 'foo'
attrs[:bar] = 'bar'
attrs[:name] = 'name'
attrs[:type] = 'text'
expect { field }.to raise_error(ArgumentError, "Invalid attributes [:foo, :bar]")
end
it 'raises an error if an invalid type is given' do
attrs[:type] = 'other'
expect { field }.to raise_error(ArgumentError, 'Invalid type "other"')
end
end
describe '#name' do describe '#name' do
before do before do
attrs[:name] = :foo attrs[:name] = :foo
@ -59,7 +90,7 @@ RSpec.describe ::Integrations::Field do
it 'has the correct default' do it 'has the correct default' do
expect(field[name]).to have_correct_default expect(field[name]).to have_correct_default
expect(field.send(name)).to have_correct_default expect(field.public_send(name)).to have_correct_default
end end
end end
@ -69,32 +100,66 @@ RSpec.describe ::Integrations::Field do
end end
it 'is known' do it 'is known' do
next if name == :type
expect(field[name]).to eq(:known) expect(field[name]).to eq(:known)
expect(field.send(name)).to eq(:known) expect(field.public_send(name)).to eq(:known)
end end
end end
context 'when set to a dynamic value' do context 'when set to a dynamic value' do
it 'is computed' do it 'is computed' do
next if name == :type
attrs[name] = -> { Time.current } attrs[name] = -> { Time.current }
start = Time.current start = Time.current
travel_to(start + 1.minute) do travel_to(start + 1.minute) do
expect(field[name]).to be_after(start) expect(field[name]).to be_after(start)
expect(field.send(name)).to be_after(start) expect(field.public_send(name)).to be_after(start)
end end
end end
it 'is executed in the class scope' do it 'is executed in the class scope' do
next if name == :type
attrs[name] = -> { default_placeholder } attrs[name] = -> { default_placeholder }
expect(field[name]).to eq('my placeholder') expect(field[name]).to eq('my placeholder')
expect(field.send(name)).to eq('my placeholder') expect(field.public_send(name)).to eq('my placeholder')
end end
end end
end end
end end
described_class::BOOLEAN_ATTRIBUTES.each do |name|
describe "##{name}?" do
it 'returns true if the value is truthy' do
attrs[name] = ''
expect(field.public_send("#{name}?")).to be(true)
end
it 'returns false if the value is falsey' do
attrs[name] = nil
expect(field.public_send("#{name}?")).to be(false)
end
end
end
described_class::TYPES.each do |type|
describe "##{type}?" do
it 'returns true if the type matches' do
attrs[:type] = type
expect(field.public_send("#{type}?")).to be(true)
end
it 'returns false if the type does not match' do
attrs[:type] = (described_class::TYPES - [type]).first
expect(field.public_send("#{type}?")).to be(false)
end
end
end
describe '#secret?' do describe '#secret?' do
context 'when empty' do context 'when empty' do
it { is_expected.not_to be_secret } it { is_expected.not_to be_secret }

View File

@ -98,6 +98,79 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
end end
end end
describe 'GET /api/v4/packages/terraform/modules/v1/:module_namespace/:module_name/:module_system/download' do
context 'empty registry' do
let(:url) { api("/packages/terraform/modules/v1/module-2/system/download") }
let(:headers) { {} }
subject { get(url, headers: headers) }
it 'returns not found when there is no module' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'with valid namespace' do
let(:url) { api("/packages/terraform/modules/v1/#{group.path}/#{package.name}/download") }
let(:headers) { {} }
subject { get(url, headers: headers) }
before_all do
create(:terraform_module_package, project: project, name: package.name, version: '1.0.1')
end
where(:visibility, :user_role, :member, :token_type, :shared_examples_name, :expected_status) do
:public | :developer | true | :personal_access_token | 'redirects to version download' | :found
:public | :guest | true | :personal_access_token | 'redirects to version download' | :found
:public | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :personal_access_token | 'redirects to version download' | :found
:public | :guest | false | :personal_access_token | 'redirects to version download' | :found
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | nil | 'redirects to version download' | :found
:private | :developer | true | :personal_access_token | 'redirects to version download' | :found
:private | :guest | true | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | nil | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | :job_token | 'redirects to version download' | :found
:public | :guest | true | :job_token | 'redirects to version download' | :found
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :job_token | 'redirects to version download' | :found
:public | :guest | false | :job_token | 'redirects to version download' | :found
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | :job_token | 'redirects to version download' | :found
:private | :guest | true | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
end
with_them do
let(:headers) { user_role == :anonymous ? {} : { 'Authorization' => "Bearer #{token}" } }
before do
group.update!(visibility: visibility.to_s)
project.update!(visibility: visibility.to_s)
end
it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member]
end
end
end
describe 'GET /api/v4/packages/terraform/modules/v1/:module_namespace/:module_name/:module_system/:module_version/download' do describe 'GET /api/v4/packages/terraform/modules/v1/:module_namespace/:module_name/:module_system/:module_version/download' do
let(:url) { api("/packages/terraform/modules/v1/#{group.path}/#{package.name}/#{package.version}/download") } let(:url) { api("/packages/terraform/modules/v1/#{group.path}/#{package.name}/#{package.version}/download") }
let(:headers) { {} } let(:headers) { {} }

View File

@ -52,6 +52,24 @@ RSpec.shared_examples 'an unimplemented route' do
it_behaves_like 'when package feature is disabled' it_behaves_like 'when package feature is disabled'
end end
RSpec.shared_examples 'redirects to version download' do |user_type, status, add_member = true|
context "for user type #{user_type}" do
before do
group.send("add_#{user_type}", user) if add_member && user_type != :anonymous
end
it_behaves_like 'returning response status', status
it 'returns a valid response' do
subject
expect(request.url).to include 'module-1/system/download'
expect(response.headers).to include 'Location'
expect(response.headers['Location']).to include 'module-1/system/1.0.1/download'
end
end
end
RSpec.shared_examples 'grants terraform module download' do |user_type, status, add_member = true| RSpec.shared_examples 'grants terraform module download' do |user_type, status, add_member = true|
context "for user type #{user_type}" do context "for user type #{user_type}" do
before do before do