Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-12-12 00:30:01 +00:00
parent 487534426d
commit 776296b3e0
64 changed files with 543 additions and 68 deletions

View File

@ -742,4 +742,4 @@ gem 'paper_trail', '~> 15.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem "i18n_data", "~> 0.13.1", feature_category: :system_access
gem "gitlab-cloud-connector", "~> 0.2.1", require: 'cloud_connector', feature_category: :cloud_connector
gem "gitlab-cloud-connector", "~> 0.2.5", require: 'cloud_connector', feature_category: :cloud_connector

View File

@ -222,7 +222,7 @@
{"name":"gitaly","version":"17.5.0.pre.rc42","platform":"ruby","checksum":"15469230245c5d83f09c6e057ae1088ce87133ff156086bf02a2b8b2ec24e817"},
{"name":"gitlab","version":"4.19.0","platform":"ruby","checksum":"3f645e3e195dbc24f0834fbf83e8ccfb2056d8e9712b01a640aad418a6949679"},
{"name":"gitlab-chronic","version":"0.10.5","platform":"ruby","checksum":"f80f18dc699b708870a80685243331290bc10cfeedb6b99c92219722f729c875"},
{"name":"gitlab-cloud-connector","version":"0.2.3","platform":"ruby","checksum":"89bc5ebf00c6421f6bc7276a8c598357faebf73769efac47064fa991394603cb"},
{"name":"gitlab-cloud-connector","version":"0.2.5","platform":"ruby","checksum":"ff9ec4032c61b4354948a8d06d4f46b757fa3658c8dc5ddc6eb5175053be643a"},
{"name":"gitlab-dangerfiles","version":"4.8.0","platform":"ruby","checksum":"b327d079552ec974a63bf34d749a0308425af6ebf51d01064f1a6ff216a523db"},
{"name":"gitlab-experiment","version":"0.9.1","platform":"ruby","checksum":"f230ee742154805a755d5f2539dc44d93cdff08c5bbbb7656018d61f93d01f48"},
{"name":"gitlab-fog-azure-rm","version":"2.2.0","platform":"ruby","checksum":"31aa7c2170f57874053144e7f716ec9e15f32e71ffbd2c56753dce46e2e78ba9"},

View File

