Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-05-12 21:08:38 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-12 21:08:38 +0300
commitaed0a60015f542db07f971fe321bd52207f632a4 (patch)
treef2a8ba4cf78799af1aff3ee49013afe791925bbb
parent0024c2f44455cf5ace9235a7efa195c12a1d72d2 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/issue_templates/Geo Replicate a new Git repository type.md27
-rw-r--r--.gitlab/issue_templates/Geo Replicate a new blob type.md28
-rw-r--r--.gitlab/merge_request_templates/Documentation.md2
-rw-r--r--app/assets/javascripts/clusters_list/components/agent_table.vue15
-rw-r--r--app/assets/javascripts/clusters_list/index.js2
-rw-r--r--app/assets/javascripts/diffs/components/diff_line_note_form.vue7
-rw-r--r--app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue20
-rw-r--r--app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js4
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue5
-rw-r--r--app/assets/javascripts/pipelines/components/graph/constants.js3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_item.vue22
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/graphql/queries/pipelines/get_pipeline_details.query.graphql1
-rw-r--r--app/helpers/clusters_helper.rb3
-rw-r--r--app/models/preloaders/user_max_access_level_in_projects_preloader.rb51
-rw-r--r--app/models/user.rb2
-rw-r--r--app/services/users/destroy_service.rb5
-rw-r--r--app/views/devise/passwords/new.html.haml8
-rw-r--r--app/views/devise/sessions/_new_base.html.haml2
-rw-r--r--app/views/devise/sessions/_new_base_user_login_label.html.haml1
-rw-r--r--config/feature_flags/development/nullify_in_batches_on_user_deletion.yml8
-rw-r--r--data/removals/15_0/15-0-advanced-search-elasticsearch-6-8.yml16
-rw-r--r--doc/administration/terraform_state.md4
-rw-r--r--doc/development/geo/framework.md6
-rw-r--r--doc/development/pipelines.md8
-rw-r--r--doc/update/removals.md14
-rw-r--r--doc/user/application_security/cluster_image_scanning/index.md4
-rw-r--r--doc/user/application_security/dependency_scanning/index.md9
-rw-r--r--doc/user/application_security/policies/scan-execution-policies.md7
-rw-r--r--doc/user/clusters/agent/troubleshooting.md8
-rw-r--r--doc/user/clusters/agent/vulnerabilities.md78
-rw-r--r--lefthook.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml8
-rw-r--r--lib/gitlab/kas.rb4
-rw-r--r--locale/gitlab.pot9
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb35
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb2
-rw-r--r--spec/frontend/clusters_list/components/agent_table_spec.js3
-rw-r--r--spec/frontend/pipelines/__snapshots__/utils_spec.js.snap11
-rw-r--r--spec/frontend/pipelines/graph/job_item_spec.js184
-rw-r--r--spec/frontend/pipelines/graph/mock_data.js97
-rw-r--r--spec/helpers/clusters_helper_spec.rb4
-rw-r--r--spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb42
-rw-r--r--spec/services/users/destroy_service_spec.rb37
-rw-r--r--spec/support/matchers/make_queries.rb31
-rw-r--r--spec/views/devise/shared/_signin_box.html.haml_spec.rb14
-rw-r--r--workhorse/internal/upload/artifacts_uploader.go8
47 files changed, 511 insertions, 352 deletions
diff --git a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
index b39356e74bd..bfcf7aca7b5 100644
--- a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
+++ b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
@@ -303,12 +303,6 @@ That's all of the required database changes.
git_access_class.error_message(:no_repo)
end
- # The feature flag follows the format `geo_#{replicable_name}_replication`,
- # so here it would be `geo_cool_widget_replication`
- def self.replication_enabled_by_default?
- false
- end
-
override :verification_feature_flag_enabled?
def self.verification_feature_flag_enabled?
# We are adding verification at the same time as replication, so we
@@ -715,27 +709,6 @@ As illustrated by the above two examples, batch destroy logic cannot be handled
- [ ] Add a step to `Test replication and verification of Cool Widgets on a non-GDK-deployment. For example, using GitLab Environment Toolkit`.
- [ ] Add a step to `Ping the Geo PM and EM to coordinate testing`. For example, you might add steps to generate Cool Widgets, and then a Geo engineer may take it from there.
- [ ] In `ee/config/feature_flags/development/geo_cool_widget_replication.yml`, set `default_enabled: true`
-
-- [ ] In `ee/app/replicators/geo/cool_widget_replicator.rb`, delete the `self.replication_enabled_by_default?` method:
-
- ```ruby
- module Geo
- class CoolWidgetReplicator < Gitlab::Geo::Replicator
- ...
- # REMOVE THIS LINE IF IT IS NO LONGER NEEDED
- extend ::Gitlab::Utils::Override
-
- # REMOVE THIS METHOD
- def self.replication_enabled_by_default?
- false
- end
- # REMOVE THIS METHOD
-
- ...
- end
- end
- ```
-
- [ ] In `ee/app/graphql/types/geo/geo_node_type.rb`, remove the `feature_flag` option for the released type:
```ruby
diff --git a/.gitlab/issue_templates/Geo Replicate a new blob type.md b/.gitlab/issue_templates/Geo Replicate a new blob type.md
index d005e0cdf43..ff678666191 100644
--- a/.gitlab/issue_templates/Geo Replicate a new blob type.md
+++ b/.gitlab/issue_templates/Geo Replicate a new blob type.md
@@ -291,12 +291,6 @@ That's all of the required database changes.
model_record.file
end
- # The feature flag follows the format `geo_#{replicable_name}_replication`,
- # so here it would be `geo_cool_widget_replication`
- def self.replication_enabled_by_default?
- false
- end
-
override :verification_feature_flag_enabled?
def self.verification_feature_flag_enabled?
# We are adding verification at the same time as replication, so we
@@ -680,28 +674,6 @@ As illustrated by the above two examples, batch destroy logic cannot be handled
- [ ] Add a step to `Test replication and verification of Cool Widgets on a non-GDK-deployment. For example, using GitLab Environment Toolkit`.
- [ ] Add a step to `Ping the Geo PM and EM to coordinate testing`. For example, you might add steps to generate Cool Widgets, and then a Geo engineer may take it from there.
- [ ] In `ee/config/feature_flags/development/geo_cool_widget_replication.yml`, set `default_enabled: true`
-
-- [ ] In `ee/app/replicators/geo/cool_widget_replicator.rb`, delete the `self.replication_enabled_by_default?` method:
-
- ```ruby
- module Geo
- class CoolWidgetReplicator < Gitlab::Geo::Replicator
- ...
- # REMOVE THIS LINE IF IT IS NO LONGER NEEDED
- extend ::Gitlab::Utils::Override
-
- ...
- # REMOVE THIS METHOD
- def self.replication_enabled_by_default?
- false
- end
- # REMOVE THIS METHOD
-
- ...
- end
- end
- ```
-
- [ ] In `ee/app/graphql/types/geo/geo_node_type.rb`, remove the `feature_flag` option for the released type:
```ruby
diff --git a/.gitlab/merge_request_templates/Documentation.md b/.gitlab/merge_request_templates/Documentation.md
index 49d1d0f79bf..cdc33b8aacb 100644
--- a/.gitlab/merge_request_templates/Documentation.md
+++ b/.gitlab/merge_request_templates/Documentation.md
@@ -8,7 +8,7 @@
## Author's checklist
-- [ ] Optional. Consider taking [the GitLab Technical Writing Fundamentals course](https://gitlab.edcast.com/pathways/ECL-02528ee2-c334-4e16-abf3-e9d8b8260de4).
+- [ ] Optional. Consider taking [the GitLab Technical Writing Fundamentals course](https://about.gitlab.com/handbook/engineering/ux/technical-writing/fundamentals/).
- [ ] Follow the:
- [Documentation process](https://docs.gitlab.com/ee/development/documentation/workflow.html).
- [Documentation guidelines](https://docs.gitlab.com/ee/development/documentation/).
diff --git a/app/assets/javascripts/clusters_list/components/agent_table.vue b/app/assets/javascripts/clusters_list/components/agent_table.vue
index b878a6835b2..496baf8cb08 100644
--- a/app/assets/javascripts/clusters_list/components/agent_table.vue
+++ b/app/assets/javascripts/clusters_list/components/agent_table.vue
@@ -39,7 +39,7 @@ export default {
configHelpLink: helpPagePath('user/clusters/agent/install/index', {
anchor: 'create-an-agent-configuration-file',
}),
- inject: ['gitlabVersion'],
+ inject: ['gitlabVersion', 'kasVersion'],
props: {
agents: {
required: true,
@@ -102,6 +102,9 @@ export default {
return { ...agent, versions };
});
},
+ serverVersion() {
+ return this.kasVersion || this.gitlabVersion;
+ },
},
methods: {
getStatusCellId(item) {
@@ -135,12 +138,12 @@ export default {
if (!agent.versions.length) return false;
const [agentMajorVersion, agentMinorVersion] = this.getAgentVersionString(agent).split('.');
- const [gitlabMajorVersion, gitlabMinorVersion] = this.gitlabVersion.split('.');
+ const [serverMajorVersion, serverMinorVersion] = this.serverVersion.split('.');
- const majorVersionMismatch = agentMajorVersion !== gitlabMajorVersion;
+ const majorVersionMismatch = agentMajorVersion !== serverMajorVersion;
// We should warn user if their current GitLab and agent versions are more than 1 minor version apart:
- const minorVersionMismatch = Math.abs(agentMinorVersion - gitlabMinorVersion) > 1;
+ const minorVersionMismatch = Math.abs(agentMinorVersion - serverMinorVersion) > 1;
return majorVersionMismatch || minorVersionMismatch;
},
@@ -240,7 +243,7 @@ export default {
<p class="gl-mb-0">
<gl-sprintf :message="$options.i18n.versionOutdatedText">
- <template #version>{{ gitlabVersion }}</template>
+ <template #version>{{ serverVersion }}</template>
</gl-sprintf>
<gl-link :href="$options.versionUpdateLink" class="gl-font-sm">
{{ $options.i18n.viewDocsText }}</gl-link
@@ -253,7 +256,7 @@ export default {
<p v-else-if="isVersionOutdated(item)" class="gl-mb-0">
<gl-sprintf :message="$options.i18n.versionOutdatedText">
- <template #version>{{ gitlabVersion }}</template>
+ <template #version>{{ serverVersion }}</template>
</gl-sprintf>
<gl-link :href="$options.versionUpdateLink" class="gl-font-sm">
{{ $options.i18n.viewDocsText }}</gl-link
diff --git a/app/assets/javascripts/clusters_list/index.js b/app/assets/javascripts/clusters_list/index.js
index 3d6890c419a..cd334d80e9c 100644
--- a/app/assets/javascripts/clusters_list/index.js
+++ b/app/assets/javascripts/clusters_list/index.js
@@ -30,6 +30,7 @@ export default () => {
canAddCluster,
canAdminCluster,
gitlabVersion,
+ kasVersion,
displayClusterAgents,
certificateBasedClustersEnabled,
} = el.dataset;
@@ -48,6 +49,7 @@ export default () => {
canAddCluster: parseBoolean(canAddCluster),
canAdminCluster: parseBoolean(canAdminCluster),
gitlabVersion,
+ kasVersion,
displayClusterAgents: parseBoolean(displayClusterAgents),
certificateBasedClustersEnabled: parseBoolean(certificateBasedClustersEnabled),
},
diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue
index 7a30740e31b..a2f0e2c2653 100644
--- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue
+++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue
@@ -1,6 +1,6 @@
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
-import { s__ } from '~/locale';
+import { s__, __ } from '~/locale';
import diffLineNoteFormMixin from '~/notes/mixins/diff_line_note_form';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -179,7 +179,10 @@ export default {
if (shouldConfirm && isDirty) {
const msg = s__('Notes|Are you sure you want to cancel creating this comment?');
- const confirmed = await confirmAction(msg);
+ const confirmed = await confirmAction(msg, {
+ primaryBtnText: __('Discard changes'),
+ cancelBtnText: __('Continue editing'),
+ });
if (!confirmed) {
return;
diff --git a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue
index 1d8eb73d3d7..3788d8ab20c 100644
--- a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue
+++ b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue
@@ -3,7 +3,6 @@ import { GlModal, GlSafeHtmlDirective } from '@gitlab/ui';
import { __ } from '~/locale';
export default {
- cancelAction: { text: __('Cancel') },
directives: {
SafeHtml: GlSafeHtmlDirective,
},
@@ -36,6 +35,16 @@ export default {
required: false,
default: 'confirm',
},
+ cancelText: {
+ type: String,
+ required: false,
+ default: __('Cancel'),
+ },
+ cancelVariant: {
+ type: String,
+ required: false,
+ default: 'default',
+ },
modalHtmlMessage: {
type: String,
required: false,
@@ -71,7 +80,14 @@ export default {
};
},
cancelAction() {
- return this.hideCancel ? null : this.$options.cancelAction;
+ return this.hideCancel
+ ? null
+ : {
+ text: this.cancelText,
+ attributes: {
+ variant: this.cancelVariant,
+ },
+ };
},
shouldShowHeader() {
return Boolean(this.title?.length);
diff --git a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js
index 1adb6f9c26f..173116062c9 100644
--- a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js
+++ b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js
@@ -7,6 +7,8 @@ export function confirmAction(
primaryBtnText,
secondaryBtnVariant,
secondaryBtnText,
+ cancelBtnVariant,
+ cancelBtnText,
modalHtmlMessage,
title,
hideCancel,
@@ -28,6 +30,8 @@ export function confirmAction(
secondaryVariant: secondaryBtnVariant,
primaryVariant: primaryBtnVariant,
primaryText: primaryBtnText,
+ cancelVariant: cancelBtnVariant,
+ cancelText: cancelBtnText,
title,
modalHtmlMessage,
hideCancel,
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index 000eb3bdff3..3f1dfea6b6a 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -176,7 +176,10 @@ export default {
if (shouldConfirm && isDirty) {
const msg = s__('Notes|Are you sure you want to cancel creating this comment?');
- const confirmed = await confirmAction(msg);
+ const confirmed = await confirmAction(msg, {
+ primaryBtnText: __('Discard changes'),
+ cancelBtnText: __('Continue editing'),
+ });
if (!confirmed) {
return;
diff --git a/app/assets/javascripts/pipelines/components/graph/constants.js b/app/assets/javascripts/pipelines/components/graph/constants.js
index aaf097b754f..85ca52f633e 100644
--- a/app/assets/javascripts/pipelines/components/graph/constants.js
+++ b/app/assets/javascripts/pipelines/components/graph/constants.js
@@ -15,5 +15,8 @@ export const VIEW_TYPE_KEY = 'pipeline_graph_view_type';
export const SINGLE_JOB = 'single_job';
export const JOB_DROPDOWN = 'job_dropdown';
+export const BUILD_KIND = 'BUILD';
+export const BRIDGE_KIND = 'BRIDGE';
+
export const ACTION_FAILURE = 'action_failure';
export const IID_FAILURE = 'missing_iid';
diff --git a/app/assets/javascripts/pipelines/components/graph/job_item.vue b/app/assets/javascripts/pipelines/components/graph/job_item.vue
index f69b25dfa7c..362571930d6 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_item.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_item.vue
@@ -1,5 +1,5 @@
<script>
-import { GlTooltipDirective, GlLink } from '@gitlab/ui';
+import { GlBadge, GlLink, GlTooltipDirective } from '@gitlab/ui';
import delayedJobMixin from '~/jobs/mixins/delayed_job_mixin';
import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { sprintf, __ } from '~/locale';
@@ -7,7 +7,7 @@ import CiIcon from '~/vue_shared/components/ci_icon.vue';
import { reportToSentry } from '../../utils';
import ActionComponent from '../jobs_shared/action_component.vue';
import JobNameComponent from '../jobs_shared/job_name_component.vue';
-import { SINGLE_JOB } from './constants';
+import { BRIDGE_KIND, SINGLE_JOB } from './constants';
/**
* Renders the badge for the pipeline graph and the job's dropdown.
@@ -35,11 +35,16 @@ import { SINGLE_JOB } from './constants';
*/
export default {
+ i18n: {
+ bridgeBadgeText: __('Trigger job'),
+ unauthorizedTooltip: __('You are not authorized to run this manual job'),
+ },
hoverClass: 'gl-shadow-x0-y0-b3-s1-blue-500',
components: {
ActionComponent,
CiIcon,
JobNameComponent,
+ GlBadge,
GlLink,
},
directives: {
@@ -113,6 +118,12 @@ export default {
isSingleItem() {
return this.type === SINGLE_JOB;
},
+ isBridge() {
+ return this.kind === BRIDGE_KIND;
+ },
+ kind() {
+ return this.job?.kind || '';
+ },
nameComponent() {
return this.hasDetails ? 'gl-link' : 'div';
},
@@ -187,6 +198,7 @@ export default {
[this.$options.hoverClass]:
this.relatedDownstreamHovered || this.relatedDownstreamExpanded,
},
+ { 'gl-rounded-lg': this.isBridge },
this.cssClassJobName,
];
},
@@ -213,9 +225,6 @@ export default {
this.$emit('pipelineActionRequestComplete');
},
},
- i18n: {
- unauthorizedTooltip: __('You are not authorized to run this manual job'),
- },
};
</script>
<template>
@@ -253,6 +262,9 @@ export default {
</div>
</div>
</div>
+ <gl-badge v-if="isBridge" class="gl-mt-3" variant="info" size="sm">
+ {{ $options.i18n.bridgeBadgeText }}
+ </gl-badge>
</component>
<action-component
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 6264f10ce2d..27969cb1a75 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -111,7 +111,7 @@ class Projects::BranchesController < Projects::ApplicationController
flash_type = result.error? ? :alert : :notice
flash[flash_type] = result.message
- redirect_to project_branches_path(@project), status: :see_other
+ redirect_back_or_default(default: project_branches_path(@project), options: { status: :see_other })
end
format.js { head result.http_status }
diff --git a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
index 003754fa4ad..c8353c738a5 100644
--- a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
+++ b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
@@ -102,6 +102,7 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
__typename
id
name
+ kind
scheduledAt
needs {
__typename
diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb
index b3abe4a71f7..8449bccd285 100644
--- a/app/helpers/clusters_helper.rb
+++ b/app/helpers/clusters_helper.rb
@@ -26,7 +26,8 @@ module ClustersHelper
default_branch_name: default_branch_name(clusterable),
project_path: clusterable_project_path(clusterable),
kas_address: Gitlab::Kas.external_url,
- gitlab_version: Gitlab.version_info
+ gitlab_version: Gitlab.version_info,
+ kas_version: Gitlab::Kas.version_info
}
end
diff --git a/app/models/preloaders/user_max_access_level_in_projects_preloader.rb b/app/models/preloaders/user_max_access_level_in_projects_preloader.rb
index 3764e9dcb16..2e2272a2ef5 100644
--- a/app/models/preloaders/user_max_access_level_in_projects_preloader.rb
+++ b/app/models/preloaders/user_max_access_level_in_projects_preloader.rb
@@ -5,25 +5,50 @@ module Preloaders
# stores the values in requests store via the ProjectTeam class.
class UserMaxAccessLevelInProjectsPreloader
def initialize(projects, user)
- @projects = projects
+ @projects = if projects.is_a?(Array)
+ Project.where(id: projects)
+ else
+ # Push projects base query in to a sub-select to avoid
+ # table name clashes. Performs better than aliasing.
+ Project.where(id: projects.reselect(:id))
+ end
+
@user = user
end
def execute
- # Use reselect to override the existing select to prevent
- # the error `subquery has too many columns`
- # NotificationsController passes in an Array so we need to check the type
- project_ids = @projects.is_a?(ActiveRecord::Relation) ? @projects.reselect(:id) : @projects
- access_levels = @user
- .project_authorizations
- .where(project_id: project_ids)
- .group(:project_id)
- .maximum(:access_level)
-
- @projects.each do |project|
- access_level = access_levels[project.id] || Gitlab::Access::NO_ACCESS
+ project_authorizations = ProjectAuthorization.arel_table
+
+ auths = @projects
+ .select(
+ Project.default_select_columns,
+ project_authorizations[:user_id],
+ project_authorizations[:access_level]
+ )
+ .joins(project_auth_join)
+
+ auths.each do |project|
+ access_level = project.access_level || Gitlab::Access::NO_ACCESS
ProjectTeam.new(project).write_member_access_for_user_id(@user.id, access_level)
end
end
+
+ private
+
+ def project_auth_join
+ project_authorizations = ProjectAuthorization.arel_table
+ projects = Project.arel_table
+
+ projects
+ .join(
+ project_authorizations.as(project_authorizations.name),
+ Arel::Nodes::OuterJoin
+ )
+ .on(
+ project_authorizations[:project_id].eq(projects[:id])
+ .and(project_authorizations[:user_id].eq(@user.id))
+ )
+ .join_sources
+ end
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index d499a6074e0..8aae4441852 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -239,6 +239,8 @@ class User < ApplicationRecord
has_many :timelogs
+ has_many :resource_label_events, dependent: :nullify # rubocop:disable Cop/ActiveRecordDependent
+
#
# Validations
#
diff --git a/app/services/users/destroy_service.rb b/app/services/users/destroy_service.rb
index 5dcdfdc604d..dfa9316889e 100644
--- a/app/services/users/destroy_service.rb
+++ b/app/services/users/destroy_service.rb
@@ -63,10 +63,7 @@ module Users
# destroying: https://github.com/rails/rails/issues/22510
# This ensures we delete records in batches.
user.destroy_dependent_associations_in_batches(exclude: [:snippets])
-
- if Feature.enabled?(:nullify_in_batches_on_user_deletion)
- user.nullify_dependent_associations_in_batches
- end
+ user.nullify_dependent_associations_in_batches
# Destroy the namespace after destroying the user since certain methods may depend on the namespace existing
user_data = user.destroy
diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml
index d5372862128..c90a9e7c672 100644
--- a/app/views/devise/passwords/new.html.haml
+++ b/app/views/devise/passwords/new.html.haml
@@ -3,17 +3,17 @@
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post, class: 'gl-show-field-errors' }) do |f|
.devise-errors
= render "devise/shared/error_messages", resource: resource
- .form-group
+ .form-group.gl-px-5.gl-pt-5
= f.label :email
= f.email_field :email, class: "form-control gl-form-input", required: true, autocomplete: 'off', value: params[:user_email], autofocus: true, title: _('Please provide a valid email address.')
.form-text.text-muted
= _('Requires your primary GitLab email address.')
- %div
- if recaptcha_enabled?
- = recaptcha_tags nonce: content_security_policy_nonce
+ .gl-px-5
+ = recaptcha_tags nonce: content_security_policy_nonce
- .gl-mt-5
+ .gl-p-5
= f.submit _("Reset password"), class: "gl-button btn-confirm btn"
.clearfix.prepend-top-20
diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml
index 1280341ba66..48b38861e6e 100644
--- a/app/views/devise/sessions/_new_base.html.haml
+++ b/app/views/devise/sessions/_new_base.html.haml
@@ -1,6 +1,6 @@
= gitlab_ui_form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'new_user gl-show-field-errors js-sign-in-form', aria: { live: 'assertive' }, data: { testid: 'sign-in-form' }}) do |f|
.form-group.gl-px-5.gl-pt-5
- = f.label _('Username or email'), for: 'user_login', class: 'label-bold'
+ = render_if_exists 'devise/sessions/new_base_user_login_label', form: f
= f.text_field :login, value: @invite_email, class: 'form-control gl-form-input top js-username-field', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', required: true, title: _('This field is required.'), data: { qa_selector: 'login_field', testid: 'username-field' }
.form-group.gl-px-5
= f.label :password, class: 'label-bold'
diff --git a/app/views/devise/sessions/_new_base_user_login_label.html.haml b/app/views/devise/sessions/_new_base_user_login_label.html.haml
new file mode 100644
index 00000000000..2aa66684cad
--- /dev/null
+++ b/app/views/devise/sessions/_new_base_user_login_label.html.haml
@@ -0,0 +1 @@
+= local_assigns[:form].label _('Username or email'), for: 'user_login', class: 'label-bold'
diff --git a/config/feature_flags/development/nullify_in_batches_on_user_deletion.yml b/config/feature_flags/development/nullify_in_batches_on_user_deletion.yml
deleted file mode 100644
index d97b4974f27..00000000000
--- a/config/feature_flags/development/nullify_in_batches_on_user_deletion.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: 'nullify_in_batches_on_user_deletion'
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84709
-rollout_issue_url:
-milestone: '14.10'
-type: development
-group: group::optimize
-default_enabled: true
diff --git a/data/removals/15_0/15-0-advanced-search-elasticsearch-6-8.yml b/data/removals/15_0/15-0-advanced-search-elasticsearch-6-8.yml
new file mode 100644
index 00000000000..5877b9cf0af
--- /dev/null
+++ b/data/removals/15_0/15-0-advanced-search-elasticsearch-6-8.yml
@@ -0,0 +1,16 @@
+- name: "Elasticsearch 6.8.x in GitLab 15.0"
+ announcement_milestone: "14.8"
+ announcement_date: "2022-02-22"
+ removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: true
+ reporter: JohnMcGuire
+ body: | # Do not modify this line, instead modify the lines below.
+ Elasticsearch 6.8 support has been removed in GitLab 15.0. Elasticsearch 6.8 has reached [end of life](https://www.elastic.co/support/eol).
+ If you use Elasticsearch 6.8, **you must upgrade your Elasticsearch version to 7.x** prior to upgrading to GitLab 15.0.
+ You should not upgrade to Elasticsearch 8 until you have completed the GitLab 15.0 upgrade.
+
+ View the [version requirements](https://docs.gitlab.com/ee/integration/elasticsearch.html#version-requirements) for details.
+# The following items are not published on the docs page, but may be used in the future.
+ stage: "Enablement"
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350275
diff --git a/doc/administration/terraform_state.md b/doc/administration/terraform_state.md
index c2fbcbdfc55..14649b82ba8 100644
--- a/doc/administration/terraform_state.md
+++ b/doc/administration/terraform_state.md
@@ -144,7 +144,7 @@ You can optionally track progress and verify that all packages migrated successf
Verify `objectstg` below (where `file_store=2`) has count of all states:
```shell
-gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM terraform_states;
+gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM terraform_state_versions;
total | filesystem | objectstg
------+------------+-----------
@@ -154,7 +154,7 @@ total | filesystem | objectstg
Verify that there are no files on disk in the `terraform_state` folder:
```shell
-sudo find /var/opt/gitlab/gitlab-rails/shared/terraform_state -type f | wc -l
+sudo find /var/opt/gitlab/gitlab-rails/shared/terraform_state -type f | grep -v tmp | wc -l
```
### S3-compatible connection settings
diff --git a/doc/development/geo/framework.md b/doc/development/geo/framework.md
index 778387986d8..055c2cd4ea8 100644
--- a/doc/development/geo/framework.md
+++ b/doc/development/geo/framework.md
@@ -93,12 +93,6 @@ module Geo
def self.model
::Packages::PackageFile
end
-
- # The feature flag follows the format `geo_#{replicable_name}_replication`,
- # so here it would be `geo_package_file_replication`
- def self.replication_enabled_by_default?
- false
- end
end
end
```
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index fec3dd3e1fb..b70f07ea7d9 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -247,12 +247,18 @@ The `* as-if-jh` jobs are run in addition to the regular EE-context jobs. The `j
The intent is to ensure that a change doesn't introduce a failure after `gitlab-org/gitlab` is synced to [GitLab JH](https://jihulab.com/gitlab-cn/gitlab).
+### When to consider applying `pipeline:run-as-if-jh` label
+
+If a Ruby file is renamed and there's a corresponding [`prepend_mod` line](jh_features_review.md#jh-features-based-on-ce-or-ee-features),
+it's likely that GitLab JH is relying on it and requires a corresponding
+change to rename the module or class it's prepending.
+
### Corresponding JH branch
You can create a corresponding JH branch on [GitLab JH](https://jihulab.com/gitlab-cn/gitlab) by
appending `-jh` to the branch name. If a corresponding JH branch is found,
`* as-if-jh` jobs grab the `jh` folder from the respective branch,
-rather than from the default branch.
+rather than from the default branch `main-jh`.
NOTE:
For now, CI will try to fetch the branch on the [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab), so it might take some time for the new JH branch to propagate to the mirror.
diff --git a/doc/update/removals.md b/doc/update/removals.md
index 3842637489f..a795d2476a3 100644
--- a/doc/update/removals.md
+++ b/doc/update/removals.md
@@ -116,6 +116,20 @@ The following `geo:db:*` tasks have been removed from GitLab 15.0 and have been
- `geo:db:test:load` -> `db:test:load:geo`
- `geo:db:test:purge` -> `db:test:purge:geo`
+### Elasticsearch 6.8.x in GitLab 15.0
+
+WARNING:
+This feature was changed or removed in 15.0
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
+
+Elasticsearch 6.8 support has been removed in GitLab 15.0. Elasticsearch 6.8 has reached [end of life](https://www.elastic.co/support/eol).
+If you use Elasticsearch 6.8, **you must upgrade your Elasticsearch version to 7.x** prior to upgrading to GitLab 15.0.
+You should not upgrade to Elasticsearch 8 until you have completed the GitLab 15.0 upgrade.
+
+View the [version requirements](https://docs.gitlab.com/ee/integration/elasticsearch.html#version-requirements) for details.
+
### GitLab Serverless
WARNING:
diff --git a/doc/user/application_security/cluster_image_scanning/index.md b/doc/user/application_security/cluster_image_scanning/index.md
index 97fcd2cdcff..aba28a5ca89 100644
--- a/doc/user/application_security/cluster_image_scanning/index.md
+++ b/doc/user/application_security/cluster_image_scanning/index.md
@@ -292,14 +292,12 @@ scan images from within your Kubernetes cluster and record the vulnerabilities i
### Prerequisites
-- [Starboard Operator](https://aquasecurity.github.io/starboard/v0.10.3/operator/installation/kubectl/)
- installed and configured in your cluster.
- [GitLab agent](../../clusters/agent/install/index.md)
set up in GitLab, installed in your cluster, and configured using a configuration repository.
### Configuration
-The agent runs the cluster image scanning once the `cluster_image_scanning`
+The agent runs the cluster image scanning once the `starboard`
directive is added to your [agent's configuration repository](../../clusters/agent/vulnerabilities.md).
## Security Dashboard
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 909f1353221..4ec6b0ccf3d 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -244,7 +244,7 @@ table.supported-languages ul {
</tr>
<tr>
<td rowspan="3">Python</td>
- <td rowspan="3">3.6</td>
+ <td rowspan="3">3.9</td>
<td><a href="https://setuptools.readthedocs.io/en/latest/">setuptools</a></td>
<td><code>setup.py</code></td>
<td><a href="https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium">Gemnasium</a></td>
@@ -915,9 +915,9 @@ import the following default dependency scanning analyzer images from `registry.
your [local Docker container registry](../../packages/container_registry/index.md):
```plaintext
-registry.gitlab.com/security-products/gemnasium:2
-registry.gitlab.com/security-products/gemnasium-maven:2
-registry.gitlab.com/security-products/gemnasium-python:2
+registry.gitlab.com/security-products/gemnasium:3
+registry.gitlab.com/security-products/gemnasium-maven:3
+registry.gitlab.com/security-products/gemnasium-python:3
```
The process for importing Docker images into a local offline Docker registry depends on
@@ -1219,5 +1219,4 @@ To work around this error, downgrade the analyzer's version of `setuptools` (e.g
gemnasium-python-dependency_scanning:
before_script:
- pip install setuptools==57.5.0
- image: registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python:2-python-3.9
```
diff --git a/doc/user/application_security/policies/scan-execution-policies.md b/doc/user/application_security/policies/scan-execution-policies.md
index 168c76ab710..9f68d2002b8 100644
--- a/doc/user/application_security/policies/scan-execution-policies.md
+++ b/doc/user/application_security/policies/scan-execution-policies.md
@@ -87,6 +87,13 @@ This rule enforces the defined actions and schedules a scan on the provided date
| `cadence` | `string` | CRON expression (for example, `0 0 * * *`) | A whitespace-separated string containing five fields that represents the scheduled time. |
| `clusters` | `object` | | The cluster where the given policy enforces running selected scans (only for `container_scanning`/`cluster_image_scanning` scans). The key of the object is the name of the Kubernetes cluster configured for your project in GitLab. In the optionally provided value of the object, you can precisely select Kubernetes resources that are scanned. |
+GitLab supports the following types of CRON syntax for the `cadence` field:
+
+- A daily cadence of once per hour at a specified hour, for example: `0 18 * * *`
+- A weekly cadence of once per week on a specified day and at a specified hour, for example: `0 13 * * 0`
+
+It is possible that other elements of the CRON syntax will work in the cadence field, however, GitLab does not officially test or support them.
+
### `cluster` schema
Use this schema to define `clusters` objects in the [`schedule` rule type](#schedule-rule-type).
diff --git a/doc/user/clusters/agent/troubleshooting.md b/doc/user/clusters/agent/troubleshooting.md
index c5c7e46c078..0932e9179f9 100644
--- a/doc/user/clusters/agent/troubleshooting.md
+++ b/doc/user/clusters/agent/troubleshooting.md
@@ -11,7 +11,7 @@ When you are using the GitLab agent for Kubernetes, you might experience issues
You can start by viewing the service logs:
```shell
-kubectl logs -f -l=app=gitlab-agent -n gitlab-kubernetes-agent
+kubectl logs -f -l=app=gitlab-agent -n gitlab-agent
```
If you are a GitLab administrator, you can also view the [GitLab agent server logs](../../../administration/clusters/kas.md#troubleshooting).
@@ -113,14 +113,14 @@ will be picked up automatically.
For example, if your internal CA certificate is `myCA.pem`:
```plaintext
-kubectl -n gitlab-kubernetes-agent create configmap ca-pemstore --from-file=myCA.pem
+kubectl -n gitlab-agent create configmap ca-pemstore --from-file=myCA.pem
```
Then in `resources.yml`:
```yaml
spec:
- serviceAccountName: gitlab-kubernetes-agent
+ serviceAccountName: gitlab-agent
containers:
- name: agent
image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:<version>"
@@ -140,7 +140,7 @@ Then in `resources.yml`:
volumes:
- name: token-volume
secret:
- secretName: gitlab-kubernetes-agent-token
+ secretName: gitlab-agent-token
- name: ca-pemstore-volume
configMap:
name: ca-pemstore
diff --git a/doc/user/clusters/agent/vulnerabilities.md b/doc/user/clusters/agent/vulnerabilities.md
index 480b09ff2ab..69f5b1d9063 100644
--- a/doc/user/clusters/agent/vulnerabilities.md
+++ b/doc/user/clusters/agent/vulnerabilities.md
@@ -34,80 +34,34 @@ You can use [cluster image scanning](../../application_security/cluster_image_sc
to scan container images in your cluster for security vulnerabilities.
To begin scanning all resources in your cluster, add a `starboard`
-configuration block to your agent configuration file with no `filters`:
+configuration block to your agent configuration with a `cadence` field
+containing a CRON expression for when the scans will be run.
```yaml
starboard:
vulnerability_report:
- filters: []
+ cadence: '0 0 * * *' # Daily at 00:00 (Kubernetes cluster time)
```
-The namespaces that are able to be scanned depend on the [Starboard Operator install mode](https://aquasecurity.github.io/starboard/latest/operator/configuration/#install-modes).
-By default, the Starboard Operator only scans resources in the `default` namespace. To change this
-behavior, edit the `STARBOARD_OPERATOR` environment variable in the `starboard-operator` deployment
-definition.
+The `cadence` field is required. GitLab supports the following types of CRON syntax for the cadence field:
-By adding filters, you can limit scans by:
+- A daily cadence of once per hour at a specified hour, for example: `0 18 * * *`
+- A weekly cadence of once per week on a specified day and at a specified hour, for example: `0 13 * * 0`
-- Resource name
-- Kind
-- Container name
-- Namespace
+It is possible that other elements of the CRON syntax will work in the cadence field, however, GitLab does not officially test or support them.
-```yaml
-starboard:
- vulnerability_report:
- filters:
- - namespaces:
- - staging
- - production
- kinds:
- - Deployment
- - DaemonSet
- containers:
- - ruby
- - postgres
- - nginx
- resources:
- - my-app-name
- - postgres
- - ingress-nginx
-```
-
-A resource is scanned if the resource matches any of the given names and all of the given filter
-types (`namespaces`, `kinds`, `containers`, `resources`). If a filter type is omitted, then all
-names are scanned. In this example, a resource isn't scanned unless it has a container named `ruby`,
-`postgres`, or `nginx`, and it's a `Deployment`:
-
-```yaml
-starboard:
- vulnerability_report:
- filters:
- - kinds:
- - Deployment
- containers:
- - ruby
- - postgres
- - nginx
-```
-
-There is also a global `namespaces` field that applies to all filters:
+By default, cluster image scanning will attempt to scan the workloads in all
+namespaces for vulnerabilities. The `vulnerability_report` block has a `namespaces`
+field which can be used to restrict which namespaces are scanned. For example,
+if you would like to scan only the `development`, `staging`, and `production`
+namespaces, you can use this configuration:
```yaml
starboard:
vulnerability_report:
+ cadence: '0 0 * * *'
namespaces:
- - production
- filters:
- - kinds:
- - Deployment
- - kinds:
- - DaemonSet
- resources:
- - log-collector
+ - development
+ - staging
+ - production
```
-
-In this example, the following resources are scanned:
-
-- All deployments (`Deployment`) in the `production` namespace.
-- All daemon sets (`DaemonSet`) named `log-collector` in the `production` namespace.
diff --git a/lefthook.yml b/lefthook.yml
index 8bfa5d015c7..ff57725dac6 100644
--- a/lefthook.yml
+++ b/lefthook.yml
@@ -31,7 +31,7 @@ pre-push:
rubocop:
tags: backend style
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
- glob: '*.rb'
+ glob: '*.{rb,rake}'
run: REVEAL_RUBOCOP_TODO=0 bundle exec rubocop --parallel --force-exclusion {files}
graphql_docs:
tags: documentation
diff --git a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
index f56e017796a..6dd55d00ae9 100644
--- a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
@@ -14,7 +14,7 @@ variables:
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
DS_EXCLUDED_ANALYZERS: ""
DS_EXCLUDED_PATHS: "spec, test, tests, tmp"
- DS_MAJOR_VERSION: 2
+ DS_MAJOR_VERSION: 3
dependency_scanning:
stage: test
@@ -82,9 +82,6 @@ gemnasium-maven-dependency_scanning:
- .cyclone-dx-reports
variables:
DS_ANALYZER_NAME: "gemnasium-maven"
- # Stop reporting Gradle as "maven".
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/338252
- DS_REPORT_PACKAGE_MANAGER_MAVEN_WHEN_JAVA: "false"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED
when: never
@@ -104,9 +101,6 @@ gemnasium-python-dependency_scanning:
- .cyclone-dx-reports
variables:
DS_ANALYZER_NAME: "gemnasium-python"
- # Stop reporting Pipenv and Setuptools as "pip".
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/338252
- DS_REPORT_PACKAGE_MANAGER_PIP_WHEN_PYTHON: "false"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED
when: never
diff --git a/lib/gitlab/kas.rb b/lib/gitlab/kas.rb
index ed7787ffc49..bf7b7f2d089 100644
--- a/lib/gitlab/kas.rb
+++ b/lib/gitlab/kas.rb
@@ -33,6 +33,10 @@ module Gitlab
@_version ||= Rails.root.join(VERSION_FILE).read.chomp
end
+ def version_info
+ Gitlab::VersionInfo.parse(version)
+ end
+
# Return GitLab KAS external_url
#
# @return [String] external_url
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0f19cae937a..872f32c67f4 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3258,6 +3258,9 @@ msgstr ""
msgid "Advanced export options"
msgstr ""
+msgid "AdvancedSearch|Elasticsearch version not compatible"
+msgstr ""
+
msgid "AdvancedSearch|Reindex required"
msgstr ""
@@ -27187,6 +27190,9 @@ msgstr ""
msgid "Pause"
msgstr ""
+msgid "Pause indexing and upgrade Elasticsearch to a supported version."
+msgstr ""
+
msgid "Pause time (ms)"
msgstr ""
@@ -39757,6 +39763,9 @@ msgstr ""
msgid "Trigger cluster reindexing. Only use this with an index that was created in GitLab 13.0 or later."
msgstr ""
+msgid "Trigger job"
+msgstr ""
+
msgid "Trigger manual job"
msgstr ""
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index 1580ad9361d..ed11d5936b0 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -307,17 +307,36 @@ RSpec.describe Projects::BranchesController do
sign_in(developer)
end
- it 'returns 303' do
- post :destroy,
- format: :html,
- params: {
- id: 'foo/bar/baz',
- namespace_id: project.namespace,
- project_id: project
- }
+ subject(:post_request) do
+ post :destroy, format: :html, params: {
+ id: 'foo/bar/baz',
+ namespace_id: project.namespace,
+ project_id: project
+ }
+ end
+ it "returns response code 303" do
+ post_request
expect(response).to have_gitlab_http_status(:see_other)
end
+
+ context 'with http referer' do
+ before do
+ request.env['HTTP_REFERER'] = '/'
+ end
+
+ it "redirects to the referer path" do
+ post_request
+ expect(response).to redirect_to('/')
+ end
+ end
+
+ context 'without http referer' do
+ it "redirects to the project branches path" do
+ post_request
+ expect(response).to redirect_to(project_branches_path(project))
+ end
+ end
end
describe "POST destroy" do
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 6f4a13c5fad..8732e2ecff2 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -445,7 +445,7 @@ RSpec.describe 'GFM autocomplete', :js do
click_button('Cancel')
page.within('.modal') do
- click_button('OK', match: :first)
+ click_button('Discard changes', match: :first)
end
wait_for_requests
diff --git a/spec/frontend/clusters_list/components/agent_table_spec.js b/spec/frontend/clusters_list/components/agent_table_spec.js
index a466a35428a..2a43b45a2f5 100644
--- a/spec/frontend/clusters_list/components/agent_table_spec.js
+++ b/spec/frontend/clusters_list/components/agent_table_spec.js
@@ -13,6 +13,7 @@ const defaultConfigHelpUrl =
const provideData = {
gitlabVersion: '14.8',
+ kasVersion: '14.8',
};
const propsData = {
agents: clusterAgents,
@@ -26,7 +27,7 @@ const outdatedTitle = I18N_AGENT_TABLE.versionOutdatedTitle;
const mismatchTitle = I18N_AGENT_TABLE.versionMismatchTitle;
const mismatchOutdatedTitle = I18N_AGENT_TABLE.versionMismatchOutdatedTitle;
const outdatedText = sprintf(I18N_AGENT_TABLE.versionOutdatedText, {
- version: provideData.gitlabVersion,
+ version: provideData.kasVersion,
});
const mismatchText = I18N_AGENT_TABLE.versionMismatchText;
diff --git a/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
index 2d2e5db598a..724ec7366d3 100644
--- a/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
+++ b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
@@ -11,6 +11,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "6",
+ "kind": "BUILD",
"name": "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
"needs": Array [],
"previousStageJobsOrNeeds": Array [],
@@ -53,6 +54,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "11",
+ "kind": "BUILD",
"name": "build_b",
"needs": Array [],
"previousStageJobsOrNeeds": Array [],
@@ -95,6 +97,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "16",
+ "kind": "BUILD",
"name": "build_c",
"needs": Array [],
"previousStageJobsOrNeeds": Array [],
@@ -137,6 +140,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "21",
+ "kind": "BUILD",
"name": "build_d 1/3",
"needs": Array [],
"previousStageJobsOrNeeds": Array [],
@@ -163,6 +167,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "24",
+ "kind": "BUILD",
"name": "build_d 2/3",
"needs": Array [],
"previousStageJobsOrNeeds": Array [],
@@ -189,6 +194,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "27",
+ "kind": "BUILD",
"name": "build_d 3/3",
"needs": Array [],
"previousStageJobsOrNeeds": Array [],
@@ -231,6 +237,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "59",
+ "kind": "BUILD",
"name": "test_c",
"needs": Array [],
"previousStageJobsOrNeeds": Array [],
@@ -275,6 +282,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "34",
+ "kind": "BUILD",
"name": "test_a",
"needs": Array [
"build_c",
@@ -325,6 +333,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "42",
+ "kind": "BUILD",
"name": "test_b 1/2",
"needs": Array [
"build_d 3/3",
@@ -363,6 +372,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "67",
+ "kind": "BUILD",
"name": "test_b 2/2",
"needs": Array [
"build_d 3/3",
@@ -417,6 +427,7 @@ Array [
Object {
"__typename": "CiJob",
"id": "53",
+ "kind": "BUILD",
"name": "test_d",
"needs": Array [
"build_b",
diff --git a/spec/frontend/pipelines/graph/job_item_spec.js b/spec/frontend/pipelines/graph/job_item_spec.js
index 23e7ed7ebb4..4f0da09fec6 100644
--- a/spec/frontend/pipelines/graph/job_item_spec.js
+++ b/spec/frontend/pipelines/graph/job_item_spec.js
@@ -1,89 +1,34 @@
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { GlBadge } from '@gitlab/ui';
import JobItem from '~/pipelines/components/graph/job_item.vue';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import {
+ delayedJob,
+ mockJob,
+ mockJobWithoutDetails,
+ mockJobWithUnauthorizedAction,
+ triggerJob,
+} from './mock_data';
describe('pipeline graph job item', () => {
let wrapper;
- const findJobWithoutLink = () => wrapper.find('[data-testid="job-without-link"]');
- const findJobWithLink = () => wrapper.find('[data-testid="job-with-link"]');
- const findActionComponent = () => wrapper.find('[data-testid="ci-action-component"]');
+ const findJobWithoutLink = () => wrapper.findByTestId('job-without-link');
+ const findJobWithLink = () => wrapper.findByTestId('job-with-link');
+ const findActionComponent = () => wrapper.findByTestId('ci-action-component');
+ const findBadge = () => wrapper.findComponent(GlBadge);
const createWrapper = (propsData) => {
- wrapper = mount(JobItem, {
- propsData,
- });
+ wrapper = extendedWrapper(
+ mount(JobItem, {
+ propsData,
+ }),
+ );
};
const triggerActiveClass = 'gl-shadow-x0-y0-b3-s1-blue-500';
- const delayedJob = {
- __typename: 'CiJob',
- name: 'delayed job',
- scheduledAt: '2015-07-03T10:01:00.000Z',
- needs: [],
- status: {
- __typename: 'DetailedStatus',
- icon: 'status_scheduled',
- tooltip: 'delayed manual action (%{remainingTime})',
- hasDetails: true,
- detailsPath: '/root/kinder-pipe/-/jobs/5339',
- group: 'scheduled',
- action: {
- __typename: 'StatusAction',
- icon: 'time-out',
- title: 'Unschedule',
- path: '/frontend-fixtures/builds-project/-/jobs/142/unschedule',
- buttonTitle: 'Unschedule job',
- },
- },
- };
-
- const mockJob = {
- id: 4256,
- name: 'test',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- tooltip: 'passed',
- group: 'success',
- detailsPath: '/root/ci-mock/builds/4256',
- hasDetails: true,
- action: {
- icon: 'retry',
- title: 'Retry',
- path: '/root/ci-mock/builds/4256/retry',
- method: 'post',
- },
- },
- };
- const mockJobWithoutDetails = {
- id: 4257,
- name: 'job_without_details',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- detailsPath: '/root/ci-mock/builds/4257',
- hasDetails: false,
- },
- };
- const mockJobWithUnauthorizedAction = {
- id: 4258,
- name: 'stop-environment',
- status: {
- icon: 'status_manual',
- label: 'manual stop action (not allowed)',
- tooltip: 'manual action',
- group: 'manual',
- detailsPath: '/root/ci-mock/builds/4258',
- hasDetails: true,
- action: null,
- },
- };
-
afterEach(() => {
wrapper.destroy();
});
@@ -148,13 +93,25 @@ describe('pipeline graph job item', () => {
});
});
- it('should render provided class name', () => {
- createWrapper({
- job: mockJob,
- cssClassJobName: 'css-class-job-name',
+ describe('job style', () => {
+ beforeEach(() => {
+ createWrapper({
+ job: mockJob,
+ cssClassJobName: 'css-class-job-name',
+ });
+ });
+
+ it('should render provided class name', () => {
+ expect(wrapper.find('a').classes()).toContain('css-class-job-name');
+ });
+
+ it('does not show a badge on the job item', () => {
+ expect(findBadge().exists()).toBe(false);
});
- expect(wrapper.find('a').classes()).toContain('css-class-job-name');
+ it('does not apply the trigger job class', () => {
+ expect(findJobWithLink().classes()).not.toContain('gl-rounded-lg');
+ });
});
describe('status label', () => {
@@ -201,34 +158,51 @@ describe('pipeline graph job item', () => {
});
});
- describe('trigger job highlighting', () => {
- it.each`
- job | jobName | expanded | link
- ${mockJob} | ${mockJob.name} | ${true} | ${true}
- ${mockJobWithoutDetails} | ${mockJobWithoutDetails.name} | ${true} | ${false}
- `(
- `trigger job should stay highlighted when downstream is expanded`,
- ({ job, jobName, expanded, link }) => {
- createWrapper({ job, pipelineExpanded: { jobName, expanded } });
- const findJobEl = link ? findJobWithLink : findJobWithoutLink;
-
- expect(findJobEl().classes()).toContain(triggerActiveClass);
- },
- );
+ describe('trigger job', () => {
+ describe('card', () => {
+ beforeEach(() => {
+ createWrapper({ job: triggerJob });
+ });
- it.each`
- job | jobName | expanded | link
- ${mockJob} | ${mockJob.name} | ${false} | ${true}
- ${mockJobWithoutDetails} | ${mockJobWithoutDetails.name} | ${false} | ${false}
- `(
- `trigger job should not be highlighted when downstream is not expanded`,
- ({ job, jobName, expanded, link }) => {
- createWrapper({ job, pipelineExpanded: { jobName, expanded } });
- const findJobEl = link ? findJobWithLink : findJobWithoutLink;
-
- expect(findJobEl().classes()).not.toContain(triggerActiveClass);
- },
- );
+ it('shows a badge on the job item', () => {
+ expect(findBadge().exists()).toBe(true);
+ expect(findBadge().text()).toBe('Trigger job');
+ });
+
+ it('applies a rounded corner style instead of the usual pill shape', () => {
+ expect(findJobWithoutLink().classes()).toContain('gl-rounded-lg');
+ });
+ });
+
+ describe('highlighting', () => {
+ it.each`
+ job | jobName | expanded | link
+ ${mockJob} | ${mockJob.name} | ${true} | ${true}
+ ${mockJobWithoutDetails} | ${mockJobWithoutDetails.name} | ${true} | ${false}
+ `(
+ `trigger job should stay highlighted when downstream is expanded`,
+ ({ job, jobName, expanded, link }) => {
+ createWrapper({ job, pipelineExpanded: { jobName, expanded } });
+ const findJobEl = link ? findJobWithLink : findJobWithoutLink;
+
+ expect(findJobEl().classes()).toContain(triggerActiveClass);
+ },
+ );
+
+ it.each`
+ job | jobName | expanded | link
+ ${mockJob} | ${mockJob.name} | ${false} | ${true}
+ ${mockJobWithoutDetails} | ${mockJobWithoutDetails.name} | ${false} | ${false}
+ `(
+ `trigger job should not be highlighted when downstream is not expanded`,
+ ({ job, jobName, expanded, link }) => {
+ createWrapper({ job, pipelineExpanded: { jobName, expanded } });
+ const findJobEl = link ? findJobWithLink : findJobWithoutLink;
+
+ expect(findJobEl().classes()).not.toContain(triggerActiveClass);
+ },
+ );
+ });
});
describe('job classes', () => {
diff --git a/spec/frontend/pipelines/graph/mock_data.js b/spec/frontend/pipelines/graph/mock_data.js
index 94915d4ce7b..6124d67af09 100644
--- a/spec/frontend/pipelines/graph/mock_data.js
+++ b/spec/frontend/pipelines/graph/mock_data.js
@@ -1,4 +1,5 @@
import { unwrapPipelineData } from '~/pipelines/components/graph/utils';
+import { BUILD_KIND, BRIDGE_KIND } from '~/pipelines/components/graph/constants';
export const mockPipelineResponse = {
data: {
@@ -50,6 +51,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '6',
+ kind: BUILD_KIND,
name: 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
scheduledAt: null,
status: {
@@ -101,6 +103,7 @@ export const mockPipelineResponse = {
__typename: 'CiJob',
id: '11',
name: 'build_b',
+ kind: BUILD_KIND,
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
@@ -151,6 +154,7 @@ export const mockPipelineResponse = {
__typename: 'CiJob',
id: '16',
name: 'build_c',
+ kind: BUILD_KIND,
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
@@ -200,6 +204,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '21',
+ kind: BUILD_KIND,
name: 'build_d 1/3',
scheduledAt: null,
status: {
@@ -232,6 +237,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '24',
+ kind: BUILD_KIND,
name: 'build_d 2/3',
scheduledAt: null,
status: {
@@ -264,6 +270,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '27',
+ kind: BUILD_KIND,
name: 'build_d 3/3',
scheduledAt: null,
status: {
@@ -329,6 +336,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '34',
+ kind: BUILD_KIND,
name: 'test_a',
scheduledAt: null,
status: {
@@ -413,6 +421,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '42',
+ kind: BUILD_KIND,
name: 'test_b 1/2',
scheduledAt: null,
status: {
@@ -499,6 +508,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '67',
+ kind: BUILD_KIND,
name: 'test_b 2/2',
scheduledAt: null,
status: {
@@ -603,6 +613,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '59',
+ kind: BUILD_KIND,
name: 'test_c',
scheduledAt: null,
status: {
@@ -646,6 +657,7 @@ export const mockPipelineResponse = {
{
__typename: 'CiJob',
id: '53',
+ kind: BUILD_KIND,
name: 'test_d',
scheduledAt: null,
status: {
@@ -871,6 +883,7 @@ export const wrappedPipelineReturn = {
{
__typename: 'CiJob',
id: '83',
+ kind: BUILD_KIND,
name: 'build_n',
scheduledAt: null,
needs: {
@@ -941,3 +954,87 @@ export const mockCalloutsResponse = (mappedCallouts) => ({
},
},
});
+
+export const delayedJob = {
+ __typename: 'CiJob',
+ kind: BUILD_KIND,
+ name: 'delayed job',
+ scheduledAt: '2015-07-03T10:01:00.000Z',
+ needs: [],
+ status: {
+ __typename: 'DetailedStatus',
+ icon: 'status_scheduled',
+ tooltip: 'delayed manual action (%{remainingTime})',
+ hasDetails: true,
+ detailsPath: '/root/kinder-pipe/-/jobs/5339',
+ group: 'scheduled',
+ action: {
+ __typename: 'StatusAction',
+ icon: 'time-out',
+ title: 'Unschedule',
+ path: '/frontend-fixtures/builds-project/-/jobs/142/unschedule',
+ buttonTitle: 'Unschedule job',
+ },
+ },
+};
+
+export const mockJob = {
+ id: 4256,
+ name: 'test',
+ kind: BUILD_KIND,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ tooltip: 'passed',
+ group: 'success',
+ detailsPath: '/root/ci-mock/builds/4256',
+ hasDetails: true,
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/root/ci-mock/builds/4256/retry',
+ method: 'post',
+ },
+ },
+};
+
+export const mockJobWithoutDetails = {
+ id: 4257,
+ name: 'job_without_details',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ detailsPath: '/root/ci-mock/builds/4257',
+ hasDetails: false,
+ },
+};
+
+export const mockJobWithUnauthorizedAction = {
+ id: 4258,
+ name: 'stop-environment',
+ status: {
+ icon: 'status_manual',
+ label: 'manual stop action (not allowed)',
+ tooltip: 'manual action',
+ group: 'manual',
+ detailsPath: '/root/ci-mock/builds/4258',
+ hasDetails: true,
+ action: null,
+ },
+};
+
+export const triggerJob = {
+ id: 4259,
+ name: 'trigger',
+ kind: BRIDGE_KIND,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ action: null,
+ },
+};
diff --git a/spec/helpers/clusters_helper_spec.rb b/spec/helpers/clusters_helper_spec.rb
index 4111b39aa41..9a3cd5fd18d 100644
--- a/spec/helpers/clusters_helper_spec.rb
+++ b/spec/helpers/clusters_helper_spec.rb
@@ -90,6 +90,10 @@ RSpec.describe ClustersHelper do
expect(subject[:gitlab_version]).to eq(Gitlab.version_info)
end
+ it 'displays KAS version' do
+ expect(subject[:kas_version]).to eq(Gitlab::Kas.version_info)
+ end
+
context 'user has no permissions to create a cluster' do
it 'displays that user can\'t add cluster' do
expect(subject[:can_add_cluster]).to eq("false")
diff --git a/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb b/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb
index 16e699b7e0e..eefe5bfc6c4 100644
--- a/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb
+++ b/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb
@@ -9,29 +9,47 @@ RSpec.describe Preloaders::UserMaxAccessLevelInProjectsPreloader do
let_it_be(:project_3) { create(:project) }
let(:projects) { [project_1, project_2, project_3] }
+ let(:query) { projects.each { |project| user.can?(:read_project, project) } }
before do
project_1.add_developer(user)
project_2.add_developer(user)
end
- context 'preload maximum access level to avoid querying project_authorizations', :request_store do
- it 'avoids N+1 queries', :request_store do
- Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects, user).execute
+ context 'without preloader' do
+ it 'runs N queries' do
+ expect { query }.to make_queries(projects.size)
+ end
+ end
+
+ describe '#execute', :request_store do
+ let(:projects_arg) { projects }
+
+ before do
+ Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects_arg, user).execute
+ end
+
+ it 'avoids N+1 queries' do
+ expect { query }.not_to make_queries
+ end
- query_count = ActiveRecord::QueryRecorder.new do
- projects.each { |project| user.can?(:read_project, project) }
- end.count
+ context 'when projects is an array of IDs' do
+ let(:projects_arg) { [project_1.id, project_2.id, project_3.id] }
- expect(query_count).to eq(0)
+ it 'avoids N+1 queries' do
+ expect { query }.not_to make_queries
+ end
end
- it 'runs N queries without preloading' do
- query_count = ActiveRecord::QueryRecorder.new do
- projects.each { |project| user.can?(:read_project, project) }
- end.count
+ # Test for handling of SQL table name clashes.
+ context 'when projects is a relation including project_authorizations' do
+ let(:projects_arg) do
+ Project.where(id: ProjectAuthorization.where(project_id: projects).select(:project_id))
+ end
- expect(query_count).to eq(projects.size)
+ it 'avoids N+1 queries' do
+ expect { query }.not_to make_queries
+ end
end
end
end
diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb
index 918251bb649..45dbe83b496 100644
--- a/spec/services/users/destroy_service_spec.rb
+++ b/spec/services/users/destroy_service_spec.rb
@@ -336,35 +336,24 @@ RSpec.describe Users::DestroyService do
context 'batched nullify' do
let(:other_user) { create(:user) }
- context 'when :nullify_in_batches_on_user_deletion feature flag is enabled' do
- it 'nullifies related associations in batches' do
- expect(other_user).to receive(:nullify_dependent_associations_in_batches).and_call_original
+ it 'nullifies related associations in batches' do
+ expect(other_user).to receive(:nullify_dependent_associations_in_batches).and_call_original
- described_class.new(user).execute(other_user, skip_authorization: true)
- end
-
- it 'nullifies last_updated_issues and closed_issues' do
- issue = create(:issue, closed_by: other_user, updated_by: other_user)
-
- described_class.new(user).execute(other_user, skip_authorization: true)
-
- issue.reload
-
- expect(issue.closed_by).to be_nil
- expect(issue.updated_by).to be_nil
- end
+ described_class.new(user).execute(other_user, skip_authorization: true)
end
- context 'when :nullify_in_batches_on_user_deletion feature flag is disabled' do
- before do
- stub_feature_flags(nullify_in_batches_on_user_deletion: false)
- end
+ it 'nullifies last_updated_issues, closed_issues, resource_label_events' do
+ issue = create(:issue, closed_by: other_user, updated_by: other_user)
+ resource_label_event = create(:resource_label_event, user: other_user)
- it 'does not use batching' do
- expect(other_user).not_to receive(:nullify_dependent_associations_in_batches)
+ described_class.new(user).execute(other_user, skip_authorization: true)
- described_class.new(user).execute(other_user, skip_authorization: true)
- end
+ issue.reload
+ resource_label_event.reload
+
+ expect(issue.closed_by).to be_nil
+ expect(issue.updated_by).to be_nil
+ expect(resource_label_event.user).to be_nil
end
end
end
diff --git a/spec/support/matchers/make_queries.rb b/spec/support/matchers/make_queries.rb
new file mode 100644
index 00000000000..19c69240a40
--- /dev/null
+++ b/spec/support/matchers/make_queries.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+RSpec::Matchers.define :make_queries do |expected_count = nil|
+ supports_block_expectations
+
+ match do |block|
+ @recorder = ActiveRecord::QueryRecorder.new(&block)
+ @counter = @recorder.count
+ if expected_count
+ @counter == expected_count
+ else
+ @counter > 0
+ end
+ end
+
+ failure_message do |_|
+ if expected_count
+ "expected to make #{expected_count} queries but made #{@counter} queries"
+ else
+ "expected to make queries but did not make any"
+ end
+ end
+
+ failure_message_when_negated do |_|
+ if expected_count
+ "expected not to make #{expected_count} queries but received #{@counter} queries"
+ else
+ "expected not to make queries but received #{@counter} queries"
+ end
+ end
+end
diff --git a/spec/views/devise/shared/_signin_box.html.haml_spec.rb b/spec/views/devise/shared/_signin_box.html.haml_spec.rb
index 8b1af1866dc..e2aa0bb9870 100644
--- a/spec/views/devise/shared/_signin_box.html.haml_spec.rb
+++ b/spec/views/devise/shared/_signin_box.html.haml_spec.rb
@@ -28,6 +28,20 @@ RSpec.describe 'devise/shared/_signin_box' do
end
end
+ describe 'Base form' do
+ before do
+ stub_devise
+ allow(view).to receive(:captcha_enabled?).and_return(false)
+ allow(view).to receive(:captcha_on_login_required?).and_return(false)
+ end
+
+ it 'renders user_login label' do
+ render
+
+ expect(rendered).to have_content(_('Username or email'))
+ end
+ end
+
def stub_devise
allow(view).to receive(:devise_mapping).and_return(Devise.mappings[:user])
allow(view).to receive(:resource).and_return(spy)
diff --git a/workhorse/internal/upload/artifacts_uploader.go b/workhorse/internal/upload/artifacts_uploader.go
index 3c2d89e976f..c1c49638e21 100644
--- a/workhorse/internal/upload/artifacts_uploader.go
+++ b/workhorse/internal/upload/artifacts_uploader.go
@@ -35,7 +35,6 @@ var zipSubcommandsErrorsCounter = promauto.NewCounterVec(
}, []string{"error"})
type artifactsUploadProcessor struct {
- opts *destination.UploadOpts
format string
SavedFileTracker
@@ -52,7 +51,7 @@ func Artifacts(myAPI *api.API, h http.Handler, p Preparer) http.Handler {
format := r.URL.Query().Get(ArtifactFormatKey)
- mg := &artifactsUploadProcessor{opts: opts, format: format, SavedFileTracker: SavedFileTracker{Request: r}}
+ mg := &artifactsUploadProcessor{format: format, SavedFileTracker: SavedFileTracker{Request: r}}
interceptMultipartFiles(w, r, h, a, mg, opts)
}, "/authorize")
}
@@ -62,12 +61,9 @@ func (a *artifactsUploadProcessor) generateMetadataFromZip(ctx context.Context,
defer metaWriter.Close()
metaOpts := &destination.UploadOpts{
- LocalTempPath: a.opts.LocalTempPath,
+ LocalTempPath: os.TempDir(),
TempFilePrefix: "metadata.gz",
}
- if metaOpts.LocalTempPath == "" {
- metaOpts.LocalTempPath = os.TempDir()
- }
fileName := file.LocalPath
if fileName == "" {