Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-04-12 15:15:44 +00:00
parent e0d7577e29
commit c1a7bcdf1b
128 changed files with 802 additions and 3215 deletions

View File

@ -115,4 +115,6 @@ _What tasks or actions should the user be capable of performing with this featur
/label ~wg-ai-integration
/cc @tmccaslin @hbenson @wayne @pedroms @jmandell
/ confidential
/confidential
Make change to this template here: https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/AI%20Project%20Proposal.md

View File

@ -227,3 +227,5 @@ Search/NamespacedClass:
- 'spec/support/helpers/filtered_search_helpers.rb'
- 'spec/support/helpers/search_helpers.rb'
- 'spec/support/helpers/search_settings_helpers.rb'
- 'lib/sidebars/search/panel.rb'
- 'spec/lib/sidebars/search/panel_spec.rb'

View File

@ -1 +1 @@
b8190668d147784e8be4a379b33f691363e08a0f
e029e3b56eacf23943a987207e8b490f45598630

View File

@ -197,7 +197,7 @@ gem 'asciidoctor-plantuml', '~> 0.0.16'
gem 'asciidoctor-kroki', '~> 0.8.0', require: false
gem 'rouge', '~> 4.1.0'
gem 'truncato', '~> 0.7.12'
gem 'nokogiri', '~> 1.14.2'
gem 'nokogiri', '~> 1.14.3'
# Calendar rendering
gem 'icalendar'

View File

@ -386,17 +386,17 @@
{"name":"nio4r","version":"2.5.8","platform":"java","checksum":"b2b1800f6bf7ce4b797ca8b639ad278a99c9c904fb087a91d944f38e4bd71401"},
{"name":"nio4r","version":"2.5.8","platform":"ruby","checksum":"3becb4ad95ab8ac0a9bd2e1b16466869402be62848082bf6329ae9091f276676"},
{"name":"no_proxy_fix","version":"0.1.2","platform":"ruby","checksum":"4e9b4c31bb146de7fcf347dc1087bb13ac2039b56d50aa019e61036256abcd00"},
{"name":"nokogiri","version":"1.14.2","platform":"aarch64-linux","checksum":"966acf4f6c1fba10518f86498141cf44265564ac5a65dcc8496b65f8c354f776"},
{"name":"nokogiri","version":"1.14.2","platform":"arm-linux","checksum":"8a3a35cadae4a800ddc0b967394257343d62196d9d059b54e38cf067981db428"},
{"name":"nokogiri","version":"1.14.2","platform":"arm64-darwin","checksum":"81404cd014ecb597725c3847523c2ee365191a968d0b5f7d857e03f388c57631"},
{"name":"nokogiri","version":"1.14.2","platform":"java","checksum":"0a39222af14e75eb0243e8d969345e03b90c0e02b0f33c61f1ebb6ae53538bb5"},
{"name":"nokogiri","version":"1.14.2","platform":"ruby","checksum":"c765a74aac6cf430a710bb0b6038b8ee11f177393cd6ae8dadc7a44a6e2658b6"},
{"name":"nokogiri","version":"1.14.2","platform":"x64-mingw-ucrt","checksum":"62a18f9213a0ceeaf563d1bc7ccfd93273323c4356ded58a5617c59bc4635bc5"},
{"name":"nokogiri","version":"1.14.2","platform":"x64-mingw32","checksum":"54f6ac2c15a7a88f431bb5e23f4616aa8fc97a92eb63336bcf65b7050f2d3be0"},
{"name":"nokogiri","version":"1.14.2","platform":"x86-linux","checksum":"c42fa0856f01f901954898e28c3c2b4dce0e843056b1b126f441d06e887e1b77"},
{"name":"nokogiri","version":"1.14.2","platform":"x86-mingw32","checksum":"f940d9c8e47b0f19875465376f2d1c8911bc9489ac9a48c124579819dc4a7f19"},
{"name":"nokogiri","version":"1.14.2","platform":"x86_64-darwin","checksum":"2508978f5ca28944919973f6300f0a7355fbe72604ab6a6913f1630be1030265"},
{"name":"nokogiri","version":"1.14.2","platform":"x86_64-linux","checksum":"bc6405e1f3ddac6e401f82d775f1c0c24c6e58c371b3fadaca0596d5d511e476"},
{"name":"nokogiri","version":"1.14.3","platform":"aarch64-linux","checksum":"9cc53dd8d92868a0f5bcee44396357a19f95e32d8b9754092622a25bc954c60c"},
{"name":"nokogiri","version":"1.14.3","platform":"arm-linux","checksum":"320fa1836b8e59e86a804baee534893bcf3b901cc255bbec6d87f3dd3e431610"},
{"name":"nokogiri","version":"1.14.3","platform":"arm64-darwin","checksum":"67dd4ac33a8cf0967c521fa57e5a5422db39da8a9d131aaa2cd53deaa12be4cd"},
{"name":"nokogiri","version":"1.14.3","platform":"java","checksum":"13969ec7f41d9cff46fc7707224c55490a519feef7cfea727c6945c5b444caa2"},
{"name":"nokogiri","version":"1.14.3","platform":"ruby","checksum":"3b1cee0eb8879e9e25b6dd431be597ca68f20283b0d4f4ca986521fad107dc3a"},
{"name":"nokogiri","version":"1.14.3","platform":"x64-mingw-ucrt","checksum":"9885085249303461ee08f9a9b161d0a570391b8f5be0316b3ac5a6d9a947e1e2"},
{"name":"nokogiri","version":"1.14.3","platform":"x64-mingw32","checksum":"997943d7582a23ad6e7a0abe081d0d40d2c1319a6b2749f9b30fd18037f0c38a"},
{"name":"nokogiri","version":"1.14.3","platform":"x86-linux","checksum":"58c30b763aebd62dc4222385509d7f83ac398ee520490fadc4b6d7877e29895a"},
{"name":"nokogiri","version":"1.14.3","platform":"x86-mingw32","checksum":"e1d58a5c56c34aab71b00901a969e19bf9f7322ee459b4e9380f433213887c04"},
{"name":"nokogiri","version":"1.14.3","platform":"x86_64-darwin","checksum":"f0a1ed1460a91fd2daf558357f4c0ceac6d994899da1bf98431aeda301e4dc74"},
{"name":"nokogiri","version":"1.14.3","platform":"x86_64-linux","checksum":"e323a7c654ef846e64582fb6e26f6fed869a96753f8e048ff723e74d8005cb11"},
{"name":"notiffany","version":"0.1.3","platform":"ruby","checksum":"d37669605b7f8dcb04e004e6373e2a780b98c776f8eb503ac9578557d7808738"},
{"name":"numerizer","version":"0.2.0","platform":"ruby","checksum":"e58076d5ee5370417b7e52d9cb25836d62acd1b8d9a194c308707986c1705d7b"},
{"name":"oauth","version":"0.5.6","platform":"ruby","checksum":"4085fe28e0c5e2434135e00a6555294fd2a4ff96a98d1bdecdcd619fc6368dff"},

View File

@ -1004,7 +1004,7 @@ GEM
netrc (0.11.0)
nio4r (2.5.8)
no_proxy_fix (0.1.2)
nokogiri (1.14.2)
nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
notiffany (0.1.3)
@ -1824,7 +1824,7 @@ DEPENDENCIES
net-ldap (~> 0.17.1)
net-ntp
net-protocol (~> 0.1.3)
nokogiri (~> 1.14.2)
nokogiri (~> 1.14.3)
oauth2 (~> 2.0)
octokit (~> 4.15)
ohai (~> 17.9)

View File

