Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-25 18:10:57 +00:00
parent c59393a068
commit 0351d9ed83
81 changed files with 199 additions and 598 deletions

View File

@ -23,21 +23,6 @@ Layout/SpaceInsideParens:
- 'ee/app/services/sitemap/create_service.rb'
- 'ee/lib/ee/gitlab/auth/ldap/access.rb'
- 'ee/lib/gitlab/auth/smartcard/session.rb'
- 'ee/spec/features/account_recovery_regular_check_spec.rb'
- 'ee/spec/features/billings/billing_plans_spec.rb'
- 'ee/spec/features/boards/board_filters_spec.rb'
- 'ee/spec/features/boards/group_boards/board_deletion_spec.rb'
- 'ee/spec/features/boards/user_visits_board_spec.rb'
- 'ee/spec/features/groups/analytics/ci_cd_analytics_spec.rb'
- 'ee/spec/features/groups/issues_spec.rb'
- 'ee/spec/features/groups/iteration_spec.rb'
- 'ee/spec/features/groups/iterations/user_creates_iteration_in_cadence_spec.rb'
- 'ee/spec/features/groups/iterations/user_edits_iteration_cadence_spec.rb'
- 'ee/spec/features/groups/iterations/user_edits_iteration_spec.rb'
- 'ee/spec/features/merge_request/user_edits_multiple_reviewers_mr_spec.rb'
- 'ee/spec/features/merge_requests/user_resets_approvers_spec.rb'
- 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb'
- 'ee/spec/features/merge_trains/two_merge_requests_on_train_spec.rb'
- 'ee/spec/finders/ee/alert_management/http_integrations_finder_spec.rb'
- 'ee/spec/finders/epics_finder_spec.rb'
- 'ee/spec/finders/security/pipeline_vulnerabilities_finder_spec.rb'

View File

@ -229,7 +229,7 @@ gem 'gitlab-sidekiq-fetcher', '0.8.0', require: 'sidekiq-reliable-fetch'
gem 'fugit', '~> 1.2.1'
# HTTP requests
gem 'httparty', '~> 0.16.4'
gem 'httparty', '~> 0.20.0'
# Colored output to console
gem 'rainbow', '~> 3.0'

View File

@ -272,7 +272,7 @@
{"name":"http-cookie","version":"1.0.5","platform":"ruby","checksum":"73756d46c7dbdc7023deecdb8a171348ea95a1b99810b31cfe8b4fb4e9a6318f"},
{"name":"http-form_data","version":"2.3.0","platform":"ruby","checksum":"cc4eeb1361d9876821e31d7b1cf0b68f1cf874b201d27903480479d86448a5f3"},
{"name":"http-parser","version":"1.2.3","platform":"ruby","checksum":"414dec1f443d68e1068509f184ee4b93e3442f626645071182ce49bc27db18a3"},
{"name":"httparty","version":"0.16.4","platform":"ruby","checksum":"62c89d00f5e8933b2d397a49b57deb18ca18e16cb7d862ee4f53b73228dc3d81"},
{"name":"httparty","version":"0.20.0","platform":"ruby","checksum":"490d2a028a5accc611f1685d479d80ef80b129140d24a93c53c119f578614867"},
{"name":"httpclient","version":"2.8.3","platform":"ruby","checksum":"2951e4991214464c3e92107e46438527d23048e634f3aee91c719e0bdfaebda6"},
{"name":"i18n","version":"1.12.0","platform":"ruby","checksum":"91e3cc1b97616d308707eedee413d82ee021d751c918661fb82152793e64aced"},
{"name":"i18n_data","version":"0.8.0","platform":"ruby","checksum":"92d942cc193dc4a54a95b68f44e52c79e024fa72e09f26a982bc61153b6f0c6c"},

View File

@ -734,7 +734,7 @@ GEM
http-form_data (2.3.0)
http-parser (1.2.3)
ffi-compiler (>= 1.0, < 2.0)
httparty (0.16.4)
httparty (0.20.0)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
httpclient (2.8.3)
@ -1666,7 +1666,7 @@ DEPENDENCIES
health_check (~> 3.0)
html-pipeline (~> 2.13.2)
html2text
httparty (~> 0.16.4)
httparty (~> 0.20.0)
icalendar
invisible_captcha (~> 1.1.0)
ipaddr (= 1.2.2)

View File

