Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
2d96e61ceb
commit
2a65a97e12
37 changed files with 363 additions and 97 deletions
|
@ -42,7 +42,6 @@ export default {
|
|||
|
||||
<template>
|
||||
<li class="linked-pipeline build">
|
||||
<div class="curve"></div>
|
||||
<gl-button
|
||||
:id="buttonId"
|
||||
v-gl-tooltip
|
||||
|
|
|
@ -9,11 +9,11 @@ module ClustersHelper
|
|||
def create_new_cluster_label(provider: nil)
|
||||
case provider
|
||||
when 'aws'
|
||||
s_('ClusterIntegration|Create new Cluster on EKS')
|
||||
s_('ClusterIntegration|Create new cluster on EKS')
|
||||
when 'gcp'
|
||||
s_('ClusterIntegration|Create new Cluster on GKE')
|
||||
s_('ClusterIntegration|Create new cluster on GKE')
|
||||
else
|
||||
s_('ClusterIntegration|Create new Cluster')
|
||||
s_('ClusterIntegration|Create new cluster')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -205,4 +205,4 @@ module TodosHelper
|
|||
end
|
||||
end
|
||||
|
||||
TodosHelper.prepend_if_ee('EE::NotesHelper'); TodosHelper.prepend_if_ee('EE::TodosHelper') # rubocop: disable Style/Semicolon
|
||||
TodosHelper.prepend_if_ee('EE::TodosHelper')
|
||||
|
|
|
@ -762,6 +762,10 @@ module Ci
|
|||
Gitlab::Ci::Build::Credentials::Factory.new(self).create!
|
||||
end
|
||||
|
||||
def all_dependencies
|
||||
(dependencies + cross_dependencies).uniq
|
||||
end
|
||||
|
||||
def dependencies
|
||||
return [] if empty_dependencies?
|
||||
|
||||
|
@ -782,6 +786,10 @@ module Ci
|
|||
depended_jobs
|
||||
end
|
||||
|
||||
def cross_dependencies
|
||||
[]
|
||||
end
|
||||
|
||||
def empty_dependencies?
|
||||
options[:dependencies]&.empty?
|
||||
end
|
||||
|
|
|
@ -47,6 +47,12 @@ class CommitStatus < ApplicationRecord
|
|||
scope :after_stage, -> (index) { where('stage_idx > ?', index) }
|
||||
scope :processables, -> { where(type: %w[Ci::Build Ci::Bridge]) }
|
||||
scope :for_ids, -> (ids) { where(id: ids) }
|
||||
scope :for_ref, -> (ref) { where(ref: ref) }
|
||||
scope :by_name, -> (name) { where(name: name) }
|
||||
|
||||
scope :for_project_paths, -> (paths) do
|
||||
where(project: Project.where_full_path_in(Array(paths)))
|
||||
end
|
||||
|
||||
scope :with_preloads, -> do
|
||||
preload(:project, :user)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Harmonize capitalization on cluster UI
|
||||
merge_request: 21878
|
||||
author: Evan Read
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Strong validate import export references
|
||||
merge_request: 19682
|
||||
author:
|
||||
type: added
|
|
@ -8,6 +8,8 @@
|
|||
#
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def instrument_classes(instrumentation)
|
||||
return if ENV['STATIC_VERIFICATION']
|
||||
|
||||
instrumentation.instrument_instance_methods(Gitlab::Shell)
|
||||
|
||||
instrumentation.instrument_methods(Gitlab::Git)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIndexForCrossProjectsDependenciesToCiBuilds < ActiveRecord::Migration[5.2]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_index :ci_builds, [:project_id, :name, :ref],
|
||||
where: "type = 'Ci::Build' AND status = 'success' AND (retried = FALSE OR retried IS NULL)"
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index :ci_builds, [:project_id, :name, :ref],
|
||||
where: "type = 'Ci::Build' AND status = 'success' AND (retried = FALSE OR retried IS NULL)"
|
||||
end
|
||||
end
|
|
@ -693,6 +693,7 @@ ActiveRecord::Schema.define(version: 2019_12_16_183532) do
|
|||
t.index ["commit_id", "type", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_ref"
|
||||
t.index ["name"], name: "index_ci_builds_on_name_for_security_products_values", where: "((name)::text = ANY (ARRAY[('container_scanning'::character varying)::text, ('dast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('license_management'::character varying)::text, ('sast'::character varying)::text]))"
|
||||
t.index ["project_id", "id"], name: "index_ci_builds_on_project_id_and_id"
|
||||
t.index ["project_id", "name", "ref"], name: "index_ci_builds_on_project_id_and_name_and_ref", where: "(((type)::text = 'Ci::Build'::text) AND ((status)::text = 'success'::text) AND ((retried = false) OR (retried IS NULL)))"
|
||||
t.index ["project_id", "status"], name: "index_ci_builds_project_id_and_status_for_live_jobs_partial2", where: "(((type)::text = 'Ci::Build'::text) AND ((status)::text = ANY (ARRAY[('running'::character varying)::text, ('pending'::character varying)::text, ('created'::character varying)::text])))"
|
||||
t.index ["project_id"], name: "index_ci_builds_on_project_id_for_successfull_pages_deploy", where: "(((type)::text = 'GenericCommitStatus'::text) AND ((stage)::text = 'deploy'::text) AND ((name)::text = 'pages:deploy'::text) AND ((status)::text = 'success'::text))"
|
||||
t.index ["protected"], name: "index_ci_builds_on_protected"
|
||||
|
|
|
@ -53,7 +53,7 @@ Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/over
|
|||
|
||||
- This utility can help you check if one method would override
|
||||
another or not. It is the same concept as Java's `@Override` annotation
|
||||
or Scala's `override` keyword. However, you should only do this check when
|
||||
or Scala's `override` keyword. However, we only run this check when
|
||||
`ENV['STATIC_VERIFICATION']` is set to avoid production runtime overhead.
|
||||
This is useful for checking:
|
||||
|
||||
|
@ -94,6 +94,15 @@ Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/over
|
|||
end
|
||||
```
|
||||
|
||||
Note that the check will only happen when either:
|
||||
|
||||
- The overriding method is defined in a class, or:
|
||||
- The overriding method is defined in a module, and it's prepended to
|
||||
a class or a module.
|
||||
|
||||
Because only a class or prepended module can actually override a method.
|
||||
Including or extending a module into another cannot override anything.
|
||||
|
||||
## `StrongMemoize`
|
||||
|
||||
Refer to <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/utils/strong_memoize.rb>:
|
||||
|
|
|
@ -1672,7 +1672,7 @@ module API
|
|||
expose :artifacts, using: Artifacts
|
||||
expose :cache, using: Cache
|
||||
expose :credentials, using: Credentials
|
||||
expose :dependencies, using: Dependency
|
||||
expose :all_dependencies, as: :dependencies, using: Dependency
|
||||
expose :features
|
||||
end
|
||||
end
|
||||
|
|
|
@ -134,7 +134,7 @@ module Gitlab
|
|||
|
||||
entry :needs, Entry::Needs,
|
||||
description: 'Needs configuration for this job.',
|
||||
metadata: { allowed_needs: %i[job] },
|
||||
metadata: { allowed_needs: %i[job cross_dependency] },
|
||||
inherit: false
|
||||
|
||||
entry :variables, Entry::Variables,
|
||||
|
|
|
@ -6,7 +6,9 @@ module Gitlab
|
|||
module Entry
|
||||
class Need < ::Gitlab::Config::Entry::Simplifiable
|
||||
strategy :JobString, if: -> (config) { config.is_a?(String) }
|
||||
strategy :JobHash, if: -> (config) { config.is_a?(Hash) && config.key?(:job) }
|
||||
|
||||
strategy :JobHash,
|
||||
if: -> (config) { config.is_a?(Hash) && config.key?(:job) && !(config.key?(:project) || config.key?(:ref)) }
|
||||
|
||||
class JobString < ::Gitlab::Config::Entry::Node
|
||||
include ::Gitlab::Config::Entry::Validatable
|
||||
|
|
|
@ -53,3 +53,5 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
::Gitlab::Ci::Config::Entry::Needs.prepend_if_ee('::EE::Gitlab::Ci::Config::Entry::Needs')
|
||||
|
|
|
@ -69,6 +69,7 @@ module Gitlab
|
|||
services: job[:services],
|
||||
artifacts: job[:artifacts],
|
||||
dependencies: job[:dependencies],
|
||||
cross_dependencies: job.dig(:needs, :cross_dependency),
|
||||
job_timeout: job[:timeout],
|
||||
before_script: job[:before_script],
|
||||
script: job[:script],
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
module Gitlab
|
||||
module ImportExport
|
||||
class AttributeCleaner
|
||||
ALLOWED_REFERENCES = RelationFactory::PROJECT_REFERENCES + RelationFactory::USER_REFERENCES + %w[group_id commit_id]
|
||||
ALLOWED_REFERENCES = RelationFactory::PROJECT_REFERENCES + RelationFactory::USER_REFERENCES + %w[group_id commit_id discussion_id]
|
||||
PROHIBITED_REFERENCES = Regexp.union(/\Acached_markdown_version\Z/, /_id\Z/, /_ids\Z/, /_html\Z/).freeze
|
||||
|
||||
def self.clean(*args)
|
||||
|
|
|
@ -172,24 +172,36 @@ excluded_attributes:
|
|||
- :external_diff
|
||||
- :stored_externally
|
||||
- :external_diff_store
|
||||
- :merge_request_id
|
||||
merge_request_diff_commits:
|
||||
- :merge_request_diff_id
|
||||
merge_request_diff_files:
|
||||
- :diff
|
||||
- :external_diff_offset
|
||||
- :external_diff_size
|
||||
- :merge_request_diff_id
|
||||
issues:
|
||||
- :milestone_id
|
||||
- :moved_to_id
|
||||
- :state_id
|
||||
- :duplicated_to_id
|
||||
- :promoted_to_epic_id
|
||||
merge_request:
|
||||
- :milestone_id
|
||||
- :ref_fetched
|
||||
- :merge_jid
|
||||
- :rebase_jid
|
||||
- :latest_merge_request_diff_id
|
||||
- :head_pipeline_id
|
||||
- :state_id
|
||||
merge_requests:
|
||||
- :milestone_id
|
||||
- :ref_fetched
|
||||
- :merge_jid
|
||||
- :rebase_jid
|
||||
- :latest_merge_request_diff_id
|
||||
- :head_pipeline_id
|
||||
- :state_id
|
||||
award_emoji:
|
||||
- :awardable_id
|
||||
statuses:
|
||||
|
@ -203,6 +215,16 @@ excluded_attributes:
|
|||
- :artifacts_metadata_store
|
||||
- :artifacts_size
|
||||
- :commands
|
||||
- :runner_id
|
||||
- :trigger_request_id
|
||||
- :erased_by_id
|
||||
- :auto_canceled_by_id
|
||||
- :stage_id
|
||||
- :upstream_pipeline_id
|
||||
- :resource_group_id
|
||||
- :waiting_for_resource_at
|
||||
sentry_issue:
|
||||
- :issue_id
|
||||
push_event_payload:
|
||||
- :event_id
|
||||
project_badges:
|
||||
|
@ -211,6 +233,9 @@ excluded_attributes:
|
|||
- :reference
|
||||
- :reference_html
|
||||
- :epic_id
|
||||
- :issue_id
|
||||
- :merge_request_id
|
||||
- :label_id
|
||||
runners:
|
||||
- :token
|
||||
- :token_encrypted
|
||||
|
@ -222,7 +247,64 @@ excluded_attributes:
|
|||
- :enabled
|
||||
service_desk_setting:
|
||||
- :outgoing_name
|
||||
|
||||
priorities:
|
||||
- :label_id
|
||||
events:
|
||||
- :target_id
|
||||
timelogs:
|
||||
- :issue_id
|
||||
- :merge_request_id
|
||||
notes:
|
||||
- :noteable_id
|
||||
- :review_id
|
||||
label_links:
|
||||
- :label_id
|
||||
- :target_id
|
||||
issue_assignees:
|
||||
- :issue_id
|
||||
zoom_meetings:
|
||||
- :issue_id
|
||||
design:
|
||||
- :issue_id
|
||||
designs:
|
||||
- :issue_id
|
||||
design_versions:
|
||||
- :issue_id
|
||||
actions:
|
||||
- :design_id
|
||||
- :version_id
|
||||
links:
|
||||
- :release_id
|
||||
project_members:
|
||||
- :source_id
|
||||
metrics:
|
||||
- :merge_request_id
|
||||
- :pipeline_id
|
||||
suggestions:
|
||||
- :note_id
|
||||
ci_pipelines:
|
||||
- :auto_canceled_by_id
|
||||
- :pipeline_schedule_id
|
||||
- :merge_request_id
|
||||
- :external_pull_request_id
|
||||
stages:
|
||||
- :pipeline_id
|
||||
merge_access_levels:
|
||||
- :protected_branch_id
|
||||
push_access_levels:
|
||||
- :protected_branch_id
|
||||
unprotect_access_levels:
|
||||
- :protected_branch_id
|
||||
create_access_levels:
|
||||
- :protected_tag_id
|
||||
deploy_access_levels:
|
||||
- :protected_environment_id
|
||||
boards:
|
||||
- :milestone_id
|
||||
lists:
|
||||
- :board_id
|
||||
- :label_id
|
||||
- :milestone_id
|
||||
methods:
|
||||
notes:
|
||||
- :type
|
||||
|
|
|
@ -146,7 +146,8 @@ module Gitlab
|
|||
def prepended(base = nil)
|
||||
super
|
||||
|
||||
queue_verification(base) if base
|
||||
# prepend can override methods, thus we need to verify it like classes
|
||||
queue_verification(base, verify: true) if base
|
||||
end
|
||||
|
||||
def extended(mod = nil)
|
||||
|
@ -155,11 +156,15 @@ module Gitlab
|
|||
queue_verification(mod.singleton_class) if mod
|
||||
end
|
||||
|
||||
def queue_verification(base)
|
||||
def queue_verification(base, verify: false)
|
||||
return unless ENV['STATIC_VERIFICATION']
|
||||
|
||||
if base.is_a?(Class) # We could check for Class in `override`
|
||||
# This could be `nil` if `override` was never called
|
||||
# We could check for Class in `override`
|
||||
# This could be `nil` if `override` was never called.
|
||||
# We also force verification for prepend because it can also override
|
||||
# a method like a class, but not the cases for include or extend.
|
||||
# This includes Rails helpers but not limited to.
|
||||
if base.is_a?(Class) || verify
|
||||
Override.extensions[self]&.add_class(base)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3790,13 +3790,13 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Create cluster on"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Create new Cluster"
|
||||
msgid "ClusterIntegration|Create new cluster"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Create new Cluster on EKS"
|
||||
msgid "ClusterIntegration|Create new cluster on EKS"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Create new Cluster on GKE"
|
||||
msgid "ClusterIntegration|Create new cluster on GKE"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Creating Kubernetes cluster"
|
||||
|
|
|
@ -39,9 +39,9 @@
|
|||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/plugin-syntax-import-meta": "^7.2.0",
|
||||
"@babel/preset-env": "^7.6.2",
|
||||
"@gitlab/svgs": "^1.85.0",
|
||||
"@gitlab/ui": "8.2.0",
|
||||
"@gitlab/visual-review-tools": "1.2.0",
|
||||
"@gitlab/svgs": "^1.88.0",
|
||||
"@gitlab/ui": "8.8.0",
|
||||
"@gitlab/visual-review-tools": "1.5.1",
|
||||
"@sentry/browser": "^5.10.2",
|
||||
"@sourcegraph/code-host-integration": "^0.0.14",
|
||||
"apollo-cache-inmemory": "^1.6.3",
|
||||
|
|
|
@ -8,17 +8,9 @@ module QA
|
|||
before do
|
||||
Flow::Login.sign_in
|
||||
|
||||
project = Resource::Project.fabricate_via_api! do |resource|
|
||||
resource.name = 'project-for-issue-suggestions'
|
||||
resource.description = 'project for issue suggestions'
|
||||
end
|
||||
|
||||
Resource::Issue.fabricate_via_api! do |issue|
|
||||
issue.title = issue_title
|
||||
issue.project = project
|
||||
end
|
||||
|
||||
project.visit!
|
||||
end.project.visit!
|
||||
end
|
||||
|
||||
it 'user sees issue suggestions when creating a new issue' do
|
||||
|
|
|
@ -22,7 +22,7 @@ describe 'Instance-level AWS EKS Cluster', :js do
|
|||
end
|
||||
|
||||
it 'user sees a form to create an EKS cluster' do
|
||||
expect(page).to have_content('Create new Cluster on EKS')
|
||||
expect(page).to have_content('Create new cluster on EKS')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ describe 'Group AWS EKS Cluster', :js do
|
|||
end
|
||||
|
||||
it 'user sees a form to create an EKS cluster' do
|
||||
expect(page).to have_content('Create new Cluster on EKS')
|
||||
expect(page).to have_content('Create new cluster on EKS')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ describe 'AWS EKS Cluster', :js do
|
|||
end
|
||||
|
||||
it 'user sees a form to create an EKS cluster' do
|
||||
expect(page).to have_content('Create new Cluster on EKS')
|
||||
expect(page).to have_content('Create new cluster on EKS')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
|
|||
visit project_clusters_path(project)
|
||||
|
||||
click_link 'Add Kubernetes cluster'
|
||||
click_link 'Create new Cluster'
|
||||
click_link 'Create new cluster'
|
||||
click_link 'Google GKE'
|
||||
end
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ describe 'Clusters', :js do
|
|||
visit project_clusters_path(project)
|
||||
|
||||
click_link 'Add Kubernetes cluster'
|
||||
click_link 'Create new Cluster'
|
||||
click_link 'Create new cluster'
|
||||
end
|
||||
|
||||
it 'user sees a link to create a GKE cluster' do
|
||||
|
|
|
@ -12,8 +12,6 @@ describe 'Import/Export - project export integration test', :js do
|
|||
|
||||
let(:user) { create(:admin) }
|
||||
let(:export_path) { "#{Dir.tmpdir}/import_file_spec" }
|
||||
let(:config_hash) { Gitlab::ImportExport::Config.new.to_h.deep_stringify_keys }
|
||||
|
||||
let(:sensitive_words) { %w[pass secret token key encrypted html] }
|
||||
let(:safe_list) do
|
||||
{
|
||||
|
|
|
@ -37,25 +37,25 @@ describe ClustersHelper do
|
|||
context 'GCP provider' do
|
||||
let(:provider) { 'gcp' }
|
||||
|
||||
it { is_expected.to eq('Create new Cluster on GKE') }
|
||||
it { is_expected.to eq('Create new cluster on GKE') }
|
||||
end
|
||||
|
||||
context 'AWS provider' do
|
||||
let(:provider) { 'aws' }
|
||||
|
||||
it { is_expected.to eq('Create new Cluster on EKS') }
|
||||
it { is_expected.to eq('Create new cluster on EKS') }
|
||||
end
|
||||
|
||||
context 'other provider' do
|
||||
let(:provider) { 'other' }
|
||||
|
||||
it { is_expected.to eq('Create new Cluster') }
|
||||
it { is_expected.to eq('Create new cluster') }
|
||||
end
|
||||
|
||||
context 'no provider' do
|
||||
let(:provider) { nil }
|
||||
|
||||
it { is_expected.to eq('Create new Cluster') }
|
||||
it { is_expected.to eq('Create new cluster') }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,21 +12,11 @@ require 'spec_helper'
|
|||
describe 'Import/Export attribute configuration' do
|
||||
include ConfigurationHelper
|
||||
|
||||
let(:config_hash) { Gitlab::ImportExport::Config.new.to_h.deep_stringify_keys }
|
||||
let(:relation_names) do
|
||||
names = names_from_tree(config_hash.dig('tree', 'project'))
|
||||
|
||||
# Remove duplicated or add missing models
|
||||
# - project is not part of the tree, so it has to be added manually.
|
||||
# - milestone, labels have both singular and plural versions in the tree, so remove the duplicates.
|
||||
names.flatten.uniq - %w(milestones labels) + ['project']
|
||||
end
|
||||
|
||||
let(:safe_attributes_file) { 'spec/lib/gitlab/import_export/safe_model_attributes.yml' }
|
||||
let(:safe_model_attributes) { YAML.load_file(safe_attributes_file) }
|
||||
|
||||
it 'has no new columns' do
|
||||
relation_names.each do |relation_name|
|
||||
relation_names_for(:project).each do |relation_name|
|
||||
relation_class = relation_class_for_name(relation_name)
|
||||
relation_attributes = relation_class.new.attributes.keys - relation_class.encrypted_attributes.keys.map(&:to_s)
|
||||
|
||||
|
|
|
@ -8,19 +8,10 @@ require 'spec_helper'
|
|||
describe 'Import/Export model configuration' do
|
||||
include ConfigurationHelper
|
||||
|
||||
let(:config_hash) { Gitlab::ImportExport::Config.new.to_h.deep_stringify_keys }
|
||||
let(:model_names) do
|
||||
names = names_from_tree(config_hash.dig('tree', 'project'))
|
||||
|
||||
# Remove duplicated or add missing models
|
||||
# - project is not part of the tree, so it has to be added manually.
|
||||
# - milestone, labels, merge_request have both singular and plural versions in the tree, so remove the duplicates.
|
||||
# - User, Author... Models we do not care about for checking models
|
||||
names.flatten.uniq - %w(milestones labels user author merge_request) + ['project']
|
||||
end
|
||||
let(:all_models_yml) { 'spec/lib/gitlab/import_export/all_models.yml' }
|
||||
let(:all_models_hash) { YAML.load_file(all_models_yml) }
|
||||
let(:current_models) { setup_models }
|
||||
let(:model_names) { relation_names_for(:project) }
|
||||
|
||||
it 'has no new models' do
|
||||
model_names.each do |model_name|
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
# Part of the test security suite for the Import/Export feature
|
||||
# Checks whether there are new reference attributes ending with _id in models that are currently being exported as part of the
|
||||
# project Import/Export feature.
|
||||
# If there are new references (foreign keys), these will have to either be replaced with actual relation
|
||||
# or to be blacklisted by using the import_export.yml configuration file.
|
||||
# Likewise, new models added to import_export.yml, will need to be added with their correspondent relations
|
||||
# to this spec.
|
||||
describe 'Import/Export Project configuration' do
|
||||
include ConfigurationHelper
|
||||
|
||||
where(:relation_path, :relation_name) do
|
||||
relation_paths_for(:project).map do |relation_names|
|
||||
next if relation_names.last == :author
|
||||
|
||||
[relation_names.join("."), relation_names.last]
|
||||
end.compact
|
||||
end
|
||||
|
||||
with_them do
|
||||
context "where relation #{params[:relation_path]}" do
|
||||
it 'does not have prohibited keys' do
|
||||
relation_class = relation_class_for_name(relation_name)
|
||||
relation_attributes = relation_class.new.attributes.keys - relation_class.encrypted_attributes.keys.map(&:to_s)
|
||||
current_attributes = parsed_attributes(relation_name, relation_attributes)
|
||||
prohibited_keys = current_attributes.select do |attribute|
|
||||
prohibited_key?(attribute) || !relation_class.attribute_method?(attribute)
|
||||
end
|
||||
expect(prohibited_keys).to be_empty, failure_message(relation_class.to_s, prohibited_keys)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def failure_message(relation_class, prohibited_keys)
|
||||
<<-MSG
|
||||
It looks like #{relation_class}, which is exported using the project Import/Export, has references: #{prohibited_keys.join(',')}
|
||||
|
||||
Please replace it with actual relation in IMPORT_EXPORT_CONFIG if you consider this can be exported.
|
||||
Please blacklist the attribute(s) in IMPORT_EXPORT_CONFIG by adding it to its correspondent
|
||||
model in the +excluded_attributes+ section.
|
||||
|
||||
IMPORT_EXPORT_CONFIG: #{Gitlab::ImportExport.config_file}
|
||||
MSG
|
||||
end
|
||||
end
|
|
@ -33,7 +33,6 @@ Issue:
|
|||
Event:
|
||||
- id
|
||||
- target_type
|
||||
- target_id
|
||||
- project_id
|
||||
- group_id
|
||||
- created_at
|
||||
|
@ -60,7 +59,6 @@ Note:
|
|||
- attachment
|
||||
- line_code
|
||||
- commit_id
|
||||
- noteable_id
|
||||
- system
|
||||
- st_diff
|
||||
- updated_by_id
|
||||
|
@ -73,11 +71,8 @@ Note:
|
|||
- resolved_by_push
|
||||
- discussion_id
|
||||
- original_discussion_id
|
||||
- review_id
|
||||
LabelLink:
|
||||
- id
|
||||
- label_id
|
||||
- target_id
|
||||
- target_type
|
||||
- created_at
|
||||
- updated_at
|
||||
|
@ -130,13 +125,11 @@ Release:
|
|||
- released_at
|
||||
Evidence:
|
||||
- id
|
||||
- release_id
|
||||
- summary
|
||||
- created_at
|
||||
- updated_at
|
||||
Releases::Link:
|
||||
- id
|
||||
- release_id
|
||||
- url
|
||||
- name
|
||||
- created_at
|
||||
|
@ -144,7 +137,6 @@ Releases::Link:
|
|||
ProjectMember:
|
||||
- id
|
||||
- access_level
|
||||
- source_id
|
||||
- source_type
|
||||
- user_id
|
||||
- notification_level
|
||||
|
@ -600,7 +592,6 @@ AwardEmoji:
|
|||
LabelPriority:
|
||||
- id
|
||||
- project_id
|
||||
- label_id
|
||||
- priority
|
||||
- created_at
|
||||
- updated_at
|
||||
|
@ -608,7 +599,6 @@ Timelog:
|
|||
- id
|
||||
- time_spent
|
||||
- merge_request_id
|
||||
- issue_id
|
||||
- user_id
|
||||
- spent_at
|
||||
- created_at
|
||||
|
@ -623,7 +613,6 @@ ProjectAutoDevops:
|
|||
- updated_at
|
||||
IssueAssignee:
|
||||
- user_id
|
||||
- issue_id
|
||||
ProjectCustomAttribute:
|
||||
- id
|
||||
- created_at
|
||||
|
@ -679,7 +668,6 @@ ProtectedEnvironment::DeployAccessLevel:
|
|||
ResourceLabelEvent:
|
||||
- id
|
||||
- action
|
||||
- issue_id
|
||||
- merge_request_id
|
||||
- label_id
|
||||
- user_id
|
||||
|
@ -691,11 +679,9 @@ ErrorTracking::ProjectErrorTrackingSetting:
|
|||
- organization_name
|
||||
SentryIssue:
|
||||
- id
|
||||
- issue_id
|
||||
- sentry_issue_identifier
|
||||
Suggestion:
|
||||
- id
|
||||
- note_id
|
||||
- relative_order
|
||||
- applied
|
||||
- commit_id
|
||||
|
@ -750,21 +736,16 @@ ExternalPullRequest:
|
|||
DesignManagement::Design:
|
||||
- id
|
||||
- project_id
|
||||
- issue_id
|
||||
- filename
|
||||
DesignManagement::Action:
|
||||
- design_id
|
||||
- event
|
||||
- version_id
|
||||
DesignManagement::Version:
|
||||
- id
|
||||
- created_at
|
||||
- sha
|
||||
- issue_id
|
||||
- author_id
|
||||
ZoomMeeting:
|
||||
- id
|
||||
- issue_id
|
||||
- project_id
|
||||
- issue_status
|
||||
- url
|
||||
|
|
|
@ -815,6 +815,27 @@ describe Ci::Build do
|
|||
it { is_expected.to contain_exactly(build, rspec_test, rubocop_test, staging) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#all_dependencies' do
|
||||
let!(:final_build) do
|
||||
create(:ci_build,
|
||||
pipeline: pipeline, name: 'deploy',
|
||||
stage_idx: 3, stage: 'deploy'
|
||||
)
|
||||
end
|
||||
|
||||
subject { final_build.all_dependencies }
|
||||
|
||||
it 'returns dependencies and cross_dependencies' do
|
||||
dependencies = [1, 2, 3]
|
||||
cross_dependencies = [3, 4]
|
||||
|
||||
allow(final_build).to receive(:dependencies).and_return(dependencies)
|
||||
allow(final_build).to receive(:cross_dependencies).and_return(cross_dependencies)
|
||||
|
||||
is_expected.to match(a_collection_containing_exactly(1, 2, 3, 4))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#triggered_by?' do
|
||||
|
|
|
@ -312,6 +312,72 @@ describe CommitStatus do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.for_ref' do
|
||||
subject { described_class.for_ref('bb').order(:id) }
|
||||
|
||||
let(:statuses) do
|
||||
[create_status(ref: 'aa'),
|
||||
create_status(ref: 'bb'),
|
||||
create_status(ref: 'cc')]
|
||||
end
|
||||
|
||||
it 'returns statuses with the specified ref' do
|
||||
is_expected.to eq(statuses.values_at(1))
|
||||
end
|
||||
end
|
||||
|
||||
describe '.by_name' do
|
||||
subject { described_class.by_name('bb').order(:id) }
|
||||
|
||||
let(:statuses) do
|
||||
[create_status(name: 'aa'),
|
||||
create_status(name: 'bb'),
|
||||
create_status(name: 'cc')]
|
||||
end
|
||||
|
||||
it 'returns statuses with the specified name' do
|
||||
is_expected.to eq(statuses.values_at(1))
|
||||
end
|
||||
end
|
||||
|
||||
describe '.for_project_paths' do
|
||||
subject do
|
||||
described_class
|
||||
.for_project_paths(paths)
|
||||
.order(:id)
|
||||
end
|
||||
|
||||
context 'with a single path' do
|
||||
let(:other_project) { create(:project, :repository) }
|
||||
let(:paths) { other_project.full_path }
|
||||
|
||||
let(:other_pipeline) do
|
||||
create(:ci_pipeline, project: other_project, sha: other_project.commit.id)
|
||||
end
|
||||
|
||||
let(:statuses) do
|
||||
[create_status(pipeline: pipeline),
|
||||
create_status(pipeline: other_pipeline)]
|
||||
end
|
||||
|
||||
it 'returns statuses for other_project' do
|
||||
is_expected.to eq(statuses.values_at(1))
|
||||
end
|
||||
end
|
||||
|
||||
context 'with array of paths' do
|
||||
let(:paths) { [project.full_path] }
|
||||
|
||||
let(:statuses) do
|
||||
[create_status(pipeline: pipeline)]
|
||||
end
|
||||
|
||||
it 'returns statuses for project' do
|
||||
is_expected.to eq(statuses.values_at(0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.status' do
|
||||
context 'when there are multiple statuses present' do
|
||||
before do
|
||||
|
|
|
@ -10,21 +10,54 @@ module ConfigurationHelper
|
|||
end
|
||||
end
|
||||
|
||||
def all_relations(tree, tree_path = [])
|
||||
tree.flat_map do |relation_name, relations|
|
||||
relation_path = tree_path + [relation_name]
|
||||
[relation_path] + all_relations(relations, relation_path)
|
||||
end
|
||||
end
|
||||
|
||||
def config_hash(config = Gitlab::ImportExport.config_file)
|
||||
Gitlab::ImportExport::Config.new(config: config).to_h
|
||||
end
|
||||
|
||||
def relation_paths_for(key, config: Gitlab::ImportExport.config_file)
|
||||
# - project is not part of the tree, so it has to be added manually.
|
||||
all_relations({ project: config_hash(config).dig(:tree, key) })
|
||||
end
|
||||
|
||||
def relation_names_for(key, config: Gitlab::ImportExport.config_file)
|
||||
names = names_from_tree(config_hash(config).dig(:tree, key))
|
||||
# Remove duplicated or add missing models
|
||||
# - project is not part of the tree, so it has to be added manually.
|
||||
# - milestone, labels, merge_request have both singular and plural versions in the tree, so remove the duplicates.
|
||||
# - User, Author... Models we do not care about for checking models
|
||||
names.flatten.uniq - %w(milestones labels user author merge_request design) + [key.to_s]
|
||||
end
|
||||
|
||||
def relation_class_for_name(relation_name)
|
||||
relation_name = Gitlab::ImportExport::RelationFactory.overrides[relation_name.to_sym] || relation_name
|
||||
Gitlab::ImportExport::RelationFactory.relation_class(relation_name)
|
||||
end
|
||||
|
||||
def parsed_attributes(relation_name, attributes)
|
||||
excluded_attributes = config_hash['excluded_attributes'][relation_name]
|
||||
included_attributes = config_hash['included_attributes'][relation_name]
|
||||
|
||||
def parsed_attributes(relation_name, attributes, config: Gitlab::ImportExport.config_file)
|
||||
import_export_config = config_hash(config)
|
||||
excluded_attributes = import_export_config[:excluded_attributes][relation_name.to_sym]
|
||||
included_attributes = import_export_config[:included_attributes][relation_name.to_sym]
|
||||
attributes = attributes - JSON[excluded_attributes.to_json] if excluded_attributes
|
||||
attributes = attributes & JSON[included_attributes.to_json] if included_attributes
|
||||
|
||||
attributes
|
||||
end
|
||||
|
||||
def prohibited_key?(key)
|
||||
key =~ Gitlab::ImportExport::AttributeCleaner::PROHIBITED_REFERENCES && !permitted_key?(key)
|
||||
end
|
||||
|
||||
def permitted_key?(key)
|
||||
Gitlab::ImportExport::AttributeCleaner::ALLOWED_REFERENCES.include?(key)
|
||||
end
|
||||
|
||||
def associations_for(safe_model)
|
||||
safe_model.reflect_on_all_associations.map { |assoc| assoc.name.to_s }
|
||||
end
|
||||
|
|
24
yarn.lock
24
yarn.lock
|
@ -732,15 +732,15 @@
|
|||
dependencies:
|
||||
vue-eslint-parser "^6.0.4"
|
||||
|
||||
"@gitlab/svgs@^1.85.0":
|
||||
version "1.85.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.85.0.tgz#c80247ec4764824385df2837136a0d4a84f881dc"
|
||||
integrity sha512-yzvKut0MPJEbSx/LExopCLpF5KEZsckF+d/Blbji1VqODVanH85oIVuJNmdECUlc7qxye9Or3evpFjW9Pkshmg==
|
||||
"@gitlab/svgs@^1.88.0":
|
||||
version "1.88.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.88.0.tgz#0a9b72e9591264fcac592ebf9944665c70f48de2"
|
||||
integrity sha512-ZgepCvZoB/lFdgttHtu8+9YlRZlVc9MnHDbbqcQCFBvrfOjY1wq12ikxnNbwKj8QNA47TRJvSS0TkHgMWYnbsA==
|
||||
|
||||
"@gitlab/ui@8.2.0":
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-8.2.0.tgz#82cf512407f8a774878969c72c4227d08ce49aa6"
|
||||
integrity sha512-ZzxA3XwmwZpol6QJjqBf3Oblb1wSFbDJ4QENvPiE9lAUHvhbe8wfKBK++RtgOtd6aXtLvoY1o1Du9qill07Jvg==
|
||||
"@gitlab/ui@8.8.0":
|
||||
version "8.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-8.8.0.tgz#c22b4dece89d224c525b3510970f3c61321a6765"
|
||||
integrity sha512-fjAGSgfau28iq+Uhivc5OPwu3ZLUL25gFuW1rKeQFgnkVEaQ9IRvdM8RD9+kgXWUsccsrafQkz/nOUmp85o8yQ==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
"@gitlab/vue-toasted" "^1.3.0"
|
||||
|
@ -755,10 +755,10 @@
|
|||
vue "^2.6.10"
|
||||
vue-loader "^15.4.2"
|
||||
|
||||
"@gitlab/visual-review-tools@1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/visual-review-tools/-/visual-review-tools-1.2.0.tgz#8d6757917193c1023012bb4a316dc1a97309a27a"
|
||||
integrity sha512-GaV/lYLmOF0hWtv8K8MLWGaCZ7PL1LF4D0/gargXYf9HO0Cw4wtz4oWyaLS15wFposJIYdPIHSNfrLVk4Dk9sQ==
|
||||
"@gitlab/visual-review-tools@1.5.1":
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/visual-review-tools/-/visual-review-tools-1.5.1.tgz#2552927cd7a376f1f06ef3293a69fe2ffcdddb52"
|
||||
integrity sha512-8d6xgK4TsLA5gucd78jzaMyginAMJ8cbu/6ghUGws84zzAEsyJsMTstyt/fA5l4toQXVxtOh90BvDzwxSjZ6hQ==
|
||||
|
||||
"@gitlab/vue-toasted@^1.3.0":
|
||||
version "1.3.0"
|
||||
|
|
Loading…
Reference in a new issue