@ -7,6 +7,8 @@ import store from '~/mr_notes/stores';
export const initReviewBar = () => {
const el = document.getElementById('js-review-bar');
if (!el) return;
Vue.use(VueApollo);
// eslint-disable-next-line no-new

View File

@ -4,7 +4,15 @@ import { stickyMonitor } from './lib/utils/sticky';
export const initDiffStatsDropdown = (stickyTop) => {
if (stickyTop) {
stickyMonitor(document.querySelector('.js-diff-files-changed'), stickyTop, false);
// We spend quite a bit of effort in our CSS to set the correct padding-top on the
// layout page, so we re-use the padding set there to determine at what height our
// element should be sticky
const pageLayout = document.querySelector('.layout-page');
const pageLayoutTopOffset = pageLayout
? parseFloat(window.getComputedStyle(pageLayout).getPropertyValue('padding-top') || 0)
: 0;
stickyMonitor(document.querySelector('.js-diff-files-changed'), pageLayoutTopOffset, false);
}
const el = document.querySelector('.js-diff-stats-dropdown');

View File

@ -36,7 +36,7 @@ export default {
},
},
i18n: {
LIST_TITLE_TEXT: s__('InfrastructureRegistry|Infrastructure Registry'),
LIST_TITLE_TEXT: s__('InfrastructureRegistry|Terraform Module Registry'),
LIST_INTRO_TEXT: s__(
'InfrastructureRegistry|Publish and share your modules. %{docLinkStart}More information%{docLinkEnd}',
),

View File

@ -18,11 +18,7 @@ import '~/sourcegraph/load';
import DiffStats from '~/diffs/components/diff_stats.vue';
import { initReportAbuse } from '~/projects/report_abuse';
const hasPerfBar = document.querySelector('.with-performance-bar');
const performanceHeight = hasPerfBar ? 35 : 0;
initDiffStatsDropdown(
(document.querySelector('.navbar-gitlab')?.offsetHeight ?? 0) + performanceHeight,
);
initDiffStatsDropdown(true);
new ZenMode();
new ShortcutsNavigation();

View File

@ -7,8 +7,7 @@ import syntaxHighlight from '~/syntax_highlight';
initCompareSelector();
new Diff(); // eslint-disable-line no-new
const paddingTop = 16;
initDiffStatsDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop);
initDiffStatsDropdown(true);
GpgBadges.fetch();
syntaxHighlight([document.querySelector('.files')]);

View File

@ -740,7 +740,7 @@ $calendar-activity-colors: (
*/
$commit-max-width-marker-color: rgba(0, 0, 0, 0);
$commit-message-text-area-bg: rgba(0, 0, 0, 0);
$commit-stat-summary-height: 36px;
$commit-stat-summary-height: 32px;
/*
* Files
@ -914,7 +914,7 @@ $mr-tabs-height: 48px;
/*
Compare Branches
*/
$compare-branches-sticky-header-height: 68px;
$compare-branches-sticky-header-height: 32px;
/*
Board Swimlanes

View File

@ -10,7 +10,6 @@ class Clusters::ClustersController < Clusters::BaseController
before_action :authorize_read_cluster!, only: [:show, :index]
before_action :authorize_create_cluster!, only: [:connect]
before_action :authorize_update_cluster!, only: [:update]
before_action :update_applications_status, only: [:cluster_status]
before_action :ensure_feature_enabled!, except: [:index, :new_cluster_docs]
helper_method :token_in_session
@ -223,10 +222,6 @@ class Clusters::ClustersController < Clusters::BaseController
@expires_at_in_session ||=
session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at]
end
def update_applications_status
@cluster.applications.each(&:schedule_status_update)
end
end
Clusters::ClustersController.prepend_mod_with('Clusters::ClustersController')

View File

@ -49,7 +49,8 @@ class Projects::BlobController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:highlight_js, @project)
push_frontend_feature_flag(:explain_code, current_user)
push_frontend_feature_flag(:explain_code_snippet, current_user)
push_licensed_feature(:explain_code, @project) if @project.licensed_feature_available?(:explain_code)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end

View File

@ -2,48 +2,48 @@
module GraphqlTriggers
def self.issuable_assignees_updated(issuable)
GitlabSchema.subscriptions.trigger('issuableAssigneesUpdated', { issuable_id: issuable.to_gid }, issuable)
GitlabSchema.subscriptions.trigger(:issuable_assignees_updated, { issuable_id: issuable.to_gid }, issuable)
end
def self.issue_crm_contacts_updated(issue)
GitlabSchema.subscriptions.trigger('issueCrmContactsUpdated', { issuable_id: issue.to_gid }, issue)
GitlabSchema.subscriptions.trigger(:issue_crm_contacts_updated, { issuable_id: issue.to_gid }, issue)
end
def self.issuable_title_updated(issuable)
GitlabSchema.subscriptions.trigger('issuableTitleUpdated', { issuable_id: issuable.to_gid }, issuable)
GitlabSchema.subscriptions.trigger(:issuable_title_updated, { issuable_id: issuable.to_gid }, issuable)
end
def self.issuable_description_updated(issuable)
GitlabSchema.subscriptions.trigger('issuableDescriptionUpdated', { issuable_id: issuable.to_gid }, issuable)
GitlabSchema.subscriptions.trigger(:issuable_description_updated, { issuable_id: issuable.to_gid }, issuable)
end
def self.issuable_labels_updated(issuable)
GitlabSchema.subscriptions.trigger('issuableLabelsUpdated', { issuable_id: issuable.to_gid }, issuable)
GitlabSchema.subscriptions.trigger(:issuable_labels_updated, { issuable_id: issuable.to_gid }, issuable)
end
def self.issuable_dates_updated(issuable)
GitlabSchema.subscriptions.trigger('issuableDatesUpdated', { issuable_id: issuable.to_gid }, issuable)
GitlabSchema.subscriptions.trigger(:issuable_dates_updated, { issuable_id: issuable.to_gid }, issuable)
end
def self.issuable_milestone_updated(issuable)
GitlabSchema.subscriptions.trigger('issuableMilestoneUpdated', { issuable_id: issuable.to_gid }, issuable)
GitlabSchema.subscriptions.trigger(:issuable_milestone_updated, { issuable_id: issuable.to_gid }, issuable)
end
def self.work_item_note_created(work_item_gid, note_data)
GitlabSchema.subscriptions.trigger('workItemNoteCreated', { noteable_id: work_item_gid }, note_data)
GitlabSchema.subscriptions.trigger(:work_item_note_created, { noteable_id: work_item_gid }, note_data)
end
def self.work_item_note_deleted(work_item_gid, note_data)
GitlabSchema.subscriptions.trigger('workItemNoteDeleted', { noteable_id: work_item_gid }, note_data)
GitlabSchema.subscriptions.trigger(:work_item_note_deleted, { noteable_id: work_item_gid }, note_data)
end
def self.work_item_note_updated(work_item_gid, note_data)
GitlabSchema.subscriptions.trigger('workItemNoteUpdated', { noteable_id: work_item_gid }, note_data)
GitlabSchema.subscriptions.trigger(:work_item_note_updated, { noteable_id: work_item_gid }, note_data)
end
def self.merge_request_reviewers_updated(merge_request)
GitlabSchema.subscriptions.trigger(
'mergeRequestReviewersUpdated', { issuable_id: merge_request.to_gid }, merge_request
:merge_request_reviewers_updated, { issuable_id: merge_request.to_gid }, merge_request
)
end
@ -51,13 +51,13 @@ module GraphqlTriggers
return unless Feature.enabled?(:realtime_mr_status_change, merge_request.project)
GitlabSchema.subscriptions.trigger(
'mergeRequestMergeStatusUpdated', { issuable_id: merge_request.to_gid }, merge_request
:merge_request_merge_status_updated, { issuable_id: merge_request.to_gid }, merge_request
)
end
def self.merge_request_approval_state_updated(merge_request)
GitlabSchema.subscriptions.trigger(
'mergeRequestApprovalStateUpdated', { issuable_id: merge_request.to_gid }, merge_request
:merge_request_approval_state_updated, { issuable_id: merge_request.to_gid }, merge_request
)
end
end

View File

@ -97,7 +97,7 @@ module NavHelper
def super_sidebar_supported?
return true if @nav.nil?
%w(your_work explore project group profile user_profile).include?(@nav)
%w(your_work explore project group profile user_profile search).include?(@nav)
end
def get_header_links

View File

@ -112,6 +112,9 @@ module SidebarsHelper
Sidebars::UserProfile::Panel.new(context)
when 'explore'
Sidebars::Explore::Panel.new(Sidebars::Context.new(current_user: user, container: nil, **context_adds))
when 'search'
context = Sidebars::Context.new(current_user: user, container: nil, **context_adds)
Sidebars::Search::Panel.new(context)
else
context = your_work_sidebar_context(user, **context_adds)
Sidebars::YourWork::Panel.new(context)

View File

@ -1,83 +0,0 @@
# frozen_string_literal: true
require 'openssl'
module Clusters
module Applications
# DEPRECATED: This model represents the Helm 2 Tiller server.
# It is being kept around to enable the cleanup of the unused Tiller server.
class Helm < ApplicationRecord
self.table_name = 'clusters_applications_helm'
attr_encrypted :ca_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc'
include ::Clusters::Concerns::ApplicationCore
include ::Clusters::Concerns::ApplicationStatus
include ::Gitlab::Utils::StrongMemoize
attribute :version, default: Gitlab::Kubernetes::Helm::V2::BaseCommand::HELM_VERSION
before_create :create_keys_and_certs
def issue_client_cert
ca_cert_obj.issue
end
def set_initial_status
# The legacy Tiller server is not installable, which is the initial status of every app
end
# DEPRECATED: This command is only for development and testing purposes, to simulate
# a Helm 2 cluster with an existing Tiller server.
def install_command
Gitlab::Kubernetes::Helm::V2::InitCommand.new(
name: name,
files: files,
rbac: cluster.platform_kubernetes_rbac?
)
end
def uninstall_command
Gitlab::Kubernetes::Helm::V2::ResetCommand.new(
name: name,
files: files,
rbac: cluster.platform_kubernetes_rbac?
)
end
def has_ssl?
ca_key.present? && ca_cert.present?
end
private
def files
{
'ca.pem': ca_cert,
'cert.pem': tiller_cert.cert_string,
'key.pem': tiller_cert.key_string
}
end
def create_keys_and_certs
ca_cert = Gitlab::Kubernetes::Helm::V2::Certificate.generate_root
self.ca_key = ca_cert.key_string
self.ca_cert = ca_cert.cert_string
end
def tiller_cert
@tiller_cert ||= ca_cert_obj.issue(expires_in: Gitlab::Kubernetes::Helm::V2::Certificate::INFINITE_EXPIRY)
end
def ca_cert_obj
return unless has_ssl?
Gitlab::Kubernetes::Helm::V2::Certificate
.from_strings(ca_key, ca_cert)
end
end
end
end

View File

@ -11,12 +11,8 @@ module Clusters
self.table_name = 'clusters'
APPLICATIONS = {
Clusters::Applications::Helm.application_name => Clusters::Applications::Helm
}.freeze
DEFAULT_ENVIRONMENT = '*'
KUBE_INGRESS_BASE_DOMAIN = 'KUBE_INGRESS_BASE_DOMAIN'
APPLICATIONS_ASSOCIATIONS = APPLICATIONS.values.map(&:association_name).freeze
self.reactive_cache_work_type = :external_dependency
@ -48,8 +44,6 @@ module Clusters
has_one application.association_name, class_name: application.to_s, inverse_of: :cluster # rubocop:disable Rails/ReflectionClassName
end
has_one_cluster_application :helm
has_many :kubernetes_namespaces
has_many :metrics_dashboard_annotations, class_name: 'Metrics::Dashboard::Annotation', inverse_of: :cluster
@ -108,7 +102,6 @@ module Clusters
scope :distinct_with_deployed_environments, -> { joins(:environments).merge(::Deployment.success).distinct }
scope :managed, -> { where(managed: true) }
scope :with_persisted_applications, -> { eager_load(*APPLICATIONS_ASSOCIATIONS) }
scope :default_environment, -> { where(environment_scope: DEFAULT_ENVIRONMENT) }
scope :with_management_project, -> { where.not(management_project: nil) }
@ -217,24 +210,6 @@ module Clusters
connection_data.merge(Gitlab::Kubernetes::Node.new(self).all)
end
def persisted_applications
APPLICATIONS_ASSOCIATIONS.filter_map { |association_name| public_send(association_name) } # rubocop:disable GitlabSecurity/PublicSend
end
def applications
APPLICATIONS.each_value.map do |application_class|
find_or_build_application(application_class)
end
end
def find_or_build_application(application_class)
raise ArgumentError, "#{application_class} is not in APPLICATIONS" unless APPLICATIONS.value?(application_class)
association_name = application_class.association_name
public_send(association_name) || public_send("build_#{association_name}") # rubocop:disable GitlabSecurity/PublicSend
end
def find_or_build_integration_prometheus
integration_prometheus || build_integration_prometheus
end
@ -255,10 +230,6 @@ module Clusters
!!platform_kubernetes&.rbac?
end
def application_helm_available?
!!application_helm&.available?
end
def integration_prometheus_available?
!!integration_prometheus&.available?
end

View File

@ -1,69 +0,0 @@
# frozen_string_literal: true
module Clusters
module Applications
class BaseHelmService
attr_accessor :app
def initialize(app)
@app = app
end
protected
def log_error(error)
meta = {
error_code: error.respond_to?(:error_code) ? error.error_code : nil,
service: self.class.name,
app_id: app.id,
app_name: app.name,
project_ids: app.cluster.project_ids,
group_ids: app.cluster.group_ids
}
Gitlab::ErrorTracking.track_exception(error, meta)
end
def log_event(event)
meta = {
service: self.class.name,
app_id: app.id,
app_name: app.name,
project_ids: app.cluster.project_ids,
group_ids: app.cluster.group_ids,
event: event
}
logger.info(meta)
end
def logger
@logger ||= Gitlab::Kubernetes::Logger.build
end
def cluster
app.cluster
end
def kubeclient
cluster.kubeclient
end
def helm_api
@helm_api ||= Gitlab::Kubernetes::Helm::API.new(kubeclient)
end
def install_command
@install_command ||= app.install_command
end
def update_command
@update_command ||= app.update_command
end
def patch_command(new_values = "")
app.patch_command(new_values)
end
end
end
end

View File

@ -1,5 +1,8 @@
#js-authenticate-token-2fa
%a.gl-button.btn.btn-block.btn-confirm#js-login-2fa-device{ href: '#' }= _("Sign in via 2FA code")
= render Pajamas::ButtonComponent.new(variant: :confirm,
block: true,
button_options: { id: 'js-login-2fa-device' }) do
= _("Sign in via 2FA code")
-# haml-lint:disable InlineJavaScript
%script#js-authenticate-token-2fa-in-progress{ type: "text/template" }
@ -9,7 +12,9 @@
%script#js-authenticate-token-2fa-error{ type: "text/template" }
%div
%p <%= error_message %> (<%= error_name %>)
%a.btn.btn-default.gl-button.btn-block#js-token-2fa-try-again= _("Try again?")
= render Pajamas::ButtonComponent.new(block: true,
button_options: { id: 'js-token-2fa-try-again', class: 'gl-mb-3' }) do
= _("Try again?")
-# haml-lint:disable InlineJavaScript
%script#js-authenticate-token-2fa-authenticated{ type: "text/template" }

View File

@ -0,0 +1 @@
-# if this file is missing empty or not the old left menu throws error

View File

@ -1,7 +1,7 @@
- add_to_breadcrumbs _("Infrastructure Registry"), project_infrastructure_registry_index_path(@project)
- add_to_breadcrumbs _("Terraform Module Registry"), project_infrastructure_registry_index_path(@project)
- add_to_breadcrumbs @package.name, project_infrastructure_registry_index_path(@project)
- breadcrumb_title @package.version
- page_title _("Infrastructure Registry")
- page_title _("Terraform Module Registry")
.row
.col-12

View File

@ -55,19 +55,12 @@ module ClusterCleanupMethods
cluster.make_cleanup_errored!("#{self.class.name} exceeded the execution limit")
end
def cluster_applications_and_status(cluster)
cluster.persisted_applications
.map { |application| "#{application.name}:#{application.status_name}" }
.join(",")
end
def log_exceeded_execution_limit_error(cluster)
logger.error({
exception: ExceededExecutionLimitError.name,
cluster_id: cluster.id,
class_name: self.class.name,
cleanup_status: cluster.cleanup_status_name,
applications: cluster_applications_and_status(cluster),
event: :failed_to_remove_cluster_and_resources,
message: "exceeded execution limit of #{execution_limit} tries"
})

View File

@ -1,5 +1,5 @@
---
name: explain_code
name: explain_code_snippet
introduced_by_url:
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/404631
milestone: '15.11'

View File

@ -1,8 +0,0 @@
---
name: service_desk_html_to_text_email_handler
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109811
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372301
milestone: '15.9'
type: development
group: group::respond
default_enabled: false

View File

@ -1,7 +1,5 @@
---
table_name: clusters_applications_helm
classes:
- Clusters::Applications::Helm
feature_categories:
- kubernetes_management
description: "(Deprecated) A GitLab managed Helm installation in a Kubernetes cluster"

View File

@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
If you have [configured LDAP to work with GitLab](index.md), GitLab can automatically synchronize
users and groups.
LDAP synchronization updates existing GitLab user and group information. It does not create new GitLab users through LDAP.
LDAP synchronization updates user and group information for existing GitLab users that have an LDAP identity assigned. It does not create new GitLab users through LDAP.
You can change when synchronization occurs.

View File

@ -47,8 +47,8 @@ verification methods:
| Blobs | Container registry _(object storage)_ | Geo with API/Managed/Docker API (*2*) | _SHA256 checksum_ |
| Blobs | Package registry _(file system)_ | Geo with API | SHA256 checksum |
| Blobs | Package registry _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
| Blobs | Infrastructure registry _(file system)_ | Geo with API | SHA256 checksum |
| Blobs | Infrastructure registry _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
| Blobs | Terraform Module Registry _(file system)_ | Geo with API | SHA256 checksum |
| Blobs | Terraform Module Registry _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
| Blobs | Versioned Terraform State _(file system)_ | Geo with API | SHA256 checksum |
| Blobs | Versioned Terraform State _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
| Blobs | External Merge Request Diffs _(file system)_ | Geo with API | SHA256 checksum |
@ -202,7 +202,7 @@ successfully, you must replicate their data using some other means.
|[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. |
|[CI Secure Files](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/ci/secure_file.rb) | [**Yes** (15.3)](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91430) | [**Yes** (15.3)](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91430) | [**Yes** (15.3)](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91430) | [No](object_storage.md#verification-of-files-in-object-storage) | Verification is behind the feature flag `geo_ci_secure_file_replication`, enabled by default in 15.3. |
|[Container Registry](../../packages/container_registry.md) | **Yes** (12.3)* | **Yes** (15.10) | **Yes** (12.3)* | **Yes** (15.10) | See [instructions](container_registry.md) to set up the Container Registry replication. |
|[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. |
|[Terraform Module Registry](../../../user/packages/terraform_module_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. |
|[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. |
|[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. |
|[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. |

View File

@ -959,7 +959,7 @@ This behavior affects only the following data types through GitLab 14.6:
| Package Registry | 13.10 |
| CI Pipeline Artifacts | 13.11 |
| Terraform State Versions | 13.12 |
| Infrastructure Registry | 14.0 |
| Infrastructure Registry (renamed to Terraform Module Registry in GitLab 15.11) | 14.0 |
| External MR diffs | 14.6 |
| LFS Objects | 14.6 |
| Pages Deployments | 14.6 |

View File

@ -4,16 +4,16 @@ group: Package Registry
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Terraform Registry API **(FREE)**
# Terraform Module Registry API **(FREE)**
This is the API documentation for [Terraform Modules](../../user/packages/terraform_module_registry/index.md).
This is the API documentation for the [Terraform Module Registry](../../user/packages/terraform_module_registry/index.md).
WARNING:
This API is used by the [Terraform CLI](https://www.terraform.io/)
and is generally not meant for manual consumption. Undocumented authentication methods might be removed in the future.
For instructions on how to upload and install Terraform modules from the GitLab
infrastructure registry, see the [Terraform modules registry documentation](../../user/packages/terraform_module_registry/index.md).
Terraform Module Registry, see the [Terraform Module Registry documentation](../../user/packages/terraform_module_registry/index.md).
## List available versions for a specific module
@ -35,7 +35,7 @@ curl --header "Authorization: Bearer <personal_access_token>" "https://gitlab.ex
Example response:
```shell
```json
{
"modules": [
{
@ -93,9 +93,9 @@ curl --header "Authorization: Bearer <personal_access_token>" "https://gitlab.ex
Example response:
```shell
```json
{
"name": "hellow-world/local",
"name": "hello-world/local",
"provider": "local",
"providers": [
"local"
@ -132,9 +132,9 @@ curl --header "Authorization: Bearer <personal_access_token>" "https://gitlab.ex
Example response:
```shell
```json
{
"name": "hellow-world/local",
"name": "hello-world/local",
"provider": "local",
"providers": [
"local"
@ -171,7 +171,7 @@ curl --header "Authorization: Bearer <personal_access_token>" "https://gitlab.ex
Example response:
```shell
```plaintext
HTTP/1.1 204 No Content
Content-Length: 0
X-Terraform-Get: /api/v4/packages/terraform/modules/v1/group/hello-world/local/1.0.0/file?token=&archive=tgz
@ -200,7 +200,7 @@ curl --header "Authorization: Bearer <personal_access_token>" "https://gitlab.ex
Example response:
```shell
```plaintext
HTTP/1.1 204 No Content
Content-Length: 0
X-Terraform-Get: /api/v4/packages/terraform/modules/v1/group/hello-world/local/1.0.0/file?token=&archive=tgz

View File

@ -240,87 +240,6 @@ We can't ship the entire Cells architecture in one go - it is too large. Instead
1. Migrate existing organizations from `cell` to `cell`
1. Add additional Cell capabilities (DR, Regions)
### Iteration 0: Introduce organizations
In the first iteration, we introduce the concept of an organization
as a way to group top-level namespaces together. Support for organizations **does not require any Cells work** but having them will make all subsequent iterations of Cells simpler. This is mainly because we can group top-level namespaces for a single organization onto a Cell. Within an organization all interactions work as normal but we eliminate any cross-organizational interactions except in well defined cases (e.g. forking).
This means that we don't have a large number of cross-cell interactions.
Introducing organizations allows GitLab to move towards a multi-tenant system that is similar to Discord's with a single user account but many different "servers" - our organizations - that allow users to switch context. This model harmonizes the UX across self-managed and our SaaS Platforms and is a good fit for Cells.
Organizations solve the following problems:
1. We can group top-level namespaces by organization. It is very similar to the initial concept of "instance groups". For example these two top-level namespaces would belong to the organization `GitLab`:
1. `https://gitlab.com/gitlab-org/`
1. `https://gitlab.com/gitlab-com/`
1. We can isolate organizations from each other. Top-level namespaces of the same organization can interact within organizations but are not allowed to interact with other namespaces in other organizations. This is useful for customers because it means an organization provides clear boundaries - similar to a self-managed instance. This means we don't have to aggregate user dashboards across everything and can locally scope them to organizations.
1. We don't need to define hierarchies inside an organization. It is a container that could be filled with whatever hierarchy / entity set makes sense (organization, top-level namespaces etc.)
1. Self-managed instances would set a default organization.
1. Organizations can control user-profiles in a central way. This could be achieved by having an organization specific user-profile. Such a profile makes it possible for the organization administrators to control the user role in a company, enforce user emails, or show a graphical indicator of a user being part of the organization. An example would be a "GitLab Employee stamp" on comments.
![Move to Organizations](images/iteration0-organizations-introduction.png)
#### Why would customers opt-in to Organizations?
By introducing organizations and Cells we can improve the reliability, performance and availability of our SaaS Platforms.
The first iteration of organizations would also have some benefits by providing more isolation. A simple example would be that `@` mentions could be scoped to an organization.
Future iterations would create additional value but are beyond the scope of this blueprint.
Organizations will likely be required in the future as well.
#### Initial user experience
1. We create a default `GitLab.com public` organization and assign all public top-level namespaces to it. This allows existing users to access all the data on GitLab.com, exactly as it does now.
1. Any user wanting to opt-in to the benefits of organizations will need to set a single default organization. Any attempts for these users to load a global page like `/dashboard` will end up redirecting to `/-/organizations/<DEFAULT_ORGANIZATION>/dashboard`.
1. New users that opted in to organizations will only ever see data that is related to a single organization. Upon login, data is shown for the default organization. It will be clear to the user how they can switch to a different organization. Users can still navigate to the `GitLab.com` organization but they won't see TODOs from their new organizations in any such views. Instead they'd need to navigate directly to `/organizations/my-company/-/dashboard`.
### Migrating to Organizations
Existing customers could also opt-in to migrate their existing top-level paid namespaces to become part of an organization. In most cases this will be a 1-to-1 mapping. But in some cases it may allow a customer to move multiple top-level namespaces into one organization (for example GitLab).
Migrating to Organizations would be optional. We could even recruit a few beta testers early on to see if this works for them. GitLab itself could dogfood organizations and we'd surface a lot of issues restricting interactions with other namespaces.
## Iteration 1 - Introduce Cell US 0
### GitLab.com as Cell US0
GitLab.com will be treated as the first cell `Cell US 0`. It will be unique and much larger compared to newly created cells. All existing top-level namespaces and organizations will remain on `Cell US 0` in the first iteration.
### Users are globally available
Users are globally available and the same for all cells. This means that user data needs to be handled separately, for example via decomposition, see [!95941](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95941).
### Cell groundwork
In this iteration, we'll lay all the groundwork to support a second Cell for new organizations. This will be transparent to customers.
## Iteration 2 - Introduce Cell US 1
### Add new organizations to Cell US 1
After we are ready to support a second Cell, newly created organizations are located by default on `Cell US 1`. The user experience for organizations is already well established.
### Migrate existing organizations from Cell US 0 to Cell US 1
We know that we'll have to move organizations from `Cell US 0` to other cells to reduce its size and ultimately retire the existing GitLab.com architecture.
By introducing organizations early, we should be able to draw strong "boundaries" across organizations and support migrating existing organizations to a new Cell.
This is likely going to be GitLab itself - if we can dogfood this, we are likely going to be successful with other organizations as well.
## Iteration 3 - Introduce Regions
We can now leverage the Cells architecture to introduce Regions.
## Iteration 4 - Introduce cross-organizational interactions as needed
Based on user research, we may want to change certain features to work across organizations. Examples include:
- Specific features allow for cross-organization interactions, for example forking, search.
## Technical Proposals
The Cells architecture do have long lasting implications to data processing, location, scalability and the GitLab architecture.

View File

@ -228,7 +228,8 @@ The version of the component can be (in order of highest priority first):
1. A commit SHA - For example: `gitlab.com/gitlab-org/dast@e3262fdd0914fa823210cdb79a8c421e2cef79d8`
1. A tag - For example: `gitlab.com/gitlab-org/dast@1.0`
1. A special moving target version that points to the most recent released tag - For example: `gitlab.com/gitlab-org/dast@~latest`
1. A special moving target version that points to the most recent released tag. The target project must be
explicitly marked as a [catalog resource](#catalog-resource) - For example: `gitlab.com/gitlab-org/dast@~latest`
1. A branch name - For example: `gitlab.com/gitlab-org/dast@master`
If a tag and branch exist with the same name, the tag takes precedence over the branch.

View File

@ -208,119 +208,7 @@ Jobs that exceed the timeout are marked as failed.
You can override this value [for individual runners](../runners/configure_runners.md#set-maximum-job-timeout-for-a-runner).
## Merge request test coverage results
If you use test coverage in your code, you can use a regular expression to
find coverage results in the job log. You can then include these results
in the merge request in GitLab.
If the pipeline succeeds, the coverage is shown in the merge request widget and
in the jobs table. If multiple jobs in the pipeline have coverage reports, they are
averaged.
![MR widget coverage](img/pipelines_test_coverage_mr_widget.png)
![Build status coverage](img/pipelines_test_coverage_build.png)
### Add test coverage results using `coverage` keyword
To add test coverage results to a merge request using the project's `.gitlab-ci.yml` file, provide a regular expression
using the [`coverage`](../yaml/index.md#coverage) keyword.
### Test coverage examples
Use this regex for commonly used test tools.
<!-- vale gitlab.Spelling = NO -->
- Simplecov (Ruby). Example: `/\(\d+.\d+\%\) covered/`.
- pytest-cov (Python). Example: `/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/`.
- Scoverage (Scala). Example: `/Statement coverage[A-Za-z\.*]\s*:\s*([^%]+)/`.
- `pest --coverage --colors=never` (PHP). Example: `/^\s*Cov:\s*\d+\.\d+?%$/`.
- `phpunit --coverage-text --colors=never` (PHP). Example: `/^\s*Lines:\s*\d+.\d+\%/`.
- gcovr (C/C++). Example: `/^TOTAL.*\s+(\d+\%)$/`.
- `tap --coverage-report=text-summary` (NodeJS). Example: `/^Statements\s*:\s*([^%]+)/`.
- `nyc npm test` (NodeJS). Example: `/All files[^|]*\|[^|]*\s+([\d\.]+)/`.
- `jest --ci --coverage` (NodeJS). Example: `/All files[^|]*\|[^|]*\s+([\d\.]+)/`.
- excoveralls (Elixir). Example: `/\[TOTAL\]\s+(\d+\.\d+)%/`.
- `mix test --cover` (Elixir). Example: `/\d+.\d+\%\s+\|\s+Total/`.
- JaCoCo (Java/Kotlin). Example: `/Total.*?([0-9]{1,3})%/`.
- `go test -cover` (Go). Example: `/coverage: \d+.\d+% of statements/`.
- .NET (OpenCover). Example: `/(Visited Points).*\((.*)\)/`.
- .NET (`dotnet test` line coverage). Example: `/Total\s*\|\s*(\d+(?:\.\d+)?)/`.
- tarpaulin (Rust). Example: `/^\d+.\d+% coverage/`.
- Pester (PowerShell). Example: `/Covered (\d+\.\d+%)/`.
<!-- vale gitlab.Spelling = YES -->
### View code coverage history
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/209121) the ability to download a `.csv` in GitLab 12.10.
> - Graph [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33743) in GitLab 13.1.
To see the evolution of your project code coverage over time,
you can view a graph or download a CSV file with this data.
1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Analytics > Repository**.
The historic data for each job is listed in the dropdown list above the graph.
To view a CSV file of the data, select **Download raw data (`.csv`)**.
![Code coverage graph of a project over time](img/code_coverage_graph_v13_1.png)
Code coverage data is also [available at the group level](../../user/group/repositories_analytics/index.md).
### Coverage check approval rule **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15765) in GitLab 14.0.
> - [Made configurable in Project Settings](https://gitlab.com/gitlab-org/gitlab/-/issues/331001) in GitLab 14.1.
You can implement merge request approvals to require approval by selected users or a group
when merging a merge request would cause the project's test coverage to decline.
Follow these steps to enable the `Coverage-Check` MR approval rule:
1. Set up a [`coverage`](../yaml/index.md#coverage) regular expression for all jobs you want to include in the overall coverage value.
1. Go to your project and select **Settings > Merge requests**.
1. Under **Merge request approvals**, select **Enable** next to the `Coverage-Check` approval rule.
1. Select the **Target branch**.
1. Set the number of **Approvals required** to greater than zero.
1. Select the users or groups to provide approval.
1. Select **Add approval rule**.
![Coverage-Check approval rule](img/coverage_check_approval_rule_14_1.png)
### Remove color codes from code coverage
Some test coverage tools output with ANSI color codes that aren't
parsed correctly by the regular expression. This causes coverage
parsing to fail.
Some coverage tools don't provide an option to disable color
codes in the output. If so, pipe the output of the coverage tool through a
small one line script that strips the color codes off.
For example:
```shell
lein cloverage | perl -pe 's/\e\[?.*?[\@-~]//g'
```
## Pipeline badges
You can use [pipeline badges](../../user/project/badges.md) to indicate the pipeline status and
test coverage of your projects. These badges are determined by the latest successful pipeline.
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
one might have when setting this up, or when something is changed, or on upgrading, it's
important to describe those, too. Think of things that may go wrong and include them here.
This is important to minimize requests for support, and to avoid doc comments with
questions that you know someone might ask.
Each scenario can be a third-level heading, for example `### Getting error message X`.
If you have none to add when creating a doc, leave this section in place
but commented out to help encourage others to add to it in the future. -->

View File

@ -0,0 +1,129 @@
---
stage: Verify
group: Pipeline Execution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Code coverage **(FREE)**
Use code coverage to provide insights on what source code is being validated by a test suite. Code coverage is one of many test metrics that can determine software performance and quality.
## View Code Coverage results
Code Coverage results are shown in:
- Merge request widget
- Project repository analytics
- Group repository analytics
- Repository badge
For more information on test coverage visualization in the file diff of the MR, see [Test Coverage Visualization](test_coverage_visualization.md).
### View code coverage results in the MR
If you use test coverage in your code, you can use a regular expression to
find coverage results in the job log. You can then include these results
in the merge request in GitLab.
If the pipeline succeeds, the coverage is shown in the merge request widget and
in the jobs table. If multiple jobs in the pipeline have coverage reports, they are
averaged.
![MR widget coverage](img/pipelines_test_coverage_mr_widget.png)
![Build status coverage](img/pipelines_test_coverage_build.png)
#### Add test coverage results using `coverage` keyword
To add test coverage results to a merge request using the project's `.gitlab-ci.yml` file, provide a regular expression
using the [`coverage`](../yaml/index.md#coverage) keyword.
#### Test coverage examples
Use this regex for commonly used test tools.
<!-- vale gitlab.Spelling = NO -->
- Simplecov (Ruby). Example: `/\(\d+.\d+\%\) covered/`.
- pytest-cov (Python). Example: `/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/`.
- Scoverage (Scala). Example: `/Statement coverage[A-Za-z\.*]\s*:\s*([^%]+)/`.
- `pest --coverage --colors=never` (PHP). Example: `/^\s*Cov:\s*\d+\.\d+?%$/`.
- `phpunit --coverage-text --colors=never` (PHP). Example: `/^\s*Lines:\s*\d+.\d+\%/`.
- gcovr (C/C++). Example: `/^TOTAL.*\s+(\d+\%)$/`.
- `tap --coverage-report=text-summary` (NodeJS). Example: `/^Statements\s*:\s*([^%]+)/`.
- `nyc npm test` (NodeJS). Example: `/All files[^|]*\|[^|]*\s+([\d\.]+)/`.
- `jest --ci --coverage` (NodeJS). Example: `/All files[^|]*\|[^|]*\s+([\d\.]+)/`.
- excoveralls (Elixir). Example: `/\[TOTAL\]\s+(\d+\.\d+)%/`.
- `mix test --cover` (Elixir). Example: `/\d+.\d+\%\s+\|\s+Total/`.
- JaCoCo (Java/Kotlin). Example: `/Total.*?([0-9]{1,3})%/`.
- `go test -cover` (Go). Example: `/coverage: \d+.\d+% of statements/`.
- .NET (OpenCover). Example: `/(Visited Points).*\((.*)\)/`.
- .NET (`dotnet test` line coverage). Example: `/Total\s*\|\s*(\d+(?:\.\d+)?)/`.
- tarpaulin (Rust). Example: `/^\d+.\d+% coverage/`.
- Pester (PowerShell). Example: `/Covered (\d+\.\d+%)/`.
<!-- vale gitlab.Spelling = YES -->
### View history of project code coverage
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/209121) the ability to download a `.csv` in GitLab 12.10.
> - Graph [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33743) in GitLab 13.1.
To see the evolution of your project code coverage over time,
you can view a graph or download a CSV file with this data.
1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Analytics > Repository**.
The historic data for each job is listed in the dropdown list above the graph.
To view a CSV file of the data, select **Download raw data (`.csv`)**.
![Code coverage graph of a project over time](img/code_coverage_graph_v13_1.png)
### View history of group code coverage **(PREMIUM)**
To see the all the project's code coverage under a group over time, you can find view [group repository analytics](../../user/group/repositories_analytics/index.md).
![Code coverage graph of a group over time](img/code_coverage_group_report.png)
### Pipeline badges
You can use [pipeline badges](../../user/project/badges.md#test-coverage-report-badges) to indicate the pipeline status and
test coverage of your projects. These badges are determined by the latest successful pipeline.
## Coverage check approval rule **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15765) in GitLab 14.0.
> - [Made configurable in Project Settings](https://gitlab.com/gitlab-org/gitlab/-/issues/331001) in GitLab 14.1.
When merging a request that would cause the project's test coverage to decline, you can stipulate that such merge requests require approval by selected users or a group.
Follow these steps to enable the `Coverage-Check` MR approval rule:
1. Set up a [`coverage`](../yaml/index.md#coverage) regular expression for all jobs you want to include in the overall coverage value.
1. Go to your project and select **Settings > Merge requests**.
1. Under **Merge request approvals**, select **Enable** next to the `Coverage-Check` approval rule.
1. Select the **Target branch**.
1. Set the number of **Approvals required** to greater than zero.
1. Select the users or groups to provide approval.
1. Select **Add approval rule**.
![Coverage-Check approval rule](img/coverage_check_approval_rule_14_1.png)
## Troubleshooting
### Remove color codes from code coverage
Some test coverage tools output with ANSI color codes that aren't
parsed correctly by the regular expression. This causes coverage
parsing to fail.
Some coverage tools do not provide an option to disable color
codes in the output. If so, pipe the output of the coverage tool through a one-line script that strips the color codes.
For example:
```shell
lein cloverage | perl -pe 's/\e\[?.*?[\@-~]//g'
```

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -14,6 +14,7 @@ display reports or link to important information directly from [merge requests](
| [Accessibility Testing](accessibility_testing.md) | Automatically report A11y violations for changed pages in merge requests. |
| [Browser Performance Testing](browser_performance_testing.md) | Quickly determine the browser performance impact of pending code changes. |
| [Load Performance Testing](load_performance_testing.md) | Quickly determine the server performance impact of pending code changes. |
| [Code Coverage](code_coverage.md) | See code coverage results in the MR, project or group. |
| [Code Quality](code_quality.md) | Analyze your source code quality using the [Code Climate](https://codeclimate.com/) analyzer and show the Code Climate report right in the merge request widget area. |
| [Display arbitrary job artifacts](../yaml/index.md#artifactsexpose_as) | Configure CI pipelines with the `artifacts:expose_as` parameter to directly link to selected [artifacts](../jobs/job_artifacts.md) in merge requests. |
| [Unit test reports](unit_test_reports.md) | Configure your CI jobs to use Unit test reports, and let GitLab display a report on the merge request so that it's easier and faster to identify the failure without having to check the entire job log. |

View File

@ -54,8 +54,8 @@ of times the line was checked by tests.
Uploading a test coverage report does not enable:
- [Test coverage results in merge requests](../pipelines/settings.md#merge-request-test-coverage-results).
- [Code coverage history](../pipelines/settings.md#view-code-coverage-history).
- [Test coverage results in merge requests](code_coverage.md#view-code-coverage-results-in-the-mr).
- [Code coverage history](code_coverage.md#view-history-of-project-code-coverage).
You must configure these separately.

View File

@ -1512,6 +1512,7 @@ In this example:
**Additional details**:
- You can find parse examples in [Code Coverage](../testing/code_coverage.md#test-coverage-examples).
- If there is more than one matched line in the job output, the last line is used
(the first result of reverse search).
- If there are multiple matches in a single line, the last match is searched

View File

@ -1329,6 +1329,13 @@ Use lowercase for **terminal**. For example:
- Open a terminal.
- From a terminal, run the `docker login` command.
## Terraform Module Registry
Use title case for the GitLab Terraform Module Registry, but use lowercase `m` when
talking about non-specific modules. For example:
- You can publish a Terraform module to your project's Terraform Module Registry.
## text box
Use **text box** instead of **field** or **box** when referring to the UI element.

View File

@ -11,7 +11,7 @@ across the GitLab frontend team.
## Overview
GitLab is built on top of [Ruby on Rails](https://rubyonrails.org). It uses [Haml](https://haml.info/) and a JavaScript-based frontend with [Vue.js](https://vuejs.org).
GitLab is built on top of [Ruby on Rails](https://rubyonrails.org). It uses [Haml](https://haml.info/) and a JavaScript-based frontend with [Vue.js](https://vuejs.org). If you are not sure when to use Vue on top of Haml-page, please read [this explanation](vue.md#when-to-add-vue-application).
<!-- vale gitlab.Spelling = NO -->

View File

@ -14,7 +14,7 @@ Existing registries:
- Package Registry
- Container Registry
- Infrastructure Registry
- Terraform Module Registry
- Dependency Proxy
## Frontend architecture

View File

@ -17,6 +17,14 @@ GitLab features use it, including:
- [Web Editor](../../user/project/repository/web_editor.md)
- [Security Policies](../../user/application_security/policies/index.md)
## When to use Source Editor
Use Source Editor only when users need to edit the file content.
If you only need to display source code, consider using the [`BlobContent`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/blob/components/blob_content.vue) component.
If the page you're working on is already loading the Source Editor,
displaying read-only content in the Source Editor is still a valid option.
## How to use Source Editor
Source Editor is framework-agnostic and can be used in any application, including both

View File

@ -16,11 +16,23 @@ What is described in the following sections can be found in these examples:
- [Security products](https://gitlab.com/gitlab-org/gitlab/-/tree/master/ee/app/assets/javascripts/vue_shared/security_reports)
- [Registry](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/assets/javascripts/registry/stores)
## When to add Vue application
Sometimes, HAML page is enough to satisfy requirements. This statement is correct primarily for the static pages or pages that have very little logic. How do we know it's worth adding a Vue application to the page? The answer is "when we need to maintain application state and synchronize the rendered page with it".
To better explain this, let's imagine the page that has one toggle, and toggling it sends an API request. This case does not involve any state we want to maintain, we send the request and switch the toggle. However, if we add ont more toggle that should always be the opposite to the first one, we need a _state_: one toggle should be "aware" about the state of another one. When written in plain JavaScript, this logic usually involves listening to DOM event and reacting with modifying DOM. Cases like this are much easier to handle with Vue.js so we should create a Vue application here.
### What are some flags signaling that you might need Vue application?
- when you need to define complex conditionals based on multiple factors and update them on user interaction;
- when you have to maintain any form of application state and share it between tags/elements;
- when you expect complex logic to be added in the future - it's easier to start with basic Vue application than having to rewrite JS/HAML to Vue on the next step.
## Vue architecture
All new features built with Vue.js must follow a [Flux architecture](https://facebookarchive.github.io/flux/).
The main goal we are trying to achieve is to have only one data flow, and only one data entry.
To achieve this goal we use [Vuex](#vuex).
To achieve this goal we use [Vuex](#vuex) or [Apollo Client](graphql.md#libraries)
You can also read about this architecture in Vue documentation about
[state management](https://v2.vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch)

View File

@ -176,6 +176,20 @@ graph LR
A --"artifact: list of test files"--> B & C
```
## Merge Trains
### Why do we need to have a “stable” master branch to enable merge trains?
If the master branch is unstable (i.e. CI/CD pipelines for the master branch are failing frequently), all of the merge requests pipelines that were added AFTER a faulty merge request pipeline would have to be **cancelled** and **added back to the train**, which would create a lot of delays if the merge train is long.
### How stable does the master branch have to be for us to enable merge trains?
We don't have a specific number, but we need to have better numbers for flaky tests failures and infrastructure failures (see the [Master Broken Incidents RCA Dashboard](https://app.periscopedata.com/app/gitlab/1082465/Master-Broken-Incidents-Root-Cause-Analysis)).
### Could we gradually move to merge trains in our CI/CD configuration?
There was a proposal from a contributor, but the approach is not without some downsides: [see the original proposal and discussion](https://gitlab.com/gitlab-org/quality/quality-engineering/team-tasks/-/issues/195#note_1117151994).
## Faster feedback for some merge requests
### Broken Master Fixes

View File

@ -1,19 +1,21 @@
---
stage: Deploy
group: Environments
info: A tutorial using Flux with Project Access Tokens
info: A tutorial using Flux
---
# Tutorial: Set up Flux for GitOps **(FREE)**
This tutorial teaches you how to set up Flux for GitOps. You'll set up a sample project,
complete a bootstrap Flux installation, and authenticate your installation with a
[project access token](../../../project/settings/project_access_tokens.md).
[project deploy token](../../../project/deploy_tokens/index.md).
You can find the fully configured tutorial project [in this GitLab repository](https://gitlab.com/gitlab-org/configure/examples/flux/flux-config). It works in conjunction with [this repository](https://gitlab.com/gitlab-org/configure/examples/flux/web-app-manifests/-/tree/main), which contains the example Kubernetes manifests.
You can find the fully configured tutorial project [in this GitLab repository](https://gitlab.com/gitlab-org/configure/examples/flux/flux-config).
It works in conjunction with [this repository](https://gitlab.com/gitlab-org/configure/examples/flux/web-app-manifests/-/tree/main), which contains the example Kubernetes manifests.
To set up Flux with a project access token:
To set up Flux for GitOps:
1. [Create a personal access token](#create-a-personal-access-token)
1. [Create the Flux repository](#create-the-flux-repository)
1. [Create the Kubernetes manifest repository](#create-the-kubernetes-manifest-repository)
1. [Configure Flux to sync your manifests](#configure-flux-to-sync-your-manifests)
@ -21,27 +23,31 @@ To set up Flux with a project access token:
Prerequisites:
- On GitLab SaaS, you must have the Premium or Ultimate tier to use a project access token.
On self-managed instances, you can have any tier.
- Not recommended. You can authenticate with a [personal or group access token](flux.md#bootstrap-installation) in all tiers.
- You must have a Kubernetes cluster running.
## Create a personal access token
To authenticate with the Flux CLI, you must create a personal access token
with the `api` scope:
1. In the upper-right corner, select your avatar.
1. Select **Edit profile**.
1. On the left sidebar, select **Access Tokens**.
1. Enter a name and optional expiry date for the token.
1. Select the `api` scope.
1. Select **Create personal access token**.
You can also use a [project](../../../project/settings/project_access_tokens.md) or [group access token](../../../group/settings/group_access_tokens.md) with the `api` scope.
## Create the Flux repository
To start, create a Git repository, install Flux, and authenticate Flux with your repo:
Create a Git repository, install Flux, and authenticate Flux with your repo:
1. Make sure your `kubectl` is configured to access your cluster.
1. [Install the Flux CLI](https://fluxcd.io/flux/installation/#install-the-flux-cli).
1. [Install the Flux CLI](https://fluxcd.io/flux/installation/#install-the-flux-cli). You must install Flux v2 or higher.
1. In GitLab, create a new empty project called `flux-config`.
1. In the `flux-config` project, create a [project access token](../../../project/settings/project_access_tokens.md#create-a-project-access-token) with the following settings:
- From the **Select a role** dropdown list, select **Maintainer**.
- Under **Select scopes**, select the **API** and **write_repository** checkboxes.
Name the project token `flux-project-access-token`.
1. From your shell, export a `GITLAB_TOKEN` environment variable with the value of your project access token.
For example, `export GITLAB_TOKEN=<flux-project-access-token>`.
1. From your shell, export a `GITLAB_TOKEN` environment variable with the value of your personal access token.
For example, `export GITLAB_TOKEN=<personal-access-token>`.
1. Run the `bootstrap` command. The exact command depends on whether you are
creating the Flux repository under a GitLab user, group, or subgroup. For more information,
see the [Flux bootstrap documentation](https://fluxcd.io/flux/installation/#gitlab-and-gitlab-enterprise).
@ -54,11 +60,13 @@ To start, create a Git repository, install Flux, and authenticate Flux with your
--repository=flux-config \
--branch=main \
--path=clusters/my-cluster
--deploy-token-auth
```
This command installs Flux on the Kubernetes cluster and configures it to manage itself from the repository `flux-config`.
The command also automatically creates the project deploy token required to access the `flux-config` repository.
Great work! You now have a repository, a project access token, and a Flux bootstrap installation authenticated to your repo. Any updates to your repo are automatically synced to the cluster.
Great work! You now have a repository bootstrapped with a Flux configuration. Any updates to your repository are automatically synced to the cluster.
## Create the Kubernetes manifest repository
@ -93,7 +101,7 @@ Next, create a repository for your Kubernetes manifests:
- containerPort: 80
```
1. In the new repository, [create a deploy token](../../../project/deploy_tokens/index.md#create-a-deploy-token) with only the **read_repository** scope.
1. In the new repository, [create a deploy token](../../../project/deploy_tokens/index.md#create-a-deploy-token) with only the `read_repository` scope.
1. Store your deploy token username and password somewhere safe.
1. In Flux CLI, create a secret with your deploy token and point the secret to the new repository. For example:

View File

@ -85,10 +85,10 @@ The following are unavailable compliance violations that are tracked in [epic 52
|:-------------------------------------|:---------------|:---------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------|
| Pipeline failed | Medium | [Pipeline results](../../../ci/pipelines/index.md) | Merge requests pipeline failed and was merged. |
| Pipeline passed with warnings | Info | [Pipeline results](../../../ci/pipelines/index.md) | Merge request pipeline passed with warnings and was merged. |
| Code coverage down more than 10% | High | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | Code coverage report for the merge request indicates a reduction in coverage of more than 10%. |
| Code coverage down between 5% to 10% | Medium | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | Code coverage report for the merge request indicates a reduction in coverage of between 5% to 10%. |
| Code coverage down between 1% to 5% | Low | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | Code coverage report for the merge request indicates a reduction in coverage of between 1% to 5%. |
| Code coverage down less than 1% | Info | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | Code coverage report for the merge request indicates a reduction in coverage of less than 1%. |
| Code coverage down more than 10% | High | [Code coverage](../../../ci/testing/code_coverage.md#view-code-coverage-results-in-the-mr) | Code coverage report for the merge request indicates a reduction in coverage of more than 10%. |
| Code coverage down between 5% to 10% | Medium | [Code coverage](../../../ci/testing/code_coverage.md#view-code-coverage-results-in-the-mr) | Code coverage report for the merge request indicates a reduction in coverage of between 5% to 10%. |
| Code coverage down between 1% to 5% | Low | [Code coverage](../../../ci/testing/code_coverage.md#view-code-coverage-results-in-the-mr) | Code coverage report for the merge request indicates a reduction in coverage of between 1% to 5%. |
| Code coverage down less than 1% | Info | [Code coverage](../../../ci/testing/code_coverage.md#view-code-coverage-results-in-the-mr) | Code coverage report for the merge request indicates a reduction in coverage of less than 1%. |
<!-- vale gitlab.SubstitutionWarning = YES -->

View File

@ -42,7 +42,7 @@ To see the latest code coverage for each project in your group:
1. In the **Latest test coverage results** section, from the **Select projects** dropdown list, choose the projects you want to check.
You can download code coverage data for specific projects using
[code coverage history](../../../ci/pipelines/settings.md#view-code-coverage-history).
[code coverage history](../../../ci/testing/code_coverage.md#view-history-of-project-code-coverage).
## Download historic test coverage data

View File

@ -100,7 +100,7 @@ For GitLab-curated template recipes, see [Terraform template recipes](terraform_
## Related topics
- View [the images that contain the `gitlab-terraform` shell script](https://gitlab.com/gitlab-org/terraform-images).
- Use GitLab as a [Terraform module registry](../../packages/terraform_module_registry/index.md).
- Use GitLab as a [Terraform Module Registry](../../packages/terraform_module_registry/index.md).
- To store state files in local storage or in a remote store, use the [GitLab-managed Terraform state](terraform_state.md).
- To collaborate on Terraform code changes and Infrastructure-as-Code workflows, use the
[Terraform integration in merge requests](mr_integration.md).

View File

@ -14,15 +14,9 @@ packages, which can be easily consumed as a dependency in downstream projects.
The GitLab [Container Registry](container_registry/index.md) is a secure and private registry for container images. It's built on open source software and completely integrated within GitLab. Use GitLab CI/CD to create and publish images. Use the GitLab [API](../../api/container_registry.md) to manage the registry across groups and projects.
## Infrastructure Registry
## Terraform Module Registry
The GitLab [Infrastructure Registry](infrastructure_registry/index.md) is a secure and private registry for infrastructure packages. You can use GitLab CI/CD to create and publish infrastructure packages.
The Infrastructure Registry supports the following formats:
| Package type | GitLab version |
| ------------ | -------------- |
| [Terraform Module](terraform_module_registry/index.md) | 14.0+ |
The GitLab [Terraform Module Registry](terraform_module_registry/index.md) is a secure and private registry for Terraform modules. You can use GitLab CI/CD to create and publish modules.
## Dependency Proxy

View File

@ -1,102 +1,11 @@
---
stage: Package
group: Package Registry
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
redirect_to: '../terraform_module_registry/index.md'
remove_date: '2023-06-13'
---
# Infrastructure Registry **(FREE)**
This document was moved to [another location](../terraform_module_registry/index.md).
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3221) in GitLab 14.0.
With the GitLab Infrastructure Registry, you can use GitLab projects as a
private registry for infrastructure packages. You can create and publish
packages with GitLab CI/CD, which can then be consumed from other private
projects.
## View packages
To view packages within your project:
1. Go to the project.
1. Go to **Packages and registries > Infrastructure Registry**.
You can search, sort, and filter packages on this page.
For information on how to create and upload a package, view the GitLab
documentation for your package type:
- [Terraform modules](../terraform_module_registry/index.md)
## Use GitLab CI/CD to build packages
To use [GitLab CI/CD](../../../ci/index.md) to build packages, you can
authenticate with the [`CI_JOB_TOKEN` predefined variable](../../../ci/variables/predefined_variables.md).
CI/CD templates, which you can use to get started, are in [this repository](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates).
For more information about using CI/CD to build Terraform modules,
see [Publish a Terraform module by using CI/CD](../terraform_module_registry/index.md#publish-a-terraform-module-by-using-cicd).
If you use CI/CD to build a package, you can find extended activity information
when you view the package details:
![Package CI/CD activity](../package_registry/img/package_activity_v12_10.png)
You can see the pipeline that published the package as well as the commit and the user who triggered it. However, the history is limited to five updates per package.
## Download a package
To download a package:
1. Go to **Packages and registries > Infrastructure Registry**.
1. Select the name of the package you want to download.
1. In the **Activity** section, select the name of the package you want to download.
## Delete a package
You cannot edit a package after you publish it in the Infrastructure Registry. Instead, you
must delete and recreate it.
To delete a package, you must have suitable [permissions](../../permissions.md).
You can delete packages by using [the API](../../../api/packages.md#delete-a-project-package) or the UI.
To delete a package in the UI, from your project:
1. Go to **Packages and registries > Infrastructure Registry**.
1. Find the name of the package you want to delete.
1. Select **Delete**.
The package is permanently deleted.
## Disable the Infrastructure Registry
The Infrastructure Registry is automatically enabled.
For self-managed instances, a GitLab administrator can
[disable](../../../administration/packages/index.md) **Packages and registries**,
which removes this menu item from the sidebar.
You can also remove the Infrastructure Registry for a specific project:
1. In your project, go to **Settings > General**.
1. Expand the **Visibility, project features, permissions** section and toggle **Packages** off (in gray).
1. Select **Save changes**.
To enable it back, follow the same steps above and toggle it on (in blue).
## How module resolution works
When you upload a new module, GitLab generates a path for the module, for example, `https://gitlab.example.com/parent-group/my-infra-package`.
- This path conforms with [the Terraform spec](https://www.terraform.io/internals/module-registry-protocol).
- The name of the path must be unique within the namespace.
For projects in subgroups, GitLab checks that the module name does not already exist anywhere in the namespace, including all subgroups and the parent group.
For example, if:
- The project is `gitlab.example.com/parent-group/sub-group/my-project`.
- The infrastructure package is `my-infra-package`.
The project name must be unique in all projects in all groups under `parent-group`.
<!-- This redirect file can be deleted after <2023-06-13>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -4,32 +4,53 @@ group: Package Registry
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Terraform module registry **(FREE)**
# Terraform Module Registry **(FREE)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3221) in GitLab 14.0.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3221) in GitLab 14.0.
> - Infrastructure registry and Terraform Module Registry [merged](https://gitlab.com/gitlab-org/gitlab/-/issues/404075) into a single Terraform Module Registry feature in GitLab 15.11.
Publish Terraform modules in your project's Infrastructure Registry, then reference them using GitLab
as a Terraform module registry.
With the Terraform Module Registry, you can use GitLab projects as a
private registry for terraform modules. You can create and publish
modules with GitLab CI/CD, which can then be consumed from other private
projects.
## Authenticate to the Terraform module registry
## View Terraform modules
To authenticate to the Terraform module registry, you need either:
To view Terraform modules in your project:
1. Go to the project.
1. On the left sidebar, select **Packages and registries > Terraform modules**.
You can search, sort, and filter modules on this page.
For information on how to create and upload a package, view the GitLab
documentation for your package type:
- [Terraform modules](../terraform_module_registry/index.md)
## Authenticate to the Terraform Module Registry
To authenticate to the Terraform Module Registry, you need either:
- A [personal access token](../../../api/rest/index.md#personalprojectgroup-access-tokens) with at least `read_api` rights.
- A [CI/CD job token](../../../ci/jobs/ci_job_token.md).
Do not use authentication methods other than the methods documented here. Undocumented authentication methods might be removed in the future.
## Publish a Terraform Module
## Publish a Terraform module
When you publish a Terraform Module, if it does not exist, it is created.
When you publish a Terraform module, if it does not exist, it is created.
### Using the API
You can publish Terraform modules by using the [Terraform Module Registry API](../../../api/packages/terraform-modules.md).
Prerequisites:
- The package name and version [must be unique in the top-level namespace](../infrastructure_registry/index.md#how-module-resolution-works).
- The package name and version [must be unique in the top-level namespace](#how-module-resolution-works).
- Your project and group names must not include a dot (`.`). For example, `source = "gitlab.example.com/my.group/project.name"`.
- You must [authenticate with the API](../../../api/rest/index.md#authentication). If authenticating with a deploy token, it must be configured with the `write_package_registry` scope.
- The name of a module [must be unique within the scope of its group](../infrastructure_registry/index.md#how-module-resolution-works), otherwise an
- The name of a module [must be unique in the scope of its group](#how-module-resolution-works), otherwise an
[error occurs](#troubleshooting).
```plaintext
@ -39,9 +60,9 @@ PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module
| Attribute | Type | Required | Description |
| -------------------| --------------- | ---------| -------------------------------------------------------------------------------------------------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../../../api/rest/index.md#namespaced-path-encoding). |
| `module-name` | string | yes | The package name. **Supported syntax**: One to 64 ASCII characters, including lowercase letters (a-z) and digits (0-9). The package name can't exceed 64 characters.
| `module-system` | string | yes | The package system. **Supported syntax**: One to 64 ASCII characters, including lowercase letters (a-z) and digits (0-9). The package system can't exceed 64 characters. More information can be found in the [Terraform Module Registry Protocol documentation](https://www.terraform.io/internals/module-registry-protocol).
| `module-version` | string | yes | The package version. It must be valid according to the [Semantic Versioning Specification](https://semver.org/).
| `module-name` | string | yes | The module name. **Supported syntax**: One to 64 ASCII characters, including lowercase letters (a-z) and digits (0-9). The module name can't exceed 64 characters.
| `module-system` | string | yes | The module system. **Supported syntax**: One to 64 ASCII characters, including lowercase letters (a-z) and digits (0-9). The module system can't exceed 64 characters. More information can be found in the [Terraform Module Registry protocol documentation](https://www.terraform.io/internals/module-registry-protocol).
| `module-version` | string | yes | The module version. It must be valid according to the [semantic versioning specification](https://semver.org/).
Provide the file content in the request body.
@ -57,14 +78,6 @@ curl --fail-with-body --header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/my-module/my-system/0.0.1/file"
```
Example response:
```json
{
"message":"201 Created"
}
```
Example request using a deploy token:
```shell
@ -81,41 +94,13 @@ Example response:
}
```
## Reference a Terraform Module
### Using a CI/CD template (recommended)
Prerequisites:
- You need to [authenticate with the API](../../../api/rest/index.md#authentication). If authenticating with a personal access token, it must be configured with the `read_api` scope.
Authentication tokens (Job Token or Personal Access Token) can be provided for `terraform` in your `~/.terraformrc` file:
```plaintext
credentials "gitlab.com" {
token = "<TOKEN>"
}
```
Where `gitlab.com` can be replaced with the hostname of your self-managed GitLab instance.
You can then refer to your Terraform Module from a downstream Terraform project:
```plaintext
module "<module>" {
source = "gitlab.com/<namespace>/<module-name>/<module-system>"
}
```
Where `<namespace>` is the [namespace](../../../user/namespace/index.md) of the Terraform module registry.
## Publish a Terraform module by using CI/CD
> CI/CD template [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110493) in GitLab 15.9.
### Use a CI/CD template (recommended)
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110493) in GitLab 15.9.
You can use the [`Terraform-Module.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform-Module.gitlab-ci.yml)
or the advanced [`Terraform/Module-Base.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform/Module-Base.gitlab-ci.yml)
CI/CD template to publish a Terraform module to the GitLab Terraform Registry:
CI/CD template to publish a Terraform module to the GitLab terraform registry:
```yaml
include:
@ -126,7 +111,7 @@ The pipeline contains the following jobs:
- `fmt` - Validate the formatting of the Terraform module.
- `kics-iac-sast` - Test the Terraform module for security issues.
- `deploy` - For tag pipelines only. Deploy the Terraform module to the GitLab Terraform Registry.
- `deploy` - For tag pipelines only. Deploy the Terraform module to the Terraform Module Registry.
#### Pipeline variables
@ -139,7 +124,7 @@ You can configure the pipeline with the following variables:
| `TERRAFORM_MODULE_SYSTEM` | `local` | The system or provider of your Terraform module targets. For example, `local`, `aws`, `google`. |
| `TERRAFORM_MODULE_VERSION` | `${CI_COMMIT_TAG}` | The Terraform module version. You should follow the semantic versioning specification. |
### Deploy manually via CI/CD
### Using CI/CD manually
To work with Terraform modules in [GitLab CI/CD](../../../ci/index.md), you can use
`CI_JOB_TOKEN` in place of the personal access token in your commands.
@ -168,14 +153,97 @@ upload:
- if: $CI_COMMIT_TAG
```
To trigger this upload job, add a Git tag to your commit. Ensure the tag follows the [Semantic Versioning Specification](https://semver.org/) that Terraform requires. The `rules:if: $CI_COMMIT_TAG` ensures that only tagged commits to your repository trigger the module upload job.
To trigger this upload job, add a Git tag to your commit. Ensure the tag follows the [Semantic versioning specification](https://semver.org/) that Terraform requires. The `rules:if: $CI_COMMIT_TAG` ensures that only tagged commits to your repository trigger the module upload job.
For other ways to control jobs in your CI/CD pipeline, refer to the [`.gitlab-ci.yml`](../../../ci/yaml/index.md) keyword reference.
## Reference a Terraform module
Prerequisites:
- You need to [authenticate with the API](../../../api/rest/index.md#authentication). If authenticating with a personal access token, it must be configured with the `read_api` scope.
Authentication tokens (Job Token or Personal Access Token) can be provided for `terraform` in your `~/.terraformrc` file:
```terraform
credentials "gitlab.com" {
token = "<TOKEN>"
}
```
Where `gitlab.com` can be replaced with the hostname of your self-managed GitLab instance.
You can then refer to your Terraform module from a downstream Terraform project:
```terraform
module "<module>" {
source = "gitlab.com/<namespace>/<module-name>/<module-system>"
}
```
Where `<namespace>` is the [namespace](../../../user/namespace/index.md) of the Terraform Module Registry.
## Download a Terraform module
To download a Terraform module:
1. On the left sidebar, select **Packages and registries > Terraform modules**.
1. Select the name of the module you want to download.
1. In the **Activity** section, select the name of the module you want to download.
## How module resolution works
When you upload a new module, GitLab generates a path for the module, for example, `https://gitlab.example.com/parent-group/my-infra-package`.
- This path conforms with [the Terraform spec](https://www.terraform.io/internals/module-registry-protocol).
- The name of the path must be unique in the namespace.
For projects in subgroups, GitLab checks that the module name does not already exist anywhere in the namespace, including all subgroups and the parent group.
For example, if:
- The project is `gitlab.example.com/parent-group/sub-group/my-project`.
- The Terraform module is `my-infra-package`.
The project name must be unique in all projects in all groups under `parent-group`.
## Delete a Terraform module
You cannot edit a Terraform module after you publish it in the Terraform Module Registry. Instead, you
must delete and recreate it.
To delete a module, you must have suitable [permissions](../../permissions.md).
You can delete modules by using [the packages API](../../../api/packages.md#delete-a-project-package) or the UI.
To delete a module in the UI, from your project:
1. On the left sidebar, select **Packages and registries > Terraform modules**.
1. Find the name of the package you want to delete.
1. Select **Delete**.
The package is permanently deleted.
## Disable the Terraform Module Registry
The Terraform Module Registry is automatically enabled.
For self-managed instances, a GitLab administrator can
[disable](../../../administration/packages/index.md) **Packages and registries**,
which removes this menu item from the sidebar.
You can also remove the Terraform Module Registry for a specific project:
1. In your project, go to **Settings > General**.
1. Expand the **Visibility, project features, permissions** section and toggle **Packages** off (in gray).
1. Select **Save changes**.
To enable it back, follow the same steps above and toggle it on (in blue).
## Example projects
For examples of the Terraform module registry, check the projects below:
For examples of the Terraform Module Registry, check the projects below:
- The [_GitLab local file_ project](https://gitlab.com/mattkasa/gitlab-local-file) creates a minimal Terraform module and uploads it into the Terraform module registry using GitLab CI/CD.
- The [_GitLab local file_ project](https://gitlab.com/mattkasa/gitlab-local-file) creates a minimal Terraform module and uploads it into the Terraform Module Registry using GitLab CI/CD.
- The [_Terraform module test_ project](https://gitlab.com/mattkasa/terraform-module-test) uses the module from the previous example.
## Troubleshooting

View File

@ -62,7 +62,7 @@ You can access a test coverage report badge image by using the following link:
https://gitlab.example.com/<namespace>/<project>/badges/<branch>/coverage.svg
```
You can define the regular expression for the [coverage report](../../ci/pipelines/settings.md#merge-request-test-coverage-results)
You can define the regular expression for the [coverage report](../../ci/testing/code_coverage.md#view-code-coverage-results-in-the-mr)
that each job log is matched against.
This means that each job in the pipeline can have the test coverage percentage value defined.

View File

@ -101,7 +101,7 @@ Without the approvals, the work cannot merge. Required approvals enable multiple
database, for all proposed code changes.
- Use the [code owners of changed files](rules.md#code-owners-as-eligible-approvers),
to determine who should review the work.
- Require an [approval before merging code that causes test coverage to decline](../../../../ci/pipelines/settings.md#coverage-check-approval-rule)
- Require an [approval before merging code that causes test coverage to decline](../../../../ci/testing/code_coverage.md#coverage-check-approval-rule)
- Users on GitLab Ultimate can also [require approval from a security team](../../../application_security/index.md#security-approvals-in-merge-requests)
before merging code that could introduce a vulnerability.

View File

@ -244,6 +244,28 @@ approval rule for certain branches:
1. To enable this configuration, read
[Code Owner's approvals for protected branches](../../protected_branches.md#require-code-owner-approval-on-a-protected-branch).
## Code coverage check approval
You can require specific approvals in the case that a merge request would reduce code test
coverage.
For more information, see [Coverage check approval rule](../../../../ci/testing/code_coverage.md#coverage-check-approval-rule).
## Security Approvals **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/357021) in GitLab 15.0.
You can use [scan result policies](../../../application_security/policies/scan-result-policies.md#scan-result-policy-editor) to define security approvals based on the status of vulnerabilities in the merge request and the default branch.
Details for each security policy is shown in the Security Approvals section of your Merge Request configuration.
The security approval rules are applied to all merge requests until the pipeline is complete. The application of the
security approval rules prevents users from merging in code before the security scans run. After the pipeline is
complete, the security approval rules are checked to determine if the security approvals are still required.
![Security Approvals](img/security_approvals_v15_0.png)
These policies are both created and edited in the [security policy editor](../../../application_security/policies/index.md#policy-editor).
## Troubleshooting
### Approval rule name can't be blank
@ -265,18 +287,3 @@ isn't recognized as a valid Code Owner for the project, nor does it display in t
project's **Approvals** list. To fix this problem, add the approval group as a shared group
high enough in the shared hierarchy so the project requiring review inherits this
group of users.
## Security Approvals **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/357021) in GitLab 15.0.
You can use [scan result policies](../../../application_security/policies/scan-result-policies.md#scan-result-policy-editor) to define security approvals based on the status of vulnerabilities in the merge request and the default branch.
Details for each security policy is shown in the Security Approvals section of your Merge Request configuration.
The security approval rules are applied to all merge requests until the pipeline is complete. The application of the
security approval rules prevents users from merging in code before the security scans run. Once the pipeline is
complete, the security approval rules are checked to determine if the security approvals are still required.
![Security Approvals](img/security_approvals_v15_0.png)
These policies are both created and edited in the [security policy editor](../../../application_security/policies/index.md#policy-editor).

View File

@ -153,13 +153,6 @@ To do this:
select **Remove approvals by Code Owners if their files changed**.
1. Select **Save changes**.
## Code coverage check approvals
You can require specific approvals if a merge request would result in a decline in code test
coverage.
For more information, see [Coverage check approval rule](../../../../ci/pipelines/settings.md#coverage-check-approval-rule).
## Settings cascading
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285410) in GitLab 14.4. [Deployed behind the `group_merge_request_approval_settings_feature_flag` flag](../../../../administration/feature_flags.md), disabled by default.

View File

@ -499,15 +499,10 @@ In GitLab 15.9 and earlier, uploads to a comment are sent as links in the email.
#### Special HTML formatting in HTML emails
<!-- When the feature flag is removed, delete this topic and add as a line in version history under one of the topics above this one.-->
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109811) in GitLab 15.9 [with a flag](../../administration/feature_flags.md) named `service_desk_html_to_text_email_handler`. Disabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116809) in GitLab 15.11. Feature flag `service_desk_html_to_text_email_handler` removed.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/372301) in GitLab 15.9 [with a flag](../../administration/feature_flags.md) named `service_desk_html_to_text_email_handler`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available per project or for your entire instance, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `service_desk_html_to_text_email_handler`.
On GitLab.com, this feature is not available.
When this feature is enabled, HTML emails correctly show additional HTML formatting, such as:
HTML emails show special HTML formatting such as:
- Tables
- Blockquotes

View File

@ -16,31 +16,30 @@ module Banzai
# by converting it into the ```math syntax. In this way, we can ensure
# that it's considered a code block and will not have any markdown processed inside it.
# Corresponds to the "$$\n...\n$$" syntax
REGEX = %r{
#{::Gitlab::Regex.markdown_code_or_html_blocks}
|
(?=(?<=^\n|\A)\$\$\ *\n.*\n\$\$\ *(?=\n$|\z))(?:
# Display math block:
# $$
# latex math
# $$
(?<=^\n|\A)\$\$\ *\n
(?<display_math>
(?:.)+?
)
\n\$\$\ *(?=\n$|\z)
)
}mx.freeze
# Display math block:
# $$
# latex math
# $$
REGEX =
"#{::Gitlab::Regex.markdown_code_or_html_blocks_or_html_comments_untrusted}" \
'|' \
'^\$\$\ *\n' \
'(?P<display_math>' \
'(?:\n|.)*?' \
')' \
'\n\$\$\ *$' \
.freeze
def call
@text.gsub(REGEX) do
if $~[:display_math]
# change from $$ to ```math
"```math\n#{$~[:display_math]}\n```"
regex = Gitlab::UntrustedRegexp.new(REGEX, multiline: true)
return @text unless regex.match?(@text)
regex.replace_gsub(@text) do |match|
# change from $$ to ```math
if match[:display_math]
"```math\n#{match[:display_math]}\n```"
else
$~[0]
match.to_s
end
end
end

View File

@ -11,7 +11,9 @@ module Gitlab
#
# Once we are done with the PK conversions we can remove this.
def com_or_dev_or_test_but_not_jh?
!Gitlab.jh? && (Gitlab.com? || Gitlab.dev_or_test_env?)
return true if Gitlab.dev_or_test_env?
Gitlab.com? && !Gitlab.jh?
end
end
end

View File

@ -34,11 +34,7 @@ module Gitlab
end
def filtered_text
@filtered_text ||= if Feature.enabled?(:service_desk_html_to_text_email_handler)
::Gitlab::Email::HtmlToMarkdownParser.convert(filtered_html)
else
Html2Text.convert(filtered_html)
end
@filtered_text ||= ::Gitlab::Email::HtmlToMarkdownParser.convert(filtered_html)
end
end
end

View File

@ -5,15 +5,14 @@ module Gitlab
class BaseBuilder
attr_accessor :object
MARKDOWN_SIMPLE_IMAGE = %r{
#{::Gitlab::Regex.markdown_code_or_html_blocks}
|
(?<image>
!
\[(?<title>[^\n]*?)\]
\((?<url>(?!(https?://|//))[^\n]+?)\)
)
}mx.freeze
MARKDOWN_SIMPLE_IMAGE =
"#{::Gitlab::Regex.markdown_code_or_html_blocks_untrusted}" \
'|' \
'(?P<image>' \
'!' \
'\[(?P<title>[^\n]*?)\]' \
'\((?P<url>(?P<https>(https?://|//)?)[^\n]+?)\)' \
')'.freeze
def initialize(object)
@object = object
@ -37,15 +36,18 @@ module Gitlab
def absolute_image_urls(markdown_text)
return markdown_text unless markdown_text.present?
markdown_text.gsub(MARKDOWN_SIMPLE_IMAGE) do
if $~[:image]
url = $~[:url]
regex = Gitlab::UntrustedRegexp.new(MARKDOWN_SIMPLE_IMAGE, multiline: false)
return markdown_text unless regex.match?(markdown_text)
regex.replace_gsub(markdown_text) do |match|
if match[:image] && !match[:https]
url = match[:url]
url = "#{uploads_prefix}#{url}" if url.start_with?('/uploads')
url = "/#{url}" unless url.start_with?('/')
"![#{$~[:title]}](#{Gitlab.config.gitlab.url}#{url})"
"![#{match[:title]}](#{Gitlab.config.gitlab.url}#{url})"
else
$~[0]
match.to_s
end
end
end

View File

@ -1,126 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
class API
def initialize(kubeclient)
@kubeclient = kubeclient
@namespace = Gitlab::Kubernetes::Namespace.new(
Gitlab::Kubernetes::Helm::NAMESPACE,
kubeclient,
labels: Gitlab::Kubernetes::Helm::NAMESPACE_LABELS
)
end
def install(command)
namespace.ensure_exists!
create_service_account(command)
create_cluster_role_binding(command)
create_config_map(command)
delete_pod!(command.pod_name)
kubeclient.create_pod(command.pod_resource)
end
alias_method :update, :install
def uninstall(command)
namespace.ensure_exists!
create_config_map(command)
delete_pod!(command.pod_name)
kubeclient.create_pod(command.pod_resource)
end
##
# Returns Pod phase
#
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
#
# values: "Pending", "Running", "Succeeded", "Failed", "Unknown"
#
def status(pod_name)
kubeclient.get_pod(pod_name, namespace.name).status.phase
end
def log(pod_name)
kubeclient.get_pod_log(pod_name, namespace.name).body
end
def delete_pod!(pod_name)
kubeclient.delete_pod(pod_name, namespace.name)
rescue ::Kubeclient::ResourceNotFoundError
# no-op
end
def get_config_map(config_map_name)
namespace.ensure_exists!
kubeclient.get_config_map(config_map_name, namespace.name)
end
private
attr_reader :kubeclient, :namespace
def create_config_map(command)
command.config_map_resource.tap do |config_map_resource|
break unless config_map_resource
if config_map_exists?(config_map_resource)
kubeclient.update_config_map(config_map_resource)
else
kubeclient.create_config_map(config_map_resource)
end
end
end
def update_config_map(command)
command.config_map_resource.tap do |config_map_resource|
kubeclient.update_config_map(config_map_resource)
end
end
def create_service_account(command)
command.service_account_resource.tap do |service_account_resource|
break unless service_account_resource
if service_account_exists?(service_account_resource)
kubeclient.update_service_account(service_account_resource)
else
kubeclient.create_service_account(service_account_resource)
end
end
end
def create_cluster_role_binding(command)
command.cluster_role_binding_resource.tap do |cluster_role_binding_resource|
break unless cluster_role_binding_resource
kubeclient.update_cluster_role_binding(cluster_role_binding_resource)
end
end
def config_map_exists?(resource)
kubeclient.get_config_map(resource.metadata.name, resource.metadata.namespace)
rescue ::Kubeclient::ResourceNotFoundError
false
end
def service_account_exists?(resource)
kubeclient.get_service_account(resource.metadata.name, resource.metadata.namespace)
rescue ::Kubeclient::ResourceNotFoundError
false
end
def cluster_role_binding_exists?(resource)
kubeclient.get_cluster_role_binding(resource.metadata.name)
rescue ::Kubeclient::ResourceNotFoundError
false
end
end
end
end
end

View File

@ -1,82 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
class Pod
def initialize(command, namespace_name, service_account_name: nil)
@command = command
@namespace_name = namespace_name
@service_account_name = service_account_name
end
def generate
spec = { containers: [container_specification], restartPolicy: 'Never' }
spec[:volumes] = volumes_specification
spec[:containers][0][:volumeMounts] = volume_mounts_specification
spec[:serviceAccountName] = service_account_name if service_account_name
::Kubeclient::Resource.new(metadata: metadata, spec: spec)
end
private
attr_reader :command, :namespace_name, :service_account_name
def container_specification
{
name: 'helm',
image: "registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/#{command.class::HELM_VERSION}-kube-#{Gitlab::Kubernetes::Helm::KUBECTL_VERSION}-alpine-3.12",
env: generate_pod_env(command),
command: %w(/bin/sh),
args: %w(-c $(COMMAND_SCRIPT))
}
end
def labels
{
'gitlab.org/action': 'install',
'gitlab.org/application': command.name
}
end
def metadata
{
name: command.pod_name,
namespace: namespace_name,
labels: labels
}
end
def generate_pod_env(command)
command.env.merge(
HELM_VERSION: command.class::HELM_VERSION,
COMMAND_SCRIPT: command.generate_script
).map { |key, value| { name: key, value: value } }
end
def volumes_specification
[
{
name: 'configuration-volume',
configMap: {
name: "values-content-configuration-#{command.name}",
items: command.file_names.map { |name| { key: name, path: name } }
}
}
]
end
def volume_mounts_specification
[
{
name: 'configuration-volume',
mountPath: "/data/helm/#{command.name}/config"
}
]
end
end
end
end
end

View File

@ -1,93 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V2
class BaseCommand
attr_reader :name, :files
HELM_VERSION = '2.17.0'
def initialize(rbac:, name:, files:)
@rbac = rbac
@name = name
@files = files
end
def env
{ TILLER_NAMESPACE: namespace }
end
def rbac?
@rbac
end
def pod_resource
pod_service_account_name = rbac? ? service_account_name : nil
Gitlab::Kubernetes::Helm::Pod.new(self, namespace, service_account_name: pod_service_account_name).generate
end
def generate_script
<<~HEREDOC
set -xeo pipefail
HEREDOC
end
def pod_name
"install-#{name}"
end
def config_map_resource
Gitlab::Kubernetes::ConfigMap.new(name, files).generate
end
def service_account_resource
return unless rbac?
Gitlab::Kubernetes::ServiceAccount.new(service_account_name, namespace).generate
end
def cluster_role_binding_resource
return unless rbac?
subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: namespace }]
Gitlab::Kubernetes::ClusterRoleBinding.new(
cluster_role_binding_name,
cluster_role_name,
subjects
).generate
end
def file_names
files.keys
end
private
def files_dir
"/data/helm/#{name}/config"
end
def namespace
Gitlab::Kubernetes::Helm::NAMESPACE
end
def service_account_name
Gitlab::Kubernetes::Helm::SERVICE_ACCOUNT
end
def cluster_role_binding_name
Gitlab::Kubernetes::Helm::CLUSTER_ROLE_BINDING
end
def cluster_role_name
Gitlab::Kubernetes::Helm::CLUSTER_ROLE
end
end
end
end
end
end

View File

@ -1,75 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V2
class Certificate
INFINITE_EXPIRY = 1000.years
SHORT_EXPIRY = 30.minutes
attr_reader :key, :cert
def key_string
@key.to_s
end
def cert_string
@cert.to_pem
end
def self.from_strings(key_string, cert_string)
key = OpenSSL::PKey::RSA.new(key_string)
cert = OpenSSL::X509::Certificate.new(cert_string)
new(key, cert)
end
def self.generate_root
_issue(signed_by: nil, expires_in: INFINITE_EXPIRY, certificate_authority: true)
end
def issue(expires_in: SHORT_EXPIRY)
self.class._issue(signed_by: self, expires_in: expires_in, certificate_authority: false)
end
private
def self._issue(signed_by:, expires_in:, certificate_authority:)
key = OpenSSL::PKey::RSA.new(4096)
public_key = key.public_key
subject = OpenSSL::X509::Name.parse("/C=US")
cert = OpenSSL::X509::Certificate.new
cert.subject = subject
cert.issuer = signed_by&.cert&.subject || subject
cert.not_before = Time.now.utc
cert.not_after = expires_in.from_now.utc
cert.public_key = public_key
cert.serial = 0x0
cert.version = 2
if certificate_authority
extension_factory = OpenSSL::X509::ExtensionFactory.new
extension_factory.subject_certificate = cert
extension_factory.issuer_certificate = cert
cert.add_extension(extension_factory.create_extension('subjectKeyIdentifier', 'hash'))
cert.add_extension(extension_factory.create_extension('basicConstraints', 'CA:TRUE', true))
cert.add_extension(extension_factory.create_extension('keyUsage', 'cRLSign,keyCertSign', true))
end
cert.sign(signed_by&.key || key, OpenSSL::Digest.new('SHA256'))
new(key, cert)
end
def initialize(key, cert)
@key = key
@cert = cert
end
end
end
end
end
end

View File

@ -1,29 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V2
module ClientCommand
def init_command
<<~SHELL.chomp
export HELM_HOST="localhost:44134"
tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
SHELL
end
def repository_command
['helm', 'repo', 'add', name, repository].shelljoin if repository
end
private
def repository_update_command
'helm repo update'
end
end
end
end
end
end

View File

@ -1,38 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V2
class DeleteCommand < BaseCommand
include ClientCommand
attr_reader :predelete, :postdelete
def initialize(predelete: nil, postdelete: nil, **args)
super(**args)
@predelete = predelete
@postdelete = postdelete
end
def generate_script
super + [
init_command,
predelete,
delete_command,
postdelete
].compact.join("\n")
end
def pod_name
"uninstall-#{name}"
end
def delete_command
['helm', 'delete', '--purge', name].shelljoin
end
end
end
end
end
end

View File

@ -1,45 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V2
class InitCommand < BaseCommand
def generate_script
super + [
init_helm_command
].join("\n")
end
private
def init_helm_command
command = %w[helm init] + init_command_flags
command.shelljoin
end
def init_command_flags
tls_flags + optional_service_account_flag
end
def tls_flags
[
'--tiller-tls',
'--tiller-tls-verify',
'--tls-ca-cert', "#{files_dir}/ca.pem",
'--tiller-tls-cert', "#{files_dir}/cert.pem",
'--tiller-tls-key', "#{files_dir}/key.pem"
]
end
def optional_service_account_flag
return [] unless rbac?
['--service-account', service_account_name]
end
end
end
end
end
end

View File

@ -1,87 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V2
class InstallCommand < BaseCommand
include ClientCommand
attr_reader :chart, :repository, :preinstall, :postinstall
attr_accessor :version
def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
super(**args)
@chart = chart
@version = version
@repository = repository
@preinstall = preinstall
@postinstall = postinstall
end
def generate_script
super + [
init_command,
repository_command,
repository_update_command,
preinstall,
install_command,
postinstall
].compact.join("\n")
end
private
# Uses `helm upgrade --install` which means we can use this for both
# installation and uprade of applications
def install_command
command = ['helm', 'upgrade', name, chart] +
install_flag +
rollback_support_flag +
reset_values_flag +
optional_version_flag +
rbac_create_flag +
namespace_flag +
value_flag
command.shelljoin
end
def install_flag
['--install']
end
def reset_values_flag
['--reset-values']
end
def value_flag
['-f', "/data/helm/#{name}/config/values.yaml"]
end
def namespace_flag
['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
end
def rbac_create_flag
if rbac?
%w[--set rbac.create=true,rbac.enabled=true]
else
%w[--set rbac.create=false,rbac.enabled=false]
end
end
def optional_version_flag
return [] unless version
['--version', version]
end
def rollback_support_flag
['--atomic', '--cleanup-on-fail']
end
end
end
end
end
end

View File

@ -1,67 +0,0 @@
# frozen_string_literal: true
# PatchCommand is for updating values in installed charts without overwriting
# existing values.
module Gitlab
module Kubernetes
module Helm
module V2
class PatchCommand < BaseCommand
include ClientCommand
attr_reader :chart, :repository
attr_accessor :version
def initialize(chart:, version:, repository: nil, **args)
super(**args)
# version is mandatory to prevent chart mismatches
# we do not want our values interpreted in the context of the wrong version
raise ArgumentError, 'version is required' if version.blank?
@chart = chart
@version = version
@repository = repository
end
def generate_script
super + [
init_command,
repository_command,
repository_update_command,
upgrade_command
].compact.join("\n")
end
private
def upgrade_command
command = ['helm', 'upgrade', name, chart] +
reuse_values_flag +
version_flag +
namespace_flag +
value_flag
command.shelljoin
end
def reuse_values_flag
['--reuse-values']
end
def value_flag
['-f', "/data/helm/#{name}/config/values.yaml"]
end
def namespace_flag
['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
end
def version_flag
['--version', version]
end
end
end
end
end
end

View File

@ -1,30 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V2
class ResetCommand < BaseCommand
include ClientCommand
def generate_script
super + [
init_command,
reset_helm_command
].join("\n")
end
def pod_name
"uninstall-#{name}"
end
private
def reset_helm_command
'helm reset --force'
end
end
end
end
end
end

View File

@ -1,101 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V3
class BaseCommand
attr_reader :name, :files
HELM_VERSION = '3.2.4'
def initialize(rbac:, name:, files:)
@rbac = rbac
@name = name
@files = files
end
def env
{}
end
def rbac?
@rbac
end
def pod_resource
pod_service_account_name = rbac? ? service_account_name : nil
Gitlab::Kubernetes::Helm::Pod.new(self, namespace, service_account_name: pod_service_account_name).generate
end
def generate_script
<<~HEREDOC
set -xeo pipefail
HEREDOC
end
def pod_name
"install-#{name}"
end
def config_map_resource
Gitlab::Kubernetes::ConfigMap.new(name, files).generate
end
def service_account_resource
return unless rbac?
Gitlab::Kubernetes::ServiceAccount.new(service_account_name, namespace).generate
end
def cluster_role_binding_resource
return unless rbac?
subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: namespace }]
Gitlab::Kubernetes::ClusterRoleBinding.new(
cluster_role_binding_name,
cluster_role_name,
subjects
).generate
end
def file_names
files.keys
end
def repository_command
['helm', 'repo', 'add', name, repository].shelljoin if repository
end
private
def repository_update_command
'helm repo update'
end
def namespace_flag
['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
end
def namespace
Gitlab::Kubernetes::Helm::NAMESPACE
end
def service_account_name
Gitlab::Kubernetes::Helm::SERVICE_ACCOUNT
end
def cluster_role_binding_name
Gitlab::Kubernetes::Helm::CLUSTER_ROLE_BINDING
end
def cluster_role_name
Gitlab::Kubernetes::Helm::CLUSTER_ROLE
end
end
end
end
end
end

View File

@ -1,35 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V3
class DeleteCommand < BaseCommand
attr_reader :predelete, :postdelete
def initialize(predelete: nil, postdelete: nil, **args)
super(**args)
@predelete = predelete
@postdelete = postdelete
end
def generate_script
super + [
predelete,
delete_command,
postdelete
].compact.join("\n")
end
def pod_name
"uninstall-#{name}"
end
def delete_command
['helm', 'uninstall', name, *namespace_flag].shelljoin
end
end
end
end
end
end

View File

@ -1,80 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module Helm
module V3
class InstallCommand < BaseCommand
attr_reader :chart, :repository, :preinstall, :postinstall
attr_accessor :version
def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
super(**args)
@chart = chart
@version = version
@repository = repository
@preinstall = preinstall
@postinstall = postinstall
end
def generate_script
super + [
repository_command,
repository_update_command,
preinstall,
install_command,
postinstall
].compact.join("\n")
end
private
# Uses `helm upgrade --install` which means we can use this for both
# installation and uprade of applications
def install_command
command = ['helm', 'upgrade', name, chart] +
install_flag +
rollback_support_flag +
reset_values_flag +
optional_version_flag +
rbac_create_flag +
namespace_flag +
value_flag
command.shelljoin
end
def install_flag
['--install']
end
def reset_values_flag
['--reset-values']
end
def value_flag
['-f', "/data/helm/#{name}/config/values.yaml"]
end
def rbac_create_flag
if rbac?
%w[--set rbac.create=true,rbac.enabled=true]
else
%w[--set rbac.create=false,rbac.enabled=false]
end
end
def optional_version_flag
return [] unless version
['--version', version]
end
def rollback_support_flag
['--atomic', '--cleanup-on-fail']
end
end
end
end
end
end

View File

@ -1,60 +0,0 @@
# frozen_string_literal: true
# PatchCommand is for updating values in installed charts without overwriting
# existing values.
module Gitlab
module Kubernetes
module Helm
module V3
class PatchCommand < BaseCommand
attr_reader :chart, :repository
attr_accessor :version
def initialize(chart:, version:, repository: nil, **args)
super(**args)
# version is mandatory to prevent chart mismatches
# we do not want our values interpreted in the context of the wrong version
raise ArgumentError, 'version is required' if version.blank?
@chart = chart
@version = version
@repository = repository
end
def generate_script
super + [
repository_command,
repository_update_command,
upgrade_command
].compact.join("\n")
end
private
def upgrade_command
command = ['helm', 'upgrade', name, chart] +
reuse_values_flag +
version_flag +
namespace_flag +
value_flag
command.shelljoin
end
def reuse_values_flag
['--reuse-values']
end
def value_flag
['-f', "/data/helm/#{name}/config/values.yaml"]
end
def version_flag
['--version', version]
end
end
end
end
end
end

View File

@ -466,7 +466,7 @@ module Gitlab
# ```
MARKDOWN_CODE_BLOCK_REGEX_UNTRUSTED =
'(?P<code>' \
'^```\n' \
'^```.*?\n' \
'(?:\n|.)*?' \
'\n```\ *$' \
')'.freeze
@ -484,6 +484,17 @@ module Gitlab
)
}mx.freeze
# HTML block:
# <tag>
# Anything, including `>>>` blocks which are ignored by this filter
# </tag>
MARKDOWN_HTML_BLOCK_REGEX_UNTRUSTED =
'(?P<html>' \
'^<[^>]+?>\ *\n' \
'(?:\n|.)*?' \
'\n<\/[^>]+?>\ *$' \
')'.freeze
# HTML comment line:
# <!-- some commented text -->
MARKDOWN_HTML_COMMENT_LINE_REGEX_UNTRUSTED =
@ -506,6 +517,13 @@ module Gitlab
}mx.freeze
end
def markdown_code_or_html_blocks_untrusted
@markdown_code_or_html_blocks_untrusted ||=
"#{MARKDOWN_CODE_BLOCK_REGEX_UNTRUSTED}" \
"|" \
"#{MARKDOWN_HTML_BLOCK_REGEX_UNTRUSTED}"
end
def markdown_code_or_html_comments_untrusted
@markdown_code_or_html_comments_untrusted ||=
"#{MARKDOWN_CODE_BLOCK_REGEX_UNTRUSTED}" \
@ -515,6 +533,17 @@ module Gitlab
"#{MARKDOWN_HTML_COMMENT_BLOCK_REGEX_UNTRUSTED}"
end
def markdown_code_or_html_blocks_or_html_comments_untrusted
@markdown_code_or_html_comments_untrusted ||=
"#{MARKDOWN_CODE_BLOCK_REGEX_UNTRUSTED}" \
"|" \
"#{MARKDOWN_HTML_BLOCK_REGEX_UNTRUSTED}" \
"|" \
"#{MARKDOWN_HTML_COMMENT_LINE_REGEX_UNTRUSTED}" \
"|" \
"#{MARKDOWN_HTML_COMMENT_BLOCK_REGEX_UNTRUSTED}"
end
# Based on Jira's project key format
# https://confluence.atlassian.com/adminjiraserver073/changing-the-project-key-format-861253229.html
# Avoids linking CVE IDs (https://cve.mitre.org/cve/identifiers/syntaxchange.html#new) as Jira issues.

View File

@ -29,6 +29,27 @@ module Gitlab
RE2.GlobalReplace(text, regexp, rewrite)
end
# There is no built-in replace with block support (like `gsub`). We can accomplish
# the same thing by parsing and rebuilding the string with the substitutions.
def replace_gsub(text)
new_text = +''
remainder = text
matched = match(remainder)
until matched.nil? || matched.to_a.compact.empty?
partitioned = remainder.partition(matched.to_s)
new_text << partitioned.first
remainder = partitioned.last
new_text << yield(matched)
matched = match(remainder)
end
new_text << remainder
end
def scan(text)
matches = scan_regexp.scan(text).to_a
matches.map!(&:first) if regexp.number_of_capturing_groups == 0

View File

@ -57,7 +57,8 @@ module Sidebars
override :pill_count
def pill_count
strong_memoize(:pill_count) do
context.project.open_issues_count(context.current_user)
count = context.project.open_issues_count(context.current_user)
format_cached_count(1000, count)
end
end

View File

@ -46,7 +46,8 @@ module Sidebars
override :pill_count
def pill_count
@pill_count ||= context.project.open_merge_requests_count
count = @pill_count ||= context.project.open_merge_requests_count
format_cached_count(1000, count)
end
override :pill_html_options

View File

@ -65,7 +65,7 @@ module Sidebars
end
::Sidebars::MenuItem.new(
title: _('Infrastructure Registry'),
title: _('Terraform modules'),
link: project_infrastructure_registry_index_path(context.project),
super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: :infrastructure_registry },

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Sidebars
module Search
class Panel < ::Sidebars::Panel
override :aria_label
def aria_label
_('Search')
end
override :super_sidebar_context_header
def super_sidebar_context_header
@super_sidebar_context_header ||= {
title: aria_label,
icon: 'search'
}
end
end
end
end

View File

@ -23087,15 +23087,15 @@ msgstr ""
msgid "InfrastructureRegistry|For more information on the Terraform registry, %{linkStart}see our documentation%{linkEnd}."
msgstr ""
msgid "InfrastructureRegistry|Infrastructure Registry"
msgstr ""
msgid "InfrastructureRegistry|Publish and share your modules. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
msgid "InfrastructureRegistry|Terraform"
msgstr ""
msgid "InfrastructureRegistry|Terraform Module Registry"
msgstr ""
msgid "InfrastructureRegistry|Terraform modules are the main way to package and reuse resource configurations with Terraform. Learn more about how to %{noPackagesLinkStart}create Terraform modules%{noPackagesLinkEnd} in GitLab."
msgstr ""
@ -43526,6 +43526,12 @@ msgstr ""
msgid "Terraform"
msgstr ""
msgid "Terraform Module Registry"
msgstr ""
msgid "Terraform modules"
msgstr ""
msgid "TerraformBanner|Learn more about GitLab's Backend State"
msgstr ""

View File

@ -26,7 +26,7 @@ module QA
def go_to_infrastructure_registry
hover_registry do
within_submenu do
click_link('Infrastructure Registry')
click_link('Terraform modules')
end
end
end

View File

@ -13,7 +13,7 @@ module QA
end
def go_to_infrastructure_registry
open_operate_submenu('Infrastructure Registry')
open_operate_submenu('Terraform modules')
end
def go_to_kubernetes_clusters

View File

@ -1,97 +0,0 @@
# frozen_string_literal: true
FactoryBot.define do
factory :clusters_applications_helm, class: 'Clusters::Applications::Helm' do
cluster factory: %i(cluster provided_by_gcp)
transient do
helm_installed { true }
end
before(:create) do |_record, evaluator|
if evaluator.helm_installed
stub_method(Gitlab::Kubernetes::Helm::V2::Certificate, :generate_root) do
OpenStruct.new( # rubocop: disable Style/OpenStructUse
key_string: File.read(Rails.root.join('spec/fixtures/clusters/sample_key.key')),
cert_string: File.read(Rails.root.join('spec/fixtures/clusters/sample_cert.pem'))
)
end
end
end
after(:create) do |_record, evaluator|
if evaluator.helm_installed
restore_original_methods(Gitlab::Kubernetes::Helm::V2::Certificate)
end
end
trait :not_installable do
status { -2 }
end
trait :errored do
status { -1 }
status_reason { 'something went wrong' }
end
trait :installable do
status { 0 }
end
trait :scheduled do
status { 1 }
end
trait :installing do
status { 2 }
end
trait :installed do
status { 3 }
end
trait :updating do
status { 4 }
end
trait :updated do
status { 5 }
end
trait :update_errored do
status { 6 }
status_reason { 'something went wrong' }
end
trait :uninstalling do
status { 7 }
end
trait :uninstall_errored do
status { 8 }
status_reason { 'something went wrong' }
end
trait :uninstalled do
status { 10 }
end
trait :externally_installed do
status { 11 }
end
trait :timed_out do
installing
updated_at { ClusterWaitForAppInstallationWorker::TIMEOUT.ago }
end
# Common trait used by the apps below
trait :no_helm_installed do
cluster factory: %i(cluster provided_by_gcp)
transient do
helm_installed { false }
end
end
end
end

View File

@ -82,18 +82,10 @@ FactoryBot.define do
sequence(:environment_scope) { |n| "production#{n}/*" }
end
trait :with_installed_helm do
application_helm factory: %i(clusters_applications_helm installed)
end
trait :with_installed_prometheus do
integration_prometheus factory: %i(clusters_integrations_prometheus)
end
trait :with_all_applications do
application_helm factory: %i(clusters_applications_helm installed)
end
trait :with_domain do
domain { 'example.com' }
end

View File

@ -59,7 +59,7 @@ RSpec.describe 'Navigation menu item pinning', :js, feature_category: :navigatio
within '#super-sidebar' do
click_on 'Operate'
add_pin('Package Registry')
add_pin('Infrastructure Registry')
add_pin('Terraform modules')
wait_for_requests
end
end
@ -75,11 +75,11 @@ RSpec.describe 'Navigation menu item pinning', :js, feature_category: :navigatio
section = find("[data-testid=\"nav-item-link\"]", text: 'Operate')
within(section.sibling('ul')) do
remove_pin('Infrastructure Registry')
remove_pin('Terraform modules')
end
within '[data-testid="pinned-nav-items"]' do
expect(page).not_to have_content 'Infrastructure Registry'
expect(page).not_to have_content 'Terraform modules'
end
end
@ -87,7 +87,7 @@ RSpec.describe 'Navigation menu item pinning', :js, feature_category: :navigatio
within '[data-testid="pinned-nav-items"]' do
pinned_items = page.find_all('a').map(&:text)
item1 = page.find('a', text: 'Package Registry')
item2 = page.find('a', text: 'Infrastructure Registry')
item2 = page.find('a', text: 'Terraform modules')
expect(pinned_items).to eq [item1.text, item2.text]
drag_item(item2, to: item1)

View File

@ -11,7 +11,7 @@ RSpec.describe "Compare", :js, feature_category: :projects do
sign_in user
end
describe "branches" do
shared_examples "compare view of branches" do
shared_examples 'compares branches' do
it 'compares branches' do
visit project_compare_index_path(project, from: 'master', to: 'master')
@ -148,7 +148,7 @@ RSpec.describe "Compare", :js, feature_category: :projects do
end
end
describe "tags" do
shared_examples "compare view of tags" do
it "compares tags" do
visit project_compare_index_path(project, from: "master", to: "master")
@ -182,4 +182,17 @@ RSpec.describe "Compare", :js, feature_category: :projects do
dropdown.all(".js-compare-#{dropdown_type}-dropdown .dropdown-item", text: selection).first.click
end
end
it_behaves_like "compare view of branches"
it_behaves_like "compare view of tags"
context "when super sidebar is enabled" do
before do
user.update!(use_new_navigation: true)
stub_feature_flags(super_sidebar_nav: true)
end
it_behaves_like "compare view of branches"
it_behaves_like "compare view of tags"
end
end

View File

@ -91,7 +91,7 @@ RSpec.describe 'Project navbar', :with_license, feature_category: :projects do
before do
stub_feature_flags(harbor_registry_integration: true)
insert_harbor_registry_nav(_('Infrastructure Registry'))
insert_harbor_registry_nav(_('Terraform modules'))
visit project_path(project)
end

View File

@ -299,6 +299,32 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e
v^2 + w^2 = x^2
```
Parsed correctly when between code blocks
```ruby
x = 1
```
$$
a^2+b^2=c^2
$$
```
plaintext
```
Parsed correctly with a mixture of HTML comments and HTML blocks
<!-- sdf -->
$$
a^2+b^2=c^2
$$
<h1>
html
</h1>
### Gollum Tags
- [[linked-resource]]

View File

@ -32,7 +32,7 @@ describe('Infrastructure Title', () => {
});
it('has the correct title', () => {
expect(findTitleArea().props('title')).toBe('Infrastructure Registry');
expect(findTitleArea().props('title')).toBe('Terraform Module Registry');
});
describe('with no modules', () => {

View File

@ -1,4 +1,4 @@
import { GlBadge, GlIcon, GlAvatarLabeled } from '@gitlab/ui';
import { GlButton, GlBadge, GlIcon, GlAvatarLabeled, GlAvatarLink } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import IssuableHeader from '~/vue_shared/issuable/show/components/issuable_header.vue';
@ -13,7 +13,10 @@ const issuableHeaderProps = {
describe('IssuableHeader', () => {
let wrapper;
const findAvatar = () => wrapper.findByTestId('avatar');
const findTaskStatusEl = () => wrapper.findByTestId('task-status');
const findButton = () => wrapper.findComponent(GlButton);
const findGlAvatarLink = () => wrapper.findComponent(GlAvatarLink);
const createComponent = (props = {}, { stubs } = {}) => {
wrapper = shallowMountExtended(IssuableHeader, {
@ -40,7 +43,7 @@ describe('IssuableHeader', () => {
describe('authorId', () => {
it('returns numeric ID from GraphQL ID of `author` prop', () => {
createComponent();
expect(wrapper.vm.authorId).toBe(1);
expect(findGlAvatarLink().attributes('data-user-id')).toBe('1');
});
});
});
@ -52,12 +55,14 @@ describe('IssuableHeader', () => {
it('dispatches `click` event on sidebar toggle button', () => {
createComponent();
wrapper.vm.toggleSidebarButtonEl = document.querySelector('.js-toggle-right-sidebar-button');
jest.spyOn(wrapper.vm.toggleSidebarButtonEl, 'dispatchEvent').mockImplementation(jest.fn);
const toggleSidebarButtonEl = document.querySelector('.js-toggle-right-sidebar-button');
const dispatchEvent = jest
.spyOn(toggleSidebarButtonEl, 'dispatchEvent')
.mockImplementation(jest.fn);
wrapper.vm.handleRightSidebarToggleClick();
findButton().vm.$emit('click');
expect(wrapper.vm.toggleSidebarButtonEl.dispatchEvent).toHaveBeenCalledWith(
expect(dispatchEvent).toHaveBeenCalledWith(
expect.objectContaining({
type: 'click',
}),
@ -109,7 +114,7 @@ describe('IssuableHeader', () => {
href: webUrl,
target: '_blank',
};
const avatarEl = wrapper.findByTestId('avatar');
const avatarEl = findAvatar();
expect(avatarEl.exists()).toBe(true);
expect(avatarEl.attributes()).toMatchObject(avatarElAttrs);
expect(avatarEl.findComponent(GlAvatarLabeled).attributes()).toMatchObject({

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe GraphqlTriggers do
RSpec.describe GraphqlTriggers, feature_category: :shared do
let_it_be(:issuable, refind: true) { create(:work_item) }
describe '.issuable_assignees_updated' do
@ -12,9 +12,9 @@ RSpec.describe GraphqlTriggers do
issuable.update!(assignees: assignees)
end
it 'triggers the issuableAssigneesUpdated subscription' do
it 'triggers the issuable_assignees_updated subscription' do
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'issuableAssigneesUpdated',
:issuable_assignees_updated,
{ issuable_id: issuable.to_gid },
issuable
)
@ -24,9 +24,9 @@ RSpec.describe GraphqlTriggers do
end
describe '.issuable_title_updated' do
it 'triggers the issuableTitleUpdated subscription' do
it 'triggers the issuable_title_updated subscription' do
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'issuableTitleUpdated',
:issuable_title_updated,
{ issuable_id: issuable.to_gid },
issuable
).and_call_original
@ -36,9 +36,9 @@ RSpec.describe GraphqlTriggers do
end
describe '.issuable_description_updated' do
it 'triggers the issuableDescriptionUpdated subscription' do
it 'triggers the issuable_description_updated subscription' do
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'issuableDescriptionUpdated',
:issuable_description_updated,
{ issuable_id: issuable.to_gid },
issuable
).and_call_original
@ -54,9 +54,9 @@ RSpec.describe GraphqlTriggers do
issuable.update!(labels: labels)
end
it 'triggers the issuableLabelsUpdated subscription' do
it 'triggers the issuable_labels_updated subscription' do
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'issuableLabelsUpdated',
:issuable_labels_updated,
{ issuable_id: issuable.to_gid },
issuable
)
@ -66,9 +66,9 @@ RSpec.describe GraphqlTriggers do
end
describe '.issuable_dates_updated' do
it 'triggers the issuableDatesUpdated subscription' do
it 'triggers the issuable_dates_updated subscription' do
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'issuableDatesUpdated',
:issuable_dates_updated,
{ issuable_id: issuable.to_gid },
issuable
).and_call_original
@ -78,9 +78,9 @@ RSpec.describe GraphqlTriggers do
end
describe '.issuable_milestone_updated' do
it 'triggers the issuableMilestoneUpdated subscription' do
it 'triggers the issuable_milestone_updated subscription' do
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'issuableMilestoneUpdated',
:issuable_milestone_updated,
{ issuable_id: issuable.to_gid },
issuable
).and_call_original
@ -90,11 +90,11 @@ RSpec.describe GraphqlTriggers do
end
describe '.merge_request_reviewers_updated' do
it 'triggers the mergeRequestReviewersUpdated subscription' do
it 'triggers the merge_request_reviewers_updated subscription' do
merge_request = build_stubbed(:merge_request)
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'mergeRequestReviewersUpdated',
:merge_request_reviewers_updated,
{ issuable_id: merge_request.to_gid },
merge_request
).and_call_original
@ -104,11 +104,11 @@ RSpec.describe GraphqlTriggers do
end
describe '.merge_request_merge_status_updated' do
it 'triggers the mergeRequestMergeStatusUpdated subscription' do
it 'triggers the merge_request_merge_status_updated subscription' do
merge_request = build_stubbed(:merge_request)
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'mergeRequestMergeStatusUpdated',
:merge_request_merge_status_updated,
{ issuable_id: merge_request.to_gid },
merge_request
).and_call_original
@ -121,7 +121,7 @@ RSpec.describe GraphqlTriggers do
stub_feature_flags(realtime_mr_status_change: false)
end
it 'does not trigger mergeRequestMergeStatusUpdated subscription' do
it 'does not trigger realtime_mr_status_change subscription' do
merge_request = build_stubbed(:merge_request)
expect(GitlabSchema.subscriptions).not_to receive(:trigger)
@ -132,11 +132,11 @@ RSpec.describe GraphqlTriggers do
end
describe '.merge_request_approval_state_updated' do
it 'triggers the mergeRequestApprovalStateUpdated subscription' do
it 'triggers the merge_request_approval_state_updated subscription' do
merge_request = build_stubbed(:merge_request)
expect(GitlabSchema.subscriptions).to receive(:trigger).with(
'mergeRequestApprovalStateUpdated',
:merge_request_approval_state_updated,
{ issuable_id: merge_request.to_gid },
merge_request
).and_call_original

View File

@ -405,6 +405,10 @@ RSpec.describe SidebarsHelper, feature_category: :navigation do
expect(helper.super_sidebar_nav_panel(nav: 'your_work', user: user)).to be_a(Sidebars::YourWork::Panel)
end
it 'returns Search Panel for search nav' do
expect(helper.super_sidebar_nav_panel(nav: 'search', user: user)).to be_a(Sidebars::Search::Panel)
end
it 'returns "Your Work" Panel as a fallback', :use_clean_rails_memory_store_caching do
expect(helper.super_sidebar_nav_panel(user: user)).to be_a(Sidebars::YourWork::Panel)
end

View File

@ -101,6 +101,7 @@ RSpec.describe Banzai::Filter::MathFilter, feature_category: :team_planning do
context 'with valid syntax' do
where(:text, :result_template) do
"$$\n2+2\n$$" | "<math>2+2\n</math>"
"$$ \n2+2\n$$" | "<math>2+2\n</math>"
"$$\n2+2\n3+4\n$$" | "<math>2+2\n3+4\n</math>"
end

View File

@ -7,9 +7,9 @@ RSpec.describe Gitlab::Database::MigrationHelpers::ConvertToBigint, feature_cate
using RSpec::Parameterized::TableSyntax
where(:dot_com, :dev_or_test, :jh, :expectation) do
true | true | true | false
true | true | true | true
true | false | true | false
false | true | true | false
false | true | true | true
false | false | true | false
true | true | false | true
true | false | false | true

Some files were not shown because too many files have changed in this diff Show More