Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot
2024-03-21 15:10:36 +00:00
parent e5de3582ae
commit 91a8a89bd6
23 changed files with 374 additions and 80 deletions

View File

@ -4,4 +4,5 @@ schema:
documents:
- ./app/assets/javascripts/**/*.graphql
- ./ee/app/assets/javascripts/**/*.graphql
- ./jh/app/assets/javascripts/**/*.graphql
- ./app/graphql/queries/**/*.graphql

View File

@ -12,8 +12,10 @@ import {
WIDGET_TYPE_PROGRESS,
WIDGET_TYPE_START_AND_DUE_DATE,
WIDGET_TYPE_TIME_TRACKING,
WIDGET_TYPE_ROLLEDUP_DATES,
WIDGET_TYPE_WEIGHT,
WIDGET_TYPE_COLOR,
WORK_ITEM_TYPE_VALUE_EPIC,
} from '../constants';
import WorkItemAssigneesInline from './work_item_assignees_inline.vue';
import WorkItemAssigneesWithEdit from './work_item_assignees_with_edit.vue';
@ -61,6 +63,8 @@ export default {
import('ee_component/work_items/components/work_item_color_inline.vue'),
WorkItemColorWithEdit: () =>
import('ee_component/work_items/components/work_item_color_with_edit.vue'),
WorkItemRolledupDates: () =>
import('ee_component/work_items/components/work_item_rolledup_dates.vue'),
},
mixins: [glFeatureFlagMixin()],
props: {
@ -92,6 +96,9 @@ export default {
workItemDueDate() {
return this.isWidgetPresent(WIDGET_TYPE_START_AND_DUE_DATE);
},
workItemRolledupDates() {
return this.isWidgetPresent(WIDGET_TYPE_ROLLEDUP_DATES);
},
workItemWeight() {
return this.isWidgetPresent(WIDGET_TYPE_WEIGHT);
},
@ -113,6 +120,11 @@ export default {
workItemMilestone() {
return this.isWidgetPresent(WIDGET_TYPE_MILESTONE);
},
showRolledupDates() {
return (
this.glFeatures.workItemsRolledupDates && this.workItemType === WORK_ITEM_TYPE_VALUE_EPIC
);
},
workItemParent() {
return this.isWidgetPresent(WIDGET_TYPE_HIERARCHY)?.parent;
},
@ -211,6 +223,20 @@ export default {
@error="$emit('error', $event)"
/>
</template>
<template v-if="workItemRolledupDates && showRolledupDates">
<work-item-rolledup-dates
:can-update="canUpdate"
:due-date-is-fixed="workItemRolledupDates.dueDateIsFixed"
:due-date-fixed="workItemRolledupDates.dueDateFixed"
:due-date-inherited="workItemRolledupDates.dueDate"
:start-date-is-fixed="workItemRolledupDates.startDateIsFixed"
:start-date-fixed="workItemRolledupDates.startDateFixed"
:start-date-inherited="workItemRolledupDates.startDate"
:work-item-type="workItemType"
:work-item="workItem"
@error="$emit('error', $event)"
/>
</template>
<template v-if="workItemMilestone">
<work-item-milestone-with-edit
v-if="workItemsBetaFeaturesEnabled"
@ -257,7 +283,7 @@ export default {
@error="$emit('error', $event)"
/>
</template>
<template v-if="workItemDueDate">
<template v-if="workItemDueDate && !showRolledupDates">
<work-item-due-date-with-edit
v-if="workItemsBetaFeaturesEnabled"
:can-update="canUpdate"

View File

@ -17,6 +17,7 @@ export const WIDGET_TYPE_CURRENT_USER_TODOS = 'CURRENT_USER_TODOS';
export const WIDGET_TYPE_LABELS = 'LABELS';
export const WIDGET_TYPE_START_AND_DUE_DATE = 'START_AND_DUE_DATE';
export const WIDGET_TYPE_TIME_TRACKING = 'TIME_TRACKING';
export const WIDGET_TYPE_ROLLEDUP_DATES = 'ROLLEDUP_DATES';
export const WIDGET_TYPE_WEIGHT = 'WEIGHT';
export const WIDGET_TYPE_PARTICIPANTS = 'PARTICIPANTS';
export const WIDGET_TYPE_PROGRESS = 'PROGRESS';

View File

@ -918,6 +918,10 @@ class Group < Namespace
feature_flag_enabled_for_self_or_ancestor?(:linked_work_items)
end
def work_items_rolledup_dates_feature_flag_enabled?
feature_flag_enabled_for_self_or_ancestor?(:work_items_rolledup_dates)
end
def supports_lock_on_merge?
feature_flag_enabled_for_self_or_ancestor?(:enforce_locked_labels_on_merge, type: :ops)
end

View File

@ -9,6 +9,7 @@ module Git
process_changes_by_action(:branch, changes.branch_changes)
process_changes_by_action(:tag, changes.tag_changes)
warn_if_over_process_limit(changes.branch_changes + changes.tag_changes)
perform_housekeeping
end
@ -63,7 +64,46 @@ module Git
end
def under_process_limit?(change)
change[:index] < PIPELINE_PROCESS_LIMIT || Feature.enabled?(:git_push_create_all_pipelines, project)
change[:index] < process_limit || Feature.enabled?(:git_push_create_all_pipelines, project)
end
def process_limit
PIPELINE_PROCESS_LIMIT
end
def warn_if_over_process_limit(changes)
return unless process_limit > 0
return if changes.length <= process_limit
# We don't know for sure whether the project has CI enabled or CI rules
# that might excluded pipelines from being created.
omitted_refs = possible_omitted_pipeline_refs(changes)
return unless omitted_refs.present?
# This notification only lets the admin know that we might have skipped some refs.
Gitlab::AppJsonLogger.info(
message: "Some pipelines may not have been created because ref count exceeded limit",
ref_limit: process_limit,
total_ref_count: changes.length,
possible_omitted_refs: omitted_refs,
possible_omitted_ref_count: omitted_refs.length,
**Gitlab::ApplicationContext.current
)
end
def possible_omitted_pipeline_refs(changes)
# Pipelines can only be created on pushed for branch creation or updates
omitted_changes = changes.select do |change|
change[:index] >= process_limit &&
change_action(change) != :removed
end
# rubocop:disable CodeReuse/ActiveRecord -- not an ActiveRecord model
# rubocop:disable Database/AvoidUsingPluckWithoutLimit -- not an ActiveRecord model
omitted_changes.pluck(:ref).sort
# rubocop:enable CodeReuse/ActiveRecord
# rubocop:enable Database/AvoidUsingPluckWithoutLimit
end
def create_bulk_push_event(ref_type, action, changes)

View File

@ -84,7 +84,8 @@ module ResourceAccessTokens
email: username_and_email_generator.email,
username: username_and_email_generator.username,
user_type: :project_bot,
skip_confirmation: true # Bot users should always have their emails confirmed.
skip_confirmation: true, # Bot users should always have their emails confirmed.
organization_id: resource.organization_id
}
end

View File

@ -15,9 +15,7 @@ module MembersDestroyer
idempotent!
# Remove the default value `nil` for `requesting_user_id` after 16.10.
# TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/442878
def perform(user_id, entity_id, entity_type, requesting_user_id = nil)
def perform(user_id, entity_id, entity_type, requesting_user_id)
unless ENTITY_TYPES.include?(entity_type)
logger.error(
message: "#{entity_type} is not a supported entity.",
@ -42,9 +40,7 @@ module MembersDestroyer
return
end
# Remove the condition requesting_user_id after 16.10.
# TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/442878
requesting_user = requesting_user_id && User.find(requesting_user_id)
requesting_user = User.find(requesting_user_id)
user = User.find(user_id)
entity = entity_type.constantize.find(entity_id)

View File

@ -42,9 +42,8 @@ const {
WEBPACK_OUTPUT_PATH,
WEBPACK_PUBLIC_PATH,
SOURCEGRAPH_PUBLIC_PATH,
SOURCEGRAPH_OUTPUT_PATH,
GITLAB_WEB_IDE_OUTPUT_PATH,
GITLAB_WEB_IDE_PUBLIC_PATH,
copyFilesPatterns,
} = require('./webpack.constants');
const createIncrementalWebpackCompiler = require('./helpers/incremental_webpack_compiler');
@ -89,9 +88,6 @@ if (WEBPACK_REPORT) {
NO_HASHED_CHUNKS = true;
}
const SOURCEGRAPH_PACKAGE = '@sourcegraph/code-host-integration';
const GITLAB_WEB_IDE_PACKAGE = '@gitlab/web-ide';
const devtool = IS_PRODUCTION ? 'source-map' : 'cheap-module-eval-source-map';
let autoEntriesCount = 0;
@ -711,34 +707,7 @@ module.exports = {
}),
new CopyWebpackPlugin({
patterns: [
{
from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/cmaps/'),
to: path.join(WEBPACK_OUTPUT_PATH, 'pdfjs/cmaps/'),
},
{
from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/legacy/build/pdf.worker.min.js'),
to: path.join(WEBPACK_OUTPUT_PATH, 'pdfjs/'),
},
{
from: path.join(ROOT_PATH, 'node_modules', SOURCEGRAPH_PACKAGE, '/'),
to: SOURCEGRAPH_OUTPUT_PATH,
globOptions: {
ignore: ['package.json'],
},
},
{
from: path.join(ROOT_PATH, 'node_modules', GITLAB_WEB_IDE_PACKAGE, 'dist', 'public'),
to: GITLAB_WEB_IDE_OUTPUT_PATH,
},
{
from: path.join(
ROOT_PATH,
'node_modules/@gitlab/visual-review-tools/dist/visual_review_toolbar.js',
),
to: WEBPACK_OUTPUT_PATH,
},
],
patterns: copyFilesPatterns,
}),
// compression can require a lot of compute time and is disabled in CI

View File

@ -18,14 +18,45 @@ const GITLAB_WEB_IDE_PUBLIC_PATH = path.join(WEBPACK_PUBLIC_PATH, GITLAB_WEB_IDE
const IS_EE = require('./helpers/is_ee_env');
const IS_JH = require('./helpers/is_jh_env');
const SOURCEGRAPH_PACKAGE = '@sourcegraph/code-host-integration';
const GITLAB_WEB_IDE_PACKAGE = '@gitlab/web-ide';
const copyFilesPatterns = [
{
from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/cmaps/'),
to: path.join(WEBPACK_OUTPUT_PATH, 'pdfjs/cmaps/'),
},
{
from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/legacy/build/pdf.worker.min.js'),
to: path.join(WEBPACK_OUTPUT_PATH, 'pdfjs/'),
},
{
from: path.join(ROOT_PATH, 'node_modules', SOURCEGRAPH_PACKAGE, '/'),
to: SOURCEGRAPH_OUTPUT_PATH,
globOptions: {
ignore: ['package.json'],
},
},
{
from: path.join(ROOT_PATH, 'node_modules', GITLAB_WEB_IDE_PACKAGE, 'dist', 'public'),
to: GITLAB_WEB_IDE_OUTPUT_PATH,
},
{
from: path.join(
ROOT_PATH,
'node_modules/@gitlab/visual-review-tools/dist/visual_review_toolbar.js',
),
to: WEBPACK_OUTPUT_PATH,
},
];
module.exports = {
IS_EE,
IS_JH,
ROOT_PATH,
WEBPACK_OUTPUT_PATH,
WEBPACK_PUBLIC_PATH,
SOURCEGRAPH_OUTPUT_PATH,
SOURCEGRAPH_PUBLIC_PATH,
GITLAB_WEB_IDE_OUTPUT_PATH,
GITLAB_WEB_IDE_PUBLIC_PATH,
copyFilesPatterns,
};

View File

@ -7,4 +7,4 @@ milestone: '16.10'
queued_migration_version: 20240209153920
# Replace with the approximate date you think it's best to ensure the completion of this BBM.
finalize_after: '2024-03-15'
finalized_by: # version of the migration that finalized this BBM
finalized_by: 20240320102510

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
class FinalizePurgeSecurityScansWithEmptyFindingData < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '16.11'
restrict_gitlab_migration gitlab_schema: :gitlab_main
def up
return if Gitlab.com? || !Gitlab.ee?
ensure_batched_background_migration_is_finished(
job_class_name: 'PurgeSecurityScansWithEmptyFindingData',
table_name: :security_scans,
column_name: :id,
job_arguments: [],
finalize: true
)
end
def down
# no-op
end
end

View File

@ -0,0 +1 @@
9cf0040ec4eb9f9baa7bdef04e8afe07bcac0091053ae7810440993609d0f1bc

View File

@ -76,31 +76,6 @@ a single URL used by all Geo sites, including the primary.
In Kubernetes, you can [use the same domain under `global.hosts.domain` as for the primary site](https://docs.gitlab.com/charts/advanced/geo/index.html).
## Geo proxying with Separate URLs
> - Geo secondary proxying for separate URLs is [enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/346112) in GitLab 15.1.
NOTE:
The feature flag described in this section is planned to be deprecated and removed in a future release. Support for read-only Geo secondary sites is proposed in [issue 366810](https://gitlab.com/gitlab-org/gitlab/-/issues/366810), you can upvote and share your use cases in that issue.
If you run into issues, to disable this feature, disable the `geo_secondary_proxy_separate_urls` feature flag.
1. SSH into one node running Rails on your primary Geo site and run:
```shell
sudo gitlab-rails runner "Feature.disable(:geo_secondary_proxy_separate_urls)"
```
1. Restart Puma on all of the nodes running Rails on your secondary Geo site:
```shell
sudo gitlab-ctl restart puma
```
In Kubernetes, you can run the same command in the toolbox pod. Refer to the
[Kubernetes cheat sheet](https://docs.gitlab.com/charts/troubleshooting/kubernetes_cheat_sheet.html#gitlab-specific-kubernetes-information)
for details.
## Limitations
- When secondary proxying is used, the asynchronous Geo replication can cause unexpected issues for accelerated
@ -204,3 +179,30 @@ gitlab:
extraEnv:
GEO_SECONDARY_PROXY: "0"
```
## Geo proxying with Separate URLs
> - Geo secondary proxying for separate URLs is [enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/346112) in GitLab 15.1.
NOTE:
The feature flag described in this section is planned to be deprecated and removed in a future release. Support for read-only Geo secondary sites is proposed in [issue 366810](https://gitlab.com/gitlab-org/gitlab/-/issues/366810), you can upvote and share your use cases in that issue.
Geo proxying for seperate URLs is enabled by default from GitLab 15.1. This allows secondary sites to proxy actions to the primary site even if the URLS are different.
If you run into issues, disable the `geo_secondary_proxy_separate_urls` feature flag to disable the feature.
1. SSH into one node running Rails on your primary Geo site and run:
```shell
sudo gitlab-rails runner "Feature.disable(:geo_secondary_proxy_separate_urls)"
```
1. Restart Puma on all of the nodes running Rails on your secondary Geo site:
```shell
sudo gitlab-ctl restart puma
```
In Kubernetes, you can run the same command in the toolbox pod. Refer to the
[Kubernetes cheat sheet](https://docs.gitlab.com/charts/troubleshooting/kubernetes_cheat_sheet.html#gitlab-specific-kubernetes-information)
for details.

View File

@ -104,8 +104,8 @@ To add a new feature bound to a scope:
services:
new_feature_scope:
service_start_time: 2024-02-15 00:00:00 UTC
min_gitlab_version: '16.8'
bundled_with: 'duo_pro'
min_gitlab_version: '16.8'
bundled_with: 'duo_pro'
```
1. **Optional:** If the backend service the token is used for requires additional claims to be embedded in the

View File

@ -16,7 +16,7 @@ module Gitlab
end
def self.script_src
"'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.recaptcha.net"
"'strict-dynamic' 'self' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.recaptcha.net"
end
def self.style_src

View File

@ -57339,12 +57339,18 @@ msgstr ""
msgid "WorkItem|Existing task"
msgstr ""
msgid "WorkItem|Fixed"
msgstr ""
msgid "WorkItem|History only"
msgstr ""
msgid "WorkItem|Incident"
msgstr ""
msgid "WorkItem|Inherited"
msgstr ""
msgid "WorkItem|Issue"
msgstr ""

View File

@ -267,6 +267,7 @@
"gettext-extractor": "^3.7.0",
"gettext-extractor-vue": "^5.1.0",
"glob": "^7.1.6",
"globby": "^11.0.1",
"jest": "^28.1.3",
"jest-canvas-mock": "^2.4.0",
"jest-diff": "^28.1.3",

View File

@ -91,10 +91,10 @@ gitlab:
# Based on https://console.cloud.google.com/monitoring/metrics-explorer;duration=P14D?pageState=%7B%22xyChart%22:%7B%22constantLines%22:%5B%5D,%22dataSets%22:%5B%7B%22plotType%22:%22LINE%22,%22targetAxis%22:%22Y1%22,%22timeSeriesFilter%22:%7B%22aggregations%22:%5B%7B%22crossSeriesReducer%22:%22REDUCE_NONE%22,%22groupByFields%22:%5B%5D,%22perSeriesAligner%22:%22ALIGN_RATE%22%7D,%7B%22crossSeriesReducer%22:%22REDUCE_NONE%22,%22groupByFields%22:%5B%5D,%22perSeriesAligner%22:%22ALIGN_MEAN%22%7D%5D,%22apiSource%22:%22DEFAULT_CLOUD%22,%22crossSeriesReducer%22:%22REDUCE_NONE%22,%22filter%22:%22metric.type%3D%5C%22kubernetes.io%2Fcontainer%2Fcpu%2Fcore_usage_time%5C%22%20resource.type%3D%5C%22k8s_container%5C%22%20resource.label.%5C%22container_name%5C%22%3D%5C%22sidekiq%5C%22%22,%22groupByFields%22:%5B%5D,%22minAlignmentPeriod%22:%2260s%22,%22perSeriesAligner%22:%22ALIGN_RATE%22,%22secondaryCrossSeriesReducer%22:%22REDUCE_NONE%22,%22secondaryGroupByFields%22:%5B%5D%7D%7D%5D,%22options%22:%7B%22mode%22:%22STATS%22%7D,%22y1Axis%22:%7B%22label%22:%22%22,%22scale%22:%22LINEAR%22%7D%7D%7D&project=gitlab-review-apps
cpu: 400m
# Based on https://console.cloud.google.com/monitoring/metrics-explorer;duration=P14D?pageState=%7B%22xyChart%22:%7B%22constantLines%22:%5B%5D,%22dataSets%22:%5B%7B%22plotType%22:%22LINE%22,%22targetAxis%22:%22Y1%22,%22timeSeriesFilter%22:%7B%22aggregations%22:%5B%7B%22crossSeriesReducer%22:%22REDUCE_NONE%22,%22groupByFields%22:%5B%5D,%22perSeriesAligner%22:%22ALIGN_MEAN%22%7D%5D,%22apiSource%22:%22DEFAULT_CLOUD%22,%22crossSeriesReducer%22:%22REDUCE_NONE%22,%22filter%22:%22metric.type%3D%5C%22kubernetes.io%2Fcontainer%2Fmemory%2Fused_bytes%5C%22%20resource.type%3D%5C%22k8s_container%5C%22%20resource.label.%5C%22container_name%5C%22%3D%5C%22sidekiq%5C%22%22,%22groupByFields%22:%5B%5D,%22minAlignmentPeriod%22:%2260s%22,%22perSeriesAligner%22:%22ALIGN_MEAN%22%7D%7D%5D,%22options%22:%7B%22mode%22:%22STATS%22%7D,%22y1Axis%22:%7B%22label%22:%22%22,%22scale%22:%22LINEAR%22%7D%7D%7D&project=gitlab-review-apps
memory: 2000Mi
memory: 1500Mi
limits:
cpu: 700m
memory: 2400Mi
memory: 2800Mi
hpa:
cpu:
targetAverageValue: 650m

View File

@ -635,6 +635,7 @@ export const workItemResponseFactory = ({
allowsMultipleAssignees = true,
assigneesWidgetPresent = true,
datesWidgetPresent = true,
rolledupDatesWidgetPresent = false,
weightWidgetPresent = true,
timeTrackingWidgetPresent = true,
participantsWidgetPresent = true,
@ -738,6 +739,18 @@ export const workItemResponseFactory = ({
startDate: '2022-01-01',
}
: { type: 'MOCK TYPE' },
rolledupDatesWidgetPresent
? {
__typename: 'WorkItemWidgetRolledupDates',
type: 'ROLLEDUP_DATES',
dueDate: null,
dueDateFixed: null,
dueDateIsFixed: false,
startDate: null,
startDateFixed: null,
startDateIsFixed: false,
}
: { type: 'MOCK TYPE' },
weightWidgetPresent
? {
__typename: 'WorkItemWidgetWeight',

View File

@ -134,6 +134,8 @@ RSpec.describe Git::ProcessRefChangesService, feature_category: :source_code_man
it "creates exactly #{described_class::PIPELINE_PROCESS_LIMIT} pipelines" do
stub_const("#{described_class}::PIPELINE_PROCESS_LIMIT", changes.count - 1)
expect(Gitlab::AppJsonLogger).not_to receive(:info)
expect { subject.execute }.to change { Ci::Pipeline.count }.by(described_class::PIPELINE_PROCESS_LIMIT)
end
end
@ -216,7 +218,7 @@ RSpec.describe Git::ProcessRefChangesService, feature_category: :source_code_man
context 'when there are merge requests associated with branches' do
let(:tag_changes) do
[
{ index: 0, oldrev: Gitlab::Git::SHA1_BLANK_SHA, newrev: '789012', ref: "refs/tags/v10.0.0" }
{ index: 7, oldrev: Gitlab::Git::SHA1_BLANK_SHA, newrev: '789012', ref: "refs/tags/v10.0.0" }
]
end
@ -232,7 +234,9 @@ RSpec.describe Git::ProcessRefChangesService, feature_category: :source_code_man
]
end
let(:git_changes) { double(branch_changes: branch_changes, tag_changes: tag_changes) }
let(:git_changes) do
double(branch_changes: branch_changes, tag_changes: tag_changes)
end
before do
allow(MergeRequests::PushedBranchesService).to receive(:new).and_return(
@ -277,6 +281,26 @@ RSpec.describe Git::ProcessRefChangesService, feature_category: :source_code_man
subject.execute
end
context 'when git_push_create_all_pipelines is disabled' do
before do
stub_feature_flags(git_push_create_all_pipelines: false)
end
it 'logs a warning' do
expect(Gitlab::AppJsonLogger).to receive(:info).with(
hash_including(
message: "Some pipelines may not have been created because ref count exceeded limit",
ref_limit: described_class::PIPELINE_PROCESS_LIMIT,
total_ref_count: branch_changes.count + tag_changes.count,
possible_omitted_refs: ["#{ref_prefix}/changed2", "refs/tags/v10.0.0"],
possible_omitted_ref_count: 2
)
)
subject.execute
end
end
end
end

View File

@ -5,9 +5,10 @@ require 'spec_helper'
RSpec.describe ResourceAccessTokens::CreateService, feature_category: :system_access do
subject { described_class.new(user, resource, params).execute }
let_it_be(:organization) { create(:organization) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
let_it_be(:group) { create(:group, :private) }
let_it_be(:project) { create(:project, :private, organization: organization) }
let_it_be(:group) { create(:group, :private, organization: organization) }
let_it_be(:params) { {} }
let_it_be(:max_pat_access_token_lifetime) do
PersonalAccessToken::MAX_PERSONAL_ACCESS_TOKEN_LIFETIME_IN_DAYS.days.from_now.to_date.freeze
@ -19,7 +20,7 @@ RSpec.describe ResourceAccessTokens::CreateService, feature_category: :system_ac
describe '#execute' do
shared_examples 'token creation fails' do
let(:resource) { create(:project) }
let_it_be(:resource) { create(:project, organization: organization) }
it 'does not add the project bot as a member' do
expect { subject }.not_to change { resource.members.count }
@ -47,6 +48,7 @@ RSpec.describe ResourceAccessTokens::CreateService, feature_category: :system_ac
expect(access_token.user.reload.user_type).to eq("project_bot")
expect(access_token.user.created_by_id).to eq(user.id)
expect(access_token.user.namespace.organization.id).to eq(resource.organization.id)
end
context 'email confirmation status' do
@ -363,5 +365,20 @@ RSpec.describe ResourceAccessTokens::CreateService, feature_category: :system_ac
end
end
end
context 'when resource organization is not set', :enable_admin_mode do
let_it_be(:resource) { create(:project, :private, organization: nil) }
let_it_be(:default_organization) { Organizations::Organization.default_organization }
let(:user) { create(:admin) }
it 'uses database default' do
response = subject
access_token = response.payload[:access_token]
expect(access_token.user.namespace.organization).to eq(
default_organization
)
end
end
end
end

View File

@ -861,3 +861,64 @@ RSpec.shared_examples 'work items iteration' do
end
end
end
RSpec.shared_context 'with work_items_rolledup_dates' do |flag|
before do
stub_feature_flags(work_items_rolledup_dates: flag)
page.refresh
wait_for_all_requests
end
end
RSpec.shared_examples 'work items rolled up dates' do
let(:work_item_rolledup_dates_selector) { '[data-testid="work-item-rolledup-dates"]' }
include_context 'with work_items_rolledup_dates', true
context 'for accessibility' do
it 'passes axe automated accessibility testing in closed state' do
expect(page).to have_selector(work_item_rolledup_dates_selector)
expect(page).to be_axe_clean.within(work_item_rolledup_dates_selector)
end
it 'passes axe automated accessibility testing in open state' do
within(work_item_rolledup_dates_selector) do
click_button _('Edit')
wait_for_requests
expect(page).to be_axe_clean.within(work_item_rolledup_dates_selector)
end
end
end
context 'when edit is clicked' do
it 'selects and updates the dates to fixed once selected', :aggregate_failures do
expect(find_field('Inherited')).to be_checked
find_and_click_edit(work_item_rolledup_dates_selector)
within work_item_rolledup_dates_selector do
fill_in 'Start', with: '2021-01-01'
fill_in 'Due', with: '2021-01-02'
end
# Click outside to save
find("body").click
within work_item_rolledup_dates_selector do
expect(find_field('Fixed')).to be_checked
expect(page).to have_text('Start: Jan 1, 2021')
expect(page).to have_text('Due: Jan 2, 2021')
end
end
end
context 'when feature flag is disabled' do
include_context 'with work_items_rolledup_dates', false
it 'does not show rolled up dates' do
expect(page).not_to have_selector(work_item_rolledup_dates_selector)
end
end
end

View File

@ -1,4 +1,5 @@
import { readFileSync } from 'node:fs';
import { stat, mkdir, copyFile } from 'node:fs/promises';
import path from 'node:path';
import { defineConfig } from 'vite';
@ -6,6 +7,7 @@ import vue from '@vitejs/plugin-vue2';
import graphql from '@rollup/plugin-graphql';
import RubyPlugin from 'vite-plugin-ruby';
import chokidar from 'chokidar';
import globby from 'globby';
import { viteCommonjs } from '@originjs/vite-plugin-commonjs';
import webpackConfig from './config/webpack.config';
import {
@ -13,6 +15,7 @@ import {
IS_JH,
SOURCEGRAPH_PUBLIC_PATH,
GITLAB_WEB_IDE_PUBLIC_PATH,
copyFilesPatterns,
} from './config/webpack.constants';
/* eslint-disable import/extensions */
import { viteCSSCompilerPlugin } from './scripts/frontend/lib/compile_css.mjs';
@ -90,6 +93,76 @@ const autoRestartPlugin = {
},
};
/**
* This is a simple-reimplementation of the copy-webpack-plugin
*
* it also uses the `globby` package under the hood, and _only_ allows for copying
* 1. absolute paths
* 2. files and directories.
*/
function viteCopyPlugin({ patterns }) {
return {
name: 'viteCopyPlugin',
async configureServer() {
console.warn('Start copying files...');
let count = 0;
const allTheFiles = patterns.map(async (patternEntry) => {
const { from, to, globOptions = {} } = patternEntry;
// By only supporting absolute paths we simplify
// the implementation a lot
if (!path.isAbsolute(from)) {
throw new Error(`'from' path is not absolute: ${path}`);
}
if (!path.isAbsolute(to)) {
throw new Error(`'to' path is not absolute: ${path}`);
}
let pattern = '';
let sourceRoot = '';
const fromStat = await stat(from);
if (fromStat.isDirectory()) {
sourceRoot = from;
pattern = path.join(from, '**/*');
} else if (fromStat.isFile()) {
sourceRoot = path.dirname(from);
pattern = from;
} else {
// No need to support globs, because we do not
// use them yet...
throw new Error('Our implementation does not support globs.');
}
globOptions.dot = globOptions.dot ?? true;
const paths = await globby(pattern, globOptions);
return paths.map((srcPath) => {
const targetPath = path.join(to, path.relative(sourceRoot, srcPath));
return { srcPath, targetPath };
});
});
const srcTargetMap = (await Promise.all(allTheFiles)).flat();
await Promise.all(
srcTargetMap.map(async ({ srcPath, targetPath }) => {
try {
await mkdir(path.dirname(targetPath), { recursive: true });
await copyFile(srcPath, targetPath);
count += 1;
} catch (e) {
console.warn(`Could not copy ${srcPath} => ${targetPath}`);
}
}),
);
console.warn(`Done copying ${count} files...`);
},
};
}
export default defineConfig({
cacheDir: path.resolve(__dirname, 'tmp/cache/vite'),
resolve: {
@ -110,6 +183,9 @@ export default defineConfig({
plugins: [
viteCSSCompilerPlugin({ shouldWatch: viteGDKConfig.hmr !== null }),
viteTailwindCompilerPlugin({ shouldWatch: viteGDKConfig.hmr !== null }),
viteCopyPlugin({
patterns: copyFilesPatterns,
}),
viteGDKConfig.enabled ? autoRestartPlugin : null,
fixedRubyPlugin,
vue({