Commit 0cb6b787 authored by Arun Kumar Mohan's avatar Arun Kumar Mohan

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into db/update-geo-nodes-primary

parents a10d80ea 4298a28a
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.21-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.29"
variables:
MYSQL_ALLOW_EMPTY_PASSWORD: "1"
RAILS_ENV: "test"
NODE_ENV: "test"
SIMPLECOV: "true"
......@@ -37,6 +36,7 @@ include:
- local: .gitlab/ci/cng.gitlab-ci.yml
- local: .gitlab/ci/docs.gitlab-ci.yml
- local: .gitlab/ci/frontend.gitlab-ci.yml
- local: .gitlab/ci/memory.gitlab-ci.yml
- local: .gitlab/ci/pages.gitlab-ci.yml
- local: .gitlab/ci/qa.gitlab-ci.yml
- local: .gitlab/ci/reports.gitlab-ci.yml
......
memory-static:
extends: .dedicated-no-docs-no-db-pull-cache-job
script:
# Uses two different reports from the 'derailed_benchmars' gem.
# Loads each of gems in the Gemfile and checks how much memory they consume when they are required.
# 'derailed_benchmarks' internally uses 'get_process_mem'
- scripts/memory-static 'tmp/memory_static_full_report.txt' 'tmp/memory_static_metrics.txt'
# Outputs detailed information about objects created while gems are loaded.
# 'derailed_benchmarks' internally uses 'memory_profiler'
- scripts/memory-static-objects 'tmp/memory_static_objects_full_report.txt' 'tmp/memory_static_metrics.txt'
artifacts:
paths:
- tmp/memory_static_full_report.txt
- tmp/memory_static_objects_full_report.txt
- tmp/memory_static_metrics.txt
reports:
metrics: tmp/memory_static_metrics.txt
......@@ -10,11 +10,6 @@
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:alpine
.use-mysql: &use-mysql
services:
- mysql:5.7
- redis:alpine
.only-schedules-master: &only-schedules-master
only:
- schedules@gitlab-org/gitlab-ce
......@@ -94,10 +89,6 @@
<<: *use-pg-10
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.21-chrome-73.0-node-12.x-yarn-1.16-postgresql-10-graphicsmagick-1.3.29"
.rspec-metadata-mysql: &rspec-metadata-mysql
<<: *rspec-metadata
<<: *use-mysql
# DB migration, rollback, and seed jobs
.db-migrate-reset: &db-migrate-reset
extends: .dedicated-no-docs-and-no-qa-pull-cache-job
......@@ -173,42 +164,6 @@ rspec system pg-10:
<<: *only-schedules-master
parallel: 24
rspec unit mysql:
<<: *rspec-metadata-mysql
<<: *only-schedules-master
parallel: 20
rspec integration mysql:
<<: *rspec-metadata-mysql
<<: *only-schedules-master
parallel: 6
rspec system mysql:
<<: *rspec-metadata-mysql
<<: *only-schedules-master
parallel: 24
.rspec-mysql-on-demand: &rspec-mysql-on-demand
only:
variables:
- $CI_COMMIT_MESSAGE =~ /\[run mysql\]/i
- $CI_COMMIT_REF_NAME =~ /mysql/
rspec unit mysql on-demand:
<<: *rspec-metadata-mysql
<<: *rspec-mysql-on-demand
parallel: 20
rspec integration mysql on-demand:
<<: *rspec-metadata-mysql
<<: *rspec-mysql-on-demand
parallel: 6
rspec system mysql on-demand:
<<: *rspec-metadata-mysql
<<: *rspec-mysql-on-demand
parallel: 24
rspec-fast-spec-helper:
<<: *rspec-metadata-pg
script:
......@@ -226,12 +181,6 @@ rspec quarantine pg:
<<: *rspec-quarantine
allow_failure: true
rspec quarantine mysql:
<<: *rspec-metadata-mysql
<<: *rspec-quarantine
<<: *only-schedules-master
allow_failure: true
static-analysis:
extends: .dedicated-no-docs-no-db-pull-cache-job
dependencies:
......@@ -281,10 +230,6 @@ db:migrate:reset-pg:
<<: *db-migrate-reset
<<: *use-pg
db:migrate:reset-mysql:
<<: *db-migrate-reset
<<: *use-mysql
db:check-schema-pg:
<<: *db-migrate-reset
<<: *use-pg
......@@ -295,10 +240,6 @@ migration:path-pg:
<<: *migration-paths
<<: *use-pg
migration:path-mysql:
<<: *migration-paths
<<: *use-mysql
.db-rollback: &db-rollback
extends: .dedicated-no-docs-and-no-qa-pull-cache-job
script:
......@@ -311,22 +252,12 @@ db:rollback-pg:
<<: *db-rollback
<<: *use-pg
db:rollback-mysql:
<<: *db-rollback
<<: *use-mysql
gitlab:setup-pg:
<<: *gitlab-setup
<<: *use-pg
dependencies:
- setup-test-env
gitlab:setup-mysql:
<<: *gitlab-setup
<<: *use-mysql
dependencies:
- setup-test-env
coverage:
# Don't include dedicated-no-docs-no-db-pull-cache-job here since we need to
# download artifacts from all the rspec jobs instead of from setup-test-env only
......
......@@ -12,6 +12,7 @@ const Api = {
groupProjectsPath: '/api/:version/groups/:id/projects.json',
projectsPath: '/api/:version/projects.json',
projectPath: '/api/:version/projects/:id',
forkedProjectsPath: '/api/:version/projects/:id/forks',
projectLabelsPath: '/:namespace_path/:project_path/-/labels',
projectMergeRequestsPath: '/api/:version/projects/:id/merge_requests',
projectMergeRequestPath: '/api/:version/projects/:id/merge_requests/:mrid',
......@@ -113,6 +114,21 @@ const Api = {
return axios.get(url);
},
/**
* Get all projects for a forked relationship to a specified project
* @param {string} projectPath - Path or ID of a project
* @param {Object} params - Get request parameters
* @returns {Promise} - Request promise
*/
projectForks(projectPath, params) {
const url = Api.buildUrl(Api.forkedProjectsPath).replace(
':id',
encodeURIComponent(projectPath),
);
return axios.get(url, { params });
},
/**
* Get all Merge Requests for a project, eventually filtering based on
* supplied parameters
......
......@@ -4,7 +4,7 @@ import { GlTooltipDirective } from '@gitlab/ui';
import { __ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
import Suggestion from './item.vue';
import query from '../queries/issues.graphql';
import query from '../queries/issues.query.graphql';
export default {
components: {
......
......@@ -3,7 +3,7 @@ import { GlPopover, GlSkeletonLoading } from '@gitlab/ui';
import Icon from '../../vue_shared/components/icon.vue';
import CiIcon from '../../vue_shared/components/ci_icon.vue';
import timeagoMixin from '../../vue_shared/mixins/timeago';
import query from '../queries/merge_request.graphql';
import query from '../queries/merge_request.query.graphql';
import { mrStates, humanMRStates } from '../constants';
export default {
......
......@@ -7,8 +7,8 @@ import OAuthRememberMe from './oauth_remember_me';
import preserveUrlFragment from './preserve_url_fragment';
document.addEventListener('DOMContentLoaded', () => {
new LengthValidator(); // eslint-disable-line no-new
new UsernameValidator(); // eslint-disable-line no-new
new LengthValidator(); // eslint-disable-line no-new
new SigninTabsMemoizer(); // eslint-disable-line no-new
new NoEmojiValidator(); // eslint-disable-line no-new
......
/* eslint-disable consistent-return, class-methods-use-this */
import InputValidator from '~/validators/input_validator';
import $ from 'jquery';
import _ from 'underscore';
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
const debounceTimeoutDuration = 1000;
const rootUrl = gon.relative_url_root;
const invalidInputClass = 'gl-field-error-outline';
const successInputClass = 'gl-field-success-outline';
const unavailableMessageSelector = '.username .validation-error';
const successMessageSelector = '.username .validation-success';
const pendingMessageSelector = '.username .validation-pending';
const invalidMessageSelector = '.username .gl-field-error';
const successMessageSelector = '.validation-success';
const pendingMessageSelector = '.validation-pending';
const unavailableMessageSelector = '.validation-error';
export default class UsernameValidator {
constructor() {
this.inputElement = $('#new_user_username');
this.inputDomElement = this.inputElement.get(0);
this.state = {
available: false,
valid: false,
pending: false,
empty: true,
};
export default class UsernameValidator extends InputValidator {
constructor(opts = {}) {
super();
const debounceTimeout = _.debounce(username => {
this.validateUsername(username);
}, debounceTimeoutDuration);
this.inputElement.on('keyup.username_check', () => {
const username = this.inputElement.val();
this.state.valid = this.inputDomElement.validity.valid;
this.state.empty = !username.length;
const container = opts.container || '';
const validateLengthElements = document.querySelectorAll(`${container} .js-validate-username`);
if (this.state.valid) {
return debounceTimeout(username);
}
this.renderState();
});
this.debounceValidateInput = _.debounce(inputDomElement => {
UsernameValidator.validateUsernameInput(inputDomElement);
}, debounceTimeoutDuration);
// Override generic field validation
this.inputElement.on('invalid', this.interceptInvalid.bind(this));
validateLengthElements.forEach(element =>
element.addEventListener('input', this.eventHandler.bind(this)),
);
}
renderState() {
// Clear all state
this.clearFieldValidationState();
if (this.state.valid && this.state.available) {
return this.setSuccessState();
}
if (this.state.empty) {
return this.clearFieldValidationState();
}
if (this.state.pending) {
return this.setPendingState();
}
eventHandler(event) {
const inputDomElement = event.target;
if (!this.state.valid) {
return this.setInvalidState();
}
if (!this.state.available) {
return this.setUnavailableState();
}
}
interceptInvalid(event) {
event.preventDefault();
event.stopPropagation();
UsernameValidator.resetInputState(inputDomElement);
this.debounceValidateInput(inputDomElement);
}
validateUsername(username) {
if (this.state.valid) {
this.state.pending = true;
this.state.available = false;
this.renderState();
axios
.get(`${gon.relative_url_root}/users/${username}/exists`)
.then(({ data }) => this.setAvailabilityState(data.exists))
static validateUsernameInput(inputDomElement) {
const username = inputDomElement.value;
if (inputDomElement.checkValidity() && username.length > 0) {
UsernameValidator.setMessageVisibility(inputDomElement, pendingMessageSelector);
UsernameValidator.fetchUsernameAvailability(username)
.then(usernameTaken => {
UsernameValidator.setInputState(inputDomElement, !usernameTaken);
UsernameValidator.setMessageVisibility(inputDomElement, pendingMessageSelector, false);
UsernameValidator.setMessageVisibility(
inputDomElement,
usernameTaken ? unavailableMessageSelector : successMessageSelector,
);
})
.catch(() => flash(__('An error occurred while validating username')));
}
}
setAvailabilityState(usernameTaken) {
if (usernameTaken) {
this.state.available = false;
} else {
this.state.available = true;
}
this.state.pending = false;
this.renderState();
static fetchUsernameAvailability(username) {
return axios.get(`${rootUrl}/users/${username}/exists`).then(({ data }) => data.exists);
}
clearFieldValidationState() {
this.inputElement.siblings('p').hide();
this.inputElement.removeClass(invalidInputClass).removeClass(successInputClass);
static setMessageVisibility(inputDomElement, messageSelector, isVisible = true) {
const messageElement = inputDomElement.parentElement.querySelector(messageSelector);
messageElement.classList.toggle('hide', !isVisible);
}
setUnavailableState() {
const $usernameUnavailableMessage = this.inputElement.siblings(unavailableMessageSelector);
this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
$usernameUnavailableMessage.show();
static setInputState(inputDomElement, success = true) {
inputDomElement.classList.toggle(successInputClass, success);
inputDomElement.classList.toggle(invalidInputClass, !success);
}
setSuccessState() {
const $usernameSuccessMessage = this.inputElement.siblings(successMessageSelector);
this.inputElement.addClass(successInputClass).removeClass(invalidInputClass);
$usernameSuccessMessage.show();
}
static resetInputState(inputDomElement) {
UsernameValidator.setMessageVisibility(inputDomElement, successMessageSelector, false);
UsernameValidator.setMessageVisibility(inputDomElement, unavailableMessageSelector, false);
setPendingState() {
const $usernamePendingMessage = $(pendingMessageSelector);
if (this.state.pending) {
$usernamePendingMessage.show();
} else {
$usernamePendingMessage.hide();
if (inputDomElement.checkValidity()) {
inputDomElement.classList.remove(successInputClass, invalidInputClass);
}
}
setInvalidState() {
const $inputErrorMessage = $(invalidMessageSelector);
this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
$inputErrorMessage.show();
}
}
<script>
import getRefMixin from '../mixins/get_ref';
import getProjectShortPath from '../queries/getProjectShortPath.graphql';
import getProjectShortPath from '../queries/getProjectShortPath.query.graphql';
export default {
apollo: {
......
......@@ -3,8 +3,8 @@ import { GlLoadingIcon } from '@gitlab/ui';
import createFlash from '~/flash';
import { sprintf, __ } from '../../../locale';
import getRefMixin from '../../mixins/get_ref';
import getFiles from '../../queries/getFiles.graphql';
import getProjectPath from '../../queries/getProjectPath.graphql';
import getFiles from '../../queries/getFiles.query.graphql';
import getProjectPath from '../../queries/getProjectPath.query.graphql';
import TableHeader from './header.vue';
import TableRow from './row.vue';
import ParentRow from './parent_row.vue';
......
import getRef from '../queries/getRef.graphql';
import getRef from '../queries/getRef.query.graphql';
export default {
apollo: {
......
......@@ -199,7 +199,6 @@
&.user-cover-block {
padding: 24px 0 0;
border-bottom: 1px solid $border-color;
.nav-links {
width: 100%;
......
......@@ -221,6 +221,11 @@
ol {
padding: 0;
margin: 0 0 16px;
ul,
ol {
margin-bottom: 0;
}
}
ul:dir(rtl),
......
......@@ -31,8 +31,12 @@ class Projects::JobsController < Projects::ApplicationController
@builds
end
@builds = @builds.includes([
{ pipeline: :project },
{ pipeline: [:project, :user] },
:job_artifacts_archive,
:metadata,
:trigger_request,
:project,
:user,
:tags
])
@builds = @builds.page(params[:page]).per(30).without_count
......
......@@ -8,8 +8,7 @@ class Projects::TagsController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project
before_action :authorize_download_code!
before_action :authorize_push_code!, only: [:new, :create]
before_action :authorize_admin_project!, only: [:destroy]
before_action :authorize_admin_tag!, only: [:new, :create, :destroy]
# rubocop: disable CodeReuse/ActiveRecord
def index
......
......@@ -34,8 +34,10 @@ class NotesFinder
target_type = @params[:target_type]
target_id = @params[:target_id]
target_iid = @params[:target_iid]
return @target = nil unless target_type && target_id
return @target = nil unless target_type
return @target = nil unless target_id || target_iid
@target =
if target_type == "commit"
......@@ -43,12 +45,22 @@ class NotesFinder
@project.commit(target_id)
end
else
noteables_for_type(target_type).find(target_id)
noteables_for_type_by_id(target_type, target_id, target_iid)
end
end
private
def noteables_for_type_by_id(type, id, iid)
query = if id
{ id: id }
else
{ iid: iid }
end
noteables_for_type(type).find_by!(query) # rubocop: disable CodeReuse/ActiveRecord
end
def init_collection
if target
notes_on_target
......
......@@ -4,6 +4,7 @@ module Types
class BaseObject < GraphQL::Schema::Object
prepend Gitlab::Graphql::Present
prepend Gitlab::Graphql::ExposePermissions
prepend Gitlab::Graphql::MarkdownField
field_class Types::BaseField
......
......@@ -14,7 +14,9 @@ module Types
field :iid, GraphQL::ID_TYPE, null: false
field :title, GraphQL::STRING_TYPE, null: false
markdown_field :title_html, null: true
field :description, GraphQL::STRING_TYPE, null: true
markdown_field :description_html, null: true
field :state, IssueStateEnum, null: false
field :reference, GraphQL::STRING_TYPE, null: false, method: :to_reference do
......
......@@ -5,6 +5,7 @@ module Types
graphql_name 'Label'
field :description, GraphQL::STRING_TYPE, null: true
markdown_field :description_html, null: true
field :title, GraphQL::STRING_TYPE, null: false
field :color, GraphQL::STRING_TYPE, null: false
field :text_color, GraphQL::STRING_TYPE, null: false
......
......@@ -15,7 +15,9 @@ module Types
field :id, GraphQL::ID_TYPE, null: false
field :iid, GraphQL::STRING_TYPE, null: false
field :title, GraphQL::STRING_TYPE, null: false
markdown_field :title_html, null: true
field :description, GraphQL::STRING_TYPE, null: true
markdown_field :description_html, null: true
field :state, MergeRequestStateEnum, null: false
field :created_at, Types::TimeType, null: false
field :updated_at, Types::TimeType, null: false
......
......@@ -12,6 +12,7 @@ module Types
field :full_path, GraphQL::ID_TYPE, null: false
field :description, GraphQL::STRING_TYPE, null: true
markdown_field :description_html, null: true
field :visibility, GraphQL::STRING_TYPE, null: true
field :lfs_enabled, GraphQL::BOOLEAN_TYPE, null: true, method: :lfs_enabled?
field :request_access_enabled, GraphQL::BOOLEAN_TYPE, null: true
......
......@@ -35,6 +35,8 @@ module Types
method: :note,
description: "The content note itself"
markdown_field :body_html, null: true, method: :note
field :created_at, Types::TimeType, null: false
field :updated_at, Types::TimeType, null: false
field :discussion, Types::Notes::DiscussionType, null: true, description: "The discussion this note is a part of"
......
......@@ -17,6 +17,7 @@ module Types
field :name, GraphQL::STRING_TYPE, null: false
field :description, GraphQL::STRING_TYPE, null: true
markdown_field :description_html, null: true
field :tag_list, GraphQL::STRING_TYPE, null: true
......
......@@ -278,7 +278,7 @@ module MarkupHelper
def prepare_for_rendering(html, context = {})
return '' unless html.present?
context.merge!(
context.reverse_merge!(
current_user: (current_user if defined?(current_user)),
# RelativeLinkFilter
......
......@@ -3,7 +3,7 @@
module Clusters
module Applications
class Knative < ApplicationRecord
VERSION = '0.5.0'.freeze
VERSION = '0.6.0'.freeze
REPOSITORY = 'https://storage.googleapis.com/triggermesh-charts'.freeze
METRICS_CONFIG = 'https://storage.googleapis.com/triggermesh-charts/istio-metrics.yaml'.freeze
FETCH_IP_ADDRESS_DELAY = 30.seconds
......
......@@ -55,8 +55,6 @@ class Project < ApplicationRecord
VALID_MIRROR_PORTS = [22, 80, 443].freeze
VALID_MIRROR_PROTOCOLS = %w(http https ssh git).freeze
ignore_column :import_status, :import_jid, :import_error
cache_markdown_field :description, pipeline: :description
delegate :feature_available?, :builds_enabled?, :wiki_enabled?,
......
......@@ -297,6 +297,7 @@ class ProjectPolicy < BasePolicy
end
rule { (mirror_available & can?(:admin_project)) | admin }.enable :admin_remote_mirror
rule { can?(:push_code) }.enable :admin_tag
rule { archived }.policy do
prevent :push_code
......
# frozen_string_literal: true
module Git
class WikiPushService < ::BaseService
def execute
# This is used in EE
end
end
end
......@@ -4,6 +4,14 @@ module Lfs
# Usage: Calling `new_file` check to see if a file should be in LFS and
# return a transformed result with `content` and `encoding` to commit.
#
# The `repository` passed to the initializer can be a Repository or
# a DesignManagement::Repository (an EE-specific class that inherits
# from Repository).
#
# The `repository_type` property will be one of the types named in
# `Gitlab::GlRepository.types`, and is recorded on the `LfsObjectsProject`
# in order to identify the repository location of the blob.
#
# For LFS an LfsObject linked to the project is stored and an LFS
# pointer returned. If the file isn't in LFS the untransformed content
# is returned to save in the commit.
......@@ -52,7 +60,7 @@ module Lfs
end
def cached_attributes
@cached_attributes ||= Gitlab::Git::AttributesAtRefParser.new(repository, branch_name)
@cached_attributes ||= repository.attributes_at(branch_name)
end
# rubocop: disable CodeReuse/ActiveRecord
......
......@@ -5,10 +5,12 @@ module Users
delegate :user_default_internal_regex_enabled?,
:user_default_internal_regex_instance,
to: :'Gitlab::CurrentSettings.current_application_settings'
attr_reader :identity_params
def initialize(current_user, params = {})
@current_user = current_user
@params = params.dup
@identity_params = params.slice(*identity_attributes)
end
def execute(skip_authorization: false)
......@@ -26,10 +28,8 @@ module Users
end
end
identity_attrs = params.slice(*identity_params)
unless identity_attrs.empty?
user.identities.build(identity_attrs)
unless identity_params.empty?
user.identities.build(identity_params)
end
user
......@@ -37,7 +37,7 @@ module Users
private
def identity_params
def identity_attributes
[:extern_uid, :provider]
end
......
......@@ -3,11 +3,13 @@
module Users
class UpdateService < BaseService
include NewUserNotifier
attr_reader :user, :identity_params
def initialize(current_user, params = {})
@current_user = current_user
@user = params.delete(:user)
@status_params = params.delete(:status)
@identity_params = params.slice(*identity_attributes)
@params = params.dup
end
......@@ -15,8 +17,8 @@ module Users
yield(@user) if block_given?
user_exists = @user.persisted?
assign_attributes
assign_identity
if @user.save(validate: validate) && update_status
notify_success(user_exists)
......@@ -55,7 +57,18 @@ module Users
params.reject! { |key, _| read_only.include?(key.to_sym) }
end
@user.assign_attributes(params) unless params.empty?
@user.assign_attributes(params.except(*identity_attributes)) unless params.empty? # rubocop: disable CodeReuse/ActiveRecord
end
def assign_identity
return unless identity_params.present?
identity = user.identities.find_or_create_by(provider: identity_params[:provider]) # rubocop: disable CodeReuse/ActiveRecord
identity.update(identity_params)
end
def identity_attributes
[:provider, :extern_uid]
end
end
end
......@@ -10,10 +10,10 @@
= f.text_field :name, class: "form-control top qa-new-user-name js-block-emoji js-validate-length", :data => { :max_length => max_name_length, :max_length_message => s_("SignUp|Name is too long (maximum is %{max_length} characters).") % { max_length: max_name_length } }, required: true, title: _("This field is required.")
.username.form-group
= f.label :username, class: 'label-bold'
= f.text_field :username, class: "form-control middle qa-new-user-username js-block-emoji js-validate-length", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length } }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
%p.validation-error.field-validation.hide= _('Username is already taken.')
%p.validation-success.field-validation.hide= _('Username is available.')
%p.validation-pending.field-validation.hide= _('Checking username availability...')
= f.text_field :username, class: "form-control middle qa-new-user-username js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length } }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
%p.validation-error.gl-field-error-ignore.field-validation.hide= _('Username is already taken.')
%p.validation-success.gl-field-error-ignore.field-validation.hide= _('Username is available.')
%p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking username availability...')
.form-group
= f.label :email, class: 'label-bold'
= f.email_field :email, class: "form-control middle qa-new-user-email", required: true, title: _("Please provide a valid email address.")
......
......@@ -26,10 +26,8 @@
.row-fixed-content.controls.flex-row
= render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name]
- if can?(current_user, :push_code, @project)
- if can?(current_user, :admin_tag, @project)
= link_to edit_project_tag_release_path(@project, tag.name), class: 'btn btn-edit has-tooltip', title: s_('TagsPage|Edit release notes'), data: { container: "body" } do
= icon("pencil")
- if can?(current_user, :admin_project, @project)
= link_to project_tag_path(@project, tag.name), class: "btn btn-remove remove-row has-tooltip prepend-left-10 #{protected_tag?(@project, tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), method: :delete, data: { confirm: s_('TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?') % { tag_name: tag.name }, container: 'body' }, remote: true do
= icon("trash-o")
= link_to project_tag_path(@project, tag.name), class: "btn btn-remove remove-row has-tooltip prepend-left-10 #{protected_tag?(@project, tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), method: :delete, data: { confirm: s_('TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?') % { tag_name: tag.name }, container: 'body' }, remote: true do
= icon("trash-o")
......@@ -24,7 +24,7 @@
- tags_sort_options_hash.each do |value, title|
%li
= link_to title, filter_tags_path(sort: value), class: ("is-active" if @sort == value)
- if can?(current_user, :push_code, @project)
- if can?(current_user, :admin_tag, @project)
= link_to new_project_tag_path(@project), class: 'btn btn-success new-tag-btn' do
= s_('TagsPage|New tag')
= link_to project_tags_path(@project, rss_url_options), title: _("Tags feed"), class: 'btn d-none d-sm-inline-block has-tooltip' do
......
......@@ -19,7 +19,7 @@
= s_("TagsPage|Can't find HEAD commit for this tag")
.nav-controls
- if can?(current_user, :push_code, @project)
- if can?(current_user, :admin_tag, @project)
= link_to edit_project_tag_release_path(@project, @tag.name), class: 'btn btn-edit controls-item has-tooltip', title: s_('TagsPage|Edit release notes') do
= icon("pencil")
= link_to project_tree_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: s_('TagsPage|Browse files') do
......@@ -28,7 +28,7 @@
= icon('history')
.btn-container.controls-item
= render 'projects/buttons/download', project: @project, ref: @tag.name
- if can?(current_user, :push_code, @project) && can?(current_user, :admin_project, @project)
- if can?(current_user, :admin_tag, @project)
.btn-container.controls-item-full
= link_to project_tag_path(@project, @tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, @tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), method: :delete, data: { confirm: s_('TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?') % { tag_name: @tag.name } } do
%i.fa.fa-trash-o
......
......@@ -9,7 +9,7 @@
= auto_discovery_link_tag(:atom, user_url(@user, format: :atom), title: "#{@user.name} activity")
.user-profile
.cover-block.user-cover-block
.cover-block.user-cover-block{ class: [('border-bottom' if profile_tabs.empty?)] }
.cover-controls
- if @user == current_user
= link_to profile_path, class: 'btn btn-default has-tooltip', title: s_('UserProfile|Edit profile'), 'aria-label': 'Edit profile' do
......
......@@ -2,12 +2,9 @@
class CleanupContainerRepositoryWorker
include ApplicationWorker
include ExclusiveLeaseGuard
queue_namespace :container_repository
LEASE_TIMEOUT = 1.hour
attr_reader :container_repository, :current_user
def perform(current_user_id, container_repository_id, params)
......@@ -16,11 +13,9 @@ class CleanupContainerRepositoryWorker
return unless valid?
try_obtain_lease do
Projects::ContainerRepository::CleanupTagsService
.new(project, current_user, params)
.execute(container_repository)
end
Projects::ContainerRepository::CleanupTagsService
.new(project, current_user, params)
.execute(container_repository)
end
private
......@@ -32,22 +27,4 @@ class CleanupContainerRepositoryWorker
def project
container_repository&.project
end
# For ExclusiveLeaseGuard concern
def lease_key
@lease_key ||= "container_repository:cleanup_tags:#{container_repository.id}"
end
# For ExclusiveLeaseGuard concern
def lease_timeout
LEASE_TIMEOUT
end
# For ExclusiveLeaseGuard concern
def lease_release?
# we don't allow to execute this worker
# more often than LEASE_TIMEOUT
# for given container repository
false
end
end
......@@ -30,15 +30,17 @@ class PostReceive
private
def identify_user(post_received)
post_received.identify.tap do |user|
log("Triggered hook for non-existing user \"#{post_received.identifier}\"") unless user
end
end
def process_project_changes(post_received)
changes = []
refs = Set.new
@user = post_received.identify
unless @user
log("Triggered hook for non-existing user \"#{post_received.identifier}\"")
return false
end
user = identify_user(post_received)
return false unless user
post_received.enum_for(:changes_refs).with_index do |(oldrev, newrev, ref), index|
service_klass =
......@@ -51,7 +53,7 @@ class PostReceive
if service_klass
service_klass.new(
post_received.project,
@user,
user,
oldrev: oldrev,
newrev: newrev,
ref: ref,
......@@ -64,7 +66,7 @@ class PostReceive
refs << ref
end
after_project_changes_hooks(post_received, @user, refs.to_a, changes)
after_project_changes_hooks(post_received, user, refs.to_a, changes)
end
def after_project_changes_hooks(post_received, user, refs, changes)
......@@ -76,6 +78,11 @@ class PostReceive
post_received.project.touch(:last_activity_at, :last_repository_updated_at)
post_received.project.wiki.repository.expire_statistics_caches
ProjectCacheWorker.perform_async(post_received.project.id, [], [:wiki_size])
user = identify_user(post_received)
return false unless user
::Git::WikiPushService.new(post_received.project, user, changes: post_received.enum_for(:changes_refs)).execute
end
def log(message)
......
---
title: Fix Container Scanning job timeout when using the kubernetes executor
merge_request: 29706
author:
type: fixed
---
title: Fix nested lists unnecessary margin
merge_request: 29775
author: Kuba Kopeć
type: fixed
---
title: Remove MySQL support
merge_request: 29790
author:
type: removed
---
title: Allow developers to delete tags
merge_request: 29668
author:
type: changed
---
title: Add token_encrypted column to operations_feature_flags_clients table
merge_request:
author:
type: other
---
title: Fix missing API notification flags for Microsoft Teams
merge_request: 29824
author: Seiji Suenaga
type: fixed
---
title: Add identity information to external authorization requests
merge_request: 29461
author:
type: changed
---
title: Return 400 when deleting tags more often than once per hour.
merge_request: 29448
author:
type: changed
---
title: Fix the signup form's username validation messages not displaying
merge_request: 29678
author: Jiaan Louw
type: fixed
---
title: Fix Double Border in Profile Page
merge_request: 29784
author: Yoginth <@yo>
type: fixed
---
title: Indent collapsible sections
merge_request: 29804
author:
type: other
---
title: Render GFM in GraphQL
merge_request: 29700
author:
type: added
---
title: Expose saml_provider_id in the users API
merge_request: 14045
author:
type: added
---
title: 'Fix favicon path with uploads of object store'
merge_request: 29482
author: Roger Meier
type: fixed
---
title: Knative version bump 0.5 -> 0.6
merge_request: 28798
author: Chris Baumbauer
type: changed
---
title: Cache feature flag names in Redis for a minute
merge_request: 29816
author:
type: performance
---
title: Remove import columns from projects table
merge_request: 29863
author:
type: performance
# frozen_string_literal: true
raise "PostgreSQL is the only supported database from GitLab 12.1" unless
Gitlab::Database.postgresql?
......@@ -80,7 +80,7 @@ def unicode_emoji_regex
))x
end
def lint_commit(commit)
def lint_commit(commit) # rubocop:disable Metrics/AbcSize
# For now we'll ignore merge commits, as getting rid of those is a problem
# separate from enforcing good commit messages.
return false if commit.message.start_with?('Merge branch')
......@@ -114,6 +114,16 @@ def lint_commit(commit)
)
end
# Fail if a suggestion commit is used and squash is not enabled
if commit.message.start_with?('Apply suggestion to') && !gitlab.mr_json['squash']
fail_commit(
commit,
'If you are applying suggestions, squash needs to be enabled in the merge request'
)
failures = true
end
unless subject_starts_with_capital?(subject)
fail_commit(commit, 'The commit subject must start with a capital letter')
failures = true
......
# frozen_string_literal: true
class AddWikiColumnsToIndexStatus < ActiveRecord::Migration[5.1]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :index_statuses, :last_wiki_commit, :binary
add_column :index_statuses, :wiki_indexed_at, :datetime_with_timezone
end
end
# frozen_string_literal: true
class RemoveImportColumnsFromProjects < ActiveRecord::Migration[5.1]
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
def change
remove_column :projects, :import_status, :string
remove_column :projects, :import_jid, :string
remove_column :projects, :import_error, :text
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20190618171120) do
ActiveRecord::Schema.define(version: 20190619175843) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -1572,6 +1572,8 @@ ActiveRecord::Schema.define(version: 20190618171120) do
t.string "last_commit"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.binary "last_wiki_commit"
t.datetime_with_timezone "wiki_indexed_at"
t.index ["project_id"], name: "index_index_statuses_on_project_id", unique: true, using: :btree
end
......@@ -2593,11 +2595,9 @@ ActiveRecord::Schema.define(version: 20190618171120) do
t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false
t.string "avatar"
t.string "import_status"
t.integer "star_count", default: 0, null: false
t.string "import_type"
t.string "import_source"
t.text "import_error"
t.boolean "shared_runners_enabled", default: true, null: false
t.string "runners_token"
t.string "build_coverage_regex"
......@@ -2619,7 +2619,6 @@ ActiveRecord::Schema.define(version: 20190618171120) do
t.boolean "only_allow_merge_if_all_discussions_are_resolved"
t.boolean "printing_merge_request_link_enabled", default: true, null: false
t.integer "auto_cancel_pending_pipelines", default: 1, null: false
t.string "import_jid"
t.integer "cached_markdown_version"
t.text "delete_error"
t.datetime "last_repository_updated_at"
......
......@@ -42,7 +42,7 @@ The list of `GITLAB_DATABASE_XXX` variables that you can set is:
Variable | Default value | Overridden by `DATABASE_URL`?
-------- | ------------- | -----------------------------
`GITLAB_DATABASE_ADAPTER` | `postgresql` (for MySQL use `mysql2`) | Yes
`GITLAB_DATABASE_ADAPTER` | `postgresql` | Yes
`GITLAB_DATABASE_DATABASE` | `gitlab_#{ENV['RAILS_ENV']` | Yes
`GITLAB_DATABASE_USERNAME` | `root` | Yes
`GITLAB_DATABASE_PASSWORD` | None | Yes
......
......@@ -489,10 +489,6 @@ work:
gitlab-ctl reconfigure
```
## MySQL replication
MySQL replication is not supported for Geo.
## Troubleshooting
Read the [troubleshooting document](troubleshooting.md).
......
......@@ -432,6 +432,24 @@ gitaly_enabled=false
When you run `service gitlab restart` Gitaly will be disabled on this
particular machine.
## Eliminating NFS altogether
If you are planning to use Gitaly without NFS for your storage needs
and want to eliminate NFS from your environment altogether, there are
a few things that you need to do:
1. Make sure the [`git` user home directory](https://docs.gitlab.com/omnibus/settings/configuration.html#moving-the-home-directory-for-a-user) is on local disk.
1. Configure [database lookup of SSH keys](https://docs.gitlab.com/ce/administration/operations/fast_ssh_key_lookup.html)
to eliminate the need for a shared authorized_keys file.
1. Configure [object storage for job artifacts](https://docs.gitlab.com/ce/administration/job_artifacts.html#using-object-storage)
including [live tracing](https://docs.gitlab.com/ce/administration/job_traces.html#new-live-trace-architecture).
1. Configure [object storage for LFS objects](https://docs.gitlab.com/ce/workflow/lfs/lfs_administration.html#storing-lfs-objects-in-remote-object-storage).
1. Configure [object storage for uploads](https://docs.gitlab.com/ce/administration/uploads.html#using-object-storage-core-only).
NOTE: **Note:** One current feature of GitLab still requires a shared directory (NFS): [GitLab Pages](../../user/project/pages/index.md).
There is [work in progress](https://gitlab.com/gitlab-org/gitlab-pages/issues/196)
to eliminate the need for NFS to support GitLab Pages.
## Troubleshooting Gitaly in production
Since GitLab 11.6, Gitaly comes with a command-line tool called
......
......@@ -33,7 +33,6 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Install](../install/README.md): Requirements, directory structures, and installation methods.
- [Database load balancing](database_load_balancing.md): Distribute database queries among multiple database servers. **[STARTER ONLY]**
- [Omnibus support for external MySQL DB](https://docs.gitlab.com/omnibus/settings/database.html#using-a-mysql-database-management-server-enterprise-edition-only): Omnibus package supports configuring an external MySQL database. **[STARTER ONLY]**
- [Omnibus support for log forwarding](https://docs.gitlab.com/omnibus/settings/logs.html#udp-log-shipping-gitlab-enterprise-edition-only) **[STARTER ONLY]**
- [High Availability](high_availability/README.md): Configure multiple servers for scaling or high availability.
- [Installing GitLab HA on Amazon Web Services (AWS)](../install/aws/index.md): Set up GitLab High Availability on Amazon AWS.
......
......@@ -35,6 +35,7 @@ The following API resources are available in the project context:
| [Environments](environments.md) | `/projects/:id/environments` |
| [Events](events.md) | `/projects/:id/events` (also available for users and standalone) |
| [Issues](issues.md) | `/projects/:id/issues` (also available for groups and standalone) |
| [Issues Statistics](issues_statistics.md) | `/projects/:id/issues_statistics` (also available for groups and standalone) |
| [Issue boards](boards.md) | `/projects/:id/boards` |
| [Issue links](issue_links.md) **[STARTER]** | `/projects/:id/issues/.../links` |
| [Jobs](jobs.md) | `/projects/:id/jobs`, `/projects/:id/pipelines/.../jobs` |
......@@ -92,6 +93,7 @@ The following API resources are available in the group context:
| [Group-level variables](group_level_variables.md) | `/groups/:id/variables` |
| [Group milestones](group_milestones.md) | `/groups/:id/milestones` |
| [Issues](issues.md) | `/groups/:id/issues` (also available for projects and standalone) |
| [Issues Statistics](issues_statistics.md) | `/groups/:id/issues_statistics` (also available for projects and standalone) |
| [Members](members.md) | `/groups/:id/members` (also available for projects) |
| [Merge requests](merge_requests.md) | `/groups/:id/merge_requests` (also available for projects and standalone) |
| [Notes](notes.md) (comments) | `/groups/:id/epics/.../notes` (also available for projects) |
......@@ -116,6 +118,7 @@ The following API resources are available outside of project and group contexts
| [Geo Nodes](geo_nodes.md) **[PREMIUM ONLY]** | `/geo_nodes` |
| [Import repository from GitHub](import.md) | `/import/github` |
| [Issues](issues.md) | `/issues` (also available for groups and projects) |
| [Issues Statistics](issues_statistics.md) | `/issues_statistics` (also available for groups and projects) |
| [Keys](keys.md) | `/keys` |
| [License](license.md) **[CORE ONLY]** | `/license` |
| [Markdown](markdown.md) | `/markdown` |
......
......@@ -145,6 +145,9 @@ DELETE /projects/:id/registry/repositories/:repository_id/tags/:tag_name
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags/v10.0.0"
```
This action does not delete blobs. In order to delete them and recycle disk space,
[run the garbage collection](https://docs.gitlab.com/omnibus/maintenance/README.html#removing-unused-layers-not-referenced-by-manifests).
## Delete repository tags in bulk
Delete repository tags in bulk based on given criteria.
......@@ -174,6 +177,8 @@ This API call performs the following operations:
These operations are executed asynchronously and it might
take time to get executed. You can run this at most
once an hour for a given container repository.
This action does not delete blobs. In order to delete them and recycle disk space,
[run the garbage collection](https://docs.gitlab.com/omnibus/maintenance/README.html#removing-unused-layers-not-referenced-by-manifests).
NOTE: **Note:**
Due to a [Docker Distribution deficiency](https://gitlab.com/gitlab-org/gitlab-ce/issues/21405),
......
......@@ -1023,6 +1023,8 @@ Parameters:
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `webhook` | string | true | The Microsoft Teams webhook. For example, `https://outlook.office.com/webhook/...` |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | Send notifications only for the default branch |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
......
......@@ -2,6 +2,8 @@
## List users
Active users = Total accounts - Blocked users
Get a list of users.
This function takes pagination parameters `page` and `per_page` to restrict the list of users.
......@@ -257,7 +259,8 @@ Parameters:
"two_factor_enabled": true,
"external": false,
"private_profile": false,
"highest_role":10
"shared_runners_minutes_limit": 133
"extra_shared_runners_minutes_limit": 133
}
```
......@@ -290,6 +293,7 @@ Parameters:
- `projects_limit` (optional) - Number of projects user can create
- `extern_uid` (optional) - External UID
- `provider` (optional) - External provider name
- `group_id_for_saml` (optional) - ID of group where SAML has been configured
- `bio` (optional) - User's biography
- `location` (optional) - User's location
- `public_email` (optional) - The public email of the user
......@@ -299,6 +303,8 @@ Parameters:
- `external` (optional) - Flags the user as external - true or false(default)
- `avatar` (optional) - Image file for user's avatar
- `private_profile` (optional) - User's profile is private - true or false
- `shared_runners_minutes_limit` (optional) - Pipeline minutes quota for this user
- `extra_shared_runners_minutes_limit` (optional) - Extra pipeline minutes quota for this user
## User modification
......@@ -322,6 +328,7 @@ Parameters:
- `projects_limit` - Limit projects each user can create
- `extern_uid` - External UID
- `provider` - External provider name
- `group_id_for_saml` (optional) - ID of group where SAML has been configured
- `bio` - User's biography
- `location` (optional) - User's location
- `public_email` (optional) - The public email of the user
......@@ -329,6 +336,8 @@ Parameters:
- `can_create_group` (optional) - User can create groups - true or false
- `skip_reconfirmation` (optional) - Skip reconfirmation - true or false (default)
- `external` (optional) - Flags the user as external - true or false(default)
- `shared_runners_minutes_limit` (optional) - Pipeline minutes quota for this user
- `extra_shared_runners_minutes_limit` (optional) - Extra pipeline minutes quota for this user
- `avatar` (optional) - Image file for user's avatar
- `private_profile` (optional) - User's profile is private - true or false
......@@ -1150,8 +1159,6 @@ settings page.
POST /users/:user_id/impersonation_tokens
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `user_id` | integer | yes | The ID of the user |
......@@ -1255,4 +1262,4 @@ Example response:
Please note that `last_activity_at` is deprecated, please use `last_activity_on`.
[gemojione-index]: https://github.com/jonathanwiesel/gemojione/blob/master/config/index.json
[gemojione-index]: https://github.com/jonathanwiesel/gemojione/blob/master/config/index.json
\ No newline at end of file
......@@ -139,6 +139,20 @@ The union of A, B, and C is (1, 4) and (6, 7). Therefore, the total running time
(4 - 1) + (7 - 6) => 4
```
### Expanding and collapsing job log sections
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/14664) in GitLab
> 12.0.
Job logs are divided into sections that can be collapsed or expanded.
In the following example:
- Two sections are expanded and can be collapsed.
- One section is collapsed and can be expanded.
![Collapsible sections](img/collapsible_log.png)
## Configuring pipelines
Pipelines, and their component jobs and stages, are defined in the [`.gitlab-ci.yml`](yaml/README.md) file for each project.
......
......@@ -149,7 +149,7 @@ Component statuses are linked to configuration documentation for each component.
| [PgBouncer Exporter](#pgbouncer-exporter) | Prometheus endpoint with PgBouncer metrics | [][pgbouncer-exporter-omnibus] | [][pgbouncer-exporter-charts] | [][pgbouncer-exporter-charts] | [](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
| [GitLab Monitor](#gitlab-monitor) | Generates a variety of GitLab metrics | [][gitlab-monitor-omnibus] | [][gitab-monitor-charts] | [][gitab-monitor-charts] | [](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
| [Node Exporter](#node-exporter) | Prometheus endpoint with system metrics | [][node-exporter-omnibus] | [][node-exporter-charts] | [][node-exporter-charts] | [](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
| [Mattermost](#mattermost) | Open-source Slack alternative | [][mattermost-omnibus] | [][mattermost-charts] | [][mattermost-charts] | [](../user/project/integrations/mattermost_slash_commands.md#manual-configuration), [](../user/project/integrations/mattermost.html) | ❌ | ❌ | CE & EE |
| [Mattermost](#mattermost) | Open-source Slack alternative | [][mattermost-omnibus] | [][mattermost-charts] | [][mattermost-charts] | [](../user/project/integrations/mattermost.md) | ❌ | ❌ | CE & EE |
| [MinIO](#minio) | Object storage service | [][minio-omnibus] | [][minio-charts] | [][minio-charts] | [](https://about.gitlab.com/handbook/engineering/infrastructure/production-architecture/#storage-architecture) | ❌ | [][minio-gdk] | CE & EE |
| [Runner](#gitlab-runner) | Executes GitLab CI jobs | [][runner-omnibus] | [][runner-charts] | [][runner-charts] | [](../user/gitlab_com/index.md#shared-runners) | [][runner-source] | [][runner-gdk] | CE & EE |
| [Database Migrations](#database-migrations) | Database migrations | [][database-migrations-omnibus] | [][database-migrations-charts] | [][database-migrations-charts] | ✅ | [][database-migrations-source] | ✅ | CE & EE |
......@@ -695,7 +695,7 @@ We've also detailed [our architecture of GitLab.com](https://about.gitlab.com/ha
[runner-gdk]: https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/runner.md
[database-migrations-omnibus]: https://docs.gitlab.com/omnibus/settings/database.html#disabling-automatic-database-migration
[database-migrations-charts]: https://docs.gitlab.com/charts/charts/gitlab/migrations/
[database-migrations-source]: ../update/upgrading_from_source.md#14-install-libs-migrations-etc
[database-migrations-source]: ../update/upgrading_from_source.md#13-install-libs-migrations-etc
[certificate-management-omnibus]: https://docs.gitlab.com/omnibus/settings/ssl.html
[certificate-management-charts]: https://docs.gitlab.com/charts/installation/tls.html
[certificate-management-source]: ../install/installation.md#using-https
......
......@@ -77,6 +77,9 @@ Or:
hello = _("Hello world!")
```
NOTE: **Note:** Messages in the API (`lib/api/` or `app/graphql`) do
not need to be externalised.
### HAML files
Given the following content in HAML:
......
......@@ -80,30 +80,6 @@ There are a few environment flags you can pass to change how projects are seeded
- `LARGE_PROJECTS`: defaults to false. If set will clone 6 large projects to help with testing.
- `FORK`: defaults to false. If set to `true` will fork `torvalds/linux` five times. Can also be set to an existing project full_path and it will fork that instead.
### Notes for MySQL
Since the seeds would contain various UTF-8 characters, such as emojis or so,
we'll need to make sure that we're using `utf8mb4` for all the encoding
settings and `utf8mb4_unicode_ci` for collation. Please check
[MySQL utf8mb4 support](../install/database_mysql.md#mysql-utf8mb4-support)
Make sure that `config/database.yml` has `encoding: utf8mb4`, too.
Next, we'll need to update the schema to make the indices fit:
``` shell
sed -i 's/limit: 255/limit: 191/g' db/schema.rb
```
Then run the setup script:
``` shell
bundle exec rake setup
```
To make sure that indices still fit. You could find great details in:
[How to support full Unicode in MySQL databases](https://mathiasbynens.be/notes/mysql-utf8mb4)
## Run tests
In order to run the test you can use the following commands:
......
......@@ -39,14 +39,6 @@ PostgreSQL you can use the `reset_pk_sequence!` method like so:
reset_pk_sequence!('events')
```
For MySQL however you need to do run the following:
```ruby
amount = Event.pluck('COALESCE(MAX(id), 1)').first
execute "ALTER TABLE events AUTO_INCREMENT = #{amount}"
```
Failure to reset the primary keys will result in newly created rows starting
with an ID value of 1. Depending on the existing data this can then lead to
duplicate key constraints from popping up, preventing users from creating new
......
......@@ -247,7 +247,7 @@ module QA
[@new_label_same_scope, @new_label_different_scope].each do |label|
Resource::Label.fabricate_via_api! do |l|
l.project = issue.project.id
l.project = issue.project
l.title = label
end
end
......@@ -414,7 +414,7 @@ def api_get_path
end
def api_post_path
"/projects/#{project}/labels"
"/projects/#{project.id}/labels"
end
def api_post_body
......
This diff is collapsed.
......@@ -293,10 +293,9 @@ sudo adduser --disabled-login --gecos 'GitLab' git
## 6. Database
We recommend using a PostgreSQL database. For MySQL, see the [MySQL setup guide](database_mysql.md).
NOTE: **Note:**
Because we need to make use of extensions and concurrent index removal, you need at least PostgreSQL 9.2.
Starting from GitLab 12.1, only PostgreSQL is supported. Because we need to make
use of extensions and concurrent index removal, you need at least PostgreSQL 9.2.
1. Install the database packages:
......@@ -502,13 +501,8 @@ If you want to use HTTPS, see [Using HTTPS](#using-https) for the additional ste
### Configure GitLab DB Settings
```sh
# PostgreSQL only:
sudo -u git cp config/database.yml.postgresql config/database.yml
# MySQL only:
sudo -u git cp config/database.yml.mysql config/database.yml
# PostgreSQL only:
# Remove host, username, and password lines from config/database.yml.
# Once modified, the `production` settings will be as follows:
#
......@@ -520,7 +514,7 @@ sudo -u git cp config/database.yml.mysql config/database.yml
#
sudo -u git -H editor config/database.yml
# MySQL and remote PostgreSQL only:
# Remote PostgreSQL only:
# Update username/password in config/database.yml.
# You only need to adapt the production settings (first part).
# If you followed the database guide then please do as follows:
......@@ -528,7 +522,6 @@ sudo -u git -H editor config/database.yml
# You can keep the double quotes around the password
sudo -u git -H editor config/database.yml
# PostgreSQL and MySQL:
# Make config/database.yml readable to git only
sudo -u git -H chmod o-rwx config/database.yml
```
......@@ -544,11 +537,7 @@ Make sure you have `bundle` (run `bundle -v`):
- `< 2.x`.
```sh
# For PostgreSQL (note, the option says "without ... mysql")
sudo -u git -H bundle install --deployment --without development test mysql aws kerberos
# Or if you use MySQL (note, the option says "without ... postgres")
sudo -u git -H bundle install --deployment --without development test postgres aws kerberos
```
NOTE: **Note:**
......
......@@ -104,32 +104,10 @@ installation (e.g. the number of users, projects, etc).
We currently support the following databases:
- PostgreSQL (highly recommended)
- MySQL/MariaDB (strongly discouraged, not all GitLab features are supported, no support for [MySQL/MariaDB GTID](https://mariadb.com/kb/en/mariadb/gtid/))
We highly recommend the use of PostgreSQL instead of MySQL/MariaDB as not all
features of GitLab work with MySQL/MariaDB:
1. MySQL support for subgroups was [dropped with GitLab 9.3][post].
See [issue #30472][30472] for more information.
1. Geo does [not support MySQL](../administration/geo/replication/database.md). This means no supported Disaster Recovery solution if using MySQL. **[PREMIUM ONLY]**
1. [Zero downtime migrations](../update/README.md#upgrading-without-downtime) do not work with MySQL.
1. [Database load balancing](../administration/database_load_balancing.md) is
supported only for PostgreSQL. **[PREMIUM ONLY]**
1. GitLab [optimizes the loading of dashboard events](https://gitlab.com/gitlab-org/gitlab-ce/issues/31806) using [PostgreSQL LATERAL JOINs](https://blog.heapanalytics.com/postgresqls-powerful-new-join-type-lateral/).
1. In general, SQL optimized for PostgreSQL may run much slower in MySQL due to
differences in query planners. For example, subqueries that work well in PostgreSQL
may not be [performant in MySQL](https://dev.mysql.com/doc/refman/5.7/en/optimizing-subqueries.html).
1. Binary column index length is limited to 20 bytes. This is accomplished with [a hack](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/initializers/mysql_set_length_for_binary_indexes.rb).
1. MySQL requires a variety of hacks to increase limits on various columns, [for example](https://gitlab.com/gitlab-org/gitlab-ce/issues/49583).
1. [The milestone filter runs slower queries on MySQL](https://gitlab.com/gitlab-org/gitlab-ce/issues/51173#note_99391731).
1. We expect this list to grow over time.
Existing users using GitLab with MySQL/MariaDB are advised to
[migrate to PostgreSQL](../update/mysql_to_postgresql.md) instead.
[30472]: https://gitlab.com/gitlab-org/gitlab-ce/issues/30472
[post]: https://about.gitlab.com/2017/06/22/gitlab-9-3-released/#dropping-support-for-subgroups-in-mysql
- PostgreSQL
Support for MySQL was removed in GitLab 12.1. Existing users using GitLab with
MySQL/MariaDB are advised to [migrate to PostgreSQL](../update/mysql_to_postgresql.md) before upgrading.
### PostgreSQL Requirements
......
......@@ -194,11 +194,7 @@ from the Omniauth provider's documentation.
gem "omniauth-your-auth-provider"
- If you're using MySQL, install the new Omniauth provider gem by running the following command:
sudo -u git -H bundle install --without development test postgres --path vendor/bundle --no-deployment
- If you're using PostgreSQL, install the new Omniauth provider gem by running the following command:
- Install the new Omniauth provider gem by running the following command:
sudo -u git -H bundle install --without development test mysql --path vendor/bundle --no-deployment
......
......@@ -936,5 +936,36 @@ A similar strategy can be employed for the remaining features - by removing the
data that cannot be decrypted, GitLab can be brought back into working order,
and the lost data can be manually replaced.
### Container Registry push failures after restoring from a backup
If you use the [Container Registry](../user/project/container_registry.md), you
may see pushes to the registry fail after restoring your backup on an Omnibus
GitLab instance after restoring the registry data.
These failures will mention permission issues in the registry logs, like:
```
level=error
msg="response completed with error"
err.code=unknown
err.detail="filesystem: mkdir /var/opt/gitlab/gitlab-rails/shared/registry/docker/registry/v2/repositories/...: permission denied"
err.message="unknown error"
```
This is caused by the restore being run as the unprivileged user `git` which was
unable to assign the correct ownership to the registry files during the restore
([issue 62759](https://gitlab.com/gitlab-org/gitlab-ce/issues/62759 "Incorrect permissions on registry filesystem after restore")).
To get your registry working again:
```bash
sudo chown -R registry:registry /var/opt/gitlab/gitlab-rails/shared/registry/docker
```
NOTE: **Note:**
If you have changed the default filesystem location for the registry, you will
want to run the chown against your custom location instead of
`/var/opt/gitlab/gitlab-rails/shared/registry/docker`.
[reconfigure GitLab]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
[restart GitLab]: ../administration/restart_gitlab.md#installations-from-source
......@@ -149,7 +149,6 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
1. [How to Install GitLab with Omnibus - Video](https://www.youtube.com/watch?v=Q69YaOjqNhg)
1. [Installing GitLab - Online Course](https://courses.platzi.com/classes/git-gitlab/concepto/part-1/part-3/material/)
1. [Using a Non-Packaged PostgreSQL Database](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#using-a-non-packaged-postgresql-database-management-server)
1. [Using a MySQL Database](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#using-a-mysql-database-management-server-enterprise-edition-only)
1. [Installing GitLab on Microsoft Azure](https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/)
1. [Installing GitLab on Digital Ocean](https://about.gitlab.com/2016/04/27/getting-started-with-gitlab-and-digitalocean/)
......
......@@ -49,8 +49,7 @@ However, for this to work there are the following requirements:
- You have to use [post-deployment
migrations](../development/post_deployment_migrations.md) (included in
zero downtime update steps below).
- You are using PostgreSQL. If you are using MySQL please look at the release
post to see if downtime is required.
- You are using PostgreSQL. Starting from GitLab 12.1, MySQL is not supported.
Most of the time you can safely upgrade from a patch release to the next minor
release if the patch release is not the latest. For example, upgrading from
......@@ -140,8 +139,6 @@ possible.
- [MySQL to PostgreSQL](mysql_to_postgresql.md) guides you through migrating
your database from MySQL to PostgreSQL.
- [MySQL installation guide](../install/database_mysql.md) contains additional
information about configuring GitLab to work with a MySQL database.
- [Restoring from backup after a failed upgrade](restore_after_failure.md)
- [Upgrading PostgreSQL Using Slony](upgrading_postgresql_using_slony.md), for
upgrading a PostgreSQL database with minimal downtime.
......
---
last_updated: 2019-03-27
last_updated: 2019-06-18
---
# Migrating from MySQL to PostgreSQL
......@@ -9,6 +9,10 @@ migrate it to a PostgreSQL database.
## Requirements
NOTE: **Note:**
Support for MySQL was removed in GitLab 12.1. This procedure should be performed
**before** installing GitLab 12.1.
[pgloader](http://pgloader.io) 3.4.1+ is required.
You can install it directly from your distribution, for example in
......
......@@ -13,8 +13,6 @@ You can select the tag in the version dropdown in the top left corner of GitLab
### 0. Backup
It's useful to make a backup just in case things go south:
(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab
user on the database version)
```bash
cd /home/git/gitlab
......@@ -48,12 +46,8 @@ sudo -u git -H git checkout LATEST_TAG -b LATEST_TAG
```bash
cd /home/git/gitlab
# PostgreSQL
sudo -u git -H bundle install --without development test mysql --deployment
# MySQL
sudo -u git -H bundle install --without development test postgres --deployment
# Optional: clean up old gems
sudo -u git -H bundle clean
......
......@@ -4,6 +4,10 @@ comments: false
# Upgrading Community Edition and Enterprise Edition from source
NOTE: **Note:**
Users wishing to upgrade to 12.0.0 will have to take some extra steps. See the
version specific upgrade instructions for 12.0.0 for more details.
Make sure you view this update guide from the branch (version) of GitLab you
would like to install (e.g., `11.8`. You can select the version in the version
dropdown at the top left corner of GitLab (below the menu bar).
......@@ -235,29 +239,7 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_PAGES_VERSION)
sudo -u git -H make
```
### 12. Update MySQL permissions
If you are using MySQL you need to grant the GitLab user the necessary
permissions on the database:
```bash
mysql -u root -p -e "GRANT TRIGGER ON \`gitlabhq_production\`.* TO 'git'@'localhost';"
```
If you use MySQL with replication, or just have MySQL configured with binary logging,
you will need to also run the following on all of your MySQL servers:
```bash
mysql -u root -p -e "SET GLOBAL log_bin_trust_function_creators = 1;"
```
You can make this setting permanent by adding it to your `my.cnf`:
```
log_bin_trust_function_creators=1
```
### 13. Update configuration files
### 12. Update configuration files
#### New configuration options for `gitlab.yml`
......@@ -331,18 +313,13 @@ For Ubuntu 16.04.1 LTS:
sudo systemctl daemon-reload
```
### 14. Install libs, migrations, etc.
### 13. Install libs, migrations, etc.
```bash
cd /home/git/gitlab
# PostgreSQL installations (note: the line below states '--without mysql')
sudo -u git -H bundle install --deployment --without development test mysql aws kerberos
# MySQL installations (note: the line below states '--without postgres')
sudo -u git -H bundle install --deployment --without development test postgres aws kerberos
# Optional: clean up old gems
sudo -u git -H bundle clean
......@@ -360,17 +337,14 @@ sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:c
sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
```
**MySQL installations**: Run through the `MySQL strings limits` and `Tables and
data conversion to utf8mb4` [tasks](../install/database_mysql.md).
### 15. Start application
### 14. Start application
```bash
sudo service gitlab start
sudo service nginx restart
```
### 16. Check application status
### 15. Check application status
Check if GitLab and its environment are configured correctly:
......@@ -404,6 +378,20 @@ Example:
Additional instructions here.
-->
### 12.0.0
In 12.0.0 we made various database related changes. These changes require that
users first upgrade to the latest 11.11 patch release. Once upgraded to 11.11.x,
users can upgrade to 12.x. Failure to do so may result in database migrations
not being applied, which could lead to application errors.
Example 1: you are currently using GitLab 11.11.3, which is the latest patch
release for 11.11.x. You can upgrade as usual to 12.0.0, 12.1.0, etc.
Example 2: you are currently using a version of GitLab 10.x. To upgrade, first
upgrade to 11.11.3. Once upgraded to 11.11.3 you can safely upgrade to 12.0.0
or future versions.
## Things went south? Revert to previous version
### 1. Revert the code to the previous version
......
......@@ -89,10 +89,8 @@ are enabled.
![Project admin info](img/admin_project_quota_view.png)
When the pipeline minutes quota for a group is set to a value different than 0,
the **Pipelines quota** page is available to the group page settings list.
You can see there an overview of the pipeline minutes quota of all projects of
the group.
You can see an overview of the pipeline minutes quota of all projects of
a group in the **Usage Quotas** page available to the group page settings list.
![Group pipelines quota](img/group_pipelines_quota.png)
......
......@@ -76,13 +76,19 @@ service with this body:
{
"user_identifier": "jane@acme.org",
"project_classification_label": "project-label",
"user_ldap_dn": "CN=Jane Doe,CN=admin,DC=acme"
"user_ldap_dn": "CN=Jane Doe,CN=admin,DC=acme",
"identities": [
{ "provider": "ldap", "extern_uid": "CN=Jane Doe,CN=admin,DC=acme" },
{ "provider": "bitbucket", "extern_uid": "2435223452345" }
]
}
```
The `user_ldap_dn` is optional and is only sent when the user is logged in
through LDAP.
`identities` will contain the details of all the identities associated with the user. This will be an empty array if there are no identities associated with the user.
When the external authorization service responds with a status code 200, the
user is granted access. When the external service responds with a status code
401 or 403, the user is denied access. In any case, the request is cached for 6 hours.
......
......@@ -381,6 +381,14 @@ Define project templates at a group level by setting a group as the template sou
for the group. **[STARTER ONLY]**
- **Pipelines quota**: Keep track of the [pipeline quota](../admin_area/settings/continuous_integration.md) for the group.
#### Storage usage quota **[STARTER]**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/13294) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.0.
A group owner can check the aggregated storage usage for all the project in a group, sub-groups included, in the **Storage** tab of the **Usage Quotas** page available to the group page settings list.
![Group storage usage quota](img/group_storage_usage_quota.png)
## User contribution analysis **[STARTER]**
With [GitLab Contribution Analytics](contribution_analytics/index.md),
......
......@@ -5,8 +5,7 @@ type: reference, howto, concepts
# Subgroups
NOTE: **Note:**
[Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/2772) in GitLab 9.0. Not available when using MySQL as external
database (support removed in GitLab 9.3 [due to performance reasons](https://gitlab.com/gitlab-org/gitlab-ce/issues/30472#note_27747600)).
[Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/2772) in GitLab 9.0.
Subgroups, also known as nested groups or hierarchical groups, allow you to have up to 20
levels of groups.
......@@ -21,16 +20,6 @@ By using subgroups you can do the following:
- **Make it easier to manage people and control visibility.** Give people
different [permissions](../../permissions.md#group-members-permissions) depending on their group [membership](#membership).
## Database Requirements
Subgroups are only supported when you use PostgreSQL. Supporting subgroups on MySQL in an
efficient way is not possible due to MySQL's limitations.
See the following links for more information:
- <https://gitlab.com/gitlab-org/gitlab-ce/issues/30472>
- <https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/10885>
## Overview
A group can have many subgroups inside it, and at the same time a group can have
......
......@@ -95,6 +95,7 @@ The following table depicts the various user permission levels in a project.
| Dismiss vulnerability **[ULTIMATE]** | | | ✓ | ✓ | ✓ |
| Apply code change suggestions | | | ✓ | ✓ | ✓ |
| Create and edit wiki pages | | | ✓ | ✓ | ✓ |
| Rewrite/remove Git tags | | | ✓ | ✓ | ✓ |
| Use environment terminals | | | | ✓ | ✓ |
| Run Web IDE's Interactive Web Terminals **[ULTIMATE ONLY]** | | | | ✓ | ✓ |
| Add new team members | | | | ✓ | ✓ |
......@@ -102,7 +103,6 @@ The following table depicts the various user permission levels in a project.
| Push to protected branches | | | | ✓ | ✓ |
| Turn on/off protected branch push for devs | | | | ✓ | ✓ |
| Enable/disable tag protections | | | | ✓ | ✓ |
| Rewrite/remove Git tags | | | | ✓ | ✓ |
| Edit project | | | | ✓ | ✓ |
| Add deploy keys to project | | | | ✓ | ✓ |
| Configure project hooks | | | | ✓ | ✓ |
......
......@@ -85,12 +85,22 @@ on a given project but not both. The current implementation makes use of a `serv
## Using an existing installation of Knative
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/58941) in GitLab 12.0.
NOTE: **Note:**
The "invocations" monitoring feature of GitLab serverless will not work when adding an existing installation of Knative.
The "invocations" monitoring feature of GitLab serverless will not work when
adding an existing installation of Knative.
It is also possible to use GitLab Serverless with an existing Kubernetes
cluster which already has Knative installed.
Simply:
It is also possible to use GitLab Serverless with an existing Kubernetes cluster which already has Knative installed.
Simply follow the steps to [add an existing Kubernetes cluster](../index.md#adding-an-existing-kubernetes-cluster)
and then follow the steps to deploy [functions](#deploying-functions) or [serverless applications](#deploying-serverless-applications) onto your cluster.
1. Follow the steps to
[add an existing Kubernetes cluster](../index.md#adding-an-existing-kubernetes-cluster).
1. Follow the steps to deploy [functions](#deploying-functions)
or [serverless applications](#deploying-serverless-applications) onto your
cluster.
## Deploying functions
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment