...@@ -46,9 +46,7 @@ docs lint: ...@@ -46,9 +46,7 @@ docs lint:
- .docs:rules:docs-lint - .docs:rules:docs-lint
image: "registry.gitlab.com/gitlab-org/gitlab-docs:docs-lint" image: "registry.gitlab.com/gitlab-org/gitlab-docs:docs-lint"
stage: test stage: test
needs: needs: []
- job: "retrieve-tests-metadata"
artifacts: false
script: script:
- scripts/lint-doc.sh - scripts/lint-doc.sh
# Lint Markdown # Lint Markdown
... ...
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
memory-static: memory-static:
extends: .only-code-memory-job-base extends: .only-code-memory-job-base
stage: test
needs:
- job: setup-test-env
artifacts: true
variables: variables:
SETUP_DB: "false" SETUP_DB: "false"
script: script:
...@@ -36,6 +40,12 @@ memory-on-boot: ...@@ -36,6 +40,12 @@ memory-on-boot:
extends: extends:
- .only-code-memory-job-base - .only-code-memory-job-base
- .use-pg10 - .use-pg10
stage: test
needs:
- job: setup-test-env
artifacts: true
- job: compile-assets pull-cache
artifacts: true
variables: variables:
NODE_ENV: "production" NODE_ENV: "production"
RAILS_ENV: "production" RAILS_ENV: "production"
... ...
......
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
- .default-tags - .default-tags
- .default-retry - .default-retry
stage: test stage: test
needs: needs: []
- job: "retrieve-tests-metadata"
artifacts: false
cache: cache:
key: "qa-framework-jobs:v1" key: "qa-framework-jobs:v1"
paths: paths:
... ...
......
...@@ -12,9 +12,7 @@ code_quality: ...@@ -12,9 +12,7 @@ code_quality:
- .default-retry - .default-retry
- .reports:rules:code_quality - .reports:rules:code_quality
stage: test stage: test
needs: needs: []
- job: "retrieve-tests-metadata"
artifacts: false
image: docker:stable image: docker:stable
allow_failure: true allow_failure: true
services: services:
...@@ -54,9 +52,7 @@ sast: ...@@ -54,9 +52,7 @@ sast:
- .reports:rules:sast - .reports:rules:sast
stage: test stage: test
allow_failure: true allow_failure: true
needs: needs: []
- job: "retrieve-tests-metadata"
artifacts: false
artifacts: artifacts:
paths: paths:
- gl-sast-report.json # GitLab-specific - gl-sast-report.json # GitLab-specific
...@@ -94,9 +90,7 @@ dependency_scanning: ...@@ -94,9 +90,7 @@ dependency_scanning:
- .default-retry - .default-retry
- .reports:rules:dependency_scanning - .reports:rules:dependency_scanning
stage: test stage: test
needs: needs: []
- job: "retrieve-tests-metadata"
artifacts: false
image: docker:stable image: docker:stable
variables: variables:
DOCKER_DRIVER: overlay2 DOCKER_DRIVER: overlay2
... ...
......
...@@ -248,9 +248,7 @@ danger-review: ...@@ -248,9 +248,7 @@ danger-review:
- .review:rules:danger - .review:rules:danger
image: registry.gitlab.com/gitlab-org/gitlab-build-images:danger image: registry.gitlab.com/gitlab-org/gitlab-build-images:danger
stage: test stage: test
needs: needs: []
- job: "retrieve-tests-metadata"
artifacts: false
script: script:
- git version - git version
- node --version - node --version
... ...
......
...@@ -23,12 +23,13 @@ cache gems: ...@@ -23,12 +23,13 @@ cache gems:
extends: extends:
- .default-tags - .default-tags
- .default-retry - .default-retry
dependencies: [] needs: []
gitlab_git_test: gitlab_git_test:
extends: extends:
- .minimal-job - .minimal-job
- .setup:rules:gitlab_git_test - .setup:rules:gitlab_git_test
stage: test
script: script:
- spec/support/prepare-gitlab-git-test-for-commit --check-for-changes - spec/support/prepare-gitlab-git-test-for-commit --check-for-changes
...@@ -36,5 +37,6 @@ no_ee_check: ...@@ -36,5 +37,6 @@ no_ee_check:
extends: extends:
- .minimal-job - .minimal-job
- .setup:rules:no_ee_check - .setup:rules:no_ee_check
stage: test
script: script:
- scripts/no-ee-check - scripts/no-ee-check
...@@ -6,7 +6,8 @@ lint-ci-gitlab: ...@@ -6,7 +6,8 @@ lint-ci-gitlab:
- .default-retry - .default-retry
- .yaml:rules - .yaml:rules
image: sdesbure/yamllint:latest image: sdesbure/yamllint:latest
dependencies: [] stage: test
needs: []
variables: variables:
LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates changelogs LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates changelogs
script: script:
... ...
......
...@@ -3,7 +3,7 @@ import { mapState, mapActions } from 'vuex'; ...@@ -3,7 +3,7 @@ import { mapState, mapActions } from 'vuex';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { UNFOLD_COUNT } from '../constants'; import { UNFOLD_COUNT, INLINE_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE } from '../constants';
import * as utils from '../store/utils'; import * as utils from '../store/utils';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
...@@ -11,6 +11,16 @@ const EXPAND_ALL = 0; ...@@ -11,6 +11,16 @@ const EXPAND_ALL = 0;
const EXPAND_UP = 1; const EXPAND_UP = 1;
const EXPAND_DOWN = 2; const EXPAND_DOWN = 2;
const lineNumberByViewType = (viewType, diffLine) => {
const numberGetters = {
[INLINE_DIFF_VIEW_TYPE]: line => line?.new_line,
[PARALLEL_DIFF_VIEW_TYPE]: line => (line?.right || line?.left)?.new_line,
};
const numberGetter = numberGetters[viewType];
return numberGetter && numberGetter(diffLine);
};
export default { export default {
directives: { directives: {
tooltip, tooltip,
...@@ -67,12 +77,16 @@ export default { ...@@ -67,12 +77,16 @@ export default {
...mapActions('diffs', ['loadMoreLines']), ...mapActions('diffs', ['loadMoreLines']),
getPrevLineNumber(oldLineNumber, newLineNumber) { getPrevLineNumber(oldLineNumber, newLineNumber) {
const diffFile = utils.findDiffFile(this.diffFiles, this.fileHash); const diffFile = utils.findDiffFile(this.diffFiles, this.fileHash);
const indexForInline = utils.findIndexInInlineLines(diffFile.highlighted_diff_lines, { const lines = {
[INLINE_DIFF_VIEW_TYPE]: diffFile.highlighted_diff_lines,
[PARALLEL_DIFF_VIEW_TYPE]: diffFile.parallel_diff_lines,
};
const index = utils.getPreviousLineIndex(this.diffViewType, diffFile, {
oldLineNumber, oldLineNumber,
newLineNumber, newLineNumber,
}); });
const prevLine = diffFile.highlighted_diff_lines[indexForInline - 2];
return (prevLine && prevLine.new_line) || 0; return lineNumberByViewType(this.diffViewType, lines[this.diffViewType][index - 2]) || 0;
}, },
callLoadMoreLines( callLoadMoreLines(
endpoint, endpoint,
...@@ -114,7 +128,7 @@ export default { ...@@ -114,7 +128,7 @@ export default {
this.handleExpandAllLines(expandOptions); this.handleExpandAllLines(expandOptions);
} }
}, },
handleExpandUpLines(expandOptions = EXPAND_ALL) { handleExpandUpLines(expandOptions) {
const { endpoint, fileHash, view, oldLineNumber, newLineNumber, offset } = expandOptions; const { endpoint, fileHash, view, oldLineNumber, newLineNumber, offset } = expandOptions;
const bottom = this.isBottom; const bottom = this.isBottom;
... ...
......
...@@ -140,6 +140,7 @@ export default { ...@@ -140,6 +140,7 @@ export default {
addContextLines({ addContextLines({
inlineLines: diffFile.highlighted_diff_lines, inlineLines: diffFile.highlighted_diff_lines,
parallelLines: diffFile.parallel_diff_lines, parallelLines: diffFile.parallel_diff_lines,
diffViewType: state.diffViewType,
contextLines: lines, contextLines: lines,
bottom, bottom,
lineNumbers, lineNumbers,
... ...
......
...@@ -13,6 +13,8 @@ import { ...@@ -13,6 +13,8 @@ import {
LINES_TO_BE_RENDERED_DIRECTLY, LINES_TO_BE_RENDERED_DIRECTLY,
MAX_LINES_TO_BE_RENDERED, MAX_LINES_TO_BE_RENDERED,
TREE_TYPE, TREE_TYPE,
INLINE_DIFF_VIEW_TYPE,
PARALLEL_DIFF_VIEW_TYPE,
} from '../constants'; } from '../constants';
export function findDiffFile(files, match, matchKey = 'file_hash') { export function findDiffFile(files, match, matchKey = 'file_hash') {
...@@ -93,8 +95,7 @@ export function getNoteFormData(params) { ...@@ -93,8 +95,7 @@ export function getNoteFormData(params) {
export const findIndexInInlineLines = (lines, lineNumbers) => { export const findIndexInInlineLines = (lines, lineNumbers) => {
const { oldLineNumber, newLineNumber } = lineNumbers; const { oldLineNumber, newLineNumber } = lineNumbers;
return _.findIndex( return lines.findIndex(
lines,
line => line.old_line === oldLineNumber && line.new_line === newLineNumber, line => line.old_line === oldLineNumber && line.new_line === newLineNumber,
); );
}; };
...@@ -102,8 +103,7 @@ export const findIndexInInlineLines = (lines, lineNumbers) => { ...@@ -102,8 +103,7 @@ export const findIndexInInlineLines = (lines, lineNumbers) => {
export const findIndexInParallelLines = (lines, lineNumbers) => { export const findIndexInParallelLines = (lines, lineNumbers) => {
const { oldLineNumber, newLineNumber } = lineNumbers; const { oldLineNumber, newLineNumber } = lineNumbers;
return _.findIndex( return lines.findIndex(
lines,
line => line =>
line.left && line.left &&
line.right && line.right &&
...@@ -112,14 +112,33 @@ export const findIndexInParallelLines = (lines, lineNumbers) => { ...@@ -112,14 +112,33 @@ export const findIndexInParallelLines = (lines, lineNumbers) => {
); );
}; };
const indexGettersByViewType = {
[INLINE_DIFF_VIEW_TYPE]: findIndexInInlineLines,
[PARALLEL_DIFF_VIEW_TYPE]: findIndexInParallelLines,
};
export const getPreviousLineIndex = (diffViewType, file, lineNumbers) => {
const findIndex = indexGettersByViewType[diffViewType];
const lines = {
[INLINE_DIFF_VIEW_TYPE]: file.highlighted_diff_lines,
[PARALLEL_DIFF_VIEW_TYPE]: file.parallel_diff_lines,
};
return findIndex && findIndex(lines[diffViewType], lineNumbers);
};
export function removeMatchLine(diffFile, lineNumbers, bottom) { export function removeMatchLine(diffFile, lineNumbers, bottom) {
const indexForInline = findIndexInInlineLines(diffFile.highlighted_diff_lines, lineNumbers); const indexForInline = findIndexInInlineLines(diffFile.highlighted_diff_lines, lineNumbers);
const indexForParallel = findIndexInParallelLines(diffFile.parallel_diff_lines, lineNumbers); const indexForParallel = findIndexInParallelLines(diffFile.parallel_diff_lines, lineNumbers);
const factor = bottom ? 1 : -1; const factor = bottom ? 1 : -1;
if (indexForInline > -1) {
diffFile.highlighted_diff_lines.splice(indexForInline + factor, 1); diffFile.highlighted_diff_lines.splice(indexForInline + factor, 1);
}
if (indexForParallel > -1) {
diffFile.parallel_diff_lines.splice(indexForParallel + factor, 1); diffFile.parallel_diff_lines.splice(indexForParallel + factor, 1);
} }
}
export function addLineReferences(lines, lineNumbers, bottom, isExpandDown, nextLineNumbers) { export function addLineReferences(lines, lineNumbers, bottom, isExpandDown, nextLineNumbers) {
const { oldLineNumber, newLineNumber } = lineNumbers; const { oldLineNumber, newLineNumber } = lineNumbers;
...@@ -160,8 +179,8 @@ export function addLineReferences(lines, lineNumbers, bottom, isExpandDown, next ...@@ -160,8 +179,8 @@ export function addLineReferences(lines, lineNumbers, bottom, isExpandDown, next
return linesWithNumbers; return linesWithNumbers;
} }
export function addContextLines(options) { function addParallelContextLines(options) {
const { inlineLines, parallelLines, contextLines, lineNumbers, isExpandDown } = options; const { parallelLines, contextLines, lineNumbers, isExpandDown } = options;
const normalizedParallelLines = contextLines.map(line => ({ const normalizedParallelLines = contextLines.map(line => ({
left: line, left: line,
right: line, right: line,
...@@ -170,17 +189,40 @@ export function addContextLines(options) { ...@@ -170,17 +189,40 @@ export function addContextLines(options) {
const factor = isExpandDown ? 1 : 0; const factor = isExpandDown ? 1 : 0;
if (!isExpandDown && options.bottom) { if (!isExpandDown && options.bottom) {
inlineLines.push(...contextLines);
parallelLines.push(...normalizedParallelLines); parallelLines.push(...normalizedParallelLines);
} else { } else {
const inlineIndex = findIndexInInlineLines(inlineLines, lineNumbers);
const parallelIndex = findIndexInParallelLines(parallelLines, lineNumbers); const parallelIndex = findIndexInParallelLines(parallelLines, lineNumbers);
inlineLines.splice(inlineIndex + factor, 0, ...contextLines);
parallelLines.splice(parallelIndex + factor, 0, ...normalizedParallelLines); parallelLines.splice(parallelIndex + factor, 0, ...normalizedParallelLines);
} }
} }
function addInlineContextLines(options) {
const { inlineLines, contextLines, lineNumbers, isExpandDown } = options;
const factor = isExpandDown ? 1 : 0;
if (!isExpandDown && options.bottom) {
inlineLines.push(...contextLines);
} else {
const inlineIndex = findIndexInInlineLines(inlineLines, lineNumbers);
inlineLines.splice(inlineIndex + factor, 0, ...contextLines);
}
}
export function addContextLines(options) {
const { diffViewType } = options;
const contextLineHandlers = {
[INLINE_DIFF_VIEW_TYPE]: addInlineContextLines,
[PARALLEL_DIFF_VIEW_TYPE]: addParallelContextLines,
};
const contextLineHandler = contextLineHandlers[diffViewType];
if (contextLineHandler) {
contextLineHandler(options);
}
}
/** /**
* Trims the first char of the `richText` property when it's either a space or a diff symbol. * Trims the first char of the `richText` property when it's either a space or a diff symbol.
* @param {Object} line * @param {Object} line
... ...
......
import _ from 'underscore'; import { escape } from 'lodash';
/** /**
Very limited implementation of sprintf supporting only named parameters. Very limited implementation of sprintf supporting only named parameters.
...@@ -17,7 +17,7 @@ export default (input, parameters, escapeParameters = true) => { ...@@ -17,7 +17,7 @@ export default (input, parameters, escapeParameters = true) => {
if (parameters) { if (parameters) {
Object.keys(parameters).forEach(parameterName => { Object.keys(parameters).forEach(parameterName => {
const parameterValue = parameters[parameterName]; const parameterValue = parameters[parameterName];
const escapedParameterValue = escapeParameters ? _.escape(parameterValue) : parameterValue; const escapedParameterValue = escapeParameters ? escape(parameterValue) : parameterValue;
output = output.replace(new RegExp(`%{${parameterName}}`, 'g'), escapedParameterValue); output = output.replace(new RegExp(`%{${parameterName}}`, 'g'), escapedParameterValue);
}); });
} }
... ...
......
...@@ -173,8 +173,10 @@ module Ci ...@@ -173,8 +173,10 @@ module Ci
scope :queued_before, ->(time) { where(arel_table[:queued_at].lt(time)) } scope :queued_before, ->(time) { where(arel_table[:queued_at].lt(time)) }
scope :order_id_desc, -> { order('ci_builds.id DESC') } scope :order_id_desc, -> { order('ci_builds.id DESC') }
PROJECT_ROUTE_AND_NAMESPACE_ROUTE = { project: [:project_feature, :route, { namespace: :route }] }.freeze scope :preload_project_and_pipeline_project, -> do
scope :preload_project_and_pipeline_project, -> { preload(PROJECT_ROUTE_AND_NAMESPACE_ROUTE, pipeline: PROJECT_ROUTE_AND_NAMESPACE_ROUTE) } preload(Ci::Pipeline::PROJECT_ROUTE_AND_NAMESPACE_ROUTE,
pipeline: Ci::Pipeline::PROJECT_ROUTE_AND_NAMESPACE_ROUTE)
end
acts_as_taggable acts_as_taggable
... ...
......
...@@ -16,6 +16,10 @@ module Ci ...@@ -16,6 +16,10 @@ module Ci
include FromUnion include FromUnion
include UpdatedAtFilterable include UpdatedAtFilterable
PROJECT_ROUTE_AND_NAMESPACE_ROUTE = {
project: [:project_feature, :route, { namespace: :route }]
}.freeze
BridgeStatusError = Class.new(StandardError) BridgeStatusError = Class.new(StandardError)
sha_attribute :source_sha sha_attribute :source_sha
... ...
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
module WithUploads module WithUploads
extend ActiveSupport::Concern extend ActiveSupport::Concern
include FastDestroyAll::Helpers include FastDestroyAll::Helpers
include FeatureGate
# Currently there is no simple way how to select only not-mounted # Currently there is no simple way how to select only not-mounted
# uploads, it should be all FileUploaders so we select them by # uploads, it should be all FileUploaders so we select them by
... ...
......
...@@ -235,12 +235,17 @@ class MergeRequest < ApplicationRecord ...@@ -235,12 +235,17 @@ class MergeRequest < ApplicationRecord
end end
scope :join_project, -> { joins(:target_project) } scope :join_project, -> { joins(:target_project) }
scope :references_project, -> { references(:target_project) } scope :references_project, -> { references(:target_project) }
PROJECT_ROUTE_AND_NAMESPACE_ROUTE = [
target_project: [:route, { namespace: :route }],
source_project: [:route, { namespace: :route }]
].freeze
scope :with_api_entity_associations, -> { scope :with_api_entity_associations, -> {
preload(:assignees, :author, :unresolved_notes, :labels, :milestone, preload(:assignees, :author, :unresolved_notes, :labels, :milestone,
:timelogs, :latest_merge_request_diff, :timelogs, :latest_merge_request_diff,
metrics: [:latest_closed_by, :merged_by], *PROJECT_ROUTE_AND_NAMESPACE_ROUTE,
target_project: [:route, { namespace: :route }], metrics: [:latest_closed_by, :merged_by])
source_project: [:route, { namespace: :route }])
} }
scope :by_target_branch_wildcard, ->(wildcard_branch_name) do scope :by_target_branch_wildcard, ->(wildcard_branch_name) do
where("target_branch LIKE ?", ApplicationRecord.sanitize_sql_like(wildcard_branch_name).tr('*', '%')) where("target_branch LIKE ?", ApplicationRecord.sanitize_sql_like(wildcard_branch_name).tr('*', '%'))
... ...
......
---
title: Refuse to start web server without a working ActiveRecord connection
merge_request: 25160
author:
type: other
---
title: Allow users to get Merge Trains entries via Public API
merge_request: 25229
author:
type: added
---
title: Remove duplicate authorization refresh for group members on project creation
merge_request:
author:
type: performance
...@@ -14,6 +14,8 @@ end ...@@ -14,6 +14,8 @@ end
if defined?(ActiveRecord::Base) if defined?(ActiveRecord::Base)
Gitlab::Cluster::LifecycleEvents.on_before_fork do Gitlab::Cluster::LifecycleEvents.on_before_fork do
raise 'ActiveRecord connection not established. Unable to start.' unless Gitlab::Database.exists?
# the following is highly recommended for Rails + "preload_app true" # the following is highly recommended for Rails + "preload_app true"
# as there's no need for the master process to hold a connection # as there's no need for the master process to hold a connection
ActiveRecord::Base.connection.disconnect! ActiveRecord::Base.connection.disconnect!
... ...
......
# frozen_string_literal: true
class AddNpmPackageRequestsForwardingToApplicationSettings < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default(:application_settings, :npm_package_requests_forwarding,
:boolean,
default: false,
allow_null: false)
end
def down
remove_column(:application_settings, :npm_package_requests_forwarding)
end
end