Skip to content

Commit

Permalink
Add latest changes from gitlab-org/gitlab@master
Browse files Browse the repository at this point in the history
  • Loading branch information
GitLab Bot committed Jan 22, 2021
1 parent 7e81076 commit 852877d
Show file tree
Hide file tree
Showing 50 changed files with 1,061 additions and 410 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ By submitting code as an individual you agree to the
By submitting code as an entity you agree to the
[corporate contributor license agreement](doc/legal/corporate_contributor_license_agreement.md).

All Documentation content that resides under the [doc/ directory](/doc) of this
All Documentation content that resides under the [`doc/` directory](/doc) of this
repository is licensed under Creative Commons:
[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).

_This notice should stay as the first item in the CONTRIBUTING.md file._
_This notice should stay as the first item in the `CONTRIBUTING.md` file._

## Contributing Documentation has been moved

Expand Down
115 changes: 115 additions & 0 deletions app/assets/javascripts/admin/users/components/user_actions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<script>
import {
GlButton,
GlDropdown,
GlDropdownItem,
GlDropdownSectionHeader,
GlDropdownDivider,
} from '@gitlab/ui';
import { s__, __ } from '~/locale';
import { convertArrayToCamelCase } from '~/lib/utils/common_utils';
import { generateUserPaths } from '../utils';
export default {
components: {
GlButton,
GlDropdown,
GlDropdownItem,
GlDropdownSectionHeader,
GlDropdownDivider,
},
props: {
user: {
type: Object,
required: true,
},
paths: {
type: Object,
required: true,
},
},
computed: {
userActions() {
return convertArrayToCamelCase(this.user.actions);
},
dropdownActions() {
return this.userActions.filter((a) => a !== 'edit');
},
dropdownDeleteActions() {
return this.dropdownActions.filter((a) => a.includes('delete'));
},
dropdownSafeActions() {
return this.dropdownActions.filter((a) => !this.dropdownDeleteActions.includes(a));
},
hasDropdownActions() {
return this.dropdownActions.length > 0;
},
hasDeleteActions() {
return this.dropdownDeleteActions.length > 0;
},
hasEditAction() {
return this.userActions.includes('edit');
},
userPaths() {
return generateUserPaths(this.paths, this.user.username);
},
},
methods: {
isLdapAction(action) {
return action === 'ldapBlocked';
},
},
i18n: {
edit: __('Edit'),
settings: __('Settings'),
unlock: __('Unlock'),
block: s__('AdminUsers|Block'),
unblock: s__('AdminUsers|Unblock'),
approve: s__('AdminUsers|Approve'),
reject: s__('AdminUsers|Reject'),
deactivate: s__('AdminUsers|Deactivate'),
activate: s__('AdminUsers|Activate'),
ldapBlocked: s__('AdminUsers|Cannot unblock LDAP blocked users'),
delete: s__('AdminUsers|Delete user'),
deleteWithContributions: s__('AdminUsers|Delete user and contributions'),
},
};
</script>

<template>
<div class="gl-display-flex gl-justify-content-end">
<gl-button v-if="hasEditAction" data-testid="edit" :href="userPaths.edit">{{
$options.i18n.edit
}}</gl-button>

<gl-dropdown
v-if="hasDropdownActions"
data-testid="actions"
right
class="gl-ml-2"
icon="settings"
>
<gl-dropdown-section-header>{{ $options.i18n.settings }}</gl-dropdown-section-header>

<template v-for="action in dropdownSafeActions">
<gl-dropdown-item v-if="isLdapAction(action)" :key="action" :data-testid="action">
{{ $options.i18n.ldap }}
</gl-dropdown-item>
<gl-dropdown-item v-else :key="action" :href="userPaths[action]" :data-testid="action">
{{ $options.i18n[action] }}
</gl-dropdown-item>
</template>

<gl-dropdown-divider v-if="hasDeleteActions" />

