Commit cb605c69 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents bbbc98bf 718e32ca
...@@ -621,6 +621,8 @@ ...@@ -621,6 +621,8 @@
- <<: *if-merge-request-title-run-all-rspec - <<: *if-merge-request-title-run-all-rspec
- <<: *if-merge-request - <<: *if-merge-request
changes: *ci-patterns changes: *ci-patterns
- <<: *if-merge-request
changes: *db-patterns
- <<: *if-automated-merge-request - <<: *if-automated-merge-request
changes: *db-patterns changes: *db-patterns
- <<: *if-merge-request-not-approved - <<: *if-merge-request-not-approved
...@@ -640,6 +642,7 @@ ...@@ -640,6 +642,7 @@
when: never when: never
- <<: *if-merge-request - <<: *if-merge-request
changes: *db-patterns changes: *db-patterns
when: never
.rails:rules:ee-and-foss-mr-with-migration: .rails:rules:ee-and-foss-mr-with-migration:
rules: rules:
...@@ -767,6 +770,8 @@ ...@@ -767,6 +770,8 @@
- <<: *if-merge-request-title-run-all-rspec - <<: *if-merge-request-title-run-all-rspec
- <<: *if-merge-request - <<: *if-merge-request
changes: *ci-patterns changes: *ci-patterns
- <<: *if-merge-request
changes: *db-patterns
- <<: *if-automated-merge-request - <<: *if-automated-merge-request
changes: *db-patterns changes: *db-patterns
- <<: *if-merge-request-not-approved - <<: *if-merge-request-not-approved
...@@ -788,6 +793,7 @@ ...@@ -788,6 +793,7 @@
when: never when: never
- <<: *if-merge-request - <<: *if-merge-request
changes: *db-patterns changes: *db-patterns
when: never
.rails:rules:ee-only-unit: .rails:rules:ee-only-unit:
rules: rules:
...@@ -883,14 +889,14 @@ ...@@ -883,14 +889,14 @@
- <<: *if-merge-request-title-run-all-rspec - <<: *if-merge-request-title-run-all-rspec
- <<: *if-merge-request - <<: *if-merge-request
changes: *ci-patterns changes: *ci-patterns
- <<: *if-automated-merge-request
changes: *db-patterns
- <<: *if-merge-request-not-approved
when: never
- <<: *if-security-merge-request - <<: *if-security-merge-request
changes: *db-patterns changes: *db-patterns
- <<: *if-merge-request-title-as-if-foss - <<: *if-merge-request-title-as-if-foss
changes: *db-patterns changes: *db-patterns
- <<: *if-automated-merge-request
changes: *db-patterns
- <<: *if-merge-request-not-approved
when: never
.rails:rules:as-if-foss-migration:minimal: .rails:rules:as-if-foss-migration:minimal:
rules: rules:
...@@ -905,8 +911,10 @@ ...@@ -905,8 +911,10 @@
when: never when: never
- <<: *if-security-merge-request - <<: *if-security-merge-request
changes: *db-patterns changes: *db-patterns
when: never
- <<: *if-merge-request-title-as-if-foss - <<: *if-merge-request-title-as-if-foss
changes: *db-patterns changes: *db-patterns
when: never
.rails:rules:as-if-foss-unit: .rails:rules:as-if-foss-unit:
rules: rules:
......
bdbed7a8a30246ee83d325615bb43213bf7a1d69 2ddefee1edfde10092a278a143c48fdcf86e380f
...@@ -586,14 +586,7 @@ class Issue < ApplicationRecord ...@@ -586,14 +586,7 @@ class Issue < ApplicationRecord
override :ensure_metrics override :ensure_metrics
def ensure_metrics def ensure_metrics
return Issue::Metrics.record!(self) if Feature.enabled?(:upsert_issue_metrics, default_enabled: :yaml) Issue::Metrics.record!(self)
if !association(:metrics).loaded? || metrics.blank?
metrics_record = Issue::Metrics.safe_find_or_create_by(issue: self)
self.metrics = metrics_record
end
metrics.record!
end end
def record_create_action def record_create_action
......
...@@ -35,22 +35,4 @@ class Issue::Metrics < ApplicationRecord ...@@ -35,22 +35,4 @@ class Issue::Metrics < ApplicationRecord
issue.labels.joins(:lists).exists? issue.labels.joins(:lists).exists?
end end
end end
def record!
if issue.milestone_id.present? && self.first_associated_with_milestone_at.blank?
self.first_associated_with_milestone_at = Time.current
end
if issue_assigned_to_list_label? && self.first_added_to_board_at.blank?
self.first_added_to_board_at = Time.current
end
self.save
end
private
def issue_assigned_to_list_label?
issue.labels.joins(:lists).exists?
end
end end
---
name: changes_batch_commits
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66731
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336992
milestone: '14.2'
type: development
group: group::gitaly
default_enabled: false
---
name: upsert_issue_metrics
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68509
rollout_issue_url:
milestone: '14.3'
type: development
group: group::project management
default_enabled: false
# frozen_string_literal: true
class RemoveAllowEditingCommitMessagesFromProjectSettings < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
def up
return unless column_exists?(:project_settings, :allow_editing_commit_messages)
with_lock_retries do
remove_column :project_settings, :allow_editing_commit_messages
end
end
def down
with_lock_retries do
add_column :project_settings, :allow_editing_commit_messages, :boolean, default: false, null: false
end
end
end
b85ef326056bb152d527e34b49caa3c40ee8685c3b14654992246c6adf082f8c
\ No newline at end of file
...@@ -17342,7 +17342,6 @@ CREATE TABLE project_settings ( ...@@ -17342,7 +17342,6 @@ CREATE TABLE project_settings (
squash_option smallint DEFAULT 3, squash_option smallint DEFAULT 3,
has_confluence boolean DEFAULT false NOT NULL, has_confluence boolean DEFAULT false NOT NULL,
has_vulnerabilities boolean DEFAULT false NOT NULL, has_vulnerabilities boolean DEFAULT false NOT NULL,
allow_editing_commit_messages boolean DEFAULT false NOT NULL,
prevent_merge_without_jira_issue boolean DEFAULT false NOT NULL, prevent_merge_without_jira_issue boolean DEFAULT false NOT NULL,
cve_id_request_enabled boolean DEFAULT true NOT NULL, cve_id_request_enabled boolean DEFAULT true NOT NULL,
mr_default_target_self boolean DEFAULT false NOT NULL, mr_default_target_self boolean DEFAULT false NOT NULL,
...@@ -25,21 +25,22 @@ export { dateFormats as DATE_FORMATS } from '~/analytics/shared/constants'; ...@@ -25,21 +25,22 @@ export { dateFormats as DATE_FORMATS } from '~/analytics/shared/constants';
export const POLICY_TYPE_COMPONENT_OPTIONS = { export const POLICY_TYPE_COMPONENT_OPTIONS = {
container: { container: {
component: 'network-policy-editor', component: 'network-policy-editor',
kind: {
cilium: 'CiliumNetworkPolicy',
network: 'NetworkPolicy',
},
shouldShowEnvironmentPicker: true, shouldShowEnvironmentPicker: true,
text: s__('SecurityOrchestration|Network'), text: s__('SecurityOrchestration|Network'),
typeName: 'NetworkPolicy',
urlParameter: 'container_policy', urlParameter: 'container_policy',
value: 'container', value: 'container',
yamlIndicator: {
cilium: 'CiliumNetworkPolicy',
network: 'NetworkPolicy',
},
}, },
scanExecution: { scanExecution: {
component: 'scan-execution-policy-editor', component: 'scan-execution-policy-editor',
text: s__('SecurityOrchestration|Scan Execution'), text: s__('SecurityOrchestration|Scan Execution'),
typeName: 'ScanExecutionPolicy',
urlParameter: 'scan_execution_policy', urlParameter: 'scan_execution_policy',
value: 'scanExecution', value: 'scanExecution',
yamlIndicator: 'scanner_profile',
}, },
}; };
......
...@@ -167,7 +167,8 @@ export default { ...@@ -167,7 +167,8 @@ export default {
return ''; return '';
}, },
policyType() { policyType() {
return this.selectedPolicy ? getPolicyType(this.selectedPolicy.yaml) : 'container'; // eslint-disable-next-line no-underscore-dangle
return this.selectedPolicy ? getPolicyType(this.selectedPolicy.__typename) : 'container';
}, },
hasExistingPolicies() { hasExistingPolicies() {
return !(this.selectedPolicyType === POLICY_TYPE_OPTIONS.ALL.value && !this.policies.length); return !(this.selectedPolicyType === POLICY_TYPE_OPTIONS.ALL.value && !this.policies.length);
......
...@@ -48,7 +48,7 @@ export default function toYaml(policy) { ...@@ -48,7 +48,7 @@ export default function toYaml(policy) {
const policySpec = { const policySpec = {
apiVersion: 'cilium.io/v2', apiVersion: 'cilium.io/v2',
kind: POLICY_TYPE_COMPONENT_OPTIONS.container.yamlIndicator.cilium, kind: POLICY_TYPE_COMPONENT_OPTIONS.container.kind.cilium,
}; };
if (description?.length > 0) { if (description?.length > 0) {
......
...@@ -168,7 +168,8 @@ export default { ...@@ -168,7 +168,8 @@ export default {
: ''; : '';
}, },
policyType() { policyType() {
return this.selectedPolicy ? getPolicyType(this.selectedPolicy.yaml) : ''; // eslint-disable-next-line no-underscore-dangle
return this.selectedPolicy ? getPolicyType(this.selectedPolicy.__typename) : '';
}, },
fields() { fields() {
const environments = { const environments = {
......
import createGqClient from '~/lib/graphql'; import createGqClient from '~/lib/graphql';
import { POLICY_TYPE_COMPONENT_OPTIONS } from './components/constants'; import { POLICY_TYPE_COMPONENT_OPTIONS } from './components/constants';
/**
* Determines if the yaml passed in is of the type `container`
* @param {String} yaml the policy in yaml form
* @returns {Boolean}
*/
const isContainerPolicyYaml = (yaml) => {
const containerYamlIndicator = Object.values(
POLICY_TYPE_COMPONENT_OPTIONS.container.yamlIndicator,
);
return containerYamlIndicator.some((str) => yaml?.includes(str));
};
/** /**
* Get the height of the wrapper page element * Get the height of the wrapper page element
* This height can be used to determine where the highest element goes in a page * This height can be used to determine where the highest element goes in a page
...@@ -30,11 +18,11 @@ export const getContentWrapperHeight = (contentWrapperClass) => { ...@@ -30,11 +18,11 @@ export const getContentWrapperHeight = (contentWrapperClass) => {
* @param {String} yaml policy's YAML manifest * @param {String} yaml policy's YAML manifest
* @returns {String|null} policy type if available * @returns {String|null} policy type if available
*/ */
export const getPolicyType = (yaml = '') => { export const getPolicyType = (typeName = '') => {
if (isContainerPolicyYaml(yaml)) { if (typeName === POLICY_TYPE_COMPONENT_OPTIONS.container.typeName) {
return POLICY_TYPE_COMPONENT_OPTIONS.container.value; return POLICY_TYPE_COMPONENT_OPTIONS.container.value;
} }
if (yaml?.includes(POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.yamlIndicator)) { if (typeName === POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.typeName) {
return POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value; return POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value;
} }
return null; return null;
......
...@@ -114,6 +114,7 @@ spec: ...@@ -114,6 +114,7 @@ spec:
- cluster`; - cluster`;
export const mockCiliumPolicy = { export const mockCiliumPolicy = {
__typename: 'NetworkPolicy',
name: 'test-policy-03', name: 'test-policy-03',
updatedAt: new Date('2021-06-07T00:00:00.000Z'), updatedAt: new Date('2021-06-07T00:00:00.000Z'),
yaml: mockCiliumManifest, yaml: mockCiliumManifest,
...@@ -121,6 +122,7 @@ export const mockCiliumPolicy = { ...@@ -121,6 +122,7 @@ export const mockCiliumPolicy = {
export const mockNetworkPoliciesResponse = [ export const mockNetworkPoliciesResponse = [
{ {
__typename: 'NetworkPolicy',
name: 'policy', name: 'policy',
kind: 'NetworkPolicy', kind: 'NetworkPolicy',
yaml: mockNetworkManifest, yaml: mockNetworkManifest,
...@@ -132,6 +134,7 @@ export const mockNetworkPoliciesResponse = [ ...@@ -132,6 +134,7 @@ export const mockNetworkPoliciesResponse = [
}, },
}, },
{ {
__typename: 'NetworkPolicy',
name: 'test-policy-02', name: 'test-policy-02',
kind: 'CiliumNetworkPolicy', kind: 'CiliumNetworkPolicy',
yaml: mockL3Manifest, yaml: mockL3Manifest,
...@@ -145,6 +148,7 @@ export const mockNetworkPoliciesResponse = [ ...@@ -145,6 +148,7 @@ export const mockNetworkPoliciesResponse = [
]; ];
export const mockScanExecutionPolicy = { export const mockScanExecutionPolicy = {
__typename: 'ScanExecutionPolicy',
name: 'Scheduled DAST scan', name: 'Scheduled DAST scan',
updatedAt: new Date('2021-06-07T00:00:00.000Z'), updatedAt: new Date('2021-06-07T00:00:00.000Z'),
yaml: mockDastScanExecutionManifest, yaml: mockDastScanExecutionManifest,
......
/* eslint-disable no-underscore-dangle */
import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/threat_monitoring/components/constants'; import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/threat_monitoring/components/constants';
import { import {
getContentWrapperHeight, getContentWrapperHeight,
...@@ -5,11 +6,7 @@ import { ...@@ -5,11 +6,7 @@ import {
removeUnnecessaryDashes, removeUnnecessaryDashes,
} from 'ee/threat_monitoring/utils'; } from 'ee/threat_monitoring/utils';
import { setHTMLFixture } from 'helpers/fixtures'; import { setHTMLFixture } from 'helpers/fixtures';
import { import { mockScanExecutionPolicy, mockNetworkPoliciesResponse } from './mocks/mock_data';
mockDastScanExecutionManifest,
mockCiliumManifest,
mockNetworkManifest,
} from './mocks/mock_data';
describe('Threat Monitoring Utils', () => { describe('Threat Monitoring Utils', () => {
describe('getContentWrapperHeight', () => { describe('getContentWrapperHeight', () => {
...@@ -36,12 +33,12 @@ describe('Threat Monitoring Utils', () => { ...@@ -36,12 +33,12 @@ describe('Threat Monitoring Utils', () => {
describe('getPolicyType', () => { describe('getPolicyType', () => {
it.each` it.each`
input | output input | output
${''} | ${null} ${''} | ${null}
${'random string'} | ${null} ${'UnknownPolicyType'} | ${null}
${mockNetworkManifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.container.value} ${mockNetworkPoliciesResponse[0].__typename} | ${POLICY_TYPE_COMPONENT_OPTIONS.container.value}
${mockCiliumManifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.container.value} ${mockNetworkPoliciesResponse[1].__typename} | ${POLICY_TYPE_COMPONENT_OPTIONS.container.value}
${mockDastScanExecutionManifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value} ${mockScanExecutionPolicy.__typename} | ${POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value}
`('returns $output when used on $input', ({ input, output }) => { `('returns $output when used on $input', ({ input, output }) => {
expect(getPolicyType(input)).toBe(output); expect(getPolicyType(input)).toBe(output);
}); });
......
...@@ -81,7 +81,7 @@ module Gitlab ...@@ -81,7 +81,7 @@ module Gitlab
def single_access_checks! def single_access_checks!
# Iterate over all changes to find if user allowed all of them to be applied # Iterate over all changes to find if user allowed all of them to be applied
changes.each do |change| changes.each do |change|
commits = Gitlab::Lazy.new { commits_for(change[:newrev]) } if Feature.enabled?(:changes_batch_commits) commits = Gitlab::Lazy.new { commits_for(change[:newrev]) }
# If user does not have access to make at least one change, cancel all # If user does not have access to make at least one change, cancel all
# push by allowing the exception to bubble up # push by allowing the exception to bubble up
......
...@@ -8,53 +8,35 @@ RSpec.describe Gitlab::Checks::ChangesAccess do ...@@ -8,53 +8,35 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
subject { changes_access } subject { changes_access }
describe '#validate!' do describe '#validate!' do
shared_examples '#validate!' do before do
before do allow(project).to receive(:lfs_enabled?).and_return(true)
allow(project).to receive(:lfs_enabled?).and_return(true) end
end
context 'without failed checks' do
it "doesn't raise an error" do
expect { subject.validate! }.not_to raise_error
end
it 'calls lfs checks' do
expect_next_instance_of(Gitlab::Checks::LfsCheck) do |instance|
expect(instance).to receive(:validate!)
end
subject.validate! context 'without failed checks' do
end it "doesn't raise an error" do
expect { subject.validate! }.not_to raise_error
end end
context 'when time limit was reached' do it 'calls lfs checks' do
it 'raises a TimeoutError' do expect_next_instance_of(Gitlab::Checks::LfsCheck) do |instance|
logger = Gitlab::Checks::TimedLogger.new(start_time: timeout.ago, timeout: timeout) expect(instance).to receive(:validate!)
access = described_class.new(changes,
project: project,
user_access: user_access,
protocol: protocol,
logger: logger)
expect { access.validate! }.to raise_error(Gitlab::Checks::TimedLogger::TimeoutError)
end end
end
end
context 'with batched commits enabled' do subject.validate!
before do
stub_feature_flags(changes_batch_commits: true)
end end
it_behaves_like '#validate!'
end end
context 'with batched commits disabled' do context 'when time limit was reached' do
before do it 'raises a TimeoutError' do
stub_feature_flags(changes_batch_commits: false) logger = Gitlab::Checks::TimedLogger.new(start_time: timeout.ago, timeout: timeout)
end access = described_class.new(changes,
project: project,
user_access: user_access,
protocol: protocol,
logger: logger)
it_behaves_like '#validate!' expect { access.validate! }.to raise_error(Gitlab::Checks::TimedLogger::TimeoutError)
end
end end
end end
......
...@@ -34,7 +34,7 @@ RSpec.describe Issue::Metrics do ...@@ -34,7 +34,7 @@ RSpec.describe Issue::Metrics do
end end
end end
shared_examples "when recording the default set of issue metrics on issue save" do context "when recording the default set of issue metrics on issue save" do
context "milestones" do context "milestones" do
it "records the first time an issue is associated with a milestone" do it "records the first time an issue is associated with a milestone" do
time = Time.current time = Time.current
...@@ -81,20 +81,4 @@ RSpec.describe Issue::Metrics do ...@@ -81,20 +81,4 @@ RSpec.describe Issue::Metrics do
end end
end end
end end
context 'when upsert_issue_metrics is enabled' do
before do
stub_feature_flags(upsert_issue_metrics: true)
end
it_behaves_like 'when recording the default set of issue metrics on issue save'
end
context 'when upsert_issue_metrics is disabled' do
before do
stub_feature_flags(upsert_issue_metrics: false)
end
it_behaves_like 'when recording the default set of issue metrics on issue save'
end
end end
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