@ -112,21 +112,21 @@ export default {
>
<div class="table-section section-20 section-wrap">
<div role="rowheader" class="table-mobile-header">{{ __('Suite') }}</div>
<div class="table-mobile-content gl-md-pr-2 gl-overflow-wrap-break">
<div class="table-mobile-content gl-pr-0 gl-sm-pr-2 gl-overflow-wrap-break">
<gl-friendly-wrap :symbols="$options.wrapSymbols" :text="testCase.classname" />
</div>
</div>
<div class="table-section section-40 section-wrap">
<div role="rowheader" class="table-mobile-header">{{ __('Name') }}</div>
<div class="table-mobile-content gl-md-pr-2 gl-overflow-wrap-break">
<div class="table-mobile-content gl-pr-0 gl-sm-pr-2 gl-overflow-wrap-break">
<gl-friendly-wrap :symbols="$options.wrapSymbols" :text="testCase.name" />
</div>
</div>
<div class="table-section section-10 section-wrap">
<div role="rowheader" class="table-mobile-header">{{ __('Filename') }}</div>
<div class="table-mobile-content gl-md-pr-2 gl-overflow-wrap-break">
<div class="table-mobile-content gl-pr-0 gl-sm-pr-2 gl-overflow-wrap-break">
<gl-link v-if="testCase.file" :href="testCase.filePath" target="_blank">
<gl-friendly-wrap :symbols="$options.wrapSymbols" :text="testCase.file" />
</gl-link>
@ -156,7 +156,7 @@ export default {
<div role="rowheader" class="table-mobile-header">
{{ __('Duration') }}
</div>
<div class="table-mobile-content gl-sm-pr-2">
<div class="table-mobile-content gl-pr-0 gl-sm-pr-2">
{{ testCase.formattedTime }}
</div>
</div>

View File

@ -170,7 +170,7 @@ export default {
this.$emit('closeForm');
},
openDatePicker() {
this.$refs.datePicker.calendar.show();
this.$refs.datePicker.show();
},
setFixedDate(isFixed) {
const date = this.issuable[dateFields[this.dateType].dateFixed];

View File

@ -1,11 +1,3 @@
export const AJAX_USERS_SELECT_OPTIONS_MAP = {
projectId: 'projectId',
groupId: 'groupId',
showCurrentUser: 'currentUser',
authorId: 'authorId',
skipUsers: 'skipUsers',
};
export const AJAX_USERS_SELECT_PARAMS_MAP = {
project_id: 'projectId',
group_id: 'groupId',

View File

@ -1,21 +1,17 @@
/* eslint-disable func-names, prefer-rest-params, consistent-return, no-shadow, no-self-compare, no-unused-expressions, yoda, prefer-spread, camelcase, no-param-reassign */
/* eslint-disable func-names, consistent-return, no-shadow, no-self-compare, no-unused-expressions, camelcase, no-param-reassign */
/* global Issuable */
/* global emitSidebarEvent */
import $ from 'jquery';
import { escape, template, uniqBy } from 'lodash';
import {
AJAX_USERS_SELECT_OPTIONS_MAP,
AJAX_USERS_SELECT_PARAMS_MAP,
} from 'ee_else_ce/users_select/constants';
import { AJAX_USERS_SELECT_PARAMS_MAP } from 'ee_else_ce/users_select/constants';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import { isUserBusy } from '~/set_status_modal/utils';
import { fixTitle, dispose } from '~/tooltips';
import axios from '~/lib/utils/axios_utils';
import { parseBoolean, spriteIcon } from '~/lib/utils/common_utils';
import { loadCSSFile } from '~/lib/utils/css_utils';
import { s__, __, sprintf } from '~/locale';
import { getAjaxUsersSelectOptions, getAjaxUsersSelectParams } from './utils';
import { getAjaxUsersSelectParams } from './utils';
// TODO: remove eventHub hack after code splitting refactor
window.emitSidebarEvent = window.emitSidebarEvent || $.noop;
@ -24,9 +20,7 @@ function UsersSelect(currentUser, els, options = {}) {
const elsClassName = els?.toString().match('.(.+$)')[1];
const $els = $(els || '.js-user-search');
this.users = this.users.bind(this);
this.user = this.user.bind(this);
this.usersPath = '/-/autocomplete/users.json';
this.userPath = '/-/autocomplete/users/:id.json';
if (currentUser != null) {
if (typeof currentUser === 'object') {
this.currentUser = currentUser;
@ -36,7 +30,6 @@ function UsersSelect(currentUser, els, options = {}) {
}
const { handleClick } = options;
const userSelect = this;
$els.each((i, dropdown) => {
const userSelect = this;
@ -619,156 +612,8 @@ function UsersSelect(currentUser, els, options = {}) {
},
});
});
if ($('.ajax-users-select').length) {
import(/* webpackChunkName: 'select2' */ 'select2/select2')
.then(() => {
// eslint-disable-next-line promise/no-nesting
loadCSSFile(gon.select2_css_path)
.then(() => {
$('.ajax-users-select').each((i, select) => {
const options = getAjaxUsersSelectOptions($(select), AJAX_USERS_SELECT_OPTIONS_MAP);
options.skipLdap = $(select).hasClass('skip_ldap');
const showNullUser = $(select).data('nullUser');
const showAnyUser = $(select).data('anyUser');
const showEmailUser = $(select).data('emailUser');
const firstUser = $(select).data('firstUser');
return $(select).select2({
placeholder: __('Search for a user'),
multiple: $(select).hasClass('multiselect'),
minimumInputLength: 0,
query(query) {
return userSelect.users(query.term, options, (users) => {
let name;
const data = {
results: users,
};
if (query.term.length === 0) {
if (firstUser) {
// Move current user to the front of the list
const ref = data.results;
for (let index = 0, len = ref.length; index < len; index += 1) {
const obj = ref[index];
if (obj.username === firstUser) {
data.results.splice(index, 1);
data.results.unshift(obj);
break;
}
}
}
if (showNullUser) {
const nullUser = {
name: s__('UsersSelect|Unassigned'),
id: 0,
};
data.results.unshift(nullUser);
}
if (showAnyUser) {
name = showAnyUser;
if (name === true) {
name = s__('UsersSelect|Any User');
}
const anyUser = {
name,
id: null,
};
data.results.unshift(anyUser);
}
}
if (
showEmailUser &&
data.results.length === 0 &&
query.term.match(/^[^@]+@[^@]+$/)
) {
const trimmed = query.term.trim();
const emailUser = {
name: sprintf(__('Invite "%{trimmed}" by email'), { trimmed }),
username: trimmed,
id: trimmed,
invite: true,
};
data.results.unshift(emailUser);
}
return query.callback(data);
});
},
initSelection() {
const args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return userSelect.initSelection.apply(userSelect, args);
},
formatResult() {
const args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return userSelect.formatResult.apply(userSelect, args);
},
formatSelection() {
const args = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return userSelect.formatSelection.apply(userSelect, args);
},
dropdownCssClass: 'ajax-users-dropdown',
// we do not want to escape markup since we are displaying html in results
escapeMarkup(m) {
return m;
},
});
});
})
.catch(() => {});
})
.catch(() => {});
}
}
UsersSelect.prototype.initSelection = function (element, callback) {
const id = $(element).val();
if (id === '0') {
const nullUser = {
name: s__('UsersSelect|Unassigned'),
};
return callback(nullUser);
} else if (id !== '') {
return this.user(id, callback);
}
};
UsersSelect.prototype.formatResult = function (user) {
let avatar = gon.default_avatar_url;
if (user.avatar_url) {
avatar = user.avatar_url;
}
return `
<div class='user-result'>
<div class='user-image'>
<img class='avatar avatar-inline s32' src='${avatar}'>
</div>
<div class='user-info'>
<div class='user-name dropdown-menu-user-full-name'>
${escape(user.name)}
</div>
<div class='user-username dropdown-menu-user-username text-secondary'>
${!user.invite ? `@${escape(user.username)}` : ''}
</div>
</div>
</div>
`;
};
UsersSelect.prototype.formatSelection = function (user) {
return escape(user.name);
};
UsersSelect.prototype.user = function (user_id, callback) {
if (!/^\d+$/.test(user_id)) {
return false;
}
let url = this.buildUrl(this.userPath);
url = url.replace(':id', user_id);
return axios.get(url).then(({ data }) => {
callback(data);
});
};
// Return users list. Filtered by query
// Only active users retrieved
UsersSelect.prototype.users = function (query, options, callback) {

View File

@ -1,17 +1,3 @@
/**
* Get options from data attributes on passed `$select`.
* @param {jQuery} $select
* @param {Object} optionsMap e.g. { optionKeyName: 'dataAttributeName' }
*/
export const getAjaxUsersSelectOptions = ($select, optionsMap) => {
return Object.keys(optionsMap).reduce((accumulator, optionKey) => {
const dataKey = optionsMap[optionKey];
accumulator[optionKey] = $select.data(dataKey);
return accumulator;
}, {});
};
/**
* Get query parameters used for users request from passed `options` parameter
* @param {Object} options e.g. { currentUserId: 1, fooBar: 'baz' }

View File

@ -538,13 +538,15 @@ export default {
<div class="media-body">
<div class="mr-widget-body-controls gl-display-flex gl-align-items-center gl-flex-wrap">
<template v-if="shouldShowMergeControls">
<div class="gl-display-flex gl-align-items-center gl-flex-wrap gl-w-full gl-mb-5">
<div
class="gl-display-flex gl-sm-flex-direction-column gl-md-align-items-center gl-flex-wrap gl-w-full gl-md-pb-5"
>
<gl-form-checkbox
v-if="canRemoveSourceBranch"
id="remove-source-branch-input"
v-model="removeSourceBranch"
:disabled="isRemoveSourceBranchButtonDisabled"
class="js-remove-source-branch-checkbox gl-display-flex gl-align-items-center gl-mr-5"
class="js-remove-source-branch-checkbox gl-display-flex gl-align-items-center gl-mr-5 gl-mb-3 gl-md-mb-0"
>
{{ __('Delete source branch') }}
</gl-form-checkbox>
@ -555,37 +557,18 @@ export default {
v-model="squashBeforeMerge"
:help-path="mr.squashBeforeMergeHelpPath"
:is-disabled="isSquashReadOnly"
class="gl-mr-5"
class="gl-mr-5 gl-mb-3 gl-md-mb-0"
/>
<gl-form-checkbox
v-if="shouldShowSquashEdit || shouldShowMergeEdit"
v-model="editCommitMessage"
data-testid="widget_edit_commit_message"
class="gl-display-flex gl-align-items-center"
class="gl-display-flex gl-align-items-center gl-mb-3 gl-md-mb-0"
>
{{ __('Edit commit message') }}
</gl-form-checkbox>
</div>
<div class="gl-w-full gl-text-gray-500 gl-mb-5">
<added-commit-message
:is-squash-enabled="squashBeforeMerge"
:is-fast-forward-enabled="!shouldShowMergeEdit"
:commits-count="commitsCount"
:target-branch="stateData.targetBranch"
/>
<template v-if="mr.relatedLinks">
&middot;
<related-links
:state="mr.state"
:related-links="mr.relatedLinks"
:show-assign-to-me="false"
:diverged-commits-count="mr.divergedCommitsCount"
:target-branch-path="mr.targetBranchPath"
class="mr-ready-merge-related-links gl-display-inline"
/>
</template>
</div>
<div v-if="editCommitMessage" class="gl-w-full" data-testid="edit_commit_message">
<ul class="border-top commits-list flex-list gl-list-style-none gl-p-0 gl-pt-4">
<commit-edit
@ -625,6 +608,25 @@ export default {
</li>
</ul>
</div>
<div class="gl-w-full gl-text-gray-500 gl-mb-3 gl-md-mb-0 gl-md-pb-5">
<added-commit-message
:is-squash-enabled="squashBeforeMerge"
:is-fast-forward-enabled="!shouldShowMergeEdit"
:commits-count="commitsCount"
:target-branch="stateData.targetBranch"
/>
<template v-if="mr.relatedLinks">
&middot;
<related-links
:state="mr.state"
:related-links="mr.relatedLinks"
:show-assign-to-me="false"
:diverged-commits-count="mr.divergedCommitsCount"
:target-branch-path="mr.targetBranchPath"
class="mr-ready-merge-related-links gl-display-inline"
/>
</template>
</div>
<gl-button-group class="gl-align-self-start">
<gl-button
size="medium"

View File

@ -134,12 +134,12 @@ export default {
async clickShowDueDate() {
this.showDueDateInput = true;
await this.$nextTick();
this.$refs.dueDatePicker.calendar.show();
this.$refs.dueDatePicker.show();
},
async clickShowStartDate() {
this.showStartDateInput = true;
await this.$nextTick();
this.$refs.startDatePicker.calendar.show();
this.$refs.startDatePicker.show();
},
handleStartDateInput() {
if (this.dirtyDueDate && this.dirtyStartDate > this.dirtyDueDate) {

View File

@ -1,15 +1,3 @@
.ajax-users-select {
width: 400px;
&.input-large {
width: 210px;
}
&.input-clamp {
max-width: 100%;
}
}
.group-result {
.group-image {
float: left;
@ -49,7 +37,3 @@
}
}
}
.ajax-users-dropdown {
min-width: 250px !important;
}

View File

@ -84,7 +84,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
format.json do
Gitlab::UsageDataCounters::ServiceUsageDataCounter.count(:download_payload_click)
render json: service_ping_data.to_json
render json: Gitlab::Json.dump(service_ping_data)
end
end
end

View File

@ -137,7 +137,7 @@ module AuthenticatesWithTwoFactor
session[:credentialRequestOptions] = get_options
session[:challenge] = get_options.challenge
gon.push(webauthn: { options: get_options.to_json })
gon.push(webauthn: { options: Gitlab::Json.dump(get_options) })
end
end
# rubocop: enable CodeReuse/ActiveRecord

View File

@ -86,7 +86,7 @@ class Projects::CommitController < Projects::ApplicationController
respond_to do |format|
format.json do
render json: @merge_requests.to_json
render json: Gitlab::Json.dump(@merge_requests)
end
end
end

View File

@ -15,7 +15,7 @@ module Projects
gcpRegions: gcp_regions,
revokeOauthUrl: revoke_oauth_url
}
@js_data = js_data.to_json
@js_data = Gitlab::Json.dump(js_data)
track_event(:render_page)
end

View File

@ -17,7 +17,8 @@ module Projects
cloudsqlInstances: ::GoogleCloud::GetCloudsqlInstancesService.new(project).execute,
emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg')
}
@js_data = js_data.to_json
@js_data = Gitlab::Json.dump(js_data)
track_event(:render_page)
end
@ -27,7 +28,7 @@ module Projects
@title = title(product)
@js_data = {
js_data = {
gcpProjects: gcp_projects,
refs: refs,
cancelPath: project_google_cloud_databases_path(project),
@ -35,7 +36,9 @@ module Projects
formDescription: description(product),
databaseVersions: Projects::GoogleCloud::CloudsqlHelper::VERSIONS[product],
tiers: Projects::GoogleCloud::CloudsqlHelper::TIERS
}.to_json
}
@js_data = Gitlab::Json.dump(js_data)
track_event(:render_form)
render template: 'projects/google_cloud/databases/cloudsql_form', formats: :html

View File

@ -11,7 +11,7 @@ class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::Base
enableCloudRunUrl: project_google_cloud_deployments_cloud_run_path(project),
enableCloudStorageUrl: project_google_cloud_deployments_cloud_storage_path(project)
}
@js_data = js_data.to_json
@js_data = Gitlab::Json.dump(js_data)
track_event(:render_page)
end

View File

@ -14,7 +14,7 @@ class Projects::GoogleCloud::GcpRegionsController < Projects::GoogleCloud::BaseC
refs: refs,
cancelPath: project_google_cloud_configuration_path(project)
}
@js_data = js_data.to_json
@js_data = Gitlab::Json.dump(js_data)
track_event(:render_form)
end

View File

@ -14,7 +14,7 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
refs: refs,
cancelPath: project_google_cloud_configuration_path(project)
}
@js_data = js_data.to_json
@js_data = Gitlab::Json.dump(js_data)
track_event(:render_form)
end

View File

@ -104,7 +104,7 @@ class Projects::GraphsController < Projects::ApplicationController
}
end
render json: @log.to_json
render json: Gitlab::Json.dump(@log)
end
def tracking_namespace_source

View File

@ -124,7 +124,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@commits_count = @merge_request.commits_count + @merge_request.context_commits_count
@diffs_count = get_diffs_count
@issuable_sidebar = serializer.represent(@merge_request, serializer: 'sidebar')
@current_user_data = UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestCurrentUserEntity).to_json
@current_user_data = Gitlab::Json.dump(UserSerializer.new(project: @project).represent(current_user, {}, MergeRequestCurrentUserEntity))
@show_whitespace_default = current_user.nil? || current_user.show_whitespace_in_diffs
@file_by_file_default = current_user&.view_diffs_file_by_file
@coverage_path = coverage_reports_project_merge_request_path(@project, @merge_request, format: :json) if @merge_request.has_coverage_reports?
@ -536,7 +536,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
render json: '', status: :no_content
when :parsed
render json: report_comparison[:data].to_json, status: :ok
render json: Gitlab::Json.dump(report_comparison[:data]), status: :ok
when :error
render json: { status_reason: report_comparison[:status_reason] }, status: :bad_request
else

View File

@ -58,7 +58,7 @@ class Projects::NotesController < Projects::ApplicationController
def outdated_line_change
diff_lines = Rails.cache.fetch(['note', note.id, 'oudated_line_change'], expires_in: 7.days) do
::MergeRequests::OutdatedDiscussionDiffLinesService.new(project: note.noteable.source_project, note: note).execute.to_json
Gitlab::Json.dump(::MergeRequests::OutdatedDiscussionDiffLinesService.new(project: note.noteable.source_project, note: note).execute)
end
render json: diff_lines

View File

@ -23,9 +23,11 @@ module Projects
def show
if Feature.enabled?(:ci_pipeline_triggers_settings_vue_ui, @project)
@triggers_json = ::Ci::TriggerSerializer.new.represent(
triggers = ::Ci::TriggerSerializer.new.represent(
@project.triggers, current_user: current_user, project: @project
).to_json
)
@triggers_json = Gitlab::Json.dump(triggers)
end
render

View File

@ -12,7 +12,7 @@ class Projects::TemplatesController < Projects::ApplicationController
templates = @template_type.template_subsets(project)
respond_to do |format|
format.json { render json: templates.to_json }
format.json { render json: Gitlab::Json.dump(templates) }
end
end
@ -20,7 +20,7 @@ class Projects::TemplatesController < Projects::ApplicationController
template = @template_type.find(params[:key], project)
respond_to do |format|
format.json { render json: template.to_json }
format.json { render json: Gitlab::Json.dump(template) }
end
end

View File

@ -343,7 +343,7 @@ class ProjectsController < Projects::ApplicationController
options['Commits'] = [ref]
end
render json: options.to_json
render json: Gitlab::Json.dump(options)
rescue Gitlab::Git::CommandError
render json: { error: _('Unable to load refs') }, status: :service_unavailable
end

View File

@ -108,7 +108,7 @@ class SearchController < ApplicationController
@ref = params[:project_ref] if params[:project_ref].present?
@filter = params[:filter]
render json: search_autocomplete_opts(term, filter: @filter).to_json
render json: Gitlab::Json.dump(search_autocomplete_opts(term, filter: @filter))
end
def opensearch

View File

@ -5,10 +5,6 @@ module Groups::GroupMembersHelper
AVATAR_SIZE = 40
def group_member_select_options
{ multiple: true, class: 'input-clamp qa-member-select-field ', scope: :all, email_user: true }
end
def group_members_app_data(group, members:, invited:, access_requests:, banned:, include_relations:, search:)
{
user: group_members_list_data(group, members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }),

View File

@ -1,30 +1,6 @@
# frozen_string_literal: true
module SelectsHelper
def users_select_tag(id, opts = {})
css_class = ["ajax-users-select"]
css_class << "multiselect" if opts[:multiple]
css_class << "skip_ldap" if opts[:skip_ldap]
css_class << (opts[:class] || '')
value = opts[:selected] || ''
html = {
class: css_class.join(' '),
data: users_select_data_attributes(opts)
}
unless opts[:scope] == :all
project = opts[:project] || @project
if project
html['data-project-id'] = project.id
elsif @group
html['data-group-id'] = @group.id
end
end
hidden_field_tag(id, value, html)
end
def groups_select_tag(id, opts = {})
classes = Array.wrap(opts[:class])
classes << 'ajax-groups-select'
@ -68,22 +44,6 @@ module SelectsHelper
hidden_field_tag(id, value, opts)
end
private
def users_select_data_attributes(opts)
{
placeholder: opts[:placeholder] || 'Search for a user',
null_user: opts[:null_user] || false,
any_user: opts[:any_user] || false,
email_user: opts[:email_user] || false,
first_user: opts[:first_user] && current_user ? current_user.username : false,
current_user: opts[:current_user] || false,
author_id: opts[:author_id] || '',
skip_users: opts[:skip_users] ? opts[:skip_users].map(&:id) : nil,
qa_selector: opts[:qa_selector] || ''
}
end
end
SelectsHelper.prepend_mod_with('SelectsHelper')

View File

@ -183,7 +183,7 @@ module Ci
false
end
def prevent_rollback_deployment?
def outdated_deployment?
false
end

View File

@ -445,9 +445,10 @@ module Ci
manual? && starts_environment? && deployment&.blocked?
end
def prevent_rollback_deployment?
strong_memoize(:prevent_rollback_deployment) do
def outdated_deployment?
strong_memoize(:outdated_deployment) do
starts_environment? &&
incomplete? &&
project.ci_forward_deployment_enabled? &&
deployment&.older_than_last_successful_deployment?
end

View File

@ -110,6 +110,10 @@ module Ci
COMPLETED_STATUSES.include?(status)
end
def incomplete?
COMPLETED_STATUSES.exclude?(status)
end
def blocked?
BLOCKED_STATUS.include?(status)
end

View File

@ -27,8 +27,8 @@ module Ci
false
end
condition(:prevent_rollback) do
@subject.prevent_rollback_deployment?
condition(:outdated_deployment) do
@subject.outdated_deployment?
end
condition(:owner_of_job) do
@ -77,12 +77,14 @@ module Ci
# Authorizing the user to access to protected entities.
# There is a "jailbreak" mode to exceptionally bypass the authorization,
# however, you should NEVER allow it, rather suspect it's a wrong feature/product design.
rule { ~can?(:jailbreak) & (archived | protected_ref | protected_environment | prevent_rollback) }.policy do
rule { ~can?(:jailbreak) & (archived | protected_ref | protected_environment) }.policy do
prevent :update_build
prevent :update_commit_status
prevent :erase_build
end
rule { outdated_deployment }.prevent :update_build
rule { can?(:admin_build) | (can?(:update_build) & owner_of_job & unprotected_ref) }.enable :erase_build
rule { can?(:public_access) & branch_allows_collaboration }.policy do

View File

@ -52,15 +52,13 @@ class EnvironmentSerializer < BaseSerializer
end
def batch_load(resource)
temp_deployment_associations = deployment_associations
resource = resource.preload(environment_associations)
Preloaders::Environments::DeploymentPreloader.new(resource)
.execute_with_union(:last_deployment, temp_deployment_associations)
.execute_with_union(:last_deployment, deployment_associations)
Preloaders::Environments::DeploymentPreloader.new(resource)
.execute_with_union(:upcoming_deployment, temp_deployment_associations)
.execute_with_union(:upcoming_deployment, deployment_associations)
resource.to_a.tap do |environments|
environments.each do |environment|

View File

@ -25,7 +25,7 @@ module Ci
end
def enqueue(build)
return build.drop!(:failed_outdated_deployment_job) if build.prevent_rollback_deployment?
return build.drop!(:failed_outdated_deployment_job) if build.outdated_deployment?
build.enqueue
end

View File

@ -0,0 +1,8 @@
---
name: scan_result_role_action
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101464
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/377866
milestone: '15.6'
type: development
group: group::security policies
default_enabled: false

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class DropFingerprintFromSbomSources < Gitlab::Database::Migration[2.0]
enable_lock_retries!
def change
remove_column :sbom_sources, :fingerprint, :bytea
end
end

View File

@ -0,0 +1 @@
8449de1e73e2fb46698e0e160641c4132b99918792b0b3379d6009bab9eab0b7

View File

@ -21098,8 +21098,7 @@ CREATE TABLE sbom_sources (
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
source_type smallint NOT NULL,
source jsonb DEFAULT '{}'::jsonb NOT NULL,
fingerprint bytea
source jsonb DEFAULT '{}'::jsonb NOT NULL
);
CREATE SEQUENCE sbom_sources_id_seq

View File

@ -30,7 +30,7 @@ The tables lists features on the left and provides their capabilities to the rig
## Geo Capabilities
If your availability needs to span multiple zones or multiple locations, please read about [Geo](geo/index.md).
If your availability needs to span multiple zones or multiple locations, read about [Geo](geo/index.md).
| | Availability | Recoverability | Data Resiliency | Performance | Risks/Trade-offs|
|-|--------------|----------------|-----------------|-------------|-----------------|

View File

@ -19,7 +19,7 @@ length of this window is determined by your replication capacity - once the
data loss.
This document assumes you already have a fully configured, working Geo setup.
Please read it and the [Disaster Recovery](index.md) failover
Read this document and the [Disaster Recovery](index.md) failover
documentation in full before proceeding. Planned failover is a major operation,
and if performed incorrectly, there is a high risk of data loss. Consider
rehearsing the procedure until you are comfortable with the necessary steps and

View File

@ -45,7 +45,7 @@ repository storage is either:
## Before deploying Gitaly Cluster
Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management.
Before deploying Gitaly Cluster, please review:
Before deploying Gitaly Cluster, review:
- Existing [known issues](#known-issues).
- [Snapshot limitations](#snapshot-backup-and-recovery-limitations).
@ -66,7 +66,7 @@ Contact your Technical Account Manager or customer support if you have any quest
### Known issues
The following table outlines current known issues impacting the use of Gitaly Cluster. For
the current status of these issues, please refer to the referenced issues and epics.
the current status of these issues, refer to the referenced issues and epics.
| Issue | Summary | How to avoid |
|:--------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------|
@ -83,11 +83,11 @@ during a restore, we recommend using the [official backup and restore Rake tasks
The [incremental backup method](../../raketasks/backup_gitlab.md#incremental-repository-backups)
can be used to speed up Gitaly Cluster backups.
If you are unable to use either method, please contact customer support for restoration help.
If you are unable to use either method, contact customer support for restoration help.
### What to do if you are on Gitaly Cluster experiencing an issue or limitation
Please contact customer support for immediate help in restoration or recovery.
Contact customer support for immediate help in restoration or recovery.
## Directly accessing repositories
@ -410,7 +410,7 @@ relative path of the repository in the metadata store.
### Moving beyond NFS
Engineering support for NFS for Git repositories is deprecated. Technical support is planned to be unavailable starting
November 22, 2022. Please see our [statement of support](https://about.gitlab.com/support/statement-of-support/#gitaly-and-nfs)
November 22, 2022. See our [statement of support](https://about.gitlab.com/support/statement-of-support/#gitaly-and-nfs)
for more details.
[Network File System (NFS)](https://en.wikipedia.org/wiki/Network_File_System)
@ -718,4 +718,4 @@ The second facet presents the only real solution. For this, we developed
## NFS deprecation notice
Engineering support for NFS for Git repositories is deprecated. Technical support is planned to be
unavailable beginning November 22, 2022. For further information, please see our [NFS Deprecation](../nfs.md#gitaly-and-nfs-deprecation) documentation.
unavailable beginning November 22, 2022. For further information, see our [NFS Deprecation](../nfs.md#gitaly-and-nfs-deprecation) documentation.

View File

@ -359,7 +359,7 @@ necessary because [this issue](https://gitlab.com/gitlab-org/gitaly/-/issues/252
If this error occurs even though file permissions are correct, it's likely that the Gitaly node is
experiencing [clock drift](https://en.wikipedia.org/wiki/Clock_drift).
Please ensure that the GitLab and Gitaly nodes are synchronized and use an NTP time
Ensure that the GitLab and Gitaly nodes are synchronized and use an NTP time
server to keep them synchronized if possible.
### Health check warnings

View File

@ -141,7 +141,7 @@ These actions pose a temporary vulnerability while your old Grafana data is in u
Deciding to take any of these actions should be weighed carefully with your need to access
existing data and dashboards.
For more information and further mitigation details, please refer to our
For more information and further mitigation details, refer to our
[blog post on the security release](https://about.gitlab.com/releases/2019/08/12/critical-security-release-gitlab-12-dot-1-dot-6-released/).
Read more on:

View File

@ -52,7 +52,7 @@ If the issue is reproducible, or if it happens intermittently but regularly, Git
NFS is not well-suited to a workload consisting of many small files, like Git repositories. NFS does provide a number of configuration options designed to improve performance. However, over time, a number of these mount options have proven to result in inconsistencies across multiple nodes mounting the NFS volume, up to and including data loss. Addressing these inconsistencies consume extraordinary development and support engineer time that hamper our ability to develop [Gitaly Cluster](gitaly/praefect.md), our purpose-built solution to addressing the deficiencies of NFS in this environment.
Please note that Gitaly Cluster provides highly-available Git repository storage. If this is not a requirement, single-node Gitaly backed by block storage is a suitable substitute.
Gitaly Cluster provides highly-available Git repository storage. If this is not a requirement, single-node Gitaly backed by block storage is a suitable substitute.
Engineering support for NFS for Git repositories is deprecated. Technical support is planned to be
unavailable from GitLab 15.0. No further enhancements are planned for this feature.

View File

@ -68,7 +68,7 @@ over a network which will require, based on implementation, ports `111` and
`2049` to be open.
NOTE:
In some cases, the GitLab Registry will be automatically enabled by default. Please see [our documentation](../packages/container_registry.md) for more details
In some cases, the GitLab Registry will be automatically enabled by default. See [our documentation](../packages/container_registry.md) for more details.
[^Consul-notes]: If using additional Consul functionality, more ports may need to be opened. See the [official documentation](https://www.consul.io/docs/install/ports#ports-table) for the list.

View File

@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Package Signatures **(FREE SELF)**
As of the release of GitLab 9.5 on August 22, 2017, GitLab provides signed Omnibus GitLab packages for RPM and DEB based distributions. This means that all packages provided on <https://packages.gitlab.com> are signed, starting with `9.5.0`, and all future versions of supported branches (for example `9.3.x` and `9.4.x` after August 22, 2017). Any package version prior to August 22, 2017, will not be signed. Please pass the appropriate argument to your package manager. (Example: `yum --nogpgcheck`)
As of the release of GitLab 9.5 on August 22, 2017, GitLab provides signed Omnibus GitLab packages for RPM and DEB based distributions. This means that all packages provided on <https://packages.gitlab.com> are signed, starting with `9.5.0`, and all future versions of supported branches (for example `9.3.x` and `9.4.x` after August 22, 2017). Any package version prior to August 22, 2017, will not be signed. Pass the appropriate argument to your package manager. (Example: `yum --nogpgcheck`)
Omnibus GitLab packages produced by GitLab are created via the [Omnibus](https://github.com/chef/omnibus) tool, for which GitLab has added DEB signing via `debsigs` in [our own fork](https://gitlab.com/gitlab-org/omnibus). This addition, combined with the existing functionality of RPM signing, allows GitLab to provide signed packages for all supported distributions using DEB or RPM.

View File

@ -606,7 +606,7 @@ Here is a list and description of each machine and the assigned IP:
- `10.6.0.33`: PostgreSQL 3
- `10.6.0.41`: GitLab application
All passwords are set to `toomanysecrets`. Please do not use this password or derived hashes and the `external_url` for GitLab is `http://gitlab.example.com`.
All passwords are set to `toomanysecrets`. Do not use this password or derived hashes and the `external_url` for GitLab is `http://gitlab.example.com`.
After the initial configuration, if a failover occurs, the PostgresSQL leader node changes to one of the available secondaries until it is failed back.
@ -957,7 +957,7 @@ For further details, see [Patroni documentation on this subject](https://patroni
### Switching from repmgr to Patroni
WARNING:
Switching from repmgr to Patroni is straightforward, the other way around is *not*. Rolling back from Patroni to repmgr can be complicated and may involve deletion of data directory. If you need to do that, please contact GitLab support.
Switching from repmgr to Patroni is straightforward, the other way around is *not*. Rolling back from Patroni to repmgr can be complicated and may involve deletion of data directory. If you need to do that, contact GitLab support.
You can switch an exiting database cluster to use Patroni instead of repmgr with the following steps:

View File

@ -66,7 +66,7 @@ When a **Primary** fails to respond, it's the application's responsibility
(in our case GitLab) to handle timeout and reconnect (querying a **Sentinel**
for a new **Primary**).
To get a better understanding on how to correctly set up Sentinel, please read
To get a better understanding on how to correctly set up Sentinel, read
the [Redis Sentinel](https://redis.io/docs/manual/sentinel/) documentation first, as
failing to configure it correctly can lead to data loss or can bring your
whole cluster down, invalidating the failover effort.
@ -350,7 +350,7 @@ Now that the Redis servers are all set up, let's configure the Sentinel
servers.
If you are not sure if your Redis servers are working and replicating
correctly, please read the [Troubleshooting Replication](troubleshooting.md#troubleshooting-redis-replication)
correctly, read the [Troubleshooting Replication](troubleshooting.md#troubleshooting-redis-replication)
and fix it before proceeding with Sentinel setup.
You must have at least `3` Redis Sentinel servers, and they need to

View File

@ -64,7 +64,7 @@ settings outlined in
We cannot stress enough the importance of reading the
[replication and failover](replication_and_failover.md) documentation of the
Omnibus Redis HA as it provides some invaluable information to the configuration
of Redis. Please proceed to read it before going forward with this guide.
of Redis. Read it before going forward with this guide.
Before proceeding on setting up the new Redis instances, here are some
requirements:

View File

@ -134,7 +134,7 @@ X-Gitlab-Event: System Hook
```
Note that `project_rename` is not triggered if the namespace changes.
Please refer to `group_rename` and `user_rename` for that case.
Refer to `group_rename` and `user_rename` for that case.
**Project transferred:**

View File

@ -20,13 +20,13 @@ are only available internally at GitLab.
## Docker
The following were tested on Docker containers running in the cloud. Support Engineers,
please see [these docs](https://gitlab.com/gitlab-com/dev-resources/tree/master/dev-resources#running-docker-containers)
see [these docs](https://gitlab.com/gitlab-com/dev-resources/tree/master/dev-resources#running-docker-containers)
on how to run Docker containers on `dev-resources`. Other setups haven't been tested,
but contributions are welcome.
### GitLab
Please see [our official Docker installation method](../../install/docker.md)
See [our official Docker installation method](../../install/docker.md)
for how to run GitLab on Docker.
### SAML

View File

@ -503,8 +503,7 @@ Example responses:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35739) in GitLab 12.7.
NOTE:
Not all deployments can be associated with merge requests.
Please see
Not all deployments can be associated with merge requests. See
[Track what merge requests were deployed to an environment](../ci/environments/index.md#track-newly-included-merge-requests-per-deployment)
for more information.

View File

@ -1,6 +1,6 @@
---
stage: Monitor
group: Respond
group: Observability
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -9,4 +9,4 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in GitLab 12.5.
This API was removed in [GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369).
Please use [the new API](feature_flags.md) instead.
Use [the new API](feature_flags.md) instead.

View File

@ -16230,6 +16230,7 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="pipelinesecurityreportfindingconfidence"></a>`confidence` **{warning-solid}** | [`String`](#string) | **Deprecated** in 15.4. This field will be removed from the Finding domain model. |
| <a id="pipelinesecurityreportfindingdescription"></a>`description` | [`String`](#string) | Description of the vulnerability finding. |
| <a id="pipelinesecurityreportfindingdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
| <a id="pipelinesecurityreportfindingdetails"></a>`details` | [`[VulnerabilityDetail!]!`](#vulnerabilitydetail) | Details of the security finding. |
| <a id="pipelinesecurityreportfindingevidence"></a>`evidence` | [`VulnerabilityEvidence`](#vulnerabilityevidence) | Evidence for the vulnerability. |
| <a id="pipelinesecurityreportfindingfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. |
| <a id="pipelinesecurityreportfindingidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerability finding. |

View File

@ -1413,7 +1413,7 @@ Parameters:
## Group members
Please consult the [Group Members](members.md) documentation.
See the [Group Members](members.md) documentation.
## LDAP Group Links

View File

@ -91,12 +91,13 @@ can be prevented in some circumstances.
### How to rollback to an outdated deployment
In some cases, you need to rollback to an outdated deployment. Current workarounds are:
> In GitLab 15.6, [rollback via job retry was introduced back](https://gitlab.com/gitlab-org/gitlab/-/issues/378359).
- Temporarily disable this feature, rollback and re-enable.
- Run a new pipeline with previous commit. It contains newer deployment jobs than the latest deployment.
In some cases, you need to rollback to an outdated deployment.
This feature explicitly allows rollback via [Environment Rollback](index.md#environment-rollback),
so that you can quickly rollback in an urgent case.
Please see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/378359) for more information about improving the usability.
Alternatively, you can run a new pipeline with a previous commit. It contains newer deployment jobs than the latest deployment.
### Example

View File

@ -1,6 +1,6 @@
---
stage: Package
group: Package
group: Container Registry
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

View File

@ -36,3 +36,4 @@ Development and architectural documentation for the container registry
- [Dependency proxy structure](dependency_proxy.md)
- [Settings](settings.md)
- [Structure / Schema](structure.md)
- [Cleanup policies](cleanup_policies.md)

View File

@ -282,7 +282,7 @@ end
#### Stubbing methods within factories
You should avoid using `allow(object).to receive(:method)` in factories, as this makes the factory unable to be used with `let_it_be`.
You should avoid using `allow(object).to receive(:method)` in factories, as this makes the factory unable to be used with `let_it_be`, as described in [common test setup](#common-test-setup).
Instead, you can use `stub_method` to stub the method:
@ -921,13 +921,16 @@ them unspecified, and look up the value after the row is created.
#### Redis
GitLab stores two main categories of data in Redis: cached items, and Sidekiq
jobs.
jobs. [View the full list of `Gitlab::Redis::Wrapper` descendants](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/redis.rb) that are backed by
a separate Redis instance.
In most specs, the Rails cache is actually an in-memory store. This is replaced
between specs, so calls to `Rails.cache.read` and `Rails.cache.write` are safe.
However, if a spec makes direct Redis calls, it should mark itself with the
`:clean_gitlab_redis_cache`, `:clean_gitlab_redis_shared_state` or
`:clean_gitlab_redis_queues` traits as appropriate.
`:clean_gitlab_redis_queues` traits as appropriate. To avoid triggering rate
limiting in specs, mark the spec with the `:clean_gitlab_redis_rate_limiting`
trait.
#### Background jobs / Sidekiq

View File

@ -132,7 +132,7 @@ PowerShell has aliases for all of the following commands so you don't have to le
- `ls` ---> `dir`
- `rm` ---> `del`
- `rm -rf nonemptydir` ---> `rmdir /S nonemptydir`
- `/` ---> `\` (path separator)
- `/` ---> <code>&#92;</code> (path separator)
- `cat` ---> `type`
- `mv` ---> `move`
- Redirection works the same (for example, `>` and `2>&1`)

View File

@ -331,7 +331,7 @@ However, you cannot mix the wrapping tags:
```
If your diff includes words in `` `code` `` font, make sure to escape each backtick `` ` `` with a
backslash `\`. Otherwise the diff highlight does not render correctly:
backslash <code>&#92;</code>. Otherwise the diff highlight does not render correctly:
```markdown
- {+ Just regular text +}

View File

@ -81,9 +81,9 @@ Images follow this naming convention:
```
If your project is `gitlab.example.com/mynamespace/myproject`, for example,
then your image must be named `gitlab.example.com/mynamespace/myproject/my-app` at a minimum.
then your image must be named `gitlab.example.com/mynamespace/myproject` at a minimum.
You can append additional names to the end of an image name, up to three levels deep.
You can append additional names to the end of an image name, up to two levels deep.
For example, these are all valid image names for images within the project named `myproject`:

View File

@ -27,7 +27,7 @@ Advanced Search searches default project branches only.
| `+` | And | [`display +banner`](https://gitlab.com/search?group_id=9970&project_id=278964&repository_ref=&scope=blobs&search=display+%2Bbanner&snippets=) |
| `-` | Exclude | [`display -banner`](https://gitlab.com/search?group_id=9970&project_id=278964&scope=blobs&search=display+-banner) |
| `*` | Partial | [`bug error 50*`](https://gitlab.com/search?group_id=9970&project_id=278964&repository_ref=&scope=blobs&search=bug+error+50%2A&snippets=) |
| `\` | Escape | [`\*md`](https://gitlab.com/search?snippets=&scope=blobs&repository_ref=&search=%5C*md&group_id=9970&project_id=278964) |
| <code>&#92;</code> | Escape | [`\*md`](https://gitlab.com/search?snippets=&scope=blobs&repository_ref=&search=%5C*md&group_id=9970&project_id=278964) |
## Code search

View File

@ -499,4 +499,4 @@ You can troubleshoot this by trying the following:
- Verify your IDO/U2F hardware security key supports
the key type provided.
- Verify the version of OpenSSH is 8.2 or greater by
running `ssh -v`.
running `ssh -V`.

View File

@ -47,6 +47,8 @@ module Gitlab
{ key: key, name: name, content: content }
end
alias_method :as_json, :to_json
def <=>(other)
name <=> other.name
end

View File

@ -22137,9 +22137,6 @@ msgstr ""
msgid "Invite \"%{email}\" by email"
msgstr ""
msgid "Invite \"%{trimmed}\" by email"
msgstr ""
msgid "Invite Members"
msgstr ""
@ -35687,9 +35684,6 @@ msgstr ""
msgid "Search for a group"
msgstr ""
msgid "Search for a user"
msgstr ""
msgid "Search for an emoji"
msgstr ""

View File

@ -54,7 +54,7 @@
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "3.5.0",
"@gitlab/ui": "46.1.0",
"@gitlab/ui": "49.0.0",
"@gitlab/visual-review-tools": "1.7.3",
"@gitlab/web-ide": "0.0.1-dev-20220815034418",
"@rails/actioncable": "6.1.4-7",

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'Environment' do
let(:project) { create(:project, :repository) }
let_it_be(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:role) { :developer }
@ -17,7 +17,7 @@ RSpec.describe 'Environment' do
end
describe 'environment details page' do
let!(:environment) { create(:environment, project: project) }
let_it_be(:environment) { create(:environment, project: project) }
let!(:permissions) {}
let!(:deployment) {}
let!(:action) {}
@ -160,10 +160,20 @@ RSpec.describe 'Environment' do
end
context 'with related deployable present' do
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline, environment: environment.name) }
let_it_be(:previous_pipeline) { create(:ci_pipeline, project: project) }
let(:deployment) do
let_it_be(:previous_build) do
create(:ci_build, :success, pipeline: previous_pipeline, environment: environment.name)
end
let_it_be(:previous_deployment) do
create(:deployment, :success, environment: environment, deployable: previous_build)
end
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
let_it_be(:build) { create(:ci_build, pipeline: pipeline, environment: environment.name) }
let_it_be(:deployment) do
create(:deployment, :success, environment: environment, deployable: build)
end
@ -171,12 +181,10 @@ RSpec.describe 'Environment' do
visit_environment(environment)
end
it 'does show build name' do
expect(page).to have_link("#{build.name} (##{build.id})")
end
it 'shows the re-deploy button' do
it 'shows deployment information and buttons', :js do
expect(page).to have_button('Re-deploy to environment')
expect(page).to have_button('Rollback environment')
expect(page).to have_link("#{build.name} (##{build.id})")
end
context 'with manual action' do

View File

@ -1,21 +1,10 @@
import $ from 'jquery';
import { getAjaxUsersSelectOptions, getAjaxUsersSelectParams } from '~/users_select/utils';
import { getAjaxUsersSelectParams } from '~/users_select/utils';
const options = {
fooBar: 'baz',
activeUserId: 1,
};
describe('getAjaxUsersSelectOptions', () => {
it('returns options built from select data attributes', () => {
const $select = $('<select />', { 'data-foo-bar': 'baz', 'data-user-id': 1 });
expect(
getAjaxUsersSelectOptions($select, { fooBar: 'fooBar', activeUserId: 'user-id' }),
).toEqual(options);
});
});
describe('getAjaxUsersSelectParams', () => {
it('returns query parameters built from provided options', () => {
expect(

View File

@ -140,7 +140,7 @@ describe('WorkItemDueDate component', () => {
beforeEach(() => {
createComponent({ canUpdate: true, dueDate: '2022-12-31', startDate: '2022-12-31' });
datePickerOpenSpy = jest.spyOn(wrapper.vm.$refs.dueDatePicker.calendar, 'show');
datePickerOpenSpy = jest.spyOn(wrapper.vm.$refs.dueDatePicker, 'show');
findStartDatePicker().vm.$emit('input', startDate);
findStartDatePicker().vm.$emit('close');
});

View File

@ -7,16 +7,6 @@ RSpec.describe Groups::GroupMembersHelper do
let_it_be(:group) { create(:group) }
describe '.group_member_select_options' do
before do
helper.instance_variable_set(:@group, group)
end
it 'returns an options hash' do
expect(helper.group_member_select_options).to include(multiple: true, scope: :all, email_user: true)
end
end
describe '#group_members_app_data' do
include_context 'group_group_link'

View File

@ -940,10 +940,8 @@ RSpec.describe Gitlab::Git::Repository do
let(:options) { { ref: 'master', path: ['PROCESS.md', 'README.md'] } }
def commit_files(commit)
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
commit.deltas.flat_map do |delta|
[delta.old_path, delta.new_path].uniq.compact
end
commit.deltas.flat_map do |delta|
[delta.old_path, delta.new_path].uniq.compact
end
end

View File

@ -9,7 +9,7 @@ RSpec.describe Gitlab::GithubImport::AttachmentsDownloader do
let_it_be(:content_type) { 'application/octet-stream' }
let(:content_length) { 1000 }
let(:chunk_double) { instance_double(HTTParty::FragmentWithResponse, code: 200) }
let(:chunk_double) { instance_double(HTTParty::ResponseFragment, code: 200) }
let(:headers_double) do
instance_double(
HTTParty::Response,

View File

@ -31,8 +31,8 @@ RSpec.describe Gitlab::Webpack::FileLoader do
stub_request(:get, "http://hostname:2000/public_path/#{error_file_path}").to_raise(StandardError)
end
it "returns content when respondes succesfully" do
expect(Gitlab::Webpack::FileLoader.load(file_path)).to be(file_contents)
it "returns content when responds successfully" do
expect(Gitlab::Webpack::FileLoader.load(file_path)).to eq(file_contents)
end
it "raises error when 404" do

View File

@ -605,8 +605,8 @@ RSpec.describe Ci::Build do
end
end
describe '#prevent_rollback_deployment?' do
subject { build.prevent_rollback_deployment? }
describe '#outdated_deployment?' do
subject { build.outdated_deployment? }
let(:build) { create(:ci_build, :created, :with_deployment, project: project, environment: 'production') }
@ -624,21 +624,33 @@ RSpec.describe Ci::Build do
it { expect(subject).to be_falsey }
end
context 'when deployment cannot rollback' do
context 'when build is not an outdated deployment' do
before do
expect(build.deployment).to receive(:older_than_last_successful_deployment?).and_return(false)
allow(build.deployment).to receive(:older_than_last_successful_deployment?).and_return(false)
end
it { expect(subject).to be_falsey }
end
context 'when build can prevent rollback deployment' do
context 'when build is older than the latest deployment and still pending status' do
before do
expect(build.deployment).to receive(:older_than_last_successful_deployment?).and_return(true)
allow(build.deployment).to receive(:older_than_last_successful_deployment?).and_return(true)
end
it { expect(subject).to be_truthy }
end
context 'when build is older than the latest deployment but succeeded once' do
let(:build) { create(:ci_build, :success, :with_deployment, project: project, environment: 'production') }
before do
allow(build.deployment).to receive(:older_than_last_successful_deployment?).and_return(true)
end
it 'returns false for allowing rollback' do
expect(subject).to be_falsey
end
end
end
describe '#schedulable?' do

View File

@ -159,7 +159,6 @@ func (c *Config) RegisterGoCloudURLOpeners() error {
if err != nil {
return err
}
c.ObjectStorageConfig.URLMux.RegisterBucket(azureblob.Scheme, urlOpener)
}
@ -168,14 +167,13 @@ func (c *Config) RegisterGoCloudURLOpeners() error {
if err != nil {
return err
}
c.ObjectStorageConfig.URLMux.RegisterBucket(gcsblob.Scheme, urlOpener)
}
return nil
}
func (creds *AzureCredentials) getURLOpener() (*azureURLOpener, error) {
func (creds *AzureCredentials) getURLOpener() (*azureblob.URLOpener, error) {
accountName := azureblob.AccountName(creds.AccountName)
accountKey := azureblob.AccountKey(creds.AccountKey)
@ -184,14 +182,10 @@ func (creds *AzureCredentials) getURLOpener() (*azureURLOpener, error) {
return nil, fmt.Errorf("error creating Azure credentials: %w", err)
}
pipeline := azureblob.NewPipeline(credential, azblob.PipelineOptions{})
return &azureURLOpener{
&azureblob.URLOpener{
AccountName: accountName,
Pipeline: pipeline,
Options: azureblob.Options{Credential: credential},
},
return &azureblob.URLOpener{
AccountName: accountName,
Pipeline: azureblob.NewPipeline(credential, azblob.PipelineOptions{}),
Options: azureblob.Options{Credential: credential},
}, nil
}

View File

@ -1,51 +0,0 @@
package config
import (
"context"
"fmt"
"net/url"
"gocloud.dev/blob"
"gocloud.dev/blob/azureblob"
)
// This code can be removed once https://github.com/google/go-cloud/pull/2851 is merged.
// URLOpener opens Azure URLs like "azblob://mybucket".
//
// The URL host is used as the bucket name.
//
// The following query options are supported:
// - domain: The domain name used to access the Azure Blob storage (e.g. blob.core.windows.net)
type azureURLOpener struct {
*azureblob.URLOpener
}
func (o *azureURLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) {
opts := new(azureblob.Options)
*opts = o.Options
err := setOptionsFromURLParams(u.Query(), opts)
if err != nil {
return nil, err
}
return azureblob.OpenBucket(ctx, o.Pipeline, o.AccountName, u.Host, opts)
}
func setOptionsFromURLParams(q url.Values, opts *azureblob.Options) error {
for param, values := range q {
if len(values) > 1 {
return fmt.Errorf("multiple values of %v not allowed", param)
}
value := values[0]
switch param {
case "domain":
opts.StorageDomain = azureblob.StorageDomain(value)
default:
return fmt.Errorf("unknown query parameter %q", param)
}
}
return nil
}

View File

@ -1,117 +0,0 @@
package config
import (
"context"
"net/url"
"testing"
"github.com/stretchr/testify/require"
"gocloud.dev/blob/azureblob"
)
func TestURLOpeners(t *testing.T) {
cfg, err := LoadConfig(azureConfig)
require.NoError(t, err)
require.NotNil(t, cfg.ObjectStorageCredentials, "Expected object storage credentials")
require.NoError(t, cfg.RegisterGoCloudURLOpeners())
require.NotNil(t, cfg.ObjectStorageConfig.URLMux)
tests := []struct {
url string
valid bool
}{
{
url: "azblob://container/object",
valid: true,
},
{
url: "azblob://container/object?domain=core.windows.net",
valid: true,
},
{
url: "azblob://container/object?domain=core.windows.net&domain=test",
valid: false,
},
{
url: "azblob://container/object?param=value",
valid: false,
},
{
url: "s3://bucket/object",
valid: false,
},
}
for _, test := range tests {
t.Run(test.url, func(t *testing.T) {
ctx := context.Background()
url, err := url.Parse(test.url)
require.NoError(t, err)
bucket, err := cfg.ObjectStorageConfig.URLMux.OpenBucketURL(ctx, url)
if bucket != nil {
defer bucket.Close()
}
if test.valid {
require.NotNil(t, bucket)
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
}
}
func TestTestURLOpenersForParams(t *testing.T) {
tests := []struct {
name string
currOpts azureblob.Options
query url.Values
wantOpts azureblob.Options
wantErr bool
}{
{
name: "InvalidParam",
query: url.Values{
"foo": {"bar"},
},
wantErr: true,
},
{
name: "StorageDomain",
query: url.Values{
"domain": {"blob.core.usgovcloudapi.net"},
},
wantOpts: azureblob.Options{StorageDomain: "blob.core.usgovcloudapi.net"},
},
{
name: "duplicate StorageDomain",
query: url.Values{
"domain": {"blob.core.usgovcloudapi.net", "blob.core.windows.net"},
},
wantErr: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
o := &azureURLOpener{
URLOpener: &azureblob.URLOpener{
Options: test.currOpts,
},
}
err := setOptionsFromURLParams(test.query, &o.Options)
if test.wantErr {
require.NotNil(t, err)
} else {
require.Nil(t, err)
require.Equal(t, test.wantOpts, o.Options)
}
})
}
}

View File

@ -1113,10 +1113,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.5.0.tgz#226240b7aa93db986f4c6f7738ca2a1846b5234d"
integrity sha512-/djPsJzUY7i/FaydRVt3ZyXiFf5HGNo1rg2mfLn1EpXvT4zc2ag5ECwnYcPb97KgqFCJX6Tk+Ndu8Wh3GoOW1g==
"@gitlab/ui@46.1.0":
version "46.1.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-46.1.0.tgz#df5918dfcf76ee444ad587f325d55555e8001de7"
integrity sha512-11zdly3bDWRqlbPo5kmhoDzcJ0n16kuhuxk2U4N8TMfHXgu6vUYp5NgjPrxzZRHlNVXsYiz7cAqifbr56fxTPg==
"@gitlab/ui@49.0.0":
version "49.0.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-49.0.0.tgz#dee2b7de7e4d7e281cd7ccf324d0fb5ad3086a5c"
integrity sha512-UOPiGi12wTvbqzJAWo1PDmtZXvcSzy5/auh8qKO9l3uYo4j0RpqYeloSkLvRSKs3V82lpVi0pyJt/S+mMzPjxA==
dependencies:
"@popperjs/core" "^2.11.2"
bootstrap-vue "2.20.1"