<gl-dropdown-item
v-for="action in dropdownDeleteActions"
:key="action"
:href="userPaths[action]"
:data-testid="`delete-${action}`"
>
<span class="gl-text-red-500">{{ $options.i18n[action] }}</span>
</gl-dropdown-item>
</gl-dropdown>
</div>
</template>
29 changes: 29 additions & 0 deletions app/assets/javascripts/admin/users/components/user_date.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script>
import { formatDate } from '~/lib/utils/datetime_utility';
import { __ } from '~/locale';
import { SHORT_DATE_FORMAT } from '../constants';
export default {
props: {
date: {
type: String,
required: false,
default: null,
},
},
computed: {
formattedDate() {
const { date } = this;
if (date === null) {
return __('Never');
}
return formatDate(new Date(date), SHORT_DATE_FORMAT);
},
},
};
</script>
<template>
<span>
{{ formattedDate }}
</span>
</template>
18 changes: 17 additions & 1 deletion app/assets/javascripts/admin/users/components/users_table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import { GlTable } from '@gitlab/ui';
import { __ } from '~/locale';
import UserAvatar from './user_avatar.vue';
import UserActions from './user_actions.vue';
import UserDate from './user_date.vue';
const DEFAULT_TH_CLASSES =
'gl-bg-transparent! gl-border-b-solid! gl-border-b-gray-100! gl-p-5! gl-border-b-1!';
Expand All @@ -11,6 +13,8 @@ export default {
components: {
GlTable,
UserAvatar,
UserActions,
UserDate,
},
props: {
users: {
Expand Down Expand Up @@ -62,7 +66,19 @@ export default {
stacked="md"
>
<template #cell(name)="{ item: user }">
<UserAvatar :user="user" :admin-user-path="paths.adminUser" />
<user-avatar :user="user" :admin-user-path="paths.adminUser" />
</template>

<template #cell(createdAt)="{ item: { createdAt } }">
<user-date :date="createdAt" />
</template>

<template #cell(lastActivityOn)="{ item: { lastActivityOn } }">
<user-date :date="lastActivityOn" show-never />
</template>

<template #cell(settings)="{ item: user }">
<user-actions :user="user" :paths="paths" />
</template>
</gl-table>
</div>
Expand Down
2 changes: 2 additions & 0 deletions app/assets/javascripts/admin/users/constants.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const USER_AVATAR_SIZE = 32;

export const SHORT_DATE_FORMAT = 'd mmm, yyyy';
7 changes: 7 additions & 0 deletions app/assets/javascripts/admin/users/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const generateUserPaths = (paths, id) => {
return Object.fromEntries(
Object.entries(paths).map(([action, genericPath]) => {
return [action, genericPath.replace('id', id)];
}),
);
};
9 changes: 9 additions & 0 deletions app/assets/javascripts/lib/utils/common_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -802,3 +802,12 @@ export const removeCookie = (name) => Cookies.remove(name);
* @returns {Boolean} on/off
*/
export const isFeatureFlagEnabled = (flag) => window.gon.features?.[flag];

/**
* This method takes in array with snake_case strings
* and returns a new array with camelCase strings
*
* @param {Array[String]} array - Array to be converted
* @returns {Array[String]} Converted array
*/
export const convertArrayToCamelCase = (array) => array.map((i) => convertToCamelCase(i));
1 change: 0 additions & 1 deletion app/assets/stylesheets/pages/groups.scss
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@
}

.pipeline-quota {
border-top: 1px solid $table-border-color;
border-bottom: 1px solid $table-border-color;
margin: 0 0 $gl-padding;

Expand Down
3 changes: 3 additions & 0 deletions app/models/ci/pipeline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ class Pipeline < ApplicationRecord
after_transition any => ::Ci::Pipeline.completed_statuses do |pipeline|
pipeline.run_after_commit do
::Ci::PipelineArtifacts::CoverageReportWorker.perform_async(pipeline.id)
::Ci::PipelineArtifacts::CreateQualityReportWorker.perform_async(pipeline.id)
end
end

Expand Down Expand Up @@ -1007,6 +1008,8 @@ def has_codequality_reports?
end

def can_generate_codequality_reports?
return false unless Feature.enabled?(:codequality_mr_diff, project)

has_reports?(Ci::JobArtifact.codequality_reports)
end

Expand Down
3 changes: 2 additions & 1 deletion app/models/ci/pipeline_artifact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ class PipelineArtifact < ApplicationRecord
EXPIRATION_DATE = 1.week.freeze

DEFAULT_FILE_NAMES = {
code_coverage: 'code_coverage.json'
code_coverage: 'code_coverage.json',
code_quality: 'code_quality.json'
}.freeze

belongs_to :project, class_name: "Project", inverse_of: :pipeline_artifacts
Expand Down
1 change: 1 addition & 0 deletions app/models/project_pages_metadatum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ class ProjectPagesMetadatum < ApplicationRecord

scope :deployed, -> { where(deployed: true) }
scope :only_on_legacy_storage, -> { deployed.where(pages_deployment: nil) }
scope :with_project_route_and_deployment, -> { preload(project: [:namespace, :route, pages_metadatum: :pages_deployment]) }
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true
module Ci
module PipelineArtifacts
class CreateQualityReportService
def execute(pipeline)
return unless pipeline.can_generate_codequality_reports?
return if pipeline.has_codequality_reports?

file = build_carrierwave_file(pipeline)

pipeline.pipeline_artifacts.create!(
project_id: pipeline.project_id,
file_type: :code_quality,
file_format: :raw,
size: file["tempfile"].size,
file: file,
expire_at: Ci::PipelineArtifact::EXPIRATION_DATE.from_now
)
end

private

def build_carrierwave_file(pipeline)
CarrierWaveStringFile.new_file(
file_content: pipeline.codequality_reports.to_json,
filename: Ci::PipelineArtifact::DEFAULT_FILE_NAMES.fetch(:code_quality),
content_type: 'application/json'
)
end
end
end
end
71 changes: 71 additions & 0 deletions app/services/pages/migrate_from_legacy_storage_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# frozen_string_literal: true

module Pages
class MigrateFromLegacyStorageService
def initialize(logger, migration_threads, batch_size)
@logger = logger
@migration_threads = migration_threads
@batch_size = batch_size

@migrated = 0
@errored = 0
@counters_lock = Mutex.new
end

def execute
@queue = SizedQueue.new(1)

threads = start_migration_threads

ProjectPagesMetadatum.only_on_legacy_storage.each_batch(of: @batch_size) do |batch|
@queue.push(batch)
end

@queue.close

@logger.info("Waiting for threads to finish...")
threads.each(&:join)

{ migrated: @migrated, errored: @errored }
end

def start_migration_threads
Array.new(@migration_threads) do
Thread.new do
while batch = @queue.pop
process_batch(batch)
end
end
end
end

def process_batch(batch)
batch.with_project_route_and_deployment.each do |metadatum|
project = metadatum.project

migrate_project(project)
end

@logger.info("#{@migrated} projects are migrated successfully, #{@errored} projects failed to be migrated")
end

def migrate_project(project)
result = nil
time = Benchmark.realtime do
result = ::Pages::MigrateLegacyStorageToDeploymentService.new(project).execute
end

if result[:status] == :success
@logger.info("project_id: #{project.id} #{project.pages_path} has been migrated in #{time} seconds")
@counters_lock.synchronize { @migrated += 1 }
else
@logger.error("project_id: #{project.id} #{project.pages_path} failed to be migrated in #{time} seconds: #{result[:message]}")
@counters_lock.synchronize { @errored += 1 }
end
rescue => e
@counters_lock.synchronize { @errored += 1 }
@logger.error("#{e.message} project_id: #{project&.id}")
Gitlab::ErrorTracking.track_exception(e, project_id: project&.id)
end
end
end
8 changes: 8 additions & 0 deletions app/workers/all_queues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,14 @@
:weight: 1
:idempotent: true
:tags: []
- :name: pipeline_background:ci_pipeline_artifacts_create_quality_report
:feature_category: :code_testing
:has_external_dependencies:
:urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent: true
:tags: []
- :name: pipeline_background:ci_pipeline_success_unlock_artifacts
:feature_category: :continuous_integration
:has_external_dependencies:
Expand Down
Loading

0 comments on commit 852877d

Please sign in to comment.