@ -726,7 +726,7 @@ GEM
terminal-table (>= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
gitlab-cloud-connector (0.2.3)
gitlab-cloud-connector (0.2.5)
activesupport (~> 7.0)
jwt (~> 2.9.3)
gitlab-dangerfiles (4.8.0)
@ -2068,7 +2068,7 @@ DEPENDENCIES
gitaly (~> 17.5.0.pre.rc1)
gitlab-backup-cli!
gitlab-chronic (~> 0.10.5)
gitlab-cloud-connector (~> 0.2.1)
gitlab-cloud-connector (~> 0.2.5)
gitlab-dangerfiles (~> 4.8.0)
gitlab-duo-workflow-service-client (~> 0.1)!
gitlab-experiment (~> 0.9.1)

View File

@ -223,7 +223,7 @@
{"name":"gitaly","version":"17.5.0.pre.rc42","platform":"ruby","checksum":"15469230245c5d83f09c6e057ae1088ce87133ff156086bf02a2b8b2ec24e817"},
{"name":"gitlab","version":"4.19.0","platform":"ruby","checksum":"3f645e3e195dbc24f0834fbf83e8ccfb2056d8e9712b01a640aad418a6949679"},
{"name":"gitlab-chronic","version":"0.10.5","platform":"ruby","checksum":"f80f18dc699b708870a80685243331290bc10cfeedb6b99c92219722f729c875"},
{"name":"gitlab-cloud-connector","version":"0.2.3","platform":"ruby","checksum":"89bc5ebf00c6421f6bc7276a8c598357faebf73769efac47064fa991394603cb"},
{"name":"gitlab-cloud-connector","version":"0.2.5","platform":"ruby","checksum":"ff9ec4032c61b4354948a8d06d4f46b757fa3658c8dc5ddc6eb5175053be643a"},
{"name":"gitlab-dangerfiles","version":"4.8.0","platform":"ruby","checksum":"b327d079552ec974a63bf34d749a0308425af6ebf51d01064f1a6ff216a523db"},
{"name":"gitlab-experiment","version":"0.9.1","platform":"ruby","checksum":"f230ee742154805a755d5f2539dc44d93cdff08c5bbbb7656018d61f93d01f48"},
{"name":"gitlab-fog-azure-rm","version":"2.2.0","platform":"ruby","checksum":"31aa7c2170f57874053144e7f716ec9e15f32e71ffbd2c56753dce46e2e78ba9"},

View File

@ -736,7 +736,7 @@ GEM
terminal-table (>= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
gitlab-cloud-connector (0.2.3)
gitlab-cloud-connector (0.2.5)
activesupport (~> 7.0)
jwt (~> 2.9.3)
gitlab-dangerfiles (4.8.0)
@ -2096,7 +2096,7 @@ DEPENDENCIES
gitaly (~> 17.5.0.pre.rc1)
gitlab-backup-cli!
gitlab-chronic (~> 0.10.5)
gitlab-cloud-connector (~> 0.2.1)
gitlab-cloud-connector (~> 0.2.5)
gitlab-dangerfiles (~> 4.8.0)
gitlab-duo-workflow-service-client (~> 0.1)!
gitlab-experiment (~> 0.9.1)

View File

@ -37,6 +37,20 @@ class Admin::ImpersonationTokensController < Admin::ApplicationController
redirect_to admin_user_impersonation_tokens_path
end
def rotate
token = finder.find(params.permit(:id)[:id])
result = PersonalAccessTokens::RotateService.new(current_user, token, nil, keep_token_lifetime: true).execute
@impersonation_token = result.payload[:personal_access_token]
if result.success?
active_access_tokens = active_impersonation_tokens
render json: { new_token: @impersonation_token.token,
active_access_tokens: active_access_tokens, total: active_access_tokens.length }, status: :ok
else
render json: { message: result.message }, status: :unprocessable_entity
end
end
private
# rubocop: disable CodeReuse/ActiveRecord

View File

@ -9,6 +9,7 @@ module Ci
include ::Gitlab::ExclusiveLeaseHelpers
include ::Gitlab::OptimisticLocking
before_validation :set_project_id, on: :create
belongs_to :build,
->(trace_chunks) { in_partition(trace_chunks) },
class_name: 'Ci::Build',
@ -322,5 +323,9 @@ module Ci
def metrics
@metrics ||= ::Gitlab::Ci::Trace::Metrics.new
end
def set_project_id
self.project_id ||= build&.project_id
end
end
end

View File

@ -7,6 +7,26 @@ module Projects
belongs_to :protected_branch, optional: false
belongs_to :project, optional: false
validates :protected_branch, uniqueness: true
validate :validate_protected_branch_not_wildcard
validate :validate_protected_branch_belongs_to_project
private
def validate_protected_branch_not_wildcard
return unless protected_branch&.wildcard?
errors.add(:protected_branch, 'cannot be a wildcard')
end
def validate_protected_branch_belongs_to_project
return unless protected_branch && project
return if protected_branch.project_id == project.id
errors.add(:protected_branch, 'must belong to project')
end
end
end
end

View File

@ -7,5 +7,9 @@ class ImpersonationAccessTokenEntity < AccessTokenEntityBase
expose :revoke_path do |token, _options|
revoke_admin_user_impersonation_token_path(token.user, token)
end
expose :rotate_path do |token, _options|
rotate_admin_user_impersonation_token_path(token.user, token)
end
end
# rubocop: enable Gitlab/NamespacedClass

View File

@ -7,6 +7,7 @@ namespace :admin do
resources :impersonation_tokens, only: [:index, :create] do
member do
put :revoke
put :rotate
end
end

View File

@ -0,0 +1,14 @@
- title: "Rename 'setPreReceiveSecretDetection' GraphQL mutation to 'setSecretPushProtection'"
removal_milestone: "18.0"
announcement_milestone: "17.7"
breaking_change: true
window: 1
reporter: smeadzinger
stage: application_security_testing
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/462504
impact: low
scope: project
resolution_role: Maintainer
manual_task: true
body: |
The 'setPreReceiveSecretDetection' GraphQL mutation has been renamed to 'setSecretPushProtection'.

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillCiBuildTraceChunksProjectId
description: Backfills sharding key `ci_build_trace_chunks.project_id` from `p_ci_builds`.
feature_category: continuous_integration
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/173767
milestone: '17.7'
queued_migration_version: 20241125174339
finalize_after: '2025-01-07'
finalized_by: # version of the migration that finalized this BBM

View File

@ -18,4 +18,5 @@ desired_sharding_key:
sharding_key: project_id
belongs_to: build
foreign_key_name: fk_89e29fa5ee_p
desired_sharding_key_migration_job_name: BackfillCiBuildTraceChunksProjectId
table_size: small

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddProjectIdToCiBuildTraceChunks < Gitlab::Database::Migration[2.2]
milestone '17.7'
def change
add_column :ci_build_trace_chunks, :project_id, :bigint
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class IndexCiBuildTraceChunksOnProjectId < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '17.7'
TABLE_NAME = :ci_build_trace_chunks
INDEX_NAME = :index_ci_build_trace_chunks_on_project_id
def up
add_concurrent_index TABLE_NAME, :project_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
end
end

View File

@ -0,0 +1,43 @@
# frozen_string_literal: true
class QueueBackfillCiBuildTraceChunksProjectId < Gitlab::Database::Migration[2.2]
milestone '17.7'
restrict_gitlab_migration gitlab_schema: :gitlab_ci
MIGRATION = "BackfillCiBuildTraceChunksProjectId"
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 25_000
SUB_BATCH_SIZE = 150
def up
queue_batched_background_migration(
MIGRATION,
:ci_build_trace_chunks,
:id,
:project_id,
:p_ci_builds,
:project_id,
:build_id,
:partition_id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(
MIGRATION,
:ci_build_trace_chunks,
:id,
[
:project_id,
:p_ci_builds,
:project_id,
:build_id,
:partition_id
]
)
end
end

View File

@ -0,0 +1 @@
8193001cd4609fdc32ac2e3061ab8fd9235fa0a71ebdda68d110636c9f570193

View File

@ -0,0 +1 @@
4df098efee1737b5564cfb98ec12e0942c09c0ff4e4f3d6d41c1ee68526964fd

View File

@ -0,0 +1 @@
e443903155eaabdaa0f0aa7962c8079e037bddcbb57b47243168484f39e48c50

View File

@ -9054,7 +9054,8 @@ CREATE TABLE ci_build_trace_chunks (
checksum bytea,
lock_version integer DEFAULT 0 NOT NULL,
build_id bigint NOT NULL,
partition_id bigint NOT NULL
partition_id bigint NOT NULL,
project_id bigint
);
CREATE SEQUENCE ci_build_trace_chunks_id_seq
@ -29696,6 +29697,8 @@ CREATE UNIQUE INDEX index_ci_build_trace_chunks_on_build_id_and_chunk_index ON c
CREATE INDEX index_ci_build_trace_chunks_on_partition_id_build_id ON ci_build_trace_chunks USING btree (partition_id, build_id);
CREATE INDEX index_ci_build_trace_chunks_on_project_id ON ci_build_trace_chunks USING btree (project_id);
CREATE INDEX p_ci_builds_metadata_build_id_idx ON ONLY p_ci_builds_metadata USING btree (build_id) WHERE (has_exposed_artifacts IS TRUE);
CREATE INDEX index_ci_builds_metadata_on_build_id_and_has_exposed_artifacts ON ci_builds_metadata USING btree (build_id) WHERE (has_exposed_artifacts IS TRUE);

View File

@ -40,6 +40,7 @@ This window takes place on April 21 - 23, 2025 from 09:00 UTC to 22:00 UTC.
| [Deprecate CI job implementation of Repository X-Ray](https://gitlab.com/gitlab-org/gitlab/-/issues/500146) | Low | Create | Project |
| [Pipeline job limits extended to the Commits API](https://gitlab.com/gitlab-org/gitlab/-/issues/436361) | Low | Verify | Project |
| [Deprecation of `name` field in `ProjectMonthlyUsageType` GraphQL API](https://gitlab.com/gitlab-org/gitlab/-/issues/381894) | Low | Fulfillment | Project |
| [Rename 'setPreReceiveSecretDetection' GraphQL mutation to 'setSecretPushProtection'](https://gitlab.com/gitlab-org/gitlab/-/issues/462504) | Low | Application_security_testing | Project |
| [Deprecation of `STORAGE` enum in `NamespaceProjectSortEnum` GraphQL API](https://gitlab.com/gitlab-org/gitlab/-/issues/396284) | Low | Fulfillment | Group |
## Window 2

View File

@ -934,6 +934,22 @@ The `previousStageJobsOrNeeds` field in GraphQL will be removed as it has been r
<div class="deprecation breaking-change" data-milestone="18.0">
### Rename 'setPreReceiveSecretDetection' GraphQL mutation to 'setSecretPushProtection'
<div class="deprecation-notes">
- Announced in GitLab <span class="milestone">17.7</span>
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/462504).
</div>
The 'setPreReceiveSecretDetection' GraphQL mutation has been renamed to 'setSecretPushProtection'.
</div>
<div class="deprecation breaking-change" data-milestone="18.0">
### Rename options to skip GitGuardian secret detection
<div class="deprecation-notes">

View File

@ -51,5 +51,5 @@ remediation.
All GitLab application security scanning tools can be run in a CI/CD pipeline, triggered by code
changes. Security scans can also be run on a schedule, outside the context of code changes, and some
can be run manually. It's important to perform detection outside the CI/CD pipeline because risks
arise outside the context of code changes. For example, a newly-discovered vulnerability in a
dependency may be a risk to any application using it.
can arise outside the context of code changes. For example, a newly-discovered vulnerability in a
dependency might be a risk to any application using it.

View File

@ -19,8 +19,8 @@ GitLab can check your application for security vulnerabilities including:
For a click-through demo, see [Integrating security to the pipeline](https://gitlab.navattic.com/gitlab-scans).
<!-- Demo published on 2024-01-15 -->
For details of what GitLab security scanners can detect and how they cover application's development
lifecycle see [Detect](detect/index.md).
For details of how vulnerabilities are detected throughout your application's development lifecycle
see [Detect](detect/index.md).
Statistics and details on vulnerabilities are included in the merge request. Providing
actionable information _before_ changes are merged enables you to be proactive.

View File

@ -28,17 +28,17 @@ module Banzai
Filter::AttributesFilter,
Filter::VideoLinkFilter,
Filter::AudioLinkFilter,
Filter::ImageLazyLoadFilter,
Filter::ImageLinkFilter,
Filter::TableOfContentsLegacyFilter,
Filter::TableOfContentsTagLegacyFilter,
Filter::TableOfContentsTagFilter,
Filter::AutolinkFilter,
Filter::ExternalLinkFilter,
Filter::SuggestionFilter,
Filter::FootnoteFilter,
Filter::InlineDiffFilter,
*reference_filters,
Filter::ImageLazyLoadFilter, # keep after reference filters
Filter::ImageLinkFilter, # keep after reference filters
Filter::ExternalLinkFilter, # keep after ImageLinkFilter
Filter::EmojiFilter,
Filter::CustomEmojiFilter,
Filter::TaskListFilter,

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillCiBuildTraceChunksProjectId < BackfillDesiredShardingKeyPartitionJob
operation_name :backfill_ci_build_trace_chunks_project_id
feature_category :continuous_integration
end
end
end

View File

@ -85,7 +85,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_refs_with_ids(ids, LegacyDiffNote, mapper.user_mapper)
push_refs_with_ids(ids, LegacyDiffNote, note[:author]&.id, mapper.user_mapper)
end
# rubocop:enabled Gitlab/BulkInsert
@ -111,7 +111,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(record, :author_id, note.author.id, mapper.user_mapper)
push_with_record(record, :author_id, note.author&.id, mapper.user_mapper)
end
def note_body

View File

@ -14,7 +14,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(created_note, :author_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(created_note, :author_id, issue_event[:actor]&.id, mapper.user_mapper)
end
private

View File

@ -25,7 +25,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(created_event, :user_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(created_event, :user_id, issue_event[:actor]&.id, mapper.user_mapper)
end
def label_finder

View File

@ -34,7 +34,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(created_event, :user_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(created_event, :user_id, issue_event[:actor]&.id, mapper.user_mapper)
end
def action(event_type)

View File

@ -38,7 +38,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(created_note, :author_id, issue_event[:review_requester].id, mapper.user_mapper)
push_with_record(created_note, :author_id, issue_event[:review_requester]&.id, mapper.user_mapper)
end
def parse_body(issue_event)

View File

@ -28,7 +28,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(created_event, :author_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(created_event, :author_id, issue_event[:actor]&.id, mapper.user_mapper)
end
def create_state_event(issue_event)
@ -47,7 +47,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(state_event, :user_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(state_event, :user_id, issue_event[:actor]&.id, mapper.user_mapper)
end
end
end

View File

@ -48,7 +48,7 @@ module Gitlab
return created_note unless mapper.user_mapping_enabled?
push_with_record(created_note, :author_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(created_note, :author_id, issue_event[:actor]&.id, mapper.user_mapper)
created_note
end

View File

@ -28,7 +28,7 @@ module Gitlab
)
return unless mapper.user_mapping_enabled?
push_with_record(event, :author_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(event, :author_id, issue_event[:actor]&.id, mapper.user_mapper)
end
def create_state_event(issue_event)
@ -47,7 +47,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(state_event, :user_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(state_event, :user_id, issue_event[:actor]&.id, mapper.user_mapper)
end
def create_note(issue_event)

View File

@ -10,7 +10,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(created_note, :author_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(created_note, :author_id, issue_event[:actor]&.id, mapper.user_mapper)
end
private

View File

@ -28,7 +28,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(created_event, :author_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(created_event, :author_id, issue_event[:actor]&.id, mapper.user_mapper)
end
def create_state_event(issue_event)
@ -43,7 +43,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(state_event, :user_id, issue_event[:actor].id, mapper.user_mapper)
push_with_record(state_event, :user_id, issue_event[:actor]&.id, mapper.user_mapper)
end
end
end

View File

@ -80,7 +80,7 @@ module Gitlab
user_mapper = mapper.user_mapper
push_with_record(new_issue, :author_id, issue.author.id, user_mapper)
push_with_record(new_issue, :author_id, issue.author&.id, user_mapper)
new_issue.issue_assignees.each do |issue_assignee|
github_user_id = issue_assignee_map[issue_assignee.user_id]

View File

@ -51,7 +51,7 @@ module Gitlab
# Gitlab::GithubImport::Importer::NoteAttachmentsImporter.
ids = ApplicationRecord.legacy_bulk_insert(Note.table_name, [attributes], return_ids: true) # rubocop:disable Gitlab/BulkInsert
push_refs_with_ids(ids, Note, mapper.user_mapper) if mapper.user_mapping_enabled?
push_refs_with_ids(ids, Note, note[:author]&.id, mapper.user_mapper) if mapper.user_mapping_enabled?
end
# Returns the ID of the issue or merge request to create the note for.

View File

@ -35,11 +35,11 @@ module Gitlab
insert_git_data(mr, already_exists)
if mapper.user_mapping_enabled?
push_with_record(mr, :author_id, pull_request.author.id, mapper.user_mapper)
push_with_record(mr, :author_id, pull_request.author&.id, mapper.user_mapper)
# we only import one PR assignee
assignee = mr.merge_request_assignees.first
push_with_record(assignee, :user_id, pull_request.assignee[:id], mapper.user_mapper) if assignee
push_with_record(assignee, :user_id, pull_request.assignee&.id, mapper.user_mapper) if assignee
end
end
end

View File

@ -27,7 +27,7 @@ module Gitlab
metrics_upsert(gitlab_user_id)
if mapper.user_mapping_enabled?
push_with_record(merge_request.metrics, :merged_by_id, merged_by.id, mapper.user_mapper)
push_with_record(merge_request.metrics, :merged_by_id, merged_by&.id, mapper.user_mapper)
else
add_legacy_note!
end

View File

@ -76,7 +76,7 @@ module Gitlab
return unless mapper.user_mapping_enabled?
push_with_record(note, :author_id, review.author.id, mapper.user_mapper)
push_with_record(note, :author_id, review.author&.id, mapper.user_mapper)
end
def note_attributes(author_id, note, extra = {})
@ -101,8 +101,8 @@ module Gitlab
return unless mapper.user_mapping_enabled? && approval
push_with_record(approval, :user_id, review.author.id, mapper.user_mapper)
push_with_record(approval_system_note, :author_id, review.author.id, mapper.user_mapper)
push_with_record(approval, :user_id, review.author&.id, mapper.user_mapper)
push_with_record(approval_system_note, :author_id, review.author&.id, mapper.user_mapper)
end
def add_reviewer!(user_id)
@ -110,7 +110,7 @@ module Gitlab
return unless mapper.user_mapping_enabled? && reviewer
push_with_record(reviewer, :user_id, review.author.id, mapper.user_mapper)
push_with_record(reviewer, :user_id, review.author&.id, mapper.user_mapper)
end
def submitted_at

View File

@ -30,7 +30,7 @@ module Gitlab
next unless mapper.user_mapping_enabled?
push_with_record(reviewer, :user_id, user.id, mapper.user_mapper)
push_with_record(reviewer, :user_id, user&.id, mapper.user_mapper)
rescue PG::UniqueViolation, ActiveRecord::RecordNotUnique
end
end

View File

@ -7,8 +7,9 @@ module Gitlab
# Pushes a placeholder reference using .from_record
# Used when the record is available and the reference only requires a numeric key
def push_with_record(record, attribute, source_user_identifier, user_mapper)
source_user = user_mapper.find_source_user(source_user_identifier)
return if source_user_identifier.nil?
source_user = user_mapper.find_source_user(source_user_identifier)
return if source_user.accepted_status?
::Import::PlaceholderReferences::PushService.from_record(
@ -23,9 +24,11 @@ module Gitlab
# Pushes placeholder references for each Note record found via an id look-up using .new
# This is used as Note records are created using legacy_bulk_insert which
# can return the ids of records created, but not the records themselves
def push_refs_with_ids(ids, model, user_mapper)
def push_refs_with_ids(ids, model, source_user_identifier, user_mapper)
return if source_user_identifier.nil?
ids.each do |id|
source_user = user_mapper.find_source_user(note[:author].id)
source_user = user_mapper.find_source_user(source_user_identifier)
next if source_user.accepted_status?
@ -43,6 +46,8 @@ module Gitlab
# Pushes a placeholder reference using a composite key.
# This is used when the record requires a composite key for the reference.
def push_with_composite_key(record, attribute, composite_key, source_user_identifier, user_mapper)
return if source_user_identifier.nil?
source_user = user_mapper.find_source_user(source_user_identifier)
return if source_user.accepted_status?

View File

@ -5898,24 +5898,102 @@ msgstr ""
msgid "Amazon Q"
msgstr ""
msgid "AmazonQ|Active cloud connector token not found."
msgstr ""
msgid "AmazonQ|Always off"
msgstr ""
msgid "AmazonQ|Amazon Q Configuration"
msgstr ""
msgid "AmazonQ|Amazon Q will be turned off by default, but still be available to any groups or projects that have previously enabled it."
msgstr ""
msgid "AmazonQ|Amazon Q will be turned off for all groups, subgroups, and projects, even if they have previously enabled it."
msgstr ""
msgid "AmazonQ|An unexpected error occurred while submitting the form. Please see the browser console log for more details."
msgstr ""
msgid "AmazonQ|Audience"
msgstr ""
msgid "AmazonQ|Availability"
msgstr ""
msgid "AmazonQ|Beta"
msgstr ""
msgid "AmazonQ|Cloud connector token could not be decoded"
msgstr ""
msgid "AmazonQ|Configure GitLab Duo with Amazon Q"
msgstr ""
msgid "AmazonQ|Configure GitLab Duo with Amazon Q (Beta)"
msgstr ""
msgid "AmazonQ|Copy to clipboard"
msgstr ""
msgid "AmazonQ|Create an identity provider for this GitLab instance within AWS using the following values. %{helpStart}Learn more%{helpEnd}."
msgstr ""
msgid "AmazonQ|Enter the IAM role's ARN."
msgstr ""
msgid "AmazonQ|Features are available. However, any group, subgroup, or project can turn them off."
msgstr ""
msgid "AmazonQ|Features are not available and cannot be turned on for any group, subgroup, or project."
msgstr ""
msgid "AmazonQ|Features are not available. However, any group, subgroup, or project can turn them on."
msgstr ""
msgid "AmazonQ|Get started"
msgstr ""
msgid "AmazonQ|GitLab Duo with Amazon Q"
msgstr ""
msgid "AmazonQ|GitLab Duo with Amazon Q is ready to go! 🎉"
msgstr ""
msgid "AmazonQ|I understand that by selecting Save changes, GitLab creates a service account for Amazon Q and sends its credentials to AWS. Use of the Amazon Q Developer capabilities as part of GitLab Duo with Amazon Q is governed by the %{helpStart}AWS Customer Agreement%{helpEnd} or other written agreement between you and AWS governing your use of AWS services."
msgstr ""
msgid "AmazonQ|IAM role's ARN"
msgstr ""
msgid "AmazonQ|Instance ID"
msgstr ""
msgid "AmazonQ|Off by default"
msgstr ""
msgid "AmazonQ|On by default"
msgstr ""
msgid "AmazonQ|Provider URL"
msgstr ""
msgid "AmazonQ|Provider type"
msgstr ""
msgid "AmazonQ|Save changes"
msgstr ""
msgid "AmazonQ|Setup"
msgstr ""
msgid "AmazonQ|Something went wrong retrieving the identity provider payload."
msgstr ""
msgid "AmazonQ|Status"
msgstr ""
msgid "AmazonQ|Use Amazon Q to automate workflows, create a merge request from an issue, upgrade Java, and improve your code with AI-powered reviews."
msgstr ""
@ -5928,6 +6006,9 @@ msgstr ""
msgid "AmazonQ|View configuration setup"
msgstr ""
msgid "AmazonQ|Within your AWS account, create an IAM role for Amazon Q and the relevant identity provider. %{helpStart}Learn how to create an IAM role%{helpEnd}."
msgstr ""
msgid "AmbiguousRef|There is a branch and a tag with the same name of %{ref}."
msgstr ""
@ -36111,6 +36192,9 @@ msgstr ""
msgid "Needs attention"
msgstr ""
msgid "Neither gitlab_instance_uid or sub found on Cloud Connector token"
msgstr ""
msgid "Network"
msgstr ""
@ -50407,6 +50491,9 @@ msgstr ""
msgid "SecurityOrchestration|Policy is invalid"
msgstr ""
msgid "SecurityOrchestration|Policy override"
msgstr ""
msgid "SecurityOrchestration|Policy scope"
msgstr ""
@ -50548,6 +50635,12 @@ msgstr ""
msgid "SecurityOrchestration|Show only linked security policy projects"
msgstr ""
msgid "SecurityOrchestration|Some settings may be affected by policy %{policyName} based on its rules."
msgstr ""
msgid "SecurityOrchestration|Some settings may be affected by the following policies based on their rules:"
msgstr ""
msgid "SecurityOrchestration|Something went wrong, unable to fetch groups"
msgstr ""

View File

@ -194,14 +194,6 @@ spec/frontend/glql/core/presenter_spec.js
spec/frontend/groups/components/group_name_and_path_spec.js
spec/frontend/groups/components/transfer_group_form_spec.js
spec/frontend/helpers/init_simple_app_helper_spec.js
spec/frontend/ide/components/commit_sidebar/list_item_spec.js
spec/frontend/ide/components/commit_sidebar/message_field_spec.js
spec/frontend/ide/components/merge_requests/item_spec.js
spec/frontend/ide/components/merge_requests/list_spec.js
spec/frontend/ide/components/new_dropdown/index_spec.js
spec/frontend/ide/ide_router_extension_spec.js
spec/frontend/ide/ide_router_spec.js
spec/frontend/ide/sync_router_and_store_spec.js
spec/frontend/integrations/edit/components/sections/connection_spec.js
spec/frontend/invite_members/components/members_token_select_spec.js
spec/frontend/issuable/components/issuable_by_email_spec.js

View File

@ -97,6 +97,7 @@ RSpec.describe 'Database schema',
ci_builds_metadata: %w[partition_id project_id build_id],
ci_build_needs: %w[project_id],
ci_build_pending_states: %w[project_id],
ci_build_trace_chunks: %w[project_id],
ci_builds_runner_session: %w[project_id],
ci_daily_build_group_report_results: %w[partition_id],
ci_deleted_objects: %w[project_id],

View File

@ -99,4 +99,35 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js, feature_category: :s
expect(page).not_to have_content("Impersonation Tokens")
end
end
describe "rotating tokens" do
let!(:impersonation_token) do
create(:personal_access_token, :impersonation, user: user, organization: organization)
end
it "displays the newly created token" do
visit admin_user_impersonation_tokens_path(user_id: user.username)
accept_gl_confirm(button_text: s_('AccessTokens|Rotate')) { click_on s_('AccessTokens|Rotate') }
wait_for_all_requests
expect(page).to have_content("Your new impersonation token has been created.")
expect(active_access_tokens).to have_text(impersonation_token.name)
expect(created_access_token).to match(/[\w-]{20}/)
end
context "when rotation fails" do
it "displays an error message" do
visit admin_user_impersonation_tokens_path(user_id: user.username)
accept_gl_confirm(button_text: s_('AccessTokens|Rotate')) do
impersonation_token.revoke!
click_on s_('AccessTokens|Rotate')
end
wait_for_all_requests
expect(page).to have_content(s_('AccessTokens|Token already revoked'))
end
end
end
end

View File

@ -2,7 +2,7 @@
require "spec_helper"
RSpec.describe 'Project wikis', :js, feature_category: :wiki do
RSpec.describe 'Project wikis', :js, feature_category: :wiki, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508966' do
let_it_be(:user) { create(:user) }
let(:wiki) { create(:project_wiki, user: user, project: project) }

View File

@ -4,11 +4,17 @@ import { nextTick } from 'vue';
import { trimText } from 'helpers/text_helper';
import waitForPromises from 'helpers/wait_for_promises';
import ListItem from '~/ide/components/commit_sidebar/list_item.vue';
import { describeSkipVue3, SkipReason } from 'helpers/vue3_conditional';
import { createRouter } from '~/ide/ide_router';
import { createStore } from '~/ide/stores';
import { file } from '../../helpers';
describe('Multi-file editor commit sidebar list item', () => {
const skipReason = new SkipReason({
name: 'Multi-file editor commit sidebar list item',
reason: 'Legacy WebIDE is due for deletion',
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508949',
});
describeSkipVue3(skipReason, () => {
let wrapper;
let testFile;
let findPathEl;

View File

@ -1,8 +1,14 @@
import { nextTick } from 'vue';
import { mount } from '@vue/test-utils';
import CommitMessageField from '~/ide/components/commit_sidebar/message_field.vue';
import { describeSkipVue3, SkipReason } from 'helpers/vue3_conditional';
describe('IDE commit message field', () => {
const skipReason = new SkipReason({
name: 'IDE commit message field',
reason: 'Legacy WebIDE is due for deletion',
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508949',
});
describeSkipVue3(skipReason, () => {
let wrapper;
beforeEach(() => {

View File

@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils';
import Vue from 'vue';
// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { describeSkipVue3, SkipReason } from 'helpers/vue3_conditional';
import Item from '~/ide/components/merge_requests/item.vue';
import { createRouter } from '~/ide/ide_router';
import { createStore } from '~/ide/stores';
@ -12,7 +13,12 @@ const TEST_ITEM = {
title: 'Merge request title',
};
describe('IDE merge request item', () => {
const skipReason = new SkipReason({
name: 'IDE merge request item',
reason: 'Legacy WebIDE is due for deletion',
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508949',
});
describeSkipVue3(skipReason, () => {
Vue.use(Vuex);
let wrapper;

View File

@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { describeSkipVue3, SkipReason } from 'helpers/vue3_conditional';
import Item from '~/ide/components/merge_requests/item.vue';
import List from '~/ide/components/merge_requests/list.vue';
import TokenedInput from '~/ide/components/shared/tokened_input.vue';
@ -10,7 +11,12 @@ import { mergeRequests as mergeRequestsMock } from '../../mock_data';
Vue.use(Vuex);
describe('IDE merge requests list', () => {
const skipReason = new SkipReason({
name: 'IDE merge requests list',
reason: 'Legacy WebIDE is due for deletion',
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508949',
});
describeSkipVue3(skipReason, () => {
let wrapper;
let fetchMergeRequestsMock;

View File

@ -1,6 +1,7 @@
import Vue from 'vue';
// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { describeSkipVue3, SkipReason } from 'helpers/vue3_conditional';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import NewDropdown from '~/ide/components/new_dropdown/index.vue';
import Button from '~/ide/components/new_dropdown/button.vue';
@ -9,7 +10,12 @@ import { stubComponent } from 'helpers/stub_component';
Vue.use(Vuex);
describe('new dropdown component', () => {
const skipReason = new SkipReason({
name: 'new dropdown component',
reason: 'Legacy WebIDE is due for deletion',
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508949',
});
describeSkipVue3(skipReason, () => {
let wrapper;
const openMock = jest.fn();
const deleteEntryMock = jest.fn();

View File

@ -1,9 +1,14 @@
import VueRouter from 'vue-router';
import { describeSkipVue3, SkipReason } from 'helpers/vue3_conditional';
import IdeRouter from '~/ide/ide_router_extension';
jest.mock('vue-router');
describe('IDE overrides of VueRouter', () => {
const skipReason = new SkipReason({
name: 'IDE overrides of VueRouter',
reason: 'Legacy WebIDE is due for deletion',
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508949',
});
describeSkipVue3(skipReason, () => {
const paths = (branch) => [
`${branch}`,
`/${branch}`,

View File

@ -1,9 +1,15 @@
import waitForPromises from 'helpers/wait_for_promises';
import { stubPerformanceWebAPI } from 'helpers/performance';
import { describeSkipVue3, SkipReason } from 'helpers/vue3_conditional';
import { createRouter } from '~/ide/ide_router';
import { createStore } from '~/ide/stores';
describe('IDE router', () => {
const skipReason = new SkipReason({
name: 'IDE router',
reason: 'Legacy WebIDE is due for deletion',
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508949',
});
describeSkipVue3(skipReason, () => {
const PROJECT_NAMESPACE = 'my-group/sub-group';
const PROJECT_NAME = 'my-project';
const TEST_PATH = `/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/merge_requests/2`;

View File

@ -1,11 +1,17 @@
import VueRouter from 'vue-router';
import waitForPromises from 'helpers/wait_for_promises';
import { describeSkipVue3, SkipReason } from 'helpers/vue3_conditional';
import { createStore } from '~/ide/stores';
import { syncRouterAndStore } from '~/ide/sync_router_and_store';
const TEST_ROUTE = '/test/lorem/ipsum';
describe('~/ide/sync_router_and_store', () => {
const skipReason = new SkipReason({
name: '~/ide/sync_router_and_store',
reason: 'Legacy WebIDE is due for deletion',
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/508949',
});
describeSkipVue3(skipReason, () => {
let unsync;
let router;
let store;

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillCiBuildTraceChunksProjectId,
feature_category: :continuous_integration,
migration: :gitlab_ci do
include_examples 'desired sharding key backfill job' do
let(:batch_table) { :ci_build_trace_chunks }
let(:backfill_column) { :project_id }
let(:backfill_via_table) { :p_ci_builds }
let(:backfill_via_column) { :project_id }
let(:backfill_via_foreign_key) { :build_id }
let(:partition_column) { :partition_id }
end
end

View File

@ -129,6 +129,7 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_fail
.with(
array_including(be_an(Integer)),
LegacyDiffNote,
note_representation.author.id,
an_instance_of(Gitlab::Import::SourceUserMapper)
)

View File

@ -56,6 +56,12 @@ RSpec.describe Gitlab::GithubImport::PushPlaceholderReferences, feature_category
source_user: import_source_user,
user_reference_column: :author_id)
end
it 'does not push a reference if source identifier is nil' do
importer.push_with_record(gitlab_note, :author_id, nil, user_mapper)
expect(::Import::PlaceholderReferences::PushService).not_to receive(:from_record)
end
end
describe '#push_refs_with_ids' do
@ -65,7 +71,7 @@ RSpec.describe Gitlab::GithubImport::PushPlaceholderReferences, feature_category
end
it 'pushes the reference using .new' do
importer.push_refs_with_ids([gitlab_note.id], Note, user_mapper)
importer.push_refs_with_ids([gitlab_note.id], Note, source_id, user_mapper)
expect(::Import::PlaceholderReferences::PushService)
.to have_received(:new)
@ -79,6 +85,12 @@ RSpec.describe Gitlab::GithubImport::PushPlaceholderReferences, feature_category
numeric_key: gitlab_note.id
)
end
it 'does not push a reference if source identifier is nil' do
importer.push_refs_with_ids([gitlab_note.id], Note, nil, user_mapper)
expect(::Import::PlaceholderReferences::PushService).not_to receive(:new)
end
end
describe '#push_with_composite_key' do
@ -104,5 +116,11 @@ RSpec.describe Gitlab::GithubImport::PushPlaceholderReferences, feature_category
composite_key: composite_key
)
end
it 'does not push a reference if source identifier is nil' do
importer.push_with_composite_key(gitlab_note, :user_id, composite_key, nil, user_mapper)
expect(::Import::PlaceholderReferences::PushService).not_to receive(:new)
end
end
end

View File

@ -0,0 +1,34 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe QueueBackfillCiBuildTraceChunksProjectId, migration: :gitlab_ci, feature_category: :continuous_integration do
let!(:batched_migration) { described_class::MIGRATION }
it 'schedules a new batched migration' do
reversible_migration do |migration|
migration.before -> {
expect(batched_migration).not_to have_scheduled_batched_migration
}
migration.after -> {
expect(batched_migration).to have_scheduled_batched_migration(
gitlab_schema: :gitlab_ci,
table_name: :ci_build_trace_chunks,
column_name: :id,
interval: described_class::DELAY_INTERVAL,
batch_size: described_class::BATCH_SIZE,
sub_batch_size: described_class::SUB_BATCH_SIZE,
job_arguments: [
:project_id,
:p_ci_builds,
:project_id,
:build_id,
:partition_id
]
)
}
end
end
end

View File

@ -999,4 +999,19 @@ RSpec.describe Ci::BuildTraceChunk, :clean_gitlab_redis_shared_state, :clean_git
end
end
end
describe '#set_project_id' do
it 'sets the project_id before validation' do
build_trace_chunk = create(:ci_build_trace_chunk)
expect(build_trace_chunk.project_id).to eq(build_trace_chunk.build.project_id)
end
it 'does not override the project_id if set' do
existing_project = create(:project)
build_trace_chunk = create(:ci_build_trace_chunk, project_id: existing_project.id)
expect(build_trace_chunk.project_id).to eq(existing_project.id)
end
end
end

View File

@ -4,4 +4,43 @@ require 'spec_helper'
RSpec.describe Projects::BranchRules::SquashOption, feature_category: :source_code_management do
it_behaves_like 'projects squash option'
describe 'Associations' do
it { is_expected.to belong_to(:protected_branch).optional(false) }
it { is_expected.to belong_to(:project).optional(false) }
end
describe 'Validations' do
let_it_be(:project) { create(:project) }
let(:protected_branch) { build(:protected_branch, name: 'master', project: project) }
context 'for protected_branch' do
subject do
described_class
.new(protected_branch: protected_branch, project: project)
.tap(&:valid?)
.errors.messages_for(:protected_branch)
end
it { is_expected.to be_empty }
context 'when protected_branch is nil' do
let(:protected_branch) { nil }
it { is_expected.to contain_exactly('must exist') }
end
context 'when protected_branch is wildcard' do
let(:protected_branch) { build(:protected_branch, name: '*', project: project) }
it { is_expected.to contain_exactly('cannot be a wildcard') }
end
context 'when protected_branch belongs to a different project' do
let(:protected_branch) { build(:protected_branch, name: 'master') }
it { is_expected.to contain_exactly('must belong to project') }
end
end
end
end

View File

@ -22,34 +22,42 @@ RSpec.describe Admin::ImpersonationTokensController, :enable_admin_mode, feature
end
end
context "when impersonation is disabled" do
context 'when impersonation is disabled' do
before do
stub_config_setting(impersonation_enabled: false)
end
it "shows error page for index page" do
it 'shows error page for index page' do
get admin_user_impersonation_tokens_path(user_id: user.username)
expect(response).to have_gitlab_http_status(:not_found)
end
it "responds with 404 for create action" do
it 'responds with 404 for create action' do
post admin_user_impersonation_tokens_path(user_id: user.username)
expect(response).to have_gitlab_http_status(:not_found)
end
it "responds with 404 for revoke action" do
it 'responds with 404 for revoke action' do
token = create(:personal_access_token, :impersonation, user: user)
put revoke_admin_user_impersonation_token_path(user_id: user.username, id: token.id)
expect(response).to have_gitlab_http_status(:not_found)
end
it 'responds with 404 for rotate action' do
token = create(:personal_access_token, :impersonation, user: user)
put rotate_admin_user_impersonation_token_path(user_id: user.username, id: token.id)
expect(response).to have_gitlab_http_status(:not_found)
end
end
describe "#create", :with_current_organization do
it_behaves_like "#create access token" do
describe '#create', :with_current_organization do
it_behaves_like '#create access token' do
let(:url) { admin_user_impersonation_tokens_path(user_id: user.username) }
let(:token_attributes) { attributes_for(:personal_access_token, impersonation: true) }
end

View File

@ -12,13 +12,18 @@ RSpec.describe ImpersonationAccessTokenEntity do
.revoke_admin_user_impersonation_token_path(
{ user_id: user, id: token })
expected_rotate_path = Gitlab::Routing.url_helpers
.rotate_admin_user_impersonation_token_path(
{ user_id: user, id: token })
expect(json).to(
include(
id: token.id,
name: token.name,
scopes: token.scopes,
user_id: token.user_id,
revoke_path: expected_revoke_path
revoke_path: expected_revoke_path,
rotate_path: expected_rotate_path
))
expect(json).not_to include(:token)