Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
0adc81d8e0
commit
5adf6557e2
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Analytics
|
||||
module CycleAnalytics
|
||||
class StageEventHash < ApplicationRecord
|
||||
has_many :cycle_analytics_project_stages, class_name: 'Analytics::CycleAnalytics::ProjectStage', inverse_of: :stage_event_hash
|
||||
|
||||
validates :hash_sha256, presence: true
|
||||
|
||||
# Creates or queries the id of the corresponding stage event hash code
|
||||
def self.record_id_by_hash_sha256(hash)
|
||||
casted_hash_code = Arel::Nodes.build_quoted(hash, Analytics::CycleAnalytics::StageEventHash.arel_table[:hash_sha256]).to_sql
|
||||
|
||||
# Atomic, safe insert without retrying
|
||||
query = <<~SQL
|
||||
WITH insert_cte AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
|
||||
INSERT INTO #{quoted_table_name} (hash_sha256) VALUES (#{casted_hash_code}) ON CONFLICT DO NOTHING RETURNING ID
|
||||
)
|
||||
SELECT ids.id FROM (
|
||||
(SELECT id FROM #{quoted_table_name} WHERE hash_sha256=#{casted_hash_code} LIMIT 1)
|
||||
UNION ALL
|
||||
(SELECT id FROM insert_cte LIMIT 1)
|
||||
) AS ids LIMIT 1
|
||||
SQL
|
||||
|
||||
connection.execute(query).first['id']
|
||||
end
|
||||
|
||||
def self.cleanup_if_unused(id)
|
||||
unused_hashes_for(id)
|
||||
.where(id: id)
|
||||
.delete_all
|
||||
end
|
||||
|
||||
def self.unused_hashes_for(id)
|
||||
exists_query = Analytics::CycleAnalytics::ProjectStage.where(stage_event_hash_id: id).select('1').limit(1)
|
||||
where.not('EXISTS (?)', exists_query)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Analytics::CycleAnalytics::StageEventHash.prepend_mod_with('Analytics::CycleAnalytics::StageEventHash')
|
|
@ -10,6 +10,7 @@ module Analytics
|
|||
included do
|
||||
belongs_to :start_event_label, class_name: 'GroupLabel', optional: true
|
||||
belongs_to :end_event_label, class_name: 'GroupLabel', optional: true
|
||||
belongs_to :stage_event_hash, class_name: 'Analytics::CycleAnalytics::StageEventHash', foreign_key: :stage_event_hash_id, optional: true
|
||||
|
||||
validates :name, presence: true
|
||||
validates :name, exclusion: { in: Gitlab::Analytics::CycleAnalytics::DefaultStages.names }, if: :custom?
|
||||
|
@ -28,6 +29,9 @@ module Analytics
|
|||
scope :ordered, -> { order(:relative_position, :id) }
|
||||
scope :for_list, -> { includes(:start_event_label, :end_event_label).ordered }
|
||||
scope :by_value_stream, -> (value_stream) { where(value_stream_id: value_stream.id) }
|
||||
|
||||
before_save :ensure_stage_event_hash_id
|
||||
after_commit :cleanup_old_stage_event_hash
|
||||
end
|
||||
|
||||
def parent=(_)
|
||||
|
@ -133,6 +137,20 @@ module Analytics
|
|||
.id_in(label_id)
|
||||
.exists?
|
||||
end
|
||||
|
||||
def ensure_stage_event_hash_id
|
||||
previous_stage_event_hash = stage_event_hash&.hash_sha256
|
||||
|
||||
if previous_stage_event_hash.blank? || events_hash_code != previous_stage_event_hash
|
||||
self.stage_event_hash_id = Analytics::CycleAnalytics::StageEventHash.record_id_by_hash_sha256(events_hash_code)
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_old_stage_event_hash
|
||||
if stage_event_hash_id_previously_changed? && stage_event_hash_id_previously_was
|
||||
Analytics::CycleAnalytics::StageEventHash.cleanup_if_unused(stage_event_hash_id_previously_was)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -337,7 +337,7 @@ class ProjectPolicy < BasePolicy
|
|||
enable :read_metrics_user_starred_dashboard
|
||||
end
|
||||
|
||||
rule { packages_disabled | repository_disabled }.policy do
|
||||
rule { packages_disabled }.policy do
|
||||
prevent(*create_read_update_admin_destroy(:package))
|
||||
end
|
||||
|
||||
|
|
|
@ -6,22 +6,22 @@
|
|||
.form-check
|
||||
= f.check_box :password_authentication_enabled_for_web, class: 'form-check-input'
|
||||
= f.label :password_authentication_enabled_for_web, class: 'form-check-label' do
|
||||
= _('Password authentication enabled for web interface')
|
||||
= _('Allow password authentication for the web interface')
|
||||
.form-text.text-muted
|
||||
= _('When disabled, an external authentication provider must be used.')
|
||||
= _('When inactive, an external authentication provider must be used.')
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :password_authentication_enabled_for_git, class: 'form-check-input'
|
||||
= f.label :password_authentication_enabled_for_git, class: 'form-check-label' do
|
||||
= _('Password authentication enabled for Git over HTTP(S)')
|
||||
= _('Allow password authentication for Git over HTTP(S)')
|
||||
.form-text.text-muted
|
||||
When disabled, a Personal Access Token
|
||||
When inactive, a Personal Access Token
|
||||
- if Gitlab::Auth::Ldap::Config.enabled?
|
||||
or LDAP password
|
||||
must be used to authenticate.
|
||||
- if omniauth_enabled? && button_based_providers.any?
|
||||
%fieldset.form-group
|
||||
%legend.gl-font-base.gl-mb-3.gl-border-none.gl-font-weight-bold= _('Enabled OAuth sign-in sources')
|
||||
%legend.gl-font-base.gl-mb-3.gl-border-none.gl-font-weight-bold= _('Enabled OAuth authentication sources')
|
||||
= hidden_field_tag 'application_setting[enabled_oauth_sign_in_sources][]'
|
||||
- oauth_providers_checkboxes.each do |source|
|
||||
= source
|
||||
|
@ -30,39 +30,44 @@
|
|||
.form-check
|
||||
= f.check_box :require_two_factor_authentication, class: 'form-check-input'
|
||||
= f.label :require_two_factor_authentication, class: 'form-check-label' do
|
||||
= _('Require all users to set up two-factor authentication')
|
||||
= _('Enforce two-factor authentication')
|
||||
%p.form-text.text-muted
|
||||
= _('Enforce two-factor authentication for all user sign-ins.')
|
||||
= link_to _('Learn more.'), help_page_path('security/two_factor_authentication.md'), target: '_blank', rel: 'noopener noreferrer'
|
||||
.form-group
|
||||
= f.label :two_factor_authentication, _('Two-factor grace period'), class: 'label-bold'
|
||||
= f.number_field :two_factor_grace_period, min: 0, class: 'form-control gl-form-input', placeholder: '0'
|
||||
.form-text.text-muted
|
||||
= _('Maximum time that users are allowed to skip the setup of two-factor authentication (in hours). Set to 0 (zero) to enforce at next sign in.')
|
||||
.form-group
|
||||
= f.label :admin_mode, _('Admin Mode'), class: 'label-bold'
|
||||
= sprite_icon('lock', css_class: 'gl-icon')
|
||||
.form-check
|
||||
= f.check_box :admin_mode, class: 'form-check-input'
|
||||
= f.label :admin_mode, class: 'form-check-label' do
|
||||
= _('Require additional authentication for administrative tasks')
|
||||
.form-text.text-muted
|
||||
= link_to _('Learn more.'), help_page_path('user/admin_area/settings/sign_in_restrictions', anchor: 'admin-mode')
|
||||
= _('Enable admin mode')
|
||||
%p.form-text.text-muted
|
||||
= _('Require additional authentication for administrative tasks.')
|
||||
= link_to _('Learn more.'), help_page_path('user/admin_area/settings/sign_in_restrictions', anchor: 'admin-mode'), target: '_blank', rel: 'noopener noreferrer'
|
||||
.form-group
|
||||
= f.label :unknown_sign_in, _('Email notification for unknown sign-ins'), class: 'label-bold'
|
||||
.form-check
|
||||
= f.check_box :notify_on_unknown_sign_in, class: 'form-check-input'
|
||||
= f.label :notify_on_unknown_sign_in, class: 'form-check-label' do
|
||||
= _('Notify users by email when sign-in location is not recognized')
|
||||
= link_to sprite_icon('question-o'),
|
||||
'https://docs.gitlab.com/ee/user/profile/unknown_sign_in_notification.html',
|
||||
target: '_blank'
|
||||
.form-group
|
||||
= f.label :two_factor_authentication, _('Two-factor grace period (hours)'), class: 'label-bold'
|
||||
= f.number_field :two_factor_grace_period, min: 0, class: 'form-control gl-form-input', placeholder: '0'
|
||||
.form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication')
|
||||
= _('Enable email notification')
|
||||
%p.form-text.text-muted
|
||||
= _('Notify users by email when sign-in location is not recognized.')
|
||||
= link_to _('Learn more.'), help_page_path('user/profile/unknown_sign_in_notification.md'), target: '_blank', rel: 'noopener noreferrer'
|
||||
.form-group
|
||||
= f.label :home_page_url, _('Home page URL'), class: 'label-bold'
|
||||
= f.text_field :home_page_url, class: 'form-control gl-form-input', placeholder: 'http://company.example.com', :'aria-describedby' => 'home_help_block'
|
||||
%span.form-text.text-muted#home_help_block= _("We will redirect non-logged in users to this page")
|
||||
%span.form-text.text-muted#home_help_block= _("Direct non-authenticated users to this page.")
|
||||
.form-group
|
||||
= f.label :after_sign_out_path, _('After sign-out path'), class: 'label-bold'
|
||||
= f.label :after_sign_out_path, _('Sign-out page URL'), class: 'label-bold'
|
||||
= f.text_field :after_sign_out_path, class: 'form-control gl-form-input', placeholder: 'http://company.example.com', :'aria-describedby' => 'after_sign_out_path_help_block'
|
||||
%span.form-text.text-muted#after_sign_out_path_help_block= _("We will redirect users to this page after they sign out")
|
||||
%span.form-text.text-muted#home_help_block= _("Direct users to this page after they sign out.")
|
||||
.form-group
|
||||
= f.label :sign_in_text, _('Sign-in text'), class: 'label-bold'
|
||||
= f.text_area :sign_in_text, class: 'form-control gl-form-input', rows: 4
|
||||
.form-text.text-muted Markdown enabled
|
||||
%span.form-text.text-muted#home_help_block= _("Add text to the sign-in page. Markdown enabled.")
|
||||
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
|
||||
|
|
|
@ -53,7 +53,8 @@
|
|||
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
|
||||
= expanded_by_default? ? _('Collapse') : _('Expand')
|
||||
%p
|
||||
= _('Set requirements for a user to sign-in. Enable mandatory two-factor authentication.')
|
||||
= _('Set sign-in restrictions for all users.')
|
||||
= link_to _('Learn more.'), help_page_path('user/admin_area/settings/sign_in_restrictions.md'), target: '_blank', rel: 'noopener noreferrer'
|
||||
.settings-content
|
||||
= render 'signin'
|
||||
|
||||
|
|
|
@ -14,9 +14,10 @@ class WebHookWorker
|
|||
worker_has_external_dependencies!
|
||||
|
||||
def perform(hook_id, data, hook_name)
|
||||
hook = WebHook.find(hook_id)
|
||||
data = data.with_indifferent_access
|
||||
hook = WebHook.find_by_id(hook_id)
|
||||
return unless hook
|
||||
|
||||
data = data.with_indifferent_access
|
||||
WebHookService.new(hook, data, hook_name, jid).execute
|
||||
end
|
||||
end
|
||||
|
|
|
@ -168,6 +168,11 @@ module Gitlab
|
|||
# like if you have constraints or database-specific column types
|
||||
config.active_record.schema_format = :sql
|
||||
|
||||
# Dump all DB schemas even if schema_search_path is defined,
|
||||
# so that we get the same db/structure.sql
|
||||
# regardless if schema_search_path is set, or not.
|
||||
config.active_record.dump_schemas = :all
|
||||
|
||||
# Use new connection handling so that we can use Rails 6.1+ multiple
|
||||
# database support.
|
||||
config.active_record.legacy_connection_handling = false
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: get_tag_signatures
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67000
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337842
|
||||
milestone: '14.2'
|
||||
type: development
|
||||
group: group::gitaly
|
||||
default_enabled: false
|
|
@ -10,6 +10,10 @@ value_type: number
|
|||
status: data_available
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- p_terraform_state_api_unique_users
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
|
|
|
@ -10,6 +10,10 @@ value_type: number
|
|||
status: data_available
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- o_pipeline_authoring_unique_users_committing_ciconfigfile
|
||||
distribution:
|
||||
- ee
|
||||
- ce
|
||||
|
|
|
@ -12,6 +12,10 @@ milestone: "13.10"
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54707
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
|
|
|
@ -12,6 +12,10 @@ milestone: '13.11'
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- users_expanding_secure_security_report
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
|
|
|
@ -12,7 +12,12 @@ status: data_available
|
|||
milestone: "13.12"
|
||||
introduced_by_url:
|
||||
time_frame: 28d
|
||||
data_source:
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- o_pipeline_authoring_unique_users_committing_ciconfigfile
|
||||
- o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
|
|
|
@ -10,6 +10,10 @@ value_type: number
|
|||
status: data_available
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- o_pipeline_authoring_unique_users_committing_ciconfigfile
|
||||
distribution:
|
||||
- ee
|
||||
- ce
|
||||
|
|
|
@ -12,6 +12,10 @@ milestone: "13.10"
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54707
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
|
|
|
@ -12,6 +12,10 @@ milestone: '13.11'
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- users_expanding_secure_security_report
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
|
|
|
@ -12,7 +12,12 @@ status: data_available
|
|||
milestone: "13.12"
|
||||
introduced_by_url:
|
||||
time_frame: 7d
|
||||
data_source:
|
||||
data_source: redis_hll
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- o_pipeline_authoring_unique_users_committing_ciconfigfile
|
||||
- o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateAnalyticsCycleAnalyticsStageEventHashes < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :analytics_cycle_analytics_stage_event_hashes do |t|
|
||||
t.binary :hash_sha256
|
||||
t.index :hash_sha256, unique: true, name: 'index_cycle_analytics_stage_event_hashes_on_hash_sha_256'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddStageHashFkToProjectStages < ActiveRecord::Migration[6.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
unless column_exists?(:analytics_cycle_analytics_project_stages, :stage_event_hash_id)
|
||||
add_column :analytics_cycle_analytics_project_stages, :stage_event_hash_id, :bigint
|
||||
end
|
||||
|
||||
add_concurrent_index :analytics_cycle_analytics_project_stages, :stage_event_hash_id, name: 'index_project_stages_on_stage_event_hash_id'
|
||||
add_concurrent_foreign_key :analytics_cycle_analytics_project_stages, :analytics_cycle_analytics_stage_event_hashes, column: :stage_event_hash_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :analytics_cycle_analytics_project_stages, :stage_event_hash_id
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddStageHashFkToGroupStages < ActiveRecord::Migration[6.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
unless column_exists?(:analytics_cycle_analytics_group_stages, :stage_event_hash_id)
|
||||
add_column :analytics_cycle_analytics_group_stages, :stage_event_hash_id, :bigint
|
||||
end
|
||||
|
||||
add_concurrent_index :analytics_cycle_analytics_group_stages, :stage_event_hash_id, name: 'index_group_stages_on_stage_event_hash_id'
|
||||
add_concurrent_foreign_key :analytics_cycle_analytics_group_stages, :analytics_cycle_analytics_stage_event_hashes, column: :stage_event_hash_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :analytics_cycle_analytics_group_stages, :stage_event_hash_id
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
f819eaed7e387f18f066180cbf9d0849b3e38db95bbf3e8487d3bc58d9b489ae
|
|
@ -0,0 +1 @@
|
|||
cb97b869bfb0b76dd0684aca1f40c86e7c1c9c9a0d52684830115288088e8066
|
|
@ -0,0 +1 @@
|
|||
5c104ffdb64943aa4828a9b961c8f9141dfd2ae861cea7116722d2b0d4598957
|
|
@ -9085,7 +9085,8 @@ CREATE TABLE analytics_cycle_analytics_group_stages (
|
|||
hidden boolean DEFAULT false NOT NULL,
|
||||
custom boolean DEFAULT true NOT NULL,
|
||||
name character varying(255) NOT NULL,
|
||||
group_value_stream_id bigint NOT NULL
|
||||
group_value_stream_id bigint NOT NULL,
|
||||
stage_event_hash_id bigint
|
||||
);
|
||||
|
||||
CREATE SEQUENCE analytics_cycle_analytics_group_stages_id_seq
|
||||
|
@ -9128,7 +9129,8 @@ CREATE TABLE analytics_cycle_analytics_project_stages (
|
|||
hidden boolean DEFAULT false NOT NULL,
|
||||
custom boolean DEFAULT true NOT NULL,
|
||||
name character varying(255) NOT NULL,
|
||||
project_value_stream_id bigint NOT NULL
|
||||
project_value_stream_id bigint NOT NULL,
|
||||
stage_event_hash_id bigint
|
||||
);
|
||||
|
||||
CREATE SEQUENCE analytics_cycle_analytics_project_stages_id_seq
|
||||
|
@ -9158,6 +9160,20 @@ CREATE SEQUENCE analytics_cycle_analytics_project_value_streams_id_seq
|
|||
|
||||
ALTER SEQUENCE analytics_cycle_analytics_project_value_streams_id_seq OWNED BY analytics_cycle_analytics_project_value_streams.id;
|
||||
|
||||
CREATE TABLE analytics_cycle_analytics_stage_event_hashes (
|
||||
id bigint NOT NULL,
|
||||
hash_sha256 bytea
|
||||
);
|
||||
|
||||
CREATE SEQUENCE analytics_cycle_analytics_stage_event_hashes_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE analytics_cycle_analytics_stage_event_hashes_id_seq OWNED BY analytics_cycle_analytics_stage_event_hashes.id;
|
||||
|
||||
CREATE TABLE analytics_devops_adoption_segments (
|
||||
id bigint NOT NULL,
|
||||
last_recorded_at timestamp with time zone,
|
||||
|
@ -19925,6 +19941,8 @@ ALTER TABLE ONLY analytics_cycle_analytics_project_stages ALTER COLUMN id SET DE
|
|||
|
||||
ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams ALTER COLUMN id SET DEFAULT nextval('analytics_cycle_analytics_project_value_streams_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY analytics_cycle_analytics_stage_event_hashes ALTER COLUMN id SET DEFAULT nextval('analytics_cycle_analytics_stage_event_hashes_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY analytics_devops_adoption_segments ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_segments_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY analytics_devops_adoption_snapshots ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_snapshots_id_seq'::regclass);
|
||||
|
@ -21044,6 +21062,9 @@ ALTER TABLE ONLY analytics_cycle_analytics_project_stages
|
|||
ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams
|
||||
ADD CONSTRAINT analytics_cycle_analytics_project_value_streams_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY analytics_cycle_analytics_stage_event_hashes
|
||||
ADD CONSTRAINT analytics_cycle_analytics_stage_event_hashes_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY analytics_devops_adoption_segments
|
||||
ADD CONSTRAINT analytics_devops_adoption_segments_pkey PRIMARY KEY (id);
|
||||
|
||||
|
@ -23536,6 +23557,8 @@ CREATE INDEX index_custom_emoji_on_creator_id ON custom_emoji USING btree (creat
|
|||
|
||||
CREATE UNIQUE INDEX index_custom_emoji_on_namespace_id_and_name ON custom_emoji USING btree (namespace_id, name);
|
||||
|
||||
CREATE UNIQUE INDEX index_cycle_analytics_stage_event_hashes_on_hash_sha_256 ON analytics_cycle_analytics_stage_event_hashes USING btree (hash_sha256);
|
||||
|
||||
CREATE UNIQUE INDEX index_daily_build_group_report_results_unique_columns ON ci_daily_build_group_report_results USING btree (project_id, ref_path, date, group_name);
|
||||
|
||||
CREATE INDEX index_dast_profile_schedules_active_next_run_at ON dast_profile_schedules USING btree (active, next_run_at);
|
||||
|
@ -23960,6 +23983,8 @@ CREATE INDEX index_group_repository_storage_moves_on_group_id ON group_repositor
|
|||
|
||||
CREATE UNIQUE INDEX index_group_stages_on_group_id_group_value_stream_id_and_name ON analytics_cycle_analytics_group_stages USING btree (group_id, group_value_stream_id, name);
|
||||
|
||||
CREATE INDEX index_group_stages_on_stage_event_hash_id ON analytics_cycle_analytics_group_stages USING btree (stage_event_hash_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_group_wiki_repositories_on_disk_path ON group_wiki_repositories USING btree (disk_path);
|
||||
|
||||
CREATE INDEX index_group_wiki_repositories_on_shard_id ON group_wiki_repositories USING btree (shard_id);
|
||||
|
@ -24762,6 +24787,8 @@ CREATE INDEX index_project_settings_on_project_id_partially ON project_settings
|
|||
|
||||
CREATE UNIQUE INDEX index_project_settings_on_push_rule_id ON project_settings USING btree (push_rule_id);
|
||||
|
||||
CREATE INDEX index_project_stages_on_stage_event_hash_id ON analytics_cycle_analytics_project_stages USING btree (stage_event_hash_id);
|
||||
|
||||
CREATE INDEX index_project_statistics_on_namespace_id ON project_statistics USING btree (namespace_id);
|
||||
|
||||
CREATE INDEX index_project_statistics_on_packages_size_and_project_id ON project_statistics USING btree (packages_size, project_id);
|
||||
|
@ -26073,6 +26100,9 @@ ALTER TABLE ONLY members
|
|||
ALTER TABLE ONLY lfs_objects_projects
|
||||
ADD CONSTRAINT fk_2eb33f7a78 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE NOT VALID;
|
||||
|
||||
ALTER TABLE ONLY analytics_cycle_analytics_group_stages
|
||||
ADD CONSTRAINT fk_3078345d6d FOREIGN KEY (stage_event_hash_id) REFERENCES analytics_cycle_analytics_stage_event_hashes(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY lists
|
||||
ADD CONSTRAINT fk_30f2a831f4 FOREIGN KEY (iteration_id) REFERENCES sprints(id) ON DELETE CASCADE;
|
||||
|
||||
|
@ -26514,6 +26544,9 @@ ALTER TABLE ONLY packages_packages
|
|||
ALTER TABLE ONLY geo_event_log
|
||||
ADD CONSTRAINT fk_c1f241c70d FOREIGN KEY (upload_deleted_event_id) REFERENCES geo_upload_deleted_events(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY analytics_cycle_analytics_project_stages
|
||||
ADD CONSTRAINT fk_c3339bdfc9 FOREIGN KEY (stage_event_hash_id) REFERENCES analytics_cycle_analytics_stage_event_hashes(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY vulnerability_exports
|
||||
ADD CONSTRAINT fk_c3d3cb5d0f FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
@ -123,6 +123,9 @@ From there, you can see the following actions:
|
|||
- Created, updated, or deleted DAST profiles, DAST scanner profiles, and DAST site profiles
|
||||
([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217872) in GitLab 14.1)
|
||||
- Changed a project's compliance framework ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/329362) in GitLab 14.1)
|
||||
- User password required for approvals was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
|
||||
- Permission to modify merge requests approval rules in merge requests was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
|
||||
- New approvals requirement when new commits are added to an MR was updated ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336211) in GitLab 14.2)
|
||||
|
||||
Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events).
|
||||
|
||||
|
|
|
@ -13,9 +13,6 @@ module Gitlab
|
|||
strategy :ArrayStrategy, if: -> (config) { config.is_a?(Array) }
|
||||
|
||||
class BooleanStrategy < ::Gitlab::Config::Entry::Boolean
|
||||
def inherit?(_key)
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
class ArrayStrategy < ::Gitlab::Config::Entry::Node
|
||||
|
@ -25,20 +22,12 @@ module Gitlab
|
|||
validates :config, type: Array
|
||||
validates :config, array_of_strings: true
|
||||
end
|
||||
|
||||
def inherit?(key)
|
||||
value.include?(key.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
class UnknownStrategy < ::Gitlab::Config::Entry::Node
|
||||
def errors
|
||||
["#{location} should be a bool or array of strings"]
|
||||
end
|
||||
|
||||
def inherit?(key)
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -71,7 +71,7 @@ module Gitlab
|
|||
'continuous_delivery'
|
||||
],
|
||||
[
|
||||
%r(#{RESERVED_WORDS_PREFIX}/environments\.json\z),
|
||||
%r(#{RESERVED_WORDS_PREFIX}/-/environments\.json\z),
|
||||
'environments',
|
||||
'continuous_delivery'
|
||||
],
|
||||
|
|
|
@ -5,6 +5,8 @@ module Gitlab
|
|||
class Tag < Ref
|
||||
extend Gitlab::EncodingHelper
|
||||
|
||||
delegate :id, to: :@raw_tag
|
||||
|
||||
attr_reader :object_sha, :repository
|
||||
|
||||
MAX_TAG_MESSAGE_DISPLAY_SIZE = 10.megabytes
|
||||
|
@ -24,6 +26,18 @@ module Gitlab
|
|||
def get_messages(repository, tag_ids)
|
||||
repository.gitaly_ref_client.get_tag_messages(tag_ids)
|
||||
end
|
||||
|
||||
def extract_signature_lazily(repository, tag_id)
|
||||
BatchLoader.for(tag_id).batch(key: repository) do |tag_ids, loader, args|
|
||||
batch_signature_extraction(args[:key], tag_ids).each do |tag_id, signature_data|
|
||||
loader.call(tag_id, signature_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def batch_signature_extraction(repository, tag_ids)
|
||||
repository.gitaly_ref_client.get_tag_signatures(tag_ids)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(repository, raw_tag)
|
||||
|
@ -81,7 +95,7 @@ module Gitlab
|
|||
when :PGP
|
||||
nil # not implemented, see https://gitlab.com/gitlab-org/gitlab/issues/19260
|
||||
when :X509
|
||||
X509::Tag.new(@raw_tag).signature
|
||||
X509::Tag.new(@repository, self).signature
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -178,6 +178,27 @@ module Gitlab
|
|||
messages
|
||||
end
|
||||
|
||||
def get_tag_signatures(tag_ids)
|
||||
request = Gitaly::GetTagSignaturesRequest.new(repository: @gitaly_repo, tag_revisions: tag_ids)
|
||||
response = GitalyClient.call(@repository.storage, :ref_service, :get_tag_signatures, request, timeout: GitalyClient.fast_timeout)
|
||||
|
||||
signatures = Hash.new { |h, k| h[k] = [+''.b, +''.b] }
|
||||
current_tag_id = nil
|
||||
|
||||
response.each do |message|
|
||||
message.signatures.each do |tag_signature|
|
||||
current_tag_id = tag_signature.tag_id if tag_signature.tag_id.present?
|
||||
|
||||
signatures[current_tag_id].first << tag_signature.signature
|
||||
signatures[current_tag_id].last << tag_signature.content
|
||||
end
|
||||
end
|
||||
|
||||
signatures
|
||||
rescue GRPC::InvalidArgument => ex
|
||||
raise ArgumentError, ex
|
||||
end
|
||||
|
||||
def pack_refs
|
||||
request = Gitaly::PackRefsRequest.new(repository: @gitaly_repo)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ module Gitlab
|
|||
Net::OpenTimeout, Net::ReadTimeout, Net::WriteTimeout, Gitlab::HTTP::ReadTotalTimeout
|
||||
].freeze
|
||||
HTTP_ERRORS = HTTP_TIMEOUT_ERRORS + [
|
||||
SocketError, OpenSSL::SSL::SSLError, OpenSSL::OpenSSLError,
|
||||
EOFError, SocketError, OpenSSL::SSL::SSLError, OpenSSL::OpenSSLError,
|
||||
Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EHOSTUNREACH,
|
||||
Gitlab::HTTP::BlockedUrlError, Gitlab::HTTP::RedirectionTooDeep
|
||||
].freeze
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
class SignedTag
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
def initialize(repository, tag)
|
||||
@repository = repository
|
||||
@tag = tag
|
||||
|
||||
if Feature.enabled?(:get_tag_signatures)
|
||||
@signature_data = Gitlab::Git::Tag.extract_signature_lazily(repository, tag.id) if repository
|
||||
else
|
||||
@signature_data = [signature_text_of_message.b, signed_text_of_message.b]
|
||||
end
|
||||
end
|
||||
|
||||
def signature
|
||||
return unless @tag.has_signature?
|
||||
end
|
||||
|
||||
def signature_text
|
||||
@signature_data&.fetch(0)
|
||||
end
|
||||
|
||||
def signed_text
|
||||
@signature_data&.fetch(1)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def signature_text_of_message
|
||||
@tag.message.slice(@tag.message.index("-----BEGIN SIGNED MESSAGE-----")..-1)
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
|
||||
def signed_text_of_message
|
||||
%{object #{@tag.target_commit.id}
|
||||
type commit
|
||||
tag #{@tag.name}
|
||||
tagger #{@tag.tagger.name} <#{@tag.tagger.email}> #{@tag.tagger.date.seconds} #{@tag.tagger.timezone}
|
||||
|
||||
#{@tag.message.gsub(/-----BEGIN SIGNED MESSAGE-----(.*)-----END SIGNED MESSAGE-----/m, "")}}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,37 +4,16 @@ require 'digest'
|
|||
|
||||
module Gitlab
|
||||
module X509
|
||||
class Tag
|
||||
class Tag < Gitlab::SignedTag
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
def initialize(raw_tag)
|
||||
@raw_tag = raw_tag
|
||||
end
|
||||
|
||||
def signature
|
||||
signature = X509::Signature.new(signature_text, signed_text, @raw_tag.tagger.email, Time.at(@raw_tag.tagger.date.seconds))
|
||||
strong_memoize(:signature) do
|
||||
super
|
||||
|
||||
return if signature.verified_signature.nil?
|
||||
|
||||
signature
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def signature_text
|
||||
@raw_tag.message.slice(@raw_tag.message.index("-----BEGIN SIGNED MESSAGE-----")..-1)
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
|
||||
def signed_text
|
||||
# signed text is reconstructed as long as there is no specific gitaly function
|
||||
%{object #{@raw_tag.target_commit.id}
|
||||
type commit
|
||||
tag #{@raw_tag.name}
|
||||
tagger #{@raw_tag.tagger.name} <#{@raw_tag.tagger.email}> #{@raw_tag.tagger.date.seconds} #{@raw_tag.tagger.timezone}
|
||||
|
||||
#{@raw_tag.message.gsub(/-----BEGIN SIGNED MESSAGE-----(.*)-----END SIGNED MESSAGE-----/m, "")}}
|
||||
signature = X509::Signature.new(signature_text, signed_text, @tag.tagger.email, Time.at(@tag.tagger.date.seconds))
|
||||
signature unless signature.verified_signature.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2056,6 +2056,9 @@ msgstr ""
|
|||
msgid "Add system hook"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add text to the sign-in page. Markdown enabled."
|
||||
msgstr ""
|
||||
|
||||
msgid "Add to Slack"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2872,9 +2875,6 @@ msgstr ""
|
|||
msgid "After a successful password update, you will be redirected to the login page where you can log in with your new password."
|
||||
msgstr ""
|
||||
|
||||
msgid "After sign-out path"
|
||||
msgstr ""
|
||||
|
||||
msgid "After that, you will not be able to use merge approvals or code quality as well as many other features."
|
||||
msgstr ""
|
||||
|
||||
|
@ -3327,6 +3327,12 @@ msgstr ""
|
|||
msgid "Allow owners to manually add users outside of LDAP"
|
||||
msgstr ""
|
||||
|
||||
msgid "Allow password authentication for Git over HTTP(S)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Allow password authentication for the web interface"
|
||||
msgstr ""
|
||||
|
||||
msgid "Allow project maintainers to configure repository mirroring"
|
||||
msgstr ""
|
||||
|
||||
|
@ -11583,6 +11589,12 @@ msgstr ""
|
|||
msgid "Direct member"
|
||||
msgstr ""
|
||||
|
||||
msgid "Direct non-authenticated users to this page."
|
||||
msgstr ""
|
||||
|
||||
msgid "Direct users to this page after they sign out."
|
||||
msgstr ""
|
||||
|
||||
msgid "Direction"
|
||||
msgstr ""
|
||||
|
||||
|
@ -12275,6 +12287,9 @@ msgstr ""
|
|||
msgid "Enable access to the performance bar for non-administrators in a given group."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable admin mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}."
|
||||
msgstr ""
|
||||
|
||||
|
@ -12296,6 +12311,9 @@ msgstr ""
|
|||
msgid "Enable delayed project deletion by default for newly-created groups."
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable email notification"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enable error tracking"
|
||||
msgstr ""
|
||||
|
||||
|
@ -12410,7 +12428,7 @@ msgstr ""
|
|||
msgid "Enabled Git access protocols"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enabled OAuth sign-in sources"
|
||||
msgid "Enabled OAuth authentication sources"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enabled sources for code import during project creation. OmniAuth must be configured for GitHub"
|
||||
|
@ -12446,6 +12464,12 @@ msgstr ""
|
|||
msgid "Enforce personal access token expiration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enforce two-factor authentication"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enforce two-factor authentication for all user sign-ins."
|
||||
msgstr ""
|
||||
|
||||
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
|
||||
msgstr ""
|
||||
|
||||
|
@ -20544,6 +20568,9 @@ msgstr ""
|
|||
msgid "Maximum time for web terminal websocket connection (in seconds). 0 for unlimited."
|
||||
msgstr ""
|
||||
|
||||
msgid "Maximum time that users are allowed to skip the setup of two-factor authentication (in hours). Set to 0 (zero) to enforce at next sign in."
|
||||
msgstr ""
|
||||
|
||||
msgid "May"
|
||||
msgstr ""
|
||||
|
||||
|
@ -22864,7 +22891,7 @@ msgstr ""
|
|||
msgid "Notifications on"
|
||||
msgstr ""
|
||||
|
||||
msgid "Notify users by email when sign-in location is not recognized"
|
||||
msgid "Notify users by email when sign-in location is not recognized."
|
||||
msgstr ""
|
||||
|
||||
msgid "Nov"
|
||||
|
@ -23952,12 +23979,6 @@ msgstr ""
|
|||
msgid "Password (optional)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Password authentication enabled for Git over HTTP(S)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Password authentication enabled for web interface"
|
||||
msgstr ""
|
||||
|
||||
msgid "Password authentication is unavailable."
|
||||
msgstr ""
|
||||
|
||||
|
@ -28152,7 +28173,7 @@ msgstr ""
|
|||
msgid "Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 or 127.0.0.0/28 are supported. Domain wildcards are not supported currently. Use comma, semicolon, or newline to separate multiple entries. The allowlist can hold a maximum of 1000 entries. Domains should use IDNA encoding. Ex: example.com, 192.168.1.1, 127.0.0.0/28, xn--itlab-j1a.com."
|
||||
msgstr ""
|
||||
|
||||
msgid "Require additional authentication for administrative tasks"
|
||||
msgid "Require additional authentication for administrative tasks."
|
||||
msgstr ""
|
||||
|
||||
msgid "Require all users in this group to setup Two-factor authentication"
|
||||
|
@ -28161,9 +28182,6 @@ msgstr ""
|
|||
msgid "Require all users in this group to setup two-factor authentication"
|
||||
msgstr ""
|
||||
|
||||
msgid "Require all users to set up two-factor authentication"
|
||||
msgstr ""
|
||||
|
||||
msgid "Required approvals (%{approvals_given} given)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -30219,10 +30237,10 @@ msgstr ""
|
|||
msgid "Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan."
|
||||
msgstr ""
|
||||
|
||||
msgid "Set requirements for a user to sign-in. Enable mandatory two-factor authentication."
|
||||
msgid "Set severity"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set severity"
|
||||
msgid "Set sign-in restrictions for all users."
|
||||
msgstr ""
|
||||
|
||||
msgid "Set size limits for displaying diffs in the browser."
|
||||
|
@ -30661,6 +30679,9 @@ msgstr ""
|
|||
msgid "Sign-in text"
|
||||
msgstr ""
|
||||
|
||||
msgid "Sign-out page URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Sign-up restrictions"
|
||||
msgstr ""
|
||||
|
||||
|
@ -35191,7 +35212,7 @@ msgstr ""
|
|||
msgid "Two-factor authentication is not enabled for this user"
|
||||
msgstr ""
|
||||
|
||||
msgid "Two-factor grace period (hours)"
|
||||
msgid "Two-factor grace period"
|
||||
msgstr ""
|
||||
|
||||
msgid "Type"
|
||||
|
@ -37016,12 +37037,6 @@ msgstr ""
|
|||
msgid "We will notify %{inviter} that you declined their invitation to join GitLab. You will stop receiving reminders."
|
||||
msgstr ""
|
||||
|
||||
msgid "We will redirect non-logged in users to this page"
|
||||
msgstr ""
|
||||
|
||||
msgid "We will redirect users to this page after they sign out"
|
||||
msgstr ""
|
||||
|
||||
msgid "We would like to inform you that your subscription GitLab Enterprise Edition %{plan_name} is nearing its user limit. You have %{active_user_count} active users, which is almost at the user limit of %{maximum_user_count}."
|
||||
msgstr ""
|
||||
|
||||
|
@ -37298,7 +37313,7 @@ msgstr ""
|
|||
msgid "When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong."
|
||||
msgstr ""
|
||||
|
||||
msgid "When disabled, an external authentication provider must be used."
|
||||
msgid "When inactive, an external authentication provider must be used."
|
||||
msgstr ""
|
||||
|
||||
msgid "When leaving the URL blank, classification labels can still be specified without disabling cross project features or performing external authorization checks."
|
||||
|
|
|
@ -24,19 +24,4 @@ RSpec.describe ::Gitlab::Ci::Config::Entry::Inherit::Variables do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#inherit?' do
|
||||
where(:config, :inherit) do
|
||||
true | true
|
||||
false | false
|
||||
%w[A] | true
|
||||
%w[B] | false
|
||||
end
|
||||
|
||||
with_them do
|
||||
it do
|
||||
expect(subject.inherit?('A')).to eq(inherit)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -87,12 +87,18 @@ RSpec.describe Gitlab::EtagCaching::Router::Restful do
|
|||
end
|
||||
|
||||
it 'matches the environments path' do
|
||||
result = match_route('/my-group/my-project/environments.json')
|
||||
result = match_route('/my-group/my-project/-/environments.json')
|
||||
|
||||
expect(result).to be_present
|
||||
expect(result.name).to eq 'environments'
|
||||
end
|
||||
|
||||
it 'does not match the operations environments list path' do
|
||||
result = match_route('/-/operations/environments.json')
|
||||
|
||||
expect(result).not_to be_present
|
||||
end
|
||||
|
||||
it 'matches pipeline#show endpoint' do
|
||||
result = match_route('/my-group/my-project/-/pipelines/2.json')
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
|
|||
it { expect(tag.tagger.timezone).to eq("+0200") }
|
||||
end
|
||||
|
||||
describe 'signed tag' do
|
||||
shared_examples 'signed tag' do
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:tag) { project.repository.find_tag('v1.1.1') }
|
||||
|
||||
|
@ -54,6 +54,18 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
|
|||
it { expect(tag.tagger.timezone).to eq("+0100") }
|
||||
end
|
||||
|
||||
context 'with :get_tag_signatures enabled' do
|
||||
it_behaves_like 'signed tag'
|
||||
end
|
||||
|
||||
context 'with :get_tag_signatures disabled' do
|
||||
before do
|
||||
stub_feature_flags(get_tag_signatures: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'signed tag'
|
||||
end
|
||||
|
||||
it { expect(repository.tags.size).to eq(SeedRepo::Repo::TAGS.size) }
|
||||
end
|
||||
|
||||
|
@ -77,6 +89,75 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.extract_signature_lazily' do
|
||||
let(:project) { create(:project, :repository) }
|
||||
|
||||
subject { described_class.extract_signature_lazily(project.repository, tag_id).itself }
|
||||
|
||||
context 'when the tag is signed' do
|
||||
let(:tag_id) { project.repository.find_tag('v1.1.1').id }
|
||||
|
||||
it 'returns signature and signed text' do
|
||||
signature, signed_text = subject
|
||||
|
||||
expect(signature).to eq(X509Helpers::User1.signed_tag_signature.chomp)
|
||||
expect(signature).to be_a_binary_string
|
||||
expect(signed_text).to eq(X509Helpers::User1.signed_tag_base_data)
|
||||
expect(signed_text).to be_a_binary_string
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the tag has no signature' do
|
||||
let(:tag_id) { project.repository.find_tag('v1.0.0').id }
|
||||
|
||||
it 'returns empty signature and message as signed text' do
|
||||
signature, signed_text = subject
|
||||
|
||||
expect(signature).to be_empty
|
||||
expect(signed_text).to eq(X509Helpers::User1.unsigned_tag_base_data)
|
||||
expect(signed_text).to be_a_binary_string
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the tag cannot be found' do
|
||||
let(:tag_id) { Gitlab::Git::BLANK_SHA }
|
||||
|
||||
it 'raises GRPC::Internal' do
|
||||
expect { subject }.to raise_error(GRPC::Internal)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the tag ID is invalid' do
|
||||
let(:tag_id) { '4b4918a572fa86f9771e5ba40fbd48e' }
|
||||
|
||||
it 'raises GRPC::Internal' do
|
||||
expect { subject }.to raise_error(GRPC::Internal)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when loading signatures in batch once' do
|
||||
it 'fetches signatures in batch once' do
|
||||
tag_ids = [project.repository.find_tag('v1.1.1').id, project.repository.find_tag('v1.0.0').id]
|
||||
signatures = tag_ids.map do |tag_id|
|
||||
described_class.extract_signature_lazily(repository, tag_id)
|
||||
end
|
||||
|
||||
other_repository = double(:repository)
|
||||
described_class.extract_signature_lazily(other_repository, tag_ids.first)
|
||||
|
||||
expect(described_class).to receive(:batch_signature_extraction)
|
||||
.with(repository, tag_ids)
|
||||
.once
|
||||
.and_return({})
|
||||
|
||||
expect(described_class).not_to receive(:batch_signature_extraction)
|
||||
.with(other_repository, tag_ids.first)
|
||||
|
||||
2.times { signatures.each(&:itself) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'tag into from Gitaly tag' do
|
||||
context 'message_size != message.size' do
|
||||
let(:gitaly_tag) { build(:gitaly_tag, message: ''.b, message_size: message_size) }
|
||||
|
|
|
@ -178,6 +178,17 @@ RSpec.describe Gitlab::GitalyClient::RefService do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#get_tag_signatures' do
|
||||
it 'sends a get_tag_signatures message' do
|
||||
expect_any_instance_of(Gitaly::RefService::Stub)
|
||||
.to receive(:get_tag_signatures)
|
||||
.with(gitaly_request_with_params(tag_revisions: ['some_tag_id']), kind_of(Hash))
|
||||
.and_return([])
|
||||
|
||||
client.get_tag_signatures(['some_tag_id'])
|
||||
end
|
||||
end
|
||||
|
||||
describe '#find_ref_name', :seed_helper do
|
||||
subject { client.find_ref_name(SeedRepo::Commit::ID, 'refs/heads/master') }
|
||||
|
||||
|
|
|
@ -87,6 +87,24 @@ RSpec.describe Gitlab::UsageDataMetrics do
|
|||
])
|
||||
end
|
||||
|
||||
it 'includes terraform monthly key' do
|
||||
expect(subject[:redis_hll_counters][:terraform].keys).to include(:p_terraform_state_api_unique_users_monthly)
|
||||
end
|
||||
|
||||
it 'includes terraform monthly and weekly keys' do
|
||||
expect(subject[:redis_hll_counters][:pipeline_authoring].keys).to contain_exactly(*[
|
||||
:o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly, :o_pipeline_authoring_unique_users_committing_ciconfigfile_weekly,
|
||||
:o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_monthly, :o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile_weekly,
|
||||
:pipeline_authoring_total_unique_counts_monthly, :pipeline_authoring_total_unique_counts_weekly
|
||||
])
|
||||
end
|
||||
|
||||
it 'includes users_expanding_secure_security_report monthly and weekly keys' do
|
||||
expect(subject[:redis_hll_counters][:secure].keys).to contain_exactly(*[
|
||||
:users_expanding_secure_security_report_monthly, :users_expanding_secure_security_report_weekly
|
||||
])
|
||||
end
|
||||
|
||||
it 'includes issues_edit monthly and weekly keys' do
|
||||
expect(subject[:redis_hll_counters][:issues_edit].keys).to include(
|
||||
:g_project_management_issue_title_changed_monthly, :g_project_management_issue_title_changed_weekly,
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::X509::Tag do
|
||||
subject(:signature) { described_class.new(tag).signature }
|
||||
subject(:signature) { described_class.new(project.repository, tag).signature }
|
||||
|
||||
describe '#signature' do
|
||||
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '', 'group/project') }
|
||||
let(:project) { create(:project, :repository) }
|
||||
|
||||
describe 'signed tag' do
|
||||
shared_examples 'signed tag' do
|
||||
let(:tag) { project.repository.find_tag('v1.1.1') }
|
||||
let(:certificate_attributes) do
|
||||
{
|
||||
|
@ -33,10 +33,24 @@ RSpec.describe Gitlab::X509::Tag do
|
|||
it { expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes) }
|
||||
end
|
||||
|
||||
context 'unsigned tag' do
|
||||
shared_examples 'unsigned tag' do
|
||||
let(:tag) { project.repository.find_tag('v1.0.0') }
|
||||
|
||||
it { expect(signature).to be_nil }
|
||||
end
|
||||
|
||||
context 'with :get_tag_signatures enabled' do
|
||||
it_behaves_like 'signed tag'
|
||||
it_behaves_like 'unsigned tag'
|
||||
end
|
||||
|
||||
context 'with :get_tag_signatures disabled' do
|
||||
before do
|
||||
stub_feature_flags(get_tag_signatures: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'signed tag'
|
||||
it_behaves_like 'unsigned tag'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Analytics::CycleAnalytics::StageEventHash, type: :model do
|
||||
let(:stage_event_hash) { described_class.create!(hash_sha256: hash_sha256) }
|
||||
let(:hash_sha256) { 'does_not_matter' }
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to have_many(:cycle_analytics_project_stages) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to validate_presence_of(:hash_sha256) }
|
||||
end
|
||||
|
||||
describe '.record_id_by_hash_sha256' do
|
||||
it 'returns an existing id' do
|
||||
id = stage_event_hash.id
|
||||
same_id = described_class.record_id_by_hash_sha256(hash_sha256)
|
||||
|
||||
expect(same_id).to eq(id)
|
||||
end
|
||||
|
||||
it 'creates a new record' do
|
||||
expect do
|
||||
described_class.record_id_by_hash_sha256(hash_sha256)
|
||||
end.to change { described_class.count }.from(0).to(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.cleanup_if_unused' do
|
||||
it 'removes the record' do
|
||||
described_class.cleanup_if_unused(stage_event_hash.id)
|
||||
|
||||
expect(described_class.find_by_id(stage_event_hash.id)).to be_nil
|
||||
end
|
||||
|
||||
it 'does not remove the record' do
|
||||
id = create(:cycle_analytics_project_stage).stage_event_hash_id
|
||||
|
||||
described_class.cleanup_if_unused(id)
|
||||
|
||||
expect(described_class.find_by_id(id)).not_to be_nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -840,6 +840,8 @@ RSpec.describe ProjectPolicy do
|
|||
it { is_expected.to be_allowed(:read_package) }
|
||||
it { is_expected.to be_allowed(:read_project) }
|
||||
it { is_expected.to be_disallowed(:create_package) }
|
||||
|
||||
it_behaves_like 'package access with repository disabled'
|
||||
end
|
||||
|
||||
context 'a deploy token with write_package_registry scope' do
|
||||
|
@ -849,6 +851,8 @@ RSpec.describe ProjectPolicy do
|
|||
it { is_expected.to be_allowed(:read_package) }
|
||||
it { is_expected.to be_allowed(:read_project) }
|
||||
it { is_expected.to be_disallowed(:destroy_package) }
|
||||
|
||||
it_behaves_like 'package access with repository disabled'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1021,18 +1025,7 @@ RSpec.describe ProjectPolicy do
|
|||
|
||||
it { is_expected.to be_allowed(:read_package) }
|
||||
|
||||
context 'when repository is disabled' do
|
||||
before do
|
||||
project.project_feature.update!(
|
||||
# Disable merge_requests and builds as well, since merge_requests and
|
||||
# builds cannot have higher visibility than repository.
|
||||
merge_requests_access_level: ProjectFeature::DISABLED,
|
||||
builds_access_level: ProjectFeature::DISABLED,
|
||||
repository_access_level: ProjectFeature::DISABLED)
|
||||
end
|
||||
|
||||
it { is_expected.to be_disallowed(:read_package) }
|
||||
end
|
||||
it_behaves_like 'package access with repository disabled'
|
||||
end
|
||||
|
||||
context 'with owner' do
|
||||
|
|
|
@ -217,6 +217,15 @@ RSpec.describe API::MavenPackages do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples 'successfully returning the file' do
|
||||
it 'returns the file', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v4/packages/maven/*path/:file_name' do
|
||||
context 'a public project' do
|
||||
subject { download_file(file_name: package_file.file_name) }
|
||||
|
@ -224,12 +233,7 @@ RSpec.describe API::MavenPackages do
|
|||
shared_examples 'getting a file' do
|
||||
it_behaves_like 'tracking the file download event'
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'returns sha1 of the file' do
|
||||
download_file(file_name: package_file.file_name + '.sha1')
|
||||
|
@ -260,12 +264,7 @@ RSpec.describe API::MavenPackages do
|
|||
shared_examples 'getting a file' do
|
||||
it_behaves_like 'tracking the file download event'
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'denies download when no private token' do
|
||||
download_file(file_name: package_file.file_name)
|
||||
|
@ -297,12 +296,7 @@ RSpec.describe API::MavenPackages do
|
|||
shared_examples 'getting a file' do
|
||||
it_behaves_like 'tracking the file download event'
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'denies download when not enough permissions' do
|
||||
unless project.root_namespace == user.namespace
|
||||
|
@ -409,12 +403,7 @@ RSpec.describe API::MavenPackages do
|
|||
shared_examples 'getting a file for a group' do
|
||||
it_behaves_like 'tracking the file download event'
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'returns sha1 of the file' do
|
||||
download_file(file_name: package_file.file_name + '.sha1')
|
||||
|
@ -445,12 +434,7 @@ RSpec.describe API::MavenPackages do
|
|||
shared_examples 'getting a file for a group' do
|
||||
it_behaves_like 'tracking the file download event'
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'denies download when no private token' do
|
||||
download_file(file_name: package_file.file_name)
|
||||
|
@ -482,12 +466,7 @@ RSpec.describe API::MavenPackages do
|
|||
shared_examples 'getting a file for a group' do
|
||||
it_behaves_like 'tracking the file download event'
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'denies download when not enough permissions' do
|
||||
group.add_guest(user)
|
||||
|
@ -516,12 +495,7 @@ RSpec.describe API::MavenPackages do
|
|||
context 'with group deploy token' do
|
||||
subject { download_file_with_token(file_name: package_file.file_name, request_headers: group_deploy_token_headers) }
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'returns the file with only write_package_registry scope' do
|
||||
deploy_token_for_group.update!(read_package_registry: false)
|
||||
|
@ -553,12 +527,7 @@ RSpec.describe API::MavenPackages do
|
|||
group.add_reporter(user)
|
||||
end
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
context 'with a non existing maven path' do
|
||||
subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3', request_headers: headers_with_token, group_id: root_group.id) }
|
||||
|
@ -657,12 +626,7 @@ RSpec.describe API::MavenPackages do
|
|||
|
||||
it_behaves_like 'tracking the file download event'
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'returns sha1 of the file' do
|
||||
download_file(file_name: package_file.file_name + '.sha1')
|
||||
|
@ -672,6 +636,19 @@ RSpec.describe API::MavenPackages do
|
|||
expect(response.body).to eq(package_file.file_sha1)
|
||||
end
|
||||
|
||||
context 'when the repository is disabled' do
|
||||
before do
|
||||
project.project_feature.update!(
|
||||
# Disable merge_requests and builds as well, since merge_requests and
|
||||
# builds cannot have higher visibility than repository.
|
||||
merge_requests_access_level: ProjectFeature::DISABLED,
|
||||
builds_access_level: ProjectFeature::DISABLED,
|
||||
repository_access_level: ProjectFeature::DISABLED)
|
||||
end
|
||||
|
||||
it_behaves_like 'successfully returning the file'
|
||||
end
|
||||
|
||||
context 'with a non existing maven path' do
|
||||
subject { download_file(file_name: package_file.file_name, path: 'foo/bar/1.2.3') }
|
||||
|
||||
|
@ -688,12 +665,7 @@ RSpec.describe API::MavenPackages do
|
|||
|
||||
it_behaves_like 'tracking the file download event'
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
it_behaves_like 'successfully returning the file'
|
||||
|
||||
it 'denies download when not enough permissions' do
|
||||
project.add_guest(user)
|
||||
|
|
|
@ -290,6 +290,17 @@ module X509Helpers
|
|||
SIGNEDDATA
|
||||
end
|
||||
|
||||
def unsigned_tag_base_data
|
||||
<<~SIGNEDDATA
|
||||
object 6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9
|
||||
type commit
|
||||
tag v1.0.0
|
||||
tagger Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> 1393491299 +0200
|
||||
|
||||
Release
|
||||
SIGNEDDATA
|
||||
end
|
||||
|
||||
def certificate_crl
|
||||
'http://ch.siemens.com/pki?ZZZZZZA2.crl'
|
||||
end
|
||||
|
|
|
@ -13,6 +13,7 @@ RSpec.shared_examples 'value stream analytics stage' do
|
|||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:end_event_label) }
|
||||
it { is_expected.to belong_to(:start_event_label) }
|
||||
it { is_expected.to belong_to(:stage_event_hash) }
|
||||
end
|
||||
|
||||
describe 'validation' do
|
||||
|
@ -138,6 +139,67 @@ RSpec.shared_examples 'value stream analytics stage' do
|
|||
expect(stage_1.events_hash_code).not_to eq(stage_2.events_hash_code)
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop: disable Rails/SaveBang
|
||||
describe '#event_hash' do
|
||||
it 'associates the same stage event hash record' do
|
||||
first = create(factory)
|
||||
second = create(factory)
|
||||
|
||||
expect(first.stage_event_hash_id).to eq(second.stage_event_hash_id)
|
||||
end
|
||||
|
||||
it 'does not introduce duplicated stage event hash records' do
|
||||
expect do
|
||||
create(factory)
|
||||
create(factory)
|
||||
end.to change { Analytics::CycleAnalytics::StageEventHash.count }.from(0).to(1)
|
||||
end
|
||||
|
||||
it 'creates different hash record for different event configurations' do
|
||||
expect do
|
||||
create(factory, start_event_identifier: :issue_created, end_event_identifier: :issue_first_mentioned_in_commit)
|
||||
create(factory, start_event_identifier: :merge_request_created, end_event_identifier: :merge_request_merged)
|
||||
end.to change { Analytics::CycleAnalytics::StageEventHash.count }.from(0).to(2)
|
||||
end
|
||||
|
||||
context 'when the stage event hash changes' do
|
||||
let(:stage) { create(factory, start_event_identifier: :merge_request_created, end_event_identifier: :merge_request_merged) }
|
||||
|
||||
it 'deletes the old, unused stage event hash record' do
|
||||
old_stage_event_hash = stage.stage_event_hash
|
||||
|
||||
stage.update!(end_event_identifier: :merge_request_first_deployed_to_production)
|
||||
|
||||
expect(stage.stage_event_hash_id).not_to eq(old_stage_event_hash.id)
|
||||
|
||||
old_stage_event_hash_from_db = Analytics::CycleAnalytics::StageEventHash.find_by_id(old_stage_event_hash.id)
|
||||
expect(old_stage_event_hash_from_db).to be_nil
|
||||
end
|
||||
|
||||
it 'does not delete used stage event hash record' do
|
||||
other_stage = create(factory, start_event_identifier: :merge_request_created, end_event_identifier: :merge_request_merged)
|
||||
|
||||
stage.update!(end_event_identifier: :merge_request_first_deployed_to_production)
|
||||
|
||||
expect(stage.stage_event_hash_id).not_to eq(other_stage.stage_event_hash_id)
|
||||
|
||||
old_stage_event_hash_from_db = Analytics::CycleAnalytics::StageEventHash.find_by_id(other_stage.stage_event_hash_id)
|
||||
expect(old_stage_event_hash_from_db).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the stage events hash code does not change' do
|
||||
it 'does not trigger extra query on save' do
|
||||
stage = create(factory, start_event_identifier: :merge_request_created, end_event_identifier: :merge_request_merged)
|
||||
|
||||
expect(Analytics::CycleAnalytics::StageEventHash).not_to receive(:record_id_by_hash_sha256)
|
||||
|
||||
stage.update!(name: 'new title')
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop: enable Rails/SaveBang
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'value stream analytics label based stage' do
|
||||
|
|
|
@ -330,3 +330,18 @@ RSpec.shared_examples 'project policies as admin without admin mode' do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'package access with repository disabled' do
|
||||
context 'when repository is disabled' do
|
||||
before do
|
||||
project.project_feature.update!(
|
||||
# Disable merge_requests and builds as well, since merge_requests and
|
||||
# builds cannot have higher visibility than repository.
|
||||
merge_requests_access_level: ProjectFeature::DISABLED,
|
||||
builds_access_level: ProjectFeature::DISABLED,
|
||||
repository_access_level: ProjectFeature::DISABLED)
|
||||
end
|
||||
|
||||
it { is_expected.to be_allowed(:read_package) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,10 @@ RSpec.describe WebHookWorker do
|
|||
subject.perform(project_hook.id, data, hook_name)
|
||||
end
|
||||
|
||||
it 'does not error when the WebHook record cannot be found' do
|
||||
expect { subject.perform(non_existing_record_id, data, hook_name) }.not_to raise_error
|
||||
end
|
||||
|
||||
it_behaves_like 'worker with data consistency',
|
||||
described_class,
|
||||
data_consistency: :delayed
|
||||
|
|
|
@ -5,9 +5,10 @@ require 'gitlab'
|
|||
require 'test_file_finder'
|
||||
|
||||
gitlab_token = ENV.fetch('DANGER_GITLAB_API_TOKEN', '')
|
||||
gitlab_endpoint = ENV.fetch('CI_API_V4_URL')
|
||||
|
||||
Gitlab.configure do |config|
|
||||
config.endpoint = 'https://gitlab.com/api/v4'
|
||||
config.endpoint = gitlab_endpoint
|
||||
config.private_token = gitlab_token
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue