Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-12-09 12:09:42 +00:00
parent 109562e64e
commit 1361891b0a
118 changed files with 1059 additions and 450 deletions

View file

@ -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

View 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>

View 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)),
},
}),
});
}

View file

@ -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>

View file

@ -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);
});

View file

@ -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>

View file

@ -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;

View file

@ -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();
});

View file

@ -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')

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -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?

View file

@ -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

View file

@ -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 }

View 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

View file

@ -618,7 +618,7 @@ class Repository
end
def readme_path
readme&.path
head_tree&.readme_path
end
cache_method :readme_path

View file

@ -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

View file

@ -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' }

View file

@ -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

View file

@ -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')

View file

@ -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

View file

@ -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'

View file

@ -0,0 +1,5 @@
---
title: Display more pipelines info in package history
merge_request: 49040
author:
type: changed

View file

@ -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

View file

@ -0,0 +1,5 @@
---
title: Check for a status in the current user dropdown
merge_request: 49203
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Add GitHub Importer pagination
merge_request: 48983
author:
type: changed

View file

@ -0,0 +1,5 @@
---
title: Add flash message for setAssignees on group issue boards
merge_request: 48277
author:
type: added

View 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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
9fba60d8805915fcf6af7812e2c752007ac17bb92c8a02c942c0c790d2997441

View file

@ -0,0 +1 @@
4340d0f6d3b660b336fdc3166a4960865c79e90f505b1173bab4e0d11c1199b3

View file

@ -0,0 +1 @@
8180908c5e577757b3f518d312cbf0ba77c65b39fa55dde487036541f49114a1

View file

@ -0,0 +1 @@
c228aa5c16e63af7520dd1bd90cefb1f74ec2371af3b0e839938d8c628f70e8a

View file

@ -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;

View file

@ -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

View file

@ -300,6 +300,7 @@ NGINX
Nokogiri
npm
Nurtch
nyc
OAuth
offboarded
offboarding

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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:

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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:

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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`.

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

View file

@ -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

View file

@ -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 |

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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)

View file

@ -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.

View file

@ -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)

View file

@ -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)

View file

@ -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.

View file

@ -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}"

View file

@ -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|

View file

@ -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

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
FactoryBot.define do
factory :experiment_subject do
experiment
user
variant { :control }
end
end

View file

@ -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