Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
109562e64e
commit
1361891b0a
118 changed files with 1059 additions and 450 deletions
|
@ -42,7 +42,7 @@ call-out responsibilities for other team members or teams.
|
|||
-->
|
||||
|
||||
- [ ] ~frontend Step 1
|
||||
- [ ] @person Step 1a
|
||||
- [ ] `@person` Step 1a
|
||||
- [ ] ~frontend Step 2
|
||||
|
||||
|
||||
|
|
21
app/assets/javascripts/admin/users/components/app.vue
Normal file
21
app/assets/javascripts/admin/users/components/app.vue
Normal file
|
@ -0,0 +1,21 @@
|
|||
<script>
|
||||
export default {
|
||||
props: {
|
||||
users: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
paths: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- Temporary empty app -->
|
||||
</div>
|
||||
</template>
|
22
app/assets/javascripts/admin/users/index.js
Normal file
22
app/assets/javascripts/admin/users/index.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
import Vue from 'vue';
|
||||
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||
import AdminUsersApp from './components/app.vue';
|
||||
|
||||
export default function(el = document.querySelector('#js-admin-users-app')) {
|
||||
if (!el) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { users, paths } = el.dataset;
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
render: createElement =>
|
||||
createElement(AdminUsersApp, {
|
||||
props: {
|
||||
users: convertObjectPropsToCamelCase(JSON.parse(users), { deep: true }),
|
||||
paths: convertObjectPropsToCamelCase(JSON.parse(paths)),
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
|
@ -134,7 +134,7 @@ export default {
|
|||
<template>
|
||||
<board-editable-item :loading="isSettingAssignees" :title="assigneeText" @close="saveAssignees">
|
||||
<template #collapsed>
|
||||
<issuable-assignees :users="selected" @assign-self="assignSelf" />
|
||||
<issuable-assignees :users="activeIssue.assignees" @assign-self="assignSelf" />
|
||||
</template>
|
||||
|
||||
<template #default>
|
||||
|
|
|
@ -13,7 +13,8 @@ import {
|
|||
formatIssue,
|
||||
} from '../boards_util';
|
||||
import boardStore from '~/boards/stores/boards_store';
|
||||
|
||||
import createFlash from '~/flash';
|
||||
import { __ } from '~/locale';
|
||||
import updateAssigneesMutation from '~/vue_shared/components/sidebar/queries/updateAssignees.mutation.graphql';
|
||||
import listsIssuesQuery from '../graphql/lists_issues.query.graphql';
|
||||
import boardLabelsQuery from '../graphql/board_labels.query.graphql';
|
||||
|
@ -340,6 +341,9 @@ export default {
|
|||
|
||||
return nodes;
|
||||
})
|
||||
.catch(() => {
|
||||
createFlash({ message: __('An error occurred while updating assignees.') });
|
||||
})
|
||||
.finally(() => {
|
||||
commit(types.SET_ASSIGNEE_LOADING, false);
|
||||
});
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
<script>
|
||||
import { GlLink, GlSprintf } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
import { first } from 'lodash';
|
||||
import { s__, n__ } from '~/locale';
|
||||
import { truncateSha } from '~/lib/utils/text_utility';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
|
||||
import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
|
||||
|
||||
export default {
|
||||
name: 'PackageHistory',
|
||||
i18n: {
|
||||
createdOn: s__('PackageRegistry|%{name} version %{version} was created %{datetime}'),
|
||||
updatedAtText: s__('PackageRegistry|%{name} version %{version} was updated %{datetime}'),
|
||||
commitText: s__('PackageRegistry|Commit %{link} on branch %{branch}'),
|
||||
pipelineText: s__('PackageRegistry|Pipeline %{link} triggered %{datetime} by %{author}'),
|
||||
createdOn: s__('PackageRegistry|%{name} version %{version} was first created %{datetime}'),
|
||||
createdByCommitText: s__('PackageRegistry|Created by commit %{link} on branch %{branch}'),
|
||||
createdByPipelineText: s__(
|
||||
'PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}',
|
||||
),
|
||||
publishText: s__('PackageRegistry|Published to the %{project} Package Registry %{datetime}'),
|
||||
combinedUpdateText: s__(
|
||||
'PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}',
|
||||
),
|
||||
archivedPipelineMessageSingular: s__('PackageRegistry|Package has %{number} archived update'),
|
||||
archivedPipelineMessagePlural: s__('PackageRegistry|Package has %{number} archived updates'),
|
||||
},
|
||||
components: {
|
||||
GlLink,
|
||||
|
@ -35,8 +44,32 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
packagePipeline() {
|
||||
return this.packageEntity.pipeline?.id ? this.packageEntity.pipeline : null;
|
||||
pipelines() {
|
||||
return this.packageEntity.pipelines || [];
|
||||
},
|
||||
firstPipeline() {
|
||||
return first(this.pipelines);
|
||||
},
|
||||
lastPipelines() {
|
||||
return this.pipelines.slice(1).slice(-HISTORY_PIPELINES_LIMIT);
|
||||
},
|
||||
showPipelinesInfo() {
|
||||
return Boolean(this.firstPipeline?.id);
|
||||
},
|
||||
archiviedLines() {
|
||||
return Math.max(this.pipelines.length - HISTORY_PIPELINES_LIMIT - 1, 0);
|
||||
},
|
||||
archivedPipelineMessage() {
|
||||
return n__(
|
||||
this.$options.i18n.archivedPipelineMessageSingular,
|
||||
this.$options.i18n.archivedPipelineMessagePlural,
|
||||
this.archiviedLines,
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
truncate(value) {
|
||||
return truncateSha(value);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -59,46 +92,35 @@ export default {
|
|||
</template>
|
||||
</gl-sprintf>
|
||||
</history-item>
|
||||
<history-item icon="pencil" data-testid="updated-at">
|
||||
<gl-sprintf :message="$options.i18n.updatedAtText">
|
||||
<template #name>
|
||||
<strong>{{ packageEntity.name }}</strong>
|
||||
</template>
|
||||
<template #version>
|
||||
<strong>{{ packageEntity.version }}</strong>
|
||||
</template>
|
||||
<template #datetime>
|
||||
<time-ago-tooltip :time="packageEntity.updated_at" />
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</history-item>
|
||||
<template v-if="packagePipeline">
|
||||
<history-item icon="commit" data-testid="commit">
|
||||
<gl-sprintf :message="$options.i18n.commitText">
|
||||
|
||||
<template v-if="showPipelinesInfo">
|
||||
<!-- FIRST PIPELINE BLOCK -->
|
||||
<history-item icon="commit" data-testid="first-pipeline-commit">
|
||||
<gl-sprintf :message="$options.i18n.createdByCommitText">
|
||||
<template #link>
|
||||
<gl-link :href="packagePipeline.project.commit_url">{{
|
||||
packagePipeline.sha
|
||||
}}</gl-link>
|
||||
</template>
|
||||
<template #branch>
|
||||
<strong>{{ packagePipeline.ref }}</strong>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</history-item>
|
||||
<history-item icon="pipeline" data-testid="pipeline">
|
||||
<gl-sprintf :message="$options.i18n.pipelineText">
|
||||
<template #link>
|
||||
<gl-link :href="packagePipeline.project.pipeline_url"
|
||||
>#{{ packagePipeline.id }}</gl-link
|
||||
<gl-link :href="firstPipeline.project.commit_url"
|
||||
>#{{ truncate(firstPipeline.sha) }}</gl-link
|
||||
>
|
||||
</template>
|
||||
<template #datetime>
|
||||
<time-ago-tooltip :time="packagePipeline.created_at" />
|
||||
<template #branch>
|
||||
<strong>{{ firstPipeline.ref }}</strong>
|
||||
</template>
|
||||
<template #author>{{ packagePipeline.user.name }}</template>
|
||||
</gl-sprintf>
|
||||
</history-item>
|
||||
<history-item icon="pipeline" data-testid="first-pipeline-pipeline">
|
||||
<gl-sprintf :message="$options.i18n.createdByPipelineText">
|
||||
<template #link>
|
||||
<gl-link :href="firstPipeline.project.pipeline_url">#{{ firstPipeline.id }}</gl-link>
|
||||
</template>
|
||||
<template #datetime>
|
||||
<time-ago-tooltip :time="firstPipeline.created_at" />
|
||||
</template>
|
||||
<template #author>{{ firstPipeline.user.name }}</template>
|
||||
</gl-sprintf>
|
||||
</history-item>
|
||||
</template>
|
||||
|
||||
<!-- PUBLISHED LINE -->
|
||||
<history-item icon="package" data-testid="published">
|
||||
<gl-sprintf :message="$options.i18n.publishText">
|
||||
<template #project>
|
||||
|
@ -109,6 +131,37 @@ export default {
|
|||
</template>
|
||||
</gl-sprintf>
|
||||
</history-item>
|
||||
|
||||
<history-item v-if="archiviedLines" icon="history" data-testid="archived">
|
||||
<gl-sprintf :message="archivedPipelineMessage">
|
||||
<template #number>
|
||||
<strong>{{ archiviedLines }}</strong>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</history-item>
|
||||
|
||||
<!-- PIPELINES LIST ENTRIES -->
|
||||
<history-item
|
||||
v-for="pipeline in lastPipelines"
|
||||
:key="pipeline.id"
|
||||
icon="pencil"
|
||||
data-testid="pipeline-entry"
|
||||
>
|
||||
<gl-sprintf :message="$options.i18n.combinedUpdateText">
|
||||
<template #link>
|
||||
<gl-link :href="pipeline.project.commit_url">#{{ truncate(pipeline.sha) }}</gl-link>
|
||||
</template>
|
||||
<template #branch>
|
||||
<strong>{{ pipeline.ref }}</strong>
|
||||
</template>
|
||||
<template #pipeline>
|
||||
<gl-link :href="pipeline.project.pipeline_url">#{{ pipeline.id }}</gl-link>
|
||||
</template>
|
||||
<template #datetime>
|
||||
<time-ago-tooltip :time="pipeline.created_at" />
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</history-item>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -45,3 +45,5 @@ export const NpmManager = {
|
|||
export const FETCH_PACKAGE_VERSIONS_ERROR = s__(
|
||||
'PackageRegistry|Unable to fetch package version information.',
|
||||
);
|
||||
|
||||
export const HISTORY_PIPELINES_LIMIT = 5;
|
||||
|
|
|
@ -4,6 +4,7 @@ import Translate from '~/vue_shared/translate';
|
|||
import ModalManager from './components/user_modal_manager.vue';
|
||||
import csrf from '~/lib/utils/csrf';
|
||||
import initConfirmModal from '~/confirm_modal';
|
||||
import initAdminUsersApp from '~/admin/users';
|
||||
|
||||
const MODAL_TEXTS_CONTAINER_SELECTOR = '#js-modal-texts';
|
||||
const MODAL_MANAGER_SELECTOR = '#js-delete-user-modal';
|
||||
|
@ -56,4 +57,5 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
});
|
||||
|
||||
initConfirmModal();
|
||||
initAdminUsersApp();
|
||||
});
|
||||
|
|
|
@ -17,6 +17,8 @@ class Import::GithubController < Import::BaseController
|
|||
rescue_from Octokit::TooManyRequests, with: :provider_rate_limit
|
||||
rescue_from Gitlab::GithubImport::RateLimitError, with: :rate_limit_threshold_exceeded
|
||||
|
||||
PAGE_LENGTH = 25
|
||||
|
||||
def new
|
||||
if !ci_cd_only? && github_import_configured? && logged_in_with_provider?
|
||||
go_to_provider_for_permissions
|
||||
|
@ -115,19 +117,16 @@ class Import::GithubController < Import::BaseController
|
|||
|
||||
def client_repos
|
||||
@client_repos ||= if Feature.enabled?(:remove_legacy_github_client)
|
||||
concatenated_repos
|
||||
if sanitized_filter_param
|
||||
client.search_repos_by_name(sanitized_filter_param, pagination_options)[:items]
|
||||
else
|
||||
client.octokit.repos(nil, pagination_options)
|
||||
end
|
||||
else
|
||||
filtered(client.repos)
|
||||
end
|
||||
end
|
||||
|
||||
def concatenated_repos
|
||||
return [] unless client.respond_to?(:each_page)
|
||||
return client.each_page(:repos).flat_map(&:objects) unless sanitized_filter_param
|
||||
|
||||
client.search_repos_by_name(sanitized_filter_param).flat_map(&:objects).flat_map(&:items)
|
||||
end
|
||||
|
||||
def sanitized_filter_param
|
||||
super
|
||||
|
||||
|
@ -257,6 +256,13 @@ class Import::GithubController < Import::BaseController
|
|||
def rate_limit_threshold_exceeded
|
||||
head :too_many_requests
|
||||
end
|
||||
|
||||
def pagination_options
|
||||
{
|
||||
page: [1, params[:page].to_i].max,
|
||||
per_page: PAGE_LENGTH
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
Import::GithubController.prepend_if_ee('EE::Import::GithubController')
|
||||
|
|
|
@ -20,8 +20,6 @@ class ProjectsController < Projects::ApplicationController
|
|||
before_action :project, except: [:index, :new, :create, :resolve]
|
||||
before_action :repository, except: [:index, :new, :create, :resolve]
|
||||
before_action :assign_ref_vars, if: -> { action_name == 'show' && repo_exists? }
|
||||
before_action :tree,
|
||||
if: -> { action_name == 'show' && repo_exists? && project_view_files? }
|
||||
before_action :project_export_enabled, only: [:export, :download_export, :remove_export, :generate_new_export]
|
||||
before_action :present_project, only: [:edit]
|
||||
before_action :authorize_download_code!, only: [:refs]
|
||||
|
|
|
@ -328,8 +328,9 @@ module BlobHelper
|
|||
end
|
||||
|
||||
def readable_blob(options, path, project, ref)
|
||||
blob = options.delete(:blob)
|
||||
blob ||= project.repository.blob_at(ref, path) rescue nil
|
||||
blob = options.fetch(:blob) do
|
||||
project.repository.blob_at(ref, path) rescue nil
|
||||
end
|
||||
|
||||
blob if blob&.readable_text?
|
||||
end
|
||||
|
|
|
@ -228,12 +228,12 @@ module TreeHelper
|
|||
gitpod_enabled: !current_user.nil? && current_user.gitpod_enabled,
|
||||
is_blob: !options[:blob].nil?,
|
||||
|
||||
show_edit_button: show_edit_button?,
|
||||
show_edit_button: show_edit_button?(options),
|
||||
show_web_ide_button: show_web_ide_button?,
|
||||
show_gitpod_button: show_gitpod_button?,
|
||||
|
||||
web_ide_url: web_ide_url,
|
||||
edit_url: edit_url,
|
||||
edit_url: edit_url(options),
|
||||
gitpod_url: gitpod_url
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module UsersHelper
|
||||
def admin_users_data_attributes(users)
|
||||
{
|
||||
users: Admin::UserSerializer.new.represent(users).to_json,
|
||||
paths: admin_users_paths.to_json
|
||||
}
|
||||
end
|
||||
|
||||
def user_link(user)
|
||||
link_to(user.name, user_path(user),
|
||||
title: user.email,
|
||||
|
@ -208,6 +215,22 @@ module UsersHelper
|
|||
|
||||
private
|
||||
|
||||
def admin_users_paths
|
||||
{
|
||||
edit: edit_admin_user_path(:id),
|
||||
approve: approve_admin_user_path(:id),
|
||||
reject: reject_admin_user_path(:id),
|
||||
unblock: unblock_admin_user_path(:id),
|
||||
block: block_admin_user_path(:id),
|
||||
deactivate: deactivate_admin_user_path(:id),
|
||||
activate: activate_admin_user_path(:id),
|
||||
unlock: unlock_admin_user_path(:id),
|
||||
delete: admin_user_path(:id),
|
||||
delete_with_contributions: admin_user_path(:id),
|
||||
admin_user: admin_user_path(:id)
|
||||
}
|
||||
end
|
||||
|
||||
def blocked_user_badge(user)
|
||||
pending_approval_badge = { text: s_('AdminUsers|Pending approval'), variant: 'info' }
|
||||
return pending_approval_badge if user.blocked_pending_approval?
|
||||
|
|
|
@ -21,8 +21,8 @@ module WebIdeButtonHelper
|
|||
can_collaborate? || can_create_mr_from_fork?
|
||||
end
|
||||
|
||||
def show_edit_button?
|
||||
readable_blob? && show_web_ide_button?
|
||||
def show_edit_button?(options = {})
|
||||
readable_blob?(options) && show_web_ide_button?
|
||||
end
|
||||
|
||||
def show_gitpod_button?
|
||||
|
@ -37,8 +37,8 @@ module WebIdeButtonHelper
|
|||
!project_fork.nil? && !can_push_code?
|
||||
end
|
||||
|
||||
def readable_blob?
|
||||
!readable_blob({}, @path, @project, @ref).nil?
|
||||
def readable_blob?(options = {})
|
||||
!readable_blob(options, @path, @project, @ref).nil?
|
||||
end
|
||||
|
||||
def needs_to_fork?
|
||||
|
@ -49,8 +49,8 @@ module WebIdeButtonHelper
|
|||
ide_edit_path(project_to_use, @ref, @path || '')
|
||||
end
|
||||
|
||||
def edit_url
|
||||
readable_blob? ? edit_blob_path(@project, @ref, @path || '') : ''
|
||||
def edit_url(options = {})
|
||||
readable_blob?(options) ? edit_blob_path(@project, @ref, @path || '') : ''
|
||||
end
|
||||
|
||||
def gitpod_url
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class Experiment < ApplicationRecord
|
||||
has_many :experiment_users
|
||||
has_many :experiment_subjects, inverse_of: :experiment
|
||||
|
||||
validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
|
||||
|
||||
|
|
28
app/models/experiment_subject.rb
Normal file
28
app/models/experiment_subject.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ExperimentSubject < ApplicationRecord
|
||||
include ::Gitlab::Experimentation::GroupTypes
|
||||
|
||||
belongs_to :experiment, inverse_of: :experiment_subjects
|
||||
belongs_to :user
|
||||
belongs_to :group
|
||||
belongs_to :project
|
||||
|
||||
validates :experiment, presence: true
|
||||
validates :variant, presence: true
|
||||
validate :must_have_one_subject_present
|
||||
|
||||
enum variant: { GROUP_CONTROL => 0, GROUP_EXPERIMENTAL => 1 }
|
||||
|
||||
private
|
||||
|
||||
def must_have_one_subject_present
|
||||
if non_nil_subjects.length != 1
|
||||
errors.add(:base, s_("ExperimentSubject|Must have exactly one of User, Group, or Project."))
|
||||
end
|
||||
end
|
||||
|
||||
def non_nil_subjects
|
||||
@non_nil_subjects ||= [user, group, project].reject(&:blank?)
|
||||
end
|
||||
end
|
|
@ -618,7 +618,7 @@ class Repository
|
|||
end
|
||||
|
||||
def readme_path
|
||||
readme&.path
|
||||
head_tree&.readme_path
|
||||
end
|
||||
cache_method :readme_path
|
||||
|
||||
|
|
|
@ -77,19 +77,19 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
|||
end
|
||||
|
||||
def readme_path
|
||||
filename_path(:readme)
|
||||
filename_path(repository.readme_path)
|
||||
end
|
||||
|
||||
def changelog_path
|
||||
filename_path(:changelog)
|
||||
filename_path(repository.changelog&.name)
|
||||
end
|
||||
|
||||
def license_path
|
||||
filename_path(:license_blob)
|
||||
filename_path(repository.license_blob&.name)
|
||||
end
|
||||
|
||||
def ci_configuration_path
|
||||
filename_path(:gitlab_ci_yml)
|
||||
filename_path(repository.gitlab_ci_yml&.name)
|
||||
end
|
||||
|
||||
def contribution_guide_path
|
||||
|
@ -244,11 +244,11 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
|||
end
|
||||
|
||||
def readme_anchor_data
|
||||
if current_user && can_current_user_push_to_default_branch? && repository.readme.nil?
|
||||
if current_user && can_current_user_push_to_default_branch? && readme_path.nil?
|
||||
AnchorData.new(false,
|
||||
statistic_icon + _('Add README'),
|
||||
empty_repo? ? add_readme_ide_path : add_readme_path)
|
||||
elsif repository.readme
|
||||
elsif readme_path
|
||||
AnchorData.new(false,
|
||||
statistic_icon('doc-text') + _('README'),
|
||||
default_view != 'readme' ? readme_path : '#readme',
|
||||
|
@ -397,13 +397,10 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
|||
current_user && can?(current_user, :create_cluster, project)
|
||||
end
|
||||
|
||||
def filename_path(filename)
|
||||
if blob = repository.public_send(filename) # rubocop:disable GitlabSecurity/PublicSend
|
||||
project_blob_path(
|
||||
project,
|
||||
tree_join(default_branch, blob.name)
|
||||
)
|
||||
end
|
||||
def filename_path(filepath)
|
||||
return if filepath.blank?
|
||||
|
||||
project_blob_path(project, tree_join(default_branch, filepath))
|
||||
end
|
||||
|
||||
def anonymous_project_view
|
||||
|
|
|
@ -72,6 +72,10 @@
|
|||
- if @users.empty?
|
||||
.nothing-here-block.border-top-0
|
||||
= s_('AdminUsers|No users found')
|
||||
- elsif Feature.enabled?(:vue_admin_users)
|
||||
#js-admin-users-app{ data: admin_users_data_attributes(@users) }
|
||||
.gl-spinner-container.gl-my-7
|
||||
%span.gl-vertical-align-bottom.gl-spinner.gl-spinner-dark.gl-spinner-lg{ aria: { label: _('Loading') } }
|
||||
- else
|
||||
.table-holder
|
||||
.thead-white.text-nowrap.gl-responsive-table-row.table-row-header{ role: 'row' }
|
||||
|
|
|
@ -7,4 +7,6 @@
|
|||
= sprite_icon('github', css_class: 'gl-mr-2')
|
||||
= _('Import repositories from GitHub')
|
||||
|
||||
= render 'import/githubish_status', provider: 'github'
|
||||
- paginatable = Feature.enabled?(:remove_legacy_github_client)
|
||||
|
||||
= render 'import/githubish_status', provider: 'github', paginatable: paginatable
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
- if can?(current_user, :update_user_status, current_user)
|
||||
%li
|
||||
%button.btn.menu-item.js-set-status-modal-trigger{ type: 'button' }
|
||||
- if current_user.status.present?
|
||||
- if show_status_emoji?(current_user.status) || user_status_set_to_busy?(current_user.status)
|
||||
= s_('SetStatusModal|Edit status')
|
||||
- else
|
||||
= s_('SetStatusModal|Set status')
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
- project = local_assigns.fetch(:project) { @project }
|
||||
- show_auto_devops_callout = show_auto_devops_callout?(@project)
|
||||
- add_page_startup_api_call logs_file_project_ref_path(@project, ref, @path, format: "json", offset: 0)
|
||||
- if @tree.readme
|
||||
- add_page_startup_api_call project_blob_path(@project, tree_join(@ref, @tree.readme.path), viewer: "rich", format: "json")
|
||||
- if readme_path = @project.repository.readme_path
|
||||
- add_page_startup_api_call project_blob_path(@project, tree_join(@ref, readme_path), viewer: "rich", format: "json")
|
||||
|
||||
#tree-holder.tree-holder.clearfix
|
||||
.nav-block
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
- type = blob ? 'blob' : 'tree'
|
||||
|
||||
.d-inline-block{ data: { options: web_ide_button_data(blob: blob).to_json }, id: "js-#{type}-web-ide-link" }
|
||||
.d-inline-block{ data: { options: web_ide_button_data({ blob: blob }).to_json }, id: "js-#{type}-web-ide-link" }
|
||||
|
||||
- if show_edit_button?
|
||||
- if show_edit_button?({ blob: blob })
|
||||
= render 'shared/confirm_fork_modal', fork_path: fork_and_edit_path(@project, @ref, @path), type: 'edit'
|
||||
- if show_web_ide_button?
|
||||
= render 'shared/confirm_fork_modal', fork_path: ide_fork_and_edit_path(@project, @ref, @path), type: 'webide'
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Display more pipelines info in package history
|
||||
merge_request: 49040
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Create a new `ExperimentSubject` model, associated to the `Experiment` model, and related database migrations.
|
||||
merge_request: 47042
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Check for a status in the current user dropdown
|
||||
merge_request: 49203
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add GitHub Importer pagination
|
||||
merge_request: 48983
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add flash message for setAssignees on group issue boards
|
||||
merge_request: 48277
|
||||
author:
|
||||
type: added
|
8
config/feature_flags/development/vue_admin_users.yml
Normal file
8
config/feature_flags/development/vue_admin_users.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: vue_admin_users
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48922
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/290737
|
||||
milestone: '13.7'
|
||||
type: development
|
||||
group: group::compliance
|
||||
default_enabled: false
|
25
db/migrate/20201110221400_create_experiment_subjects.rb
Normal file
25
db/migrate/20201110221400_create_experiment_subjects.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateExperimentSubjects < ActiveRecord::Migration[6.0]
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
create_table :experiment_subjects do |t|
|
||||
t.references :experiment, index: true, foreign_key: { on_delete: :cascade }, null: false
|
||||
t.bigint :user_id, index: true
|
||||
t.bigint :group_id, index: true
|
||||
t.bigint :project_id, index: true
|
||||
t.integer :variant, limit: 2, null: false, default: 0
|
||||
t.timestamps_with_timezone null: false
|
||||
end
|
||||
|
||||
# Require exactly one of user_id, group_id, or project_id to be NOT NULL
|
||||
execute <<-SQL
|
||||
ALTER TABLE experiment_subjects ADD CONSTRAINT chk_has_one_subject CHECK (num_nonnulls(user_id, group_id, project_id) = 1);
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :experiment_subjects
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddForeignKeyToExperimentSubjectsOnUser < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :experiment_subjects, :users, column: :user_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :experiment_subjects, column: :user_id
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddForeignKeyToExperimentSubjectsOnGroup < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :experiment_subjects, :namespaces, column: :group_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :experiment_subjects, column: :group_id
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddForeignKeyToExperimentSubjectsOnProject < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :experiment_subjects, :projects, column: :project_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :experiment_subjects, column: :project_id
|
||||
end
|
||||
end
|
||||
end
|
1
db/schema_migrations/20201110221400
Normal file
1
db/schema_migrations/20201110221400
Normal file
|
@ -0,0 +1 @@
|
|||
9fba60d8805915fcf6af7812e2c752007ac17bb92c8a02c942c0c790d2997441
|
1
db/schema_migrations/20201111051655
Normal file
1
db/schema_migrations/20201111051655
Normal file
|
@ -0,0 +1 @@
|
|||
4340d0f6d3b660b336fdc3166a4960865c79e90f505b1173bab4e0d11c1199b3
|
1
db/schema_migrations/20201111051847
Normal file
1
db/schema_migrations/20201111051847
Normal file
|
@ -0,0 +1 @@
|
|||
8180908c5e577757b3f518d312cbf0ba77c65b39fa55dde487036541f49114a1
|
1
db/schema_migrations/20201111051904
Normal file
1
db/schema_migrations/20201111051904
Normal file
|
@ -0,0 +1 @@
|
|||
c228aa5c16e63af7520dd1bd90cefb1f74ec2371af3b0e839938d8c628f70e8a
|
|
@ -12138,6 +12138,27 @@ CREATE SEQUENCE evidences_id_seq
|
|||
|
||||
ALTER SEQUENCE evidences_id_seq OWNED BY evidences.id;
|
||||
|
||||
CREATE TABLE experiment_subjects (
|
||||
id bigint NOT NULL,
|
||||
experiment_id bigint NOT NULL,
|
||||
user_id bigint,
|
||||
group_id bigint,
|
||||
project_id bigint,
|
||||
variant smallint DEFAULT 0 NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
CONSTRAINT chk_has_one_subject CHECK ((num_nonnulls(user_id, group_id, project_id) = 1))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE experiment_subjects_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE experiment_subjects_id_seq OWNED BY experiment_subjects.id;
|
||||
|
||||
CREATE TABLE experiment_users (
|
||||
id bigint NOT NULL,
|
||||
experiment_id bigint NOT NULL,
|
||||
|
@ -18187,6 +18208,8 @@ ALTER TABLE ONLY events ALTER COLUMN id SET DEFAULT nextval('events_id_seq'::reg
|
|||
|
||||
ALTER TABLE ONLY evidences ALTER COLUMN id SET DEFAULT nextval('evidences_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY experiment_subjects ALTER COLUMN id SET DEFAULT nextval('experiment_subjects_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY experiment_users ALTER COLUMN id SET DEFAULT nextval('experiment_users_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY experiments ALTER COLUMN id SET DEFAULT nextval('experiments_id_seq'::regclass);
|
||||
|
@ -19353,6 +19376,9 @@ ALTER TABLE ONLY events
|
|||
ALTER TABLE ONLY evidences
|
||||
ADD CONSTRAINT evidences_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY experiment_subjects
|
||||
ADD CONSTRAINT experiment_subjects_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY experiment_users
|
||||
ADD CONSTRAINT experiment_users_pkey PRIMARY KEY (id);
|
||||
|
||||
|
@ -21233,6 +21259,14 @@ CREATE UNIQUE INDEX index_events_on_target_type_and_target_id_and_fingerprint ON
|
|||
|
||||
CREATE INDEX index_evidences_on_release_id ON evidences USING btree (release_id);
|
||||
|
||||
CREATE INDEX index_experiment_subjects_on_experiment_id ON experiment_subjects USING btree (experiment_id);
|
||||
|
||||
CREATE INDEX index_experiment_subjects_on_group_id ON experiment_subjects USING btree (group_id);
|
||||
|
||||
CREATE INDEX index_experiment_subjects_on_project_id ON experiment_subjects USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_experiment_subjects_on_user_id ON experiment_subjects USING btree (user_id);
|
||||
|
||||
CREATE INDEX index_experiment_users_on_experiment_id ON experiment_users USING btree (experiment_id);
|
||||
|
||||
CREATE INDEX index_experiment_users_on_user_id ON experiment_users USING btree (user_id);
|
||||
|
@ -23424,6 +23458,9 @@ ALTER TABLE ONLY packages_package_files
|
|||
ALTER TABLE ONLY ci_builds
|
||||
ADD CONSTRAINT fk_87f4cefcda FOREIGN KEY (upstream_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY experiment_subjects
|
||||
ADD CONSTRAINT fk_88489af1b1 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY vulnerabilities
|
||||
ADD CONSTRAINT fk_88b4d546ef FOREIGN KEY (start_date_sourcing_milestone_id) REFERENCES milestones(id) ON DELETE SET NULL;
|
||||
|
||||
|
@ -23610,6 +23647,9 @@ ALTER TABLE ONLY issues
|
|||
ALTER TABLE ONLY issue_links
|
||||
ADD CONSTRAINT fk_c900194ff2 FOREIGN KEY (source_id) REFERENCES issues(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY experiment_subjects
|
||||
ADD CONSTRAINT fk_ccc28f8ceb FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY todos
|
||||
ADD CONSTRAINT fk_ccf0373936 FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
|
@ -23670,6 +23710,9 @@ ALTER TABLE ONLY analytics_devops_adoption_segment_selections
|
|||
ALTER TABLE ONLY issues
|
||||
ADD CONSTRAINT fk_df75a7c8b8 FOREIGN KEY (promoted_to_epic_id) REFERENCES epics(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY experiment_subjects
|
||||
ADD CONSTRAINT fk_dfc3e211d4 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_resources
|
||||
ADD CONSTRAINT fk_e169a8e3d5 FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE SET NULL;
|
||||
|
||||
|
@ -25032,6 +25075,9 @@ ALTER TABLE ONLY snippet_statistics
|
|||
ALTER TABLE ONLY project_security_settings
|
||||
ADD CONSTRAINT fk_rails_ed4abe1338 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY experiment_subjects
|
||||
ADD CONSTRAINT fk_rails_ede5754774 FOREIGN KEY (experiment_id) REFERENCES experiments(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_daily_build_group_report_results
|
||||
ADD CONSTRAINT fk_rails_ee072d13b3 FOREIGN KEY (last_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ first: '\b([A-Z]{3,5})\b'
|
|||
second: '(?:\b[A-Z][a-z]+ )+\(([A-Z]{3,5})\)'
|
||||
# ... with the exception of these:
|
||||
exceptions:
|
||||
- AJAX
|
||||
- ANSI
|
||||
- API
|
||||
- ARM
|
||||
|
@ -21,11 +22,14 @@ exceptions:
|
|||
- ASCII
|
||||
- AWS
|
||||
- BSD
|
||||
- CAS
|
||||
- CLI
|
||||
- CNA
|
||||
- CNAME
|
||||
- CORE
|
||||
- CPU
|
||||
- CRIME
|
||||
- CSRF
|
||||
- CSS
|
||||
- CSV
|
||||
- CVE
|
||||
|
@ -33,19 +37,28 @@ exceptions:
|
|||
- DAST
|
||||
- DHCP
|
||||
- DNS
|
||||
- DOM
|
||||
- DSA
|
||||
- DVCS
|
||||
- ECDSA
|
||||
- EKS
|
||||
- EOL
|
||||
- EXIF
|
||||
- FAQ
|
||||
- FOSS
|
||||
- FQDN
|
||||
- GCP
|
||||
- GDK
|
||||
- GDPR
|
||||
- GET
|
||||
- GIF
|
||||
- GKE
|
||||
- GNU
|
||||
- GPG
|
||||
- GPL
|
||||
- GUI
|
||||
- HAML
|
||||
- HIPAA
|
||||
- HTML
|
||||
- HTTP
|
||||
- HTTPS
|
||||
|
@ -55,11 +68,13 @@ exceptions:
|
|||
- IDE
|
||||
- IID
|
||||
- IMAP
|
||||
- IOPS
|
||||
- IRC
|
||||
- ISO
|
||||
- JPEG
|
||||
- JPG
|
||||
- JSON
|
||||
- JWT
|
||||
- LAN
|
||||
- LDAP
|
||||
- LDAPS
|
||||
|
@ -76,17 +91,25 @@ exceptions:
|
|||
- NOTE
|
||||
- NPM
|
||||
- ONLY
|
||||
- OWASP
|
||||
- PAT
|
||||
- PCI-DSS
|
||||
- PDF
|
||||
- PEM
|
||||
- PEP
|
||||
- PGP
|
||||
- PHP
|
||||
- PNG
|
||||
- POST
|
||||
- PUT
|
||||
- RAM
|
||||
- RDP
|
||||
- REST
|
||||
- RFC
|
||||
- RHEL
|
||||
- RPC
|
||||
- RPM
|
||||
- RPS
|
||||
- RSA
|
||||
- RSS
|
||||
- RVM
|
||||
|
@ -101,8 +124,12 @@ exceptions:
|
|||
- SLA
|
||||
- SMS
|
||||
- SMTP
|
||||
- SOC
|
||||
- SOX
|
||||
- SPF
|
||||
- SQL
|
||||
- SSD
|
||||
- SSG
|
||||
- SSH
|
||||
- SSL
|
||||
- SSO
|
||||
|
@ -119,9 +146,12 @@ exceptions:
|
|||
- URL
|
||||
- USB
|
||||
- UTC
|
||||
- UTF
|
||||
- UUID
|
||||
- VCS
|
||||
- VPC
|
||||
- WIP
|
||||
- WSL
|
||||
- XML
|
||||
- XSS
|
||||
- YAML
|
||||
|
|
|
@ -300,6 +300,7 @@ NGINX
|
|||
Nokogiri
|
||||
npm
|
||||
Nurtch
|
||||
nyc
|
||||
OAuth
|
||||
offboarded
|
||||
offboarding
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
---
|
||||
stage: Plan
|
||||
group: Project Management
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||
---
|
||||
|
||||
<!---
|
||||
This documentation is auto generated by a script.
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ This page is a development guide for application secrets.
|
|||
|Installation type |Location |
|
||||
|--- |--- |
|
||||
|Omnibus |[`/etc/gitlab/gitlab-secrets.json`](https://docs.gitlab.com/omnibus/settings/backups.html#backup-and-restore-omnibus-gitlab-configuration) |
|
||||
|Cloud Native GitLab Charts |[Kubernets Secrets](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/f65c3d37fc8cf09a7987544680413552fb666aac/doc/installation/secrets.md#gitlab-rails-secret)|
|
||||
|Cloud Native GitLab Charts |[Kubernetes Secrets](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/f65c3d37fc8cf09a7987544680413552fb666aac/doc/installation/secrets.md#gitlab-rails-secret)|
|
||||
|Source |`<path-to-gitlab-rails>/config/secrets.yml` (Automatically generated by [01_secret_token.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/01_secret_token.rb)) |
|
||||
|
||||
## Warning: Before you add a new secret to application secrets
|
||||
|
|
|
@ -17,7 +17,7 @@ Please note that the intent is not to retroactively change names in existing dat
|
|||
| **Foreign Key** | `fk_<table name>_<column name>[_and_<column name>]*_<foreign table name>` | | `fk_projects_group_id_groups` |
|
||||
| **Index** | `index_<table name>_on_<column name>[_and_<column name>]*[_and_<column name in partial clause>]*` | | `index_repositories_on_group_id` |
|
||||
| **Unique Constraint** | `unique_<table name>_<column name>[_and_<column name>]*` | | `unique_projects_group_id_and_name` |
|
||||
| **Check Constraint** | `check_<table name>_<column name>[_and_<column name>]*[_<suffix>]?` | The optional suffix should denote the type of validation, such as `length` and `enum`. It can also be used to desambiguate multiple `CHECK` constraints on the same column. | `check_projects_name_length`<br />`check_projects_type_enum`<br />`check_projects_admin1_id_and_admin2_id_differ` |
|
||||
| **Check Constraint** | `check_<table name>_<column name>[_and_<column name>]*[_<suffix>]?` | The optional suffix should denote the type of validation, such as `length` and `enum`. It can also be used to disambiguate multiple `CHECK` constraints on the same column. | `check_projects_name_length`<br />`check_projects_type_enum`<br />`check_projects_admin1_id_and_admin2_id_differ` |
|
||||
| **Exclusion Constraint** | `excl_<table name>_<column name>[_and_<column name>]*_[_<suffix>]?` | The optional suffix should denote the type of exclusion being performed. | `excl_reservations_start_at_end_at_no_overlap` |
|
||||
|
||||
## Observations
|
||||
|
|
|
@ -119,7 +119,7 @@ Patterns:
|
|||
- `'"((?:\\"|[^"]|\\")*)"'`: captures terms inside quotes, removing the quotes
|
||||
- `"'((?:\\'|[^']|\\')*)'"`: same as above, for single-quotes
|
||||
- `'\.([^.]+)(?=\.|\s|\Z)'`: separate terms with periods in-between
|
||||
- `'([\p{L}_.-]+)'`: some common chars in file names to keep the whole filename intact (eg. `my_file-ñame.txt`)
|
||||
- `'([\p{L}_.-]+)'`: some common chars in file names to keep the whole filename intact (for example `my_file-ñame.txt`)
|
||||
- `'([\p{L}\d_]+)'`: letters, numbers and underscores are the most common tokens in programming. Always capture them greedily regardless of context.
|
||||
|
||||
## Gotchas
|
||||
|
|
|
@ -58,7 +58,7 @@ The editor follows the same public API as [provided by Monaco editor](https://mi
|
|||
| Function | Arguments | Description
|
||||
| ----- | ----- | ----- |
|
||||
| `updateModelLanguage` | `path`: String | Updates the instance's syntax highlighting to follow the extension of the passed `path`. Available only on _instance_ level|
|
||||
| `use` | Array of objects | Array of **extensions** to apply to the instance. Accepts only the array of _objects_, which means that the extensions' ES6 modules should be fetched and resolved in your views/components before being passed to `use`. This prop is available on _instance_ (applies extension to this particular instance) and _global edtor_ (applies the same extension to all instances) levels. |
|
||||
| `use` | Array of objects | Array of **extensions** to apply to the instance. Accepts only the array of _objects_, which means that the extensions' ES6 modules should be fetched and resolved in your views/components before being passed to `use`. This prop is available on _instance_ (applies extension to this particular instance) and _global editor_ (applies the same extension to all instances) levels. |
|
||||
| Monaco Editor options | See [documentation](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandalonecodeeditor.html) | Default Monaco editor options |
|
||||
|
||||
## Tips
|
||||
|
|
|
@ -79,10 +79,8 @@ CSS classes should use the `lowercase-hyphenated` format rather than
|
|||
```
|
||||
|
||||
Class names should be used instead of tag name selectors.
|
||||
Using tag name selectors are discouraged in CSS because
|
||||
they can affect unintended elements in the hierarchy.
|
||||
Also, since they are not meaningful names, they do not
|
||||
add meaning to the code.
|
||||
Using tag name selectors is discouraged because they can affect
|
||||
unintended elements in the hierarchy.
|
||||
|
||||
```scss
|
||||
// Bad
|
||||
|
@ -94,149 +92,14 @@ ul {
|
|||
.class-name {
|
||||
color: #fff;
|
||||
}
|
||||
```
|
||||
|
||||
### Formatting
|
||||
// Best
|
||||
// prefer an existing utility class over adding existing styles
|
||||
```0
|
||||
|
||||
You should always use a space before a brace, braces should be on the same
|
||||
line, each property should each get its own line, and there should be a space
|
||||
between the property and its value.
|
||||
|
||||
```scss
|
||||
// Bad
|
||||
.container-item {
|
||||
width: 100px; height: 100px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
// Bad
|
||||
.container-item
|
||||
{
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
// Bad
|
||||
.container-item{
|
||||
width:100px;
|
||||
height:100px;
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
// Good
|
||||
.container-item {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-top: 0;
|
||||
}
|
||||
```
|
||||
|
||||
Note that there is an exception for single-line rulesets, although these are
|
||||
not typically recommended.
|
||||
|
||||
```scss
|
||||
p { margin: 0; padding: 0; }
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
HEX (hexadecimal) colors should use shorthand where possible, and should use
|
||||
lower case letters to differentiate between letters and numbers, e.g. `#E3E3E3`
|
||||
vs. `#e3e3e3`.
|
||||
|
||||
```scss
|
||||
// Bad
|
||||
p {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
// Bad
|
||||
p {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
// Good
|
||||
p {
|
||||
color: #fff;
|
||||
}
|
||||
```
|
||||
|
||||
### Indentation
|
||||
|
||||
Indentation should always use two spaces for each indentation level.
|
||||
|
||||
```scss
|
||||
// Bad, four spaces
|
||||
p {
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
// Good
|
||||
p {
|
||||
color: #f00;
|
||||
}
|
||||
```
|
||||
|
||||
### Semicolons
|
||||
|
||||
Always include semicolons after every property. When the stylesheets are
|
||||
minified, the semicolons will be removed automatically.
|
||||
|
||||
```scss
|
||||
// Bad
|
||||
.container-item {
|
||||
width: 100px;
|
||||
height: 100px
|
||||
}
|
||||
|
||||
// Good
|
||||
.container-item {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
```
|
||||
|
||||
### Shorthand
|
||||
|
||||
The shorthand form should be used for properties that support it.
|
||||
|
||||
```scss
|
||||
// Bad
|
||||
margin: 10px 15px 10px 15px;
|
||||
padding: 10px 10px 10px 10px;
|
||||
|
||||
// Good
|
||||
margin: 10px 15px;
|
||||
padding: 10px;
|
||||
```
|
||||
|
||||
### Zero Units
|
||||
|
||||
Omit length units on zero values, they're unnecessary and not including them
|
||||
is slightly more performant.
|
||||
|
||||
```scss
|
||||
// Bad
|
||||
.item-with-padding {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
// Good
|
||||
.item-with-padding {
|
||||
padding: 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Selectors with a `js-` Prefix
|
||||
|
||||
Do not use any selector prefixed with `js-` for styling purposes. These
|
||||
selectors are intended for use only with JavaScript to allow for removal or
|
||||
renaming without breaking styling.
|
||||
|
||||
### IDs
|
||||
|
||||
Don't use ID selectors in CSS.
|
||||
Class names are also preferable to IDs. Rules that use IDs
|
||||
are not-reusable, as there can only be one affected element on
|
||||
the page.
|
||||
|
||||
```scss
|
||||
// Bad
|
||||
|
@ -250,11 +113,17 @@ Don't use ID selectors in CSS.
|
|||
}
|
||||
```
|
||||
|
||||
### Selectors with a `js-` Prefix
|
||||
|
||||
Do not use any selector prefixed with `js-` for styling purposes. These
|
||||
selectors are intended for use only with JavaScript to allow for removal or
|
||||
renaming without breaking styling.
|
||||
|
||||
### Variables
|
||||
|
||||
Before adding a new variable for a color or a size, guarantee:
|
||||
|
||||
- There isn't already one
|
||||
- There isn't an existing one.
|
||||
- There isn't a similar one we can use instead.
|
||||
|
||||
## Linting
|
||||
|
@ -279,22 +148,3 @@ CSSComb globally (system-wide). Run it in the GitLab directory with
|
|||
`csscomb app/assets/stylesheets` to automatically fix issues with CSS/SCSS.
|
||||
|
||||
Note that this won't fix every problem, but it should fix a majority.
|
||||
|
||||
### Ignoring issues
|
||||
|
||||
If you want a line or set of lines to be ignored by the linter, you can use
|
||||
`// scss-lint:disable RuleName` ([more information](https://github.com/sds/scss-lint#disabling-linters-via-source)):
|
||||
|
||||
```scss
|
||||
// This lint rule is disabled because it is supported only in Chrome/Safari
|
||||
// scss-lint:disable PropertySpelling
|
||||
body {
|
||||
text-decoration-skip: ink;
|
||||
}
|
||||
// scss-lint:enable PropertySpelling
|
||||
```
|
||||
|
||||
Make sure a comment is added on the line above the `disable` rule, otherwise the
|
||||
linter will throw a warning. `DisableLinterReason` is enabled to make sure the
|
||||
style guide isn't being ignored, and to communicate to others why the style
|
||||
guide is ignored in this instance.
|
||||
|
|
|
@ -11,7 +11,7 @@ info: "See the Technical Writers assigned to Development Guidelines: https://abo
|
|||
GitLab uses internal users (sometimes referred to as "bots") to perform
|
||||
actions or functions that cannot be attributed to a regular user.
|
||||
|
||||
These users are created programatically throughout the codebase itself when
|
||||
These users are created programmatically throughout the codebase itself when
|
||||
necessary, and do not count towards a license limit.
|
||||
|
||||
They are used when a traditional user account would not be applicable, for
|
||||
|
|
|
@ -172,7 +172,7 @@ In this particular example the database had to read 10 rows (regardless of our b
|
|||
|
||||
#### Improve filtering with `each_batch`
|
||||
|
||||
##### Specialized conditinal index
|
||||
##### Specialized conditional index
|
||||
|
||||
```sql
|
||||
CREATE INDEX index_on_users_never_logged_in ON users (id) WHERE sign_in_count = 0
|
||||
|
@ -230,7 +230,7 @@ CREATE INDEX index_on_users_never_logged_in ON users (sign_in_count)
|
|||
|
||||
Since `each_batch` builds range queries based on the `id` column, this index cannot be used efficiently. The DB reads the rows from the table or uses a bitmap search where the primary key index is also read.
|
||||
|
||||
##### "Slow" iteraton
|
||||
##### "Slow" iteration
|
||||
|
||||
Slow iteration means that we use a good index configuration to iterate over the table and apply filtering on the yielded relation.
|
||||
|
||||
|
@ -369,4 +369,4 @@ end
|
|||
|
||||
### `EachBatch` vs `BatchCount`
|
||||
|
||||
When adding new counters for usage ping, the preferred way to count records is using the `Gitlab::Database::BatchCount` class. The iteration logic implemented in `BatchCount` has similar performance characterisics like `EachBatch`. Most of the tips and suggestions for improving `BatchCount` mentioned above applies to `BatchCount` as well.
|
||||
When adding new counters for usage ping, the preferred way to count records is using the `Gitlab::Database::BatchCount` class. The iteration logic implemented in `BatchCount` has similar performance characteristics like `EachBatch`. Most of the tips and suggestions for improving `BatchCount` mentioned above applies to `BatchCount` as well.
|
||||
|
|
|
@ -17,7 +17,7 @@ into the widget that will match the existing design and interaction as other ext
|
|||
|
||||
To use extensions you need to first create a new extension object that will be used to fetch the
|
||||
data that will be rendered in the extension. See the example file in
|
||||
app/assets/javascripts/vue_merge_request_widget/extensions/issues.js for a working example.
|
||||
`app/assets/javascripts/vue_merge_request_widget/extensions/issues.js` for a working example.
|
||||
|
||||
The basic object structure is as below:
|
||||
|
||||
|
|
|
@ -690,7 +690,7 @@ and included in `rules` definitions via [YAML anchors](../ci/yaml/README.md#anch
|
|||
| `if-cache-credentials-schedule` | Limits jobs to scheduled pipelines with the `$CI_REPO_CACHE_CREDENTIALS` variable set. | |
|
||||
| `if-rspec-fail-fast-disabled` | Limits jobs to pipelines with `$RSPEC_FAIL_FAST_ENABLED` variable not set to `"true"`. | |
|
||||
| `if-rspec-fail-fast-skipped` | Matches if the pipeline is for a merge request and the MR title includes "SKIP RSPEC FAIL-FAST". | |
|
||||
| `if-security-pipeline-merge-result` | Matches if the pipeline is for a security merge request triggerred by `@gitlab-release-tools-bot`. | |
|
||||
| `if-security-pipeline-merge-result` | Matches if the pipeline is for a security merge request triggered by `@gitlab-release-tools-bot`. | |
|
||||
<!-- vale gitlab.Substitutions = YES -->
|
||||
|
||||
#### `changes:` patterns
|
||||
|
|
|
@ -204,6 +204,7 @@ possible selectors include:
|
|||
|
||||
- A semantic attribute like `name` (also verifies that `name` was setup properly)
|
||||
- A `data-testid` attribute ([recommended by maintainers of `@vue/test-utils`](https://github.com/vuejs/vue-test-utils/issues/1498#issuecomment-610133465))
|
||||
optionally combined with [`findByTestId`](#extendedwrapper-and-findbytestid)
|
||||
- a Vue `ref` (if using `@vue/test-utils`)
|
||||
|
||||
```javascript
|
||||
|
@ -220,7 +221,8 @@ it('exists', () => {
|
|||
// Good (especially for unit tests)
|
||||
wrapper.find(FooComponent);
|
||||
wrapper.find('input[name=foo]');
|
||||
wrapper.find('[data-testid="foo"]');
|
||||
wrapper.find('[data-testid="my-foo-id"]');
|
||||
wrapper.findByTestId('my-foo-id'); // with the extendedWrapper utility – check below
|
||||
wrapper.find({ ref: 'foo'});
|
||||
|
||||
// Bad
|
||||
|
@ -231,6 +233,8 @@ it('exists', () => {
|
|||
});
|
||||
```
|
||||
|
||||
It is recommended to use `kebab-case` for `data-testid` attribute.
|
||||
|
||||
It is not recommended that you add `.js-*` classes just for testing purposes. Only do this if there are no other feasible options available.
|
||||
|
||||
Do not use a `.qa-*` class or `data-qa-selector` attribute for any tests other than QA end-to-end testing.
|
||||
|
@ -1041,7 +1045,7 @@ testAction(
|
|||
);
|
||||
```
|
||||
|
||||
Check an example in [`spec/javascripts/ide/stores/actions_spec.jsspec/javascripts/ide/stores/actions_spec.js`](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/javascripts/ide/stores/actions_spec.js).
|
||||
Check an example in [`spec/frontend/ide/stores/actions_spec.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/fdc7197609dfa7caeb1d962042a26248e49f27da/spec/frontend/ide/stores/actions_spec.js#L392).
|
||||
|
||||
### Wait until Axios requests finish
|
||||
|
||||
|
@ -1053,6 +1057,29 @@ These are very useful if you don't have a handle to the request's Promise, for e
|
|||
|
||||
Both functions run `callback` on the next tick after the requests finish (using `setImmediate()`), to allow any `.then()` or `.catch()` handlers to run.
|
||||
|
||||
### `extendedWrapper` and `findByTestId`
|
||||
|
||||
Using `data-testid` is one of the [recommended ways to query DOM elements](#how-to-query-dom-elements).
|
||||
You can use the `extendedWrapper` utility on the `wrapper` returned by `shalowMount`/`mount`.
|
||||
By doing so, the `wrapper` provides you with the ability to perform a `findByTestId`,
|
||||
which is a shortcut to the more verbose `wrapper.find('[data-testid="my-test-id"]');`
|
||||
|
||||
```javascript
|
||||
import { extendedWrapper } from 'jest/helpers/vue_test_utils_helper';
|
||||
|
||||
describe('FooComponent', () => {
|
||||
const wrapper = extendedWrapper(shallowMount({
|
||||
template: `<div data-testid="my-test-id"></div>`,
|
||||
}));
|
||||
|
||||
it('exists', () => {
|
||||
expect(wrapper.findByTestId('my-test-id').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
Check an example in [`spec/frontend/alert_management/components/alert_details_spec.js`](https://gitlab.com/gitlab-org/gitlab/-/blob/ac1c9fa4c5b3b45f9566147b1c88fd1339cd7c25/spec/frontend/alert_management/components/alert_details_spec.js#L32).
|
||||
|
||||
## Testing with older browsers
|
||||
|
||||
Some regressions only affect a specific browser version. We can install and test in particular browsers with either Firefox or BrowserStack using the following steps:
|
||||
|
|
|
@ -32,7 +32,7 @@ This information is no longer up to date, as the current versions
|
|||
have changed and products have been renamed.
|
||||
|
||||
OpenShift 3 is not yet deployed on RedHat's offered [Online platform](https://www.openshift.com/),
|
||||
so in order to test it, we will use an [all-in-one Virtualbox image](https://www.okd.io/minishift/) that is
|
||||
so in order to test it, we will use an [all-in-one VirtualBox image](https://www.okd.io/minishift/) that is
|
||||
offered by the OpenShift developers and managed by Vagrant. If you haven't done
|
||||
already, go ahead and install the following components as they are essential to
|
||||
test OpenShift easily:
|
||||
|
@ -464,7 +464,7 @@ OpenShift's website about [autoscaling](https://docs.okd.io/3.11/dev_guide/pod_a
|
|||
As stated in the [all-in-one VM](https://www.okd.io/minishift/) page:
|
||||
|
||||
> By default, OpenShift will not allow a container to run as root or even a
|
||||
non-random container assigned userid. Most Docker images in the Dockerhub do not
|
||||
non-random container assigned userid. Most Docker images in Docker Hub do not
|
||||
follow this best practice and instead run as root.
|
||||
|
||||
The all-in-one VM we are using has this security turned off so it will not
|
||||
|
|
|
@ -78,7 +78,7 @@ amount of information you need.
|
|||
|
||||
### Alert details tab
|
||||
|
||||
The **Alert details** tab has two sections. The top section provides a short list of critical details such as the severity, start time, number of events, and originating monitorting tool. The second section displays the full alert payload.
|
||||
The **Alert details** tab has two sections. The top section provides a short list of critical details such as the severity, start time, number of events, and originating monitoring tool. The second section displays the full alert payload.
|
||||
|
||||
### Metrics tab
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
|
|||
### 1.1. Version Control and Git
|
||||
|
||||
1. [Version Control Systems](https://docs.google.com/presentation/d/16sX7hUrCZyOFbpvnrAFrg6tVO5_yT98IgdAqOmXwBho/edit#slide=id.g72f2e4906_2_29)
|
||||
1. [Katakoda: Learn Git Version Control using Interactive Browser-Based Scenarios](https://www.katacoda.com/courses/git)
|
||||
1. [Katacoda: Learn Git Version Control using Interactive Browser-Based Scenarios](https://www.katacoda.com/courses/git)
|
||||
|
||||
### 1.2. GitLab Basics
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ Value Stream Analytics measures the time spent to go from an
|
|||
(also known as cycle time) for each of your projects or groups. Value Stream Analytics displays the median time
|
||||
spent in each stage defined in the process.
|
||||
|
||||
Value Stream Analytics can help you quickly dtermine the velocity of a given
|
||||
Value Stream Analytics can help you quickly determine the velocity of a given
|
||||
group. It points to bottlenecks in the development process, enabling management
|
||||
to uncover, triage, and identify the root cause of slowdowns in the software development life cycle.
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ compilers. This example uses the CMake compiler.
|
|||
|
||||
To install CMake:
|
||||
|
||||
- For Mac, use [homebrew](https://brew.sh/) and run `brew install cmake`.
|
||||
- For Mac, use [Homebrew](https://brew.sh/) and run `brew install cmake`.
|
||||
- For other operating systems, follow the instructions at [cmake.org](https://cmake.org/install/).
|
||||
|
||||
When installation is complete, verify you can use CMake in your terminal by
|
||||
|
|
|
@ -39,7 +39,7 @@ PUT /projects/:id/packages/generic/:package_name/:package_version/:file_name
|
|||
| -------------------| --------------- | ---------| -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../../../api/README.md#namespaced-path-encoding). |
|
||||
| `package_name` | string | yes | The package name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), or underscores (`_`).
|
||||
| `package_version` | string | yes | The package version. It can contain only numbers (`0-9`), and dots (`.`). Must be in the format of `X.Y.Z`, i.e. should match `/\A\d+\.\d+\.\d+\z/` regular expresion.
|
||||
| `package_version` | string | yes | The package version. It can contain only numbers (`0-9`), and dots (`.`). Must be in the format of `X.Y.Z`, i.e. should match `/\A\d+\.\d+\.\d+\z/` regular expression.
|
||||
| `file_name` | string | yes | The file name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), or underscores (`_`).
|
||||
|
||||
Provide the file context in the request body.
|
||||
|
|
|
@ -159,7 +159,7 @@ later, can be written with `go env -w <var>=<value>`. For example,
|
|||
|
||||
Go modules and module versions are defined by source repositories, such as Git,
|
||||
SVN, and Mercurial. A module is a repository that contains `go.mod` and Go
|
||||
files. Module versions are defined by VCS tags.
|
||||
files. Module versions are defined by version control system (VCS) tags.
|
||||
|
||||
To publish a module, push `go.mod` and source files to a VCS repository. To
|
||||
publish a module version, push a VCS tag.
|
||||
|
|
|
@ -112,7 +112,7 @@ in the `.gitignore` file followed by one or more of:
|
|||
- A user's `@username`.
|
||||
- A user's email address.
|
||||
- The `@name` of one or more groups that should be owners of the file.
|
||||
- Lines starting with `#` are escaped.
|
||||
- Lines starting with `#` are ignored.
|
||||
|
||||
The order in which the paths are defined is significant: the last pattern that
|
||||
matches a given path will be used to find the code owners.
|
||||
|
|
|
@ -28,7 +28,7 @@ The paths here are simply Git's built-in [`.gitattributes` interface](https://gi
|
|||
/Nicefile gitlab-language=ruby
|
||||
```
|
||||
|
||||
To disable highlighting entirely, use `gitlab-language=text`. Lots more fun shenanigans are available through CGI options, such as:
|
||||
To disable highlighting entirely, use `gitlab-language=text`. Lots more fun shenanigans are available through common gateway interface (CGI) options, such as:
|
||||
|
||||
``` conf
|
||||
# json with erb in it
|
||||
|
|
|
@ -157,7 +157,7 @@ of the above are automatically configured. **(PREMIUM)**
|
|||
## Improving the speed of imports on self-managed instances
|
||||
|
||||
NOTE:
|
||||
Admin access to the GitLab server is required.
|
||||
Administrator access to the GitLab server is required.
|
||||
|
||||
For large projects it may take a while to import all data. To reduce the time necessary, you can increase the number of
|
||||
Sidekiq workers that process the following queues:
|
||||
|
|
|
@ -61,7 +61,7 @@ Docker pulls and pushes and re-run any CI pipelines to retrieve any build artifa
|
|||
|
||||
## Migrating from GitLab.com to self-managed GitLab
|
||||
|
||||
The process is essentially the same as for [migrating from self-managed GitLab to GitLab.com](#migrating-from-self-managed-gitlab-to-gitlabcom). The main difference is that users can be created on the self-managed GitLab instance by an admin through the UI or the [users API](../../../api/users.md#user-creation).
|
||||
The process is essentially the same as for [migrating from self-managed GitLab to GitLab.com](#migrating-from-self-managed-gitlab-to-gitlabcom). The main difference is that users can be created on the self-managed GitLab instance by an administrator through the UI or the [users API](../../../api/users.md#user-creation).
|
||||
|
||||
## Migrating between two self-managed GitLab instances
|
||||
|
||||
|
@ -73,4 +73,4 @@ then restore it on the new server.
|
|||
In the event of merging two GitLab instances together (for example, both instances have existing data on them and one can't be wiped),
|
||||
refer to the instructions in [Migrating from self-managed GitLab to GitLab.com](#migrating-from-self-managed-gitlab-to-gitlabcom).
|
||||
|
||||
Additionally, you can migrate users using the [Users API](../../../api/users.md) with an admin user.
|
||||
Additionally, you can migrate users using the [Users API](../../../api/users.md) with an administrator user.
|
||||
|
|
|
@ -35,7 +35,7 @@ Git:
|
|||
|
||||
## Why migrate
|
||||
|
||||
Perforce Helix can be difficult to manage both from a user and an admin
|
||||
Perforce Helix can be difficult to manage both from a user and an administrator
|
||||
perspective. Migrating to Git/GitLab there is:
|
||||
|
||||
- **No licensing costs**, Git is GPL while Perforce Helix is proprietary.
|
||||
|
|
|
@ -19,7 +19,7 @@ HipChat v1 API (legacy) supports "API Auth Tokens" in the Group API menu. A v1
|
|||
token is allowed to send messages to *any* room.
|
||||
|
||||
HipChat v2 API has tokens that are can be created using the Integrations tab
|
||||
in the Group or Room admin page. By design, these are lightweight tokens that
|
||||
in the Group or Room administration page. By design, these are lightweight tokens that
|
||||
allow GitLab to send messages only to *one* room.
|
||||
|
||||
### Complete these steps in HipChat
|
||||
|
|
|
@ -19,7 +19,7 @@ To enable Mattermost integration you must create an incoming webhook integration
|
|||
1. Choose a display name, description and channel, those can be overridden on GitLab.
|
||||
1. Save it and copy the **Webhook URL** because we need this later for GitLab.
|
||||
|
||||
Incoming Webhooks might be blocked on your Mattermost instance. Ask your Mattermost admin
|
||||
Incoming Webhooks might be blocked on your Mattermost instance. Ask your Mattermost administrator
|
||||
to enable it on:
|
||||
|
||||
- **Mattermost System Console > Integrations > Integration Management** in Mattermost
|
||||
|
@ -27,7 +27,7 @@ to enable it on:
|
|||
- **Mattermost System Console > Integrations > Custom Integrations** in Mattermost
|
||||
versions 5.11 and earlier.
|
||||
|
||||
Display name override is not enabled by default, you need to ask your admin to enable it on that same section.
|
||||
Display name override is not enabled by default, you need to ask your administrator to enable it on that same section.
|
||||
|
||||
## On GitLab
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ preconfigured with the right settings.
|
|||
The first thing to do in Mattermost is to enable custom slash commands from
|
||||
the administrator console.
|
||||
|
||||
1. Log in with an account that has admin privileges and navigate to the system
|
||||
1. Log in with an account that has administrator privileges and navigate to the system
|
||||
console.
|
||||
|
||||
![Mattermost go to console](img/mattermost_goto_console.png)
|
||||
|
|
|
@ -37,7 +37,7 @@ to be enabled:
|
|||
|
||||
Design Management also requires that projects are using
|
||||
[hashed storage](../../../administration/raketasks/storage.md#migrate-to-hashed-storage). Since
|
||||
GitLab 10.0, newly created projects use hashed storage by default. A GitLab admin can verify the storage type of a
|
||||
GitLab 10.0, newly created projects use hashed storage by default. A GitLab administrator can verify the storage type of a
|
||||
project by navigating to **Admin Area > Projects** and then selecting the project in question.
|
||||
A project can be identified as hashed-stored if its *Gitaly relative path* contains `@hashed`.
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ The "Move issue" button is at the bottom of the right-sidebar when viewing the i
|
|||
If you have advanced technical skills you can also bulk move all the issues from one project to another in the rails console. The below script will move all the issues from one project to another that are not in status **closed**.
|
||||
|
||||
To access rails console run `sudo gitlab-rails console` on the GitLab server and run the below
|
||||
script. Please be sure to change **project**, **admin_user** and **target_project** to your values.
|
||||
script. Please be sure to change `project`, `admin_user`, and `target_project` to your values.
|
||||
We do also recommend [creating a backup](../../../raketasks/backup_restore.md#back-up-gitlab) before
|
||||
attempting any changes in the console.
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
Binary file not shown.
After Width: | Height: | Size: 285 KiB |
Binary file not shown.
Before Width: | Height: | Size: 36 KiB |
Binary file not shown.
Before Width: | Height: | Size: 36 KiB |
Binary file not shown.
After Width: | Height: | Size: 369 KiB |
BIN
doc/user/project/members/img/share_project_with_groups_v13_6.png
Normal file
BIN
doc/user/project/members/img/share_project_with_groups_v13_6.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 387 KiB |
|
@ -24,27 +24,28 @@ This is where the group sharing feature can be of use.
|
|||
|
||||
To share 'Project Acme' with the 'Engineering' group:
|
||||
|
||||
1. For 'Project Acme' use the left navigation menu to go to **Members**
|
||||
1. For 'Project Acme' use the left navigation menu to go to **Members**.
|
||||
|
||||
![share project with groups](img/share_project_with_groups.png)
|
||||
![share project with groups](img/share_project_with_groups_tab_v13_6.png)
|
||||
|
||||
1. Select the 'Share with group' tab
|
||||
1. Add the 'Engineering' group with the maximum access level of your choice
|
||||
1. Click **Share** to share it
|
||||
1. Select the **Invite group** tab.
|
||||
1. Add the 'Engineering' group with the maximum access level of your choice.
|
||||
1. Optionally, select an expiring date.
|
||||
1. Click **Invite**.
|
||||
|
||||
![share project with groups tab](img/share_project_with_groups_tab.png)
|
||||
![share project with groups tab](img/share_project_with_groups_tab_v13_6.png)
|
||||
|
||||
1. After sharing 'Project Acme' with 'Engineering', the project is listed
|
||||
on the group dashboard
|
||||
|
||||
!['Project Acme' is listed as a shared project for 'Engineering'](img/other_group_sees_shared_project.png)
|
||||
!['Project Acme' is listed as a shared project for 'Engineering'](img/other_group_sees_shared_project_v13_6.png)
|
||||
|
||||
Note that you can only share a project with:
|
||||
|
||||
- groups for which you have an explicitly defined membership
|
||||
- groups that contain a nested subgroup or project for which you have an explicitly defined role
|
||||
|
||||
Admins are able to share projects with any group in the system.
|
||||
Administrators are able to share projects with any group in the system.
|
||||
|
||||
## Maximum access level
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ The following table shows what attributes will be present in the CSV.
|
|||
|
||||
| Column | Description |
|
||||
|--------------------|--------------------------------------------------------------|
|
||||
| MR ID | MR iid |
|
||||
| MR ID | MR `iid` |
|
||||
| URL | A link to the merge request on GitLab |
|
||||
| Title | Merge request title |
|
||||
| State | Opened, Closed, Locked, or Merged |
|
||||
|
|
|
@ -95,7 +95,7 @@ merge request:
|
|||
|
||||
1. Go to the merge request's **Changes** tab.
|
||||
1. Click the cog icon (**{settings}**) to reveal the merge request's settings dropdown.
|
||||
1. Select or unselect the checkbox **Show one file at a time** to change the setting accordingly.
|
||||
1. Select or deselect the checkbox **Show one file at a time** to change the setting accordingly.
|
||||
|
||||
This change overrides the choice you made in your user preferences and persists until you clear your
|
||||
browser's cookies or change this behavior again.
|
||||
|
|
|
@ -60,7 +60,7 @@ the `filename` of a `class` element contains the full path relative to the proje
|
|||
### JavaScript example
|
||||
|
||||
The following [`gitlab-ci.yml`](../../../ci/yaml/README.md) example uses [Mocha](https://mochajs.org/)
|
||||
JavaScript testing and [NYC](https://github.com/istanbuljs/nyc) coverage-tooling to
|
||||
JavaScript testing and [nyc](https://github.com/istanbuljs/nyc) coverage-tooling to
|
||||
generate the coverage artifact:
|
||||
|
||||
```yaml
|
||||
|
@ -78,7 +78,7 @@ test:
|
|||
#### Maven example
|
||||
|
||||
The following [`gitlab-ci.yml`](../../../ci/yaml/README.md) example for Java or Kotlin uses [Maven](https://maven.apache.org/)
|
||||
to build the project and [Jacoco](https://www.eclemma.org/jacoco/) coverage-tooling to
|
||||
to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to
|
||||
generate the coverage artifact.
|
||||
You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image.
|
||||
|
||||
|
@ -118,7 +118,7 @@ coverage-jdk11:
|
|||
#### Gradle example
|
||||
|
||||
The following [`gitlab-ci.yml`](../../../ci/yaml/README.md) example for Java or Kotlin uses [Gradle](https://gradle.org/)
|
||||
to build the project and [Jacoco](https://www.eclemma.org/jacoco/) coverage-tooling to
|
||||
to build the project and [JaCoCo](https://www.eclemma.org/jacoco/) coverage-tooling to
|
||||
generate the coverage artifact.
|
||||
You can check the [Docker image configuration and scripts](https://gitlab.com/haynes/jacoco2cobertura) if you want to build your own image.
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ GitLab Pages site.
|
|||
|
||||
Note that **how to** add DNS records depends on which server your domain
|
||||
is hosted on. Every control panel has its own place to do it. If you are
|
||||
not an admin of your domain, and don't have access to your registrar,
|
||||
not an administrator of your domain, and don't have access to your registrar,
|
||||
you'll need to ask for the technical support of your hosting service
|
||||
to do it for you.
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ it secured by HTTPS, you will have to issue a certificate for that
|
|||
(sub)domain and install it on your project.
|
||||
|
||||
NOTE:
|
||||
Certificates are NOT required to add to your custom
|
||||
Certificates are **not** required to add to your custom
|
||||
(sub)domain on your GitLab Pages project, though they are
|
||||
highly recommendable.
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Create a Pages website from a forked sample
|
||||
|
||||
GitLab provides [sample projects for the most popular Static Site Generators](https://gitlab.com/pages).
|
||||
GitLab provides [sample projects for the most popular Static Site Generators (SSG)](https://gitlab.com/pages).
|
||||
You can fork one of the sample projects and run the CI/CD pipeline to generate a Pages website.
|
||||
|
||||
Fork a sample project when you want to test GitLab Pages or start a new project that's already
|
||||
|
|
|
@ -85,7 +85,7 @@ scripts that GitLab CI/CD runs to accomplish this task is created from a file na
|
|||
|
||||
You can either use GitLab's [default domain for GitLab Pages websites](getting_started_part_one.md#gitlab-pages-default-domain-names),
|
||||
`*.gitlab.io`, or your own domain (`example.com`). In that case, you'll
|
||||
need admin access to your domain's registrar (or control panel) to set it up with Pages.
|
||||
need administrator access to your domain's registrar (or control panel) to set it up with Pages.
|
||||
|
||||
The following diagrams show the workflows you might follow to get started with Pages.
|
||||
|
||||
|
@ -103,7 +103,7 @@ To restrict access to your website, enable [GitLab Pages Access Control](pages_a
|
|||
|
||||
If you're using a self-managed instance (Core, Starter, Premium, or Ultimate),
|
||||
your websites will be published on your own server, according to the
|
||||
[Pages admin settings](../../../administration/pages/index.md) chosen by your sysadmin,
|
||||
[Pages settings](../../../administration/pages/index.md) chosen by your sysadmin,
|
||||
who can make them public or internal.
|
||||
|
||||
## Pages examples
|
||||
|
|
|
@ -13,7 +13,7 @@ This method is still valid but was **deprecated** in favor of the
|
|||
introduced in GitLab 12.1.
|
||||
|
||||
If you have a GitLab Pages website served under your own domain,
|
||||
you might want to secure it with a SSL/TSL certificate.
|
||||
you might want to secure it with a SSL/TLS certificate.
|
||||
|
||||
[Let's Encrypt](https://letsencrypt.org) is a free, automated, and
|
||||
open source Certificate Authority.
|
||||
|
|
|
@ -22,7 +22,7 @@ By default, a protected branch does four simple things:
|
|||
- It prevents **anyone** from deleting the branch.
|
||||
|
||||
NOTE:
|
||||
A GitLab admin is allowed to push to the protected branches.
|
||||
A GitLab administrator is allowed to push to the protected branches.
|
||||
|
||||
See the [Changelog](#changelog) section for changes over time.
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ updated every 15 minutes at most, so may not reflect recent activity. The displa
|
|||
|
||||
The project size may differ slightly from one instance to another due to compression, housekeeping, and other factors.
|
||||
|
||||
[Repository size limit](../../admin_area/settings/account_and_limit_settings.md) may be set by admins.
|
||||
[Repository size limit](../../admin_area/settings/account_and_limit_settings.md) may be set by administrators.
|
||||
GitLab.com's repository size limit [is set by GitLab](../../gitlab_com/index.md#account-and-limit-settings).
|
||||
|
||||
## Contributors
|
||||
|
|
|
@ -202,12 +202,6 @@ To purge files from GitLab storage:
|
|||
|
||||
## Repository cleanup
|
||||
|
||||
NOTE:
|
||||
Safely cleaning the repository requires it to be made read-only for the duration
|
||||
of the operation. This happens automatically, but submitting the cleanup request
|
||||
fails if any writes are ongoing, so cancel any outstanding `git push`
|
||||
operations before continuing.
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/19376) in GitLab 11.6.
|
||||
|
||||
Repository cleanup allows you to upload a text file of objects and GitLab removes internal Git
|
||||
|
@ -215,6 +209,12 @@ references to these objects. You can use
|
|||
[`git filter-repo`](https://github.com/newren/git-filter-repo) to produce a list of objects (in a
|
||||
`commit-map` file) that can be used with repository cleanup.
|
||||
|
||||
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45058) in GitLab 13.6,
|
||||
safely cleaning the repository requires it to be made read-only for the duration
|
||||
of the operation. This happens automatically, but submitting the cleanup request
|
||||
fails if any writes are ongoing, so cancel any outstanding `git push`
|
||||
operations before continuing.
|
||||
|
||||
To clean up a repository:
|
||||
|
||||
1. Go to the project for the repository.
|
||||
|
@ -233,7 +233,7 @@ To clean up a repository:
|
|||
This:
|
||||
|
||||
- Removes any internal Git references to old commits.
|
||||
- Runs `git gc` against the repository to remove unreferenced objects. Repacking your repository temporarily
|
||||
- Runs `git gc --prune=30.minutes.ago` against the repository to remove unreferenced objects. Repacking your repository temporarily
|
||||
causes the size of your repository to increase significantly, because the old pack files are not removed until the
|
||||
new pack files have been created.
|
||||
- Unlinks any unused LFS objects currently attached to your project, freeing up storage space.
|
||||
|
@ -241,12 +241,17 @@ This:
|
|||
|
||||
GitLab sends an email notification with the recalculated repository size after the cleanup has completed.
|
||||
|
||||
If the repository size does not decrease, this may be caused by loose objects
|
||||
being kept around because they were referenced in a Git operation that happened
|
||||
in the last 30 minutes. Try re-running these steps once the repository has been
|
||||
dormant for at least 30 minutes.
|
||||
|
||||
When using repository cleanup, note:
|
||||
|
||||
- Project statistics are cached. You may need to wait 5-10 minutes to see a reduction in storage utilization.
|
||||
- Housekeeping prunes loose objects older than 2 weeks. This means objects added in the last 2 weeks
|
||||
- The cleanup prunes loose objects older than 30 minutes. This means objects added or referenced in the last 30 minutes
|
||||
are not be removed immediately. If you have access to the
|
||||
[Gitaly](../../../administration/gitaly/index.md) server, you may run `git gc --prune=now` to
|
||||
[Gitaly](../../../administration/gitaly/index.md) server, you may slip that delay and run `git gc --prune=now` to
|
||||
prune all loose objects immediately.
|
||||
- This process removes some copies of the rewritten commits from GitLab's cache and database,
|
||||
but there are still numerous gaps in coverage and some of the copies may persist indefinitely.
|
||||
|
|
|
@ -137,7 +137,7 @@ The repository will push soon. To force a push, click the **Update now** (**{ret
|
|||
|
||||
AWS CodeCommit push mirroring is currently the best way to connect GitLab repositories to AWS CodePipeline, as GitLab is not yet supported as one of their Source Code Management (SCM) providers.
|
||||
|
||||
Each new AWS Codepipeline needs significant AWS infrastructure setup. It also requires an individual pipeline per branch.
|
||||
Each new AWS CodePipeline needs significant AWS infrastructure setup. It also requires an individual pipeline per branch.
|
||||
|
||||
If AWS CodeDeploy is the final step of a CodePipeline, you can, instead, leverage GitLab CI/CD pipelines and simply use the AWS CLI in the final job in `.gitlab-ci.yml` to deploy to CodeDeploy.
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ When you are satisfied with your new file, click **Commit Changes** at the botto
|
|||
### Shortcuts
|
||||
|
||||
You can use handy shortcuts when editing a file through the Web Editor, which are the same as
|
||||
the WEB IDE's. For details, see the documentation for [Command Palette](../web_ide/index.md#command-palette).
|
||||
the Web IDE's. For details, see the documentation for [Command Palette](../web_ide/index.md#command-palette).
|
||||
|
||||
### Template dropdowns
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ Note the following:
|
|||
- Exports are stored in a temporary [shared directory](../../../development/shared_files.md)
|
||||
and are deleted every 24 hours by a specific worker.
|
||||
- Group members are exported as project members, as long as the user has
|
||||
maintainer or admin access to the group where the exported project lives.
|
||||
maintainer or administrator access to the group where the exported project lives.
|
||||
- Project members with owner access will be imported as maintainers.
|
||||
- Imported users can be mapped by their primary email on self-managed instances, if an administrative user (not an owner) does the import.
|
||||
Otherwise, a supplementary comment is left to mention that the original author and
|
||||
|
@ -119,7 +119,7 @@ The following items will be exported:
|
|||
- Pipelines history
|
||||
- Push Rules
|
||||
|
||||
The following items will NOT be exported:
|
||||
The following items will **not** be exported:
|
||||
|
||||
- Build traces and artifacts
|
||||
- Container registry images
|
||||
|
@ -180,7 +180,7 @@ all imported projects are given the visibility of `Private`.
|
|||
|
||||
NOTE:
|
||||
The maximum import file size can be set by the Administrator, default is 50MB.
|
||||
As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [Application settings API](../../../api/settings.md#change-application-settings) or the [Admin UI](../../admin_area/settings/account_and_limit_settings.md).
|
||||
As an administrator, you can modify the maximum import file size. To do so, use the `max_import_size` option in the [Application settings API](../../../api/settings.md#change-application-settings) or the [Admin Area UI](../../admin_area/settings/account_and_limit_settings.md).
|
||||
|
||||
### Project import status
|
||||
|
||||
|
|
|
@ -31,11 +31,11 @@ The project description also partially supports [standard Markdown](../../markdo
|
|||
|
||||
You can select a framework label to identify that your project has certain compliance requirements or needs additional oversight. Available labels include:
|
||||
|
||||
- GDPR - General Data Protection Regulation
|
||||
- HIPAA - Health Insurance Portability and Accountability Act
|
||||
- PCI-DSS - Payment Card Industry-Data Security Standard
|
||||
- SOC 2 - Service Organization Control 2
|
||||
- SOX - Sarbanes-Oxley
|
||||
- GDPR (General Data Protection Regulation)
|
||||
- HIPAA (Health Insurance Portability and Accountability Act)
|
||||
- PCI-DSS (Payment Card Industry-Data Security Standard)
|
||||
- SOC 2 (Service Organization Control 2)
|
||||
- SOX (Sarbanes-Oxley)
|
||||
|
||||
NOTE:
|
||||
Compliance framework labels do not affect your project settings.
|
||||
|
|
|
@ -262,8 +262,8 @@ quickly share your project with others.
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/268288) in GitLab 12.9, third-party assets and libraries required for Live Preview are hosted at `https://sandbox-prod.gitlab-static.net` when it is enabled. However, some libraries are still served from other third-party services which may or may not be desirable in your environment.
|
||||
|
||||
The Live Preview feature needs to be enabled in the GitLab instances
|
||||
admin settings. Live Preview is enabled for all projects on
|
||||
The Live Preview feature needs to be enabled in the GitLab instance's
|
||||
Admin Area. Live Preview is enabled for all projects on
|
||||
GitLab.com
|
||||
|
||||
![Administrator Live Preview setting](img/admin_live_preview_v13_0.png)
|
||||
|
|
|
@ -226,4 +226,4 @@ Example for `_sidebar` (using Markdown format):
|
|||
- [Sidebar](_sidebar)
|
||||
```
|
||||
|
||||
Support for displaying a generated TOC with a custom side navigation is planned.
|
||||
Support for displaying a generated table of contents with a custom side navigation is planned.
|
||||
|
|
|
@ -180,6 +180,8 @@ module Gitlab
|
|||
end
|
||||
|
||||
def subject_starts_with_lowercase?
|
||||
return false if ('A'..'Z').cover?(subject[0])
|
||||
|
||||
first_char = subject.sub(/\A(\[.+\]|\w+:)\s/, '')[0]
|
||||
first_char_downcased = first_char.downcase
|
||||
return true unless ('a'..'z').cover?(first_char_downcased)
|
||||
|
|
|
@ -163,8 +163,8 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def search_repos_by_name(name)
|
||||
each_page(:search_repositories, search_query(str: name, type: :name))
|
||||
def search_repos_by_name(name, options = {})
|
||||
octokit.search_repositories(search_query(str: name, type: :name), options)
|
||||
end
|
||||
|
||||
def search_query(str:, type:, include_collaborations: true, include_orgs: true)
|
||||
|
|
|
@ -13,6 +13,12 @@ module Gitlab
|
|||
|
||||
def auto_generated_comment
|
||||
<<-MD.strip_heredoc
|
||||
---
|
||||
stage: Plan
|
||||
group: Project Management
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||
---
|
||||
|
||||
<!---
|
||||
This documentation is auto generated by a script.
|
||||
|
||||
|
|
|
@ -3297,6 +3297,9 @@ msgstr ""
|
|||
msgid "An error occurred while updating approvers"
|
||||
msgstr ""
|
||||
|
||||
msgid "An error occurred while updating assignees."
|
||||
msgstr ""
|
||||
|
||||
msgid "An error occurred while updating configuration."
|
||||
msgstr ""
|
||||
|
||||
|
@ -9631,6 +9634,9 @@ msgstr ""
|
|||
msgid "DevopsAdoption|DevOps adoption uses segments to track adoption across key features. Segments are a way to track multiple related projects and groups at once. For example, you could create a segment for the engineering department or a particular product team."
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Edit segment"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Feature adoption is based on usage in the last calendar month. Last updated: %{timestamp}."
|
||||
msgstr ""
|
||||
|
||||
|
@ -9655,6 +9661,9 @@ msgstr ""
|
|||
msgid "DevopsAdoption|Runners"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Save changes"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Scanning"
|
||||
msgstr ""
|
||||
|
||||
|
@ -11310,6 +11319,9 @@ msgstr ""
|
|||
msgid "Experienced"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExperimentSubject|Must have exactly one of User, Group, or Project."
|
||||
msgstr ""
|
||||
|
||||
msgid "Expiration"
|
||||
msgstr ""
|
||||
|
||||
|
@ -19555,10 +19567,7 @@ msgstr ""
|
|||
msgid "Package type must be PyPi"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|%{name} version %{version} was created %{datetime}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|%{name} version %{version} was updated %{datetime}"
|
||||
msgid "PackageRegistry|%{name} version %{version} was first created %{datetime}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Add Conan Remote"
|
||||
|
@ -19576,7 +19585,7 @@ msgstr ""
|
|||
msgid "PackageRegistry|App name: %{name}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Commit %{link} on branch %{branch}"
|
||||
msgid "PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Composer"
|
||||
|
@ -19636,6 +19645,9 @@ msgstr ""
|
|||
msgid "PackageRegistry|Copy yarn setup command"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Created by commit %{link} on branch %{branch}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Delete Package Version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -19702,10 +19714,16 @@ msgstr ""
|
|||
msgid "PackageRegistry|Package Registry"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Pip Command"
|
||||
msgid "PackageRegistry|Package has %{number} archived update"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Pipeline %{link} triggered %{datetime} by %{author}"
|
||||
msgid "PackageRegistry|Package has %{number} archived updates"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Pip Command"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}"
|
||||
|
|
|
@ -31,7 +31,7 @@ module QA
|
|||
runner.remove_via_api!
|
||||
end
|
||||
|
||||
it 'publishes a conan package and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1077' do
|
||||
it 'publishes, installs, and deletes a Conan package', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1077' do
|
||||
Flow::Login.sign_in
|
||||
|
||||
Resource::Repository::Commit.fabricate_via_api! do |commit|
|
||||
|
@ -43,13 +43,14 @@ module QA
|
|||
<<~YAML
|
||||
image: conanio/gcc7
|
||||
|
||||
create_package:
|
||||
test_package:
|
||||
stage: deploy
|
||||
script:
|
||||
- "conan remote add gitlab #{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/conan"
|
||||
- "conan new #{package_name}/0.1 -t"
|
||||
- "conan create . mycompany/stable"
|
||||
- "CONAN_LOGIN_USERNAME=ci_user CONAN_PASSWORD=${CI_JOB_TOKEN} conan upload #{package_name}/0.1@mycompany/stable --all --remote=gitlab"
|
||||
- "conan install conantest/0.1@mycompany/stable --remote=gitlab"
|
||||
tags:
|
||||
- "runner-for-#{project.name}"
|
||||
YAML
|
||||
|
@ -60,7 +61,7 @@ module QA
|
|||
Flow::Pipeline.visit_latest_pipeline
|
||||
|
||||
Page::Project::Pipeline::Show.perform do |pipeline|
|
||||
pipeline.click_job('create_package')
|
||||
pipeline.click_job('test_package')
|
||||
end
|
||||
|
||||
Page::Project::Job::Show.perform do |job|
|
||||
|
|
|
@ -123,26 +123,33 @@ RSpec.describe Import::GithubController do
|
|||
end
|
||||
|
||||
it 'fetches repos using latest github client' do
|
||||
expect_next_instance_of(Gitlab::GithubImport::Client) do |client|
|
||||
expect(client).to receive(:each_page).with(:repos).and_return([].to_enum)
|
||||
expect_next_instance_of(Octokit::Client) do |client|
|
||||
expect(client).to receive(:repos).and_return([].to_enum)
|
||||
end
|
||||
|
||||
get :status
|
||||
end
|
||||
|
||||
it 'concatenates list of repos from multiple pages' do
|
||||
repo_1 = OpenStruct.new(login: 'emacs', full_name: 'asd/emacs', name: 'emacs', owner: { login: 'owner' })
|
||||
repo_2 = OpenStruct.new(login: 'vim', full_name: 'asd/vim', name: 'vim', owner: { login: 'owner' })
|
||||
repos = [OpenStruct.new(objects: [repo_1]), OpenStruct.new(objects: [repo_2])].to_enum
|
||||
context 'pagination' do
|
||||
context 'when no page is specified' do
|
||||
it 'requests first page' do
|
||||
expect_next_instance_of(Octokit::Client) do |client|
|
||||
expect(client).to receive(:repos).with(nil, { page: 1, per_page: 25 }).and_return([].to_enum)
|
||||
end
|
||||
|
||||
allow(stub_client).to receive(:each_page).and_return(repos)
|
||||
get :status
|
||||
end
|
||||
end
|
||||
|
||||
get :status, format: :json
|
||||
context 'when page is specified' do
|
||||
it 'requests repos with specified page' do
|
||||
expect_next_instance_of(Octokit::Client) do |client|
|
||||
expect(client).to receive(:repos).with(nil, { page: 2, per_page: 25 }).and_return([].to_enum)
|
||||
end
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response.dig('provider_repos').count).to eq(2)
|
||||
expect(json_response.dig('provider_repos', 0, 'id')).to eq(repo_1.id)
|
||||
expect(json_response.dig('provider_repos', 1, 'id')).to eq(repo_2.id)
|
||||
get :status, params: { page: 2 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filtering' do
|
||||
|
@ -150,6 +157,7 @@ RSpec.describe Import::GithubController do
|
|||
let(:user_login) { 'user' }
|
||||
let(:collaborations_subquery) { 'repo:repo1 repo:repo2' }
|
||||
let(:organizations_subquery) { 'org:org1 org:org2' }
|
||||
let(:search_query) { "test in:name is:public,private user:#{user_login} #{collaborations_subquery} #{organizations_subquery}" }
|
||||
|
||||
before do
|
||||
allow_next_instance_of(Octokit::Client) do |client|
|
||||
|
@ -158,20 +166,56 @@ RSpec.describe Import::GithubController do
|
|||
end
|
||||
|
||||
it 'makes request to github search api' do
|
||||
expected_query = "test in:name is:public,private user:#{user_login} #{collaborations_subquery} #{organizations_subquery}"
|
||||
expect_next_instance_of(Octokit::Client) do |client|
|
||||
expect(client).to receive(:user).and_return(double(login: user_login))
|
||||
expect(client).to receive(:search_repositories).with(search_query, { page: 1, per_page: 25 }).and_return({ items: [].to_enum })
|
||||
end
|
||||
|
||||
expect_next_instance_of(Gitlab::GithubImport::Client) do |client|
|
||||
expect(client).to receive(:collaborations_subquery).and_return(collaborations_subquery)
|
||||
expect(client).to receive(:organizations_subquery).and_return(organizations_subquery)
|
||||
expect(client).to receive(:each_page).with(:search_repositories, expected_query).and_return([].to_enum)
|
||||
end
|
||||
|
||||
get :status, params: { filter: filter }, format: :json
|
||||
end
|
||||
|
||||
context 'pagination' do
|
||||
context 'when no page is specified' do
|
||||
it 'requests first page' do
|
||||
expect_next_instance_of(Octokit::Client) do |client|
|
||||
expect(client).to receive(:user).and_return(double(login: user_login))
|
||||
expect(client).to receive(:search_repositories).with(search_query, { page: 1, per_page: 25 }).and_return({ items: [].to_enum })
|
||||
end
|
||||
|
||||
expect_next_instance_of(Gitlab::GithubImport::Client) do |client|
|
||||
expect(client).to receive(:collaborations_subquery).and_return(collaborations_subquery)
|
||||
expect(client).to receive(:organizations_subquery).and_return(organizations_subquery)
|
||||
end
|
||||
|
||||
get :status, params: { filter: filter }, format: :json
|
||||
end
|
||||
end
|
||||
|
||||
context 'when page is specified' do
|
||||
it 'requests repos with specified page' do
|
||||
expect_next_instance_of(Octokit::Client) do |client|
|
||||
expect(client).to receive(:user).and_return(double(login: user_login))
|
||||
expect(client).to receive(:search_repositories).with(search_query, { page: 2, per_page: 25 }).and_return({ items: [].to_enum })
|
||||
end
|
||||
|
||||
expect_next_instance_of(Gitlab::GithubImport::Client) do |client|
|
||||
expect(client).to receive(:collaborations_subquery).and_return(collaborations_subquery)
|
||||
expect(client).to receive(:organizations_subquery).and_return(organizations_subquery)
|
||||
end
|
||||
|
||||
get :status, params: { filter: filter, page: 2 }, format: :json
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user input contains colons and spaces' do
|
||||
before do
|
||||
stub_client(search_repos_by_name: [])
|
||||
allow(controller).to receive(:client_repos).and_return([])
|
||||
end
|
||||
|
||||
it 'sanitizes user input' do
|
||||
|
|
9
spec/factories/experiment_subjects.rb
Normal file
9
spec/factories/experiment_subjects.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :experiment_subject do
|
||||
experiment
|
||||
user
|
||||
variant { :control }
|
||||
end
|
||||
end
|
|
@ -9,6 +9,7 @@ RSpec.describe 'Admin::Users::User' do
|
|||
before do
|
||||
sign_in(current_user)
|
||||
gitlab_enable_admin_mode_sign_in(current_user)
|
||||
stub_feature_flags(vue_admin_users: false)
|
||||
end
|
||||
|
||||
describe 'GET /admin/users/:id' do
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue