Skip to content
Snippets Groups Projects
Commit 143f196f authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 575ccb03
No related branches found
No related tags found
No related merge requests found
Showing
with 230 additions and 136 deletions
Loading
Loading
@@ -10,7 +10,9 @@ module Gitlab
:trigger_request, :schedule, :merge_request, :external_pull_request,
:ignore_skip_ci, :save_incompleted,
:seeds_block, :variables_attributes, :push_options,
:chat_data, :allow_mirror_update
:chat_data, :allow_mirror_update,
# These attributes are set by Chains during processing:
:config_content, :config_processor, :stage_seeds
) do
include Gitlab::Utils::StrongMemoize
 
Loading
Loading
# frozen_string_literal: true
module Gitlab
module Ci
module Pipeline
module Chain
module Config
class Content < Chain::Base
include Chain::Helpers
def perform!
return if @command.config_content
if content = content_from_repo
@command.config_content = content
@pipeline.config_source = :repository_source
# TODO: we should persist ci_config_path
# @pipeline.config_path = ci_config_path
elsif content = content_from_auto_devops
@command.config_content = content
@pipeline.config_source = :auto_devops_source
end
unless @command.config_content
return error("Missing #{ci_config_path} file")
end
end
def break?
@pipeline.errors.any? || @pipeline.persisted?
end
private
def content_from_repo
return unless project
return unless @pipeline.sha
return unless ci_config_path
project.repository.gitlab_ci_yml_for(@pipeline.sha, ci_config_path)
rescue GRPC::NotFound, GRPC::Internal
nil
end
def content_from_auto_devops
return unless project&.auto_devops_enabled?
Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps').content
end
def ci_config_path
project.ci_config_path.presence || '.gitlab-ci.yml'
end
end
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Ci
module Pipeline
module Chain
module Config
class Process < Chain::Base
include Chain::Helpers
def perform!
raise ArgumentError, 'missing config content' unless @command.config_content
@command.config_processor = ::Gitlab::Ci::YamlProcessor.new(
@command.config_content, {
project: project,
sha: @pipeline.sha,
user: current_user
}
)
rescue Gitlab::Ci::YamlProcessor::ValidationError => ex
error(ex.message, config_error: true)
rescue => ex
Gitlab::Sentry.track_acceptable_exception(ex, extra: {
project_id: project.id,
sha: @pipeline.sha
})
error("Undefined error (#{Labkit::Correlation::CorrelationId.current_id})",
config_error: true)
end
def break?
@pipeline.errors.any? || @pipeline.persisted?
end
end
end
end
end
end
end
Loading
Loading
@@ -41,7 +41,7 @@ module Gitlab
end
 
def workflow_config
@pipeline.config_processor.workflow_attributes || {}
@command.config_processor.workflow_attributes || {}
end
end
end
Loading
Loading
Loading
Loading
@@ -10,29 +10,12 @@ module Gitlab
PopulateError = Class.new(StandardError)
 
def perform!
# Allocate next IID. This operation must be outside of transactions of pipeline creations.
pipeline.ensure_project_iid!
# Protect the pipeline. This is assigned in Populate instead of
# Build to prevent erroring out on ambiguous refs.
pipeline.protected = @command.protected_ref?
##
# Populate pipeline with block argument of CreatePipelineService#execute.
#
@command.seeds_block&.call(pipeline)
##
# Gather all runtime build/stage errors
#
if seeds_errors = pipeline.stage_seeds.flat_map(&:errors).compact.presence
return error(seeds_errors.join("\n"), config_error: true)
end
raise ArgumentError, 'missing stage seeds' unless @command.stage_seeds
 
##
# Populate pipeline with all stages, and stages with builds.
#
pipeline.stages = pipeline.stage_seeds.map(&:to_resource)
pipeline.stages = @command.stage_seeds.map(&:to_resource)
 
if pipeline.stages.none?
return error('No stages / jobs for this pipeline.')
Loading
Loading
Loading
Loading
@@ -6,11 +6,13 @@ module Gitlab
module Chain
class RemoveUnwantedChatJobs < Chain::Base
def perform!
return unless pipeline.config_processor && pipeline.chat?
raise ArgumentError, 'missing config processor' unless @command.config_processor
return unless pipeline.chat?
 
# When scheduling a chat pipeline we only want to run the build
# that matches the chat command.
pipeline.config_processor.jobs.select! do |name, _|
@command.config_processor.jobs.select! do |name, _|
name.to_s == command.chat_data[:command].to_s
end
end
Loading
Loading
# frozen_string_literal: true
module Gitlab
module Ci
module Pipeline
module Chain
class Seed < Chain::Base
include Chain::Helpers
include Gitlab::Utils::StrongMemoize
def perform!
raise ArgumentError, 'missing config processor' unless @command.config_processor
# Allocate next IID. This operation must be outside of transactions of pipeline creations.
pipeline.ensure_project_iid!
# Protect the pipeline. This is assigned in Populate instead of
# Build to prevent erroring out on ambiguous refs.
pipeline.protected = @command.protected_ref?
##
# Populate pipeline with block argument of CreatePipelineService#execute.
#
@command.seeds_block&.call(pipeline)
##
# Gather all runtime build/stage errors
#
if stage_seeds_errors
return error(stage_seeds_errors.join("\n"), config_error: true)
end
@command.stage_seeds = stage_seeds
end
def break?
pipeline.errors.any?
end
private
def stage_seeds_errors
stage_seeds.flat_map(&:errors).compact.presence
end
def stage_seeds
strong_memoize(:stage_seeds) do
seeds = stages_attributes.inject([]) do |previous_stages, attributes|
seed = Gitlab::Ci::Pipeline::Seed::Stage.new(pipeline, attributes, previous_stages)
previous_stages + [seed]
end
seeds.select(&:included?)
end
end
def stages_attributes
@command.config_processor.stages_attributes
end
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Ci
module Pipeline
module Chain
module Validate
class Config < Chain::Base
include Chain::Helpers
def perform!
unless @pipeline.config_processor
unless @pipeline.ci_yaml_file
return error("Missing #{@pipeline.ci_yaml_file_path} file")
end
if @command.save_incompleted && @pipeline.has_yaml_errors?
@pipeline.drop!(:config_error)
end
error(@pipeline.yaml_errors)
end
end
def break?
@pipeline.errors.any? || @pipeline.persisted?
end
end
end
end
end
end
end
Loading
Loading
@@ -66,11 +66,13 @@ module Gitlab
def move_repositories(namespace, old_full_path, new_full_path)
repo_shards_for_namespace(namespace).each do |repository_storage|
# Ensure old directory exists before moving it
gitlab_shell.add_namespace(repository_storage, old_full_path)
Gitlab::GitalyClient::NamespaceService.allow do
gitlab_shell.add_namespace(repository_storage, old_full_path)
 
unless gitlab_shell.mv_namespace(repository_storage, old_full_path, new_full_path)
message = "Exception moving on shard #{repository_storage} from #{old_full_path} to #{new_full_path}"
Rails.logger.error message # rubocop:disable Gitlab/RailsLogger
unless gitlab_shell.mv_namespace(repository_storage, old_full_path, new_full_path)
message = "Exception moving on shard #{repository_storage} from #{old_full_path} to #{new_full_path}"
Rails.logger.error message # rubocop:disable Gitlab/RailsLogger
end
end
end
end
Loading
Loading
Loading
Loading
@@ -3,7 +3,22 @@
module Gitlab
module GitalyClient
class NamespaceService
extend Gitlab::TemporarilyAllow
NamespaceServiceAccessError = Class.new(StandardError)
ALLOW_KEY = :allow_namespace
def self.allow
temporarily_allow(ALLOW_KEY) { yield }
end
def self.denied?
!temporarily_allowed?(ALLOW_KEY)
end
def initialize(storage)
raise NamespaceServiceAccessError if self.class.denied?
@storage = storage
end
 
Loading
Loading
Loading
Loading
@@ -261,9 +261,6 @@ msgstr ""
msgid "%{from} to %{to}"
msgstr ""
 
msgid "%{gitlab_ci_yml} not found in this commit"
msgstr ""
msgid "%{group_docs_link_start}Groups%{group_docs_link_end} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""
 
Loading
Loading
@@ -908,6 +905,9 @@ msgstr ""
msgid "Add Kubernetes cluster"
msgstr ""
 
msgid "Add LICENSE"
msgstr ""
msgid "Add README"
msgstr ""
 
Loading
Loading
@@ -11947,6 +11947,9 @@ msgstr ""
msgid "Owner"
msgstr ""
 
msgid "Package deleted successfully"
msgstr ""
msgid "Package information"
msgstr ""
 
Loading
Loading
@@ -11965,10 +11968,10 @@ msgstr ""
msgid "PackageRegistry|Copy yarn setup command"
msgstr ""
 
msgid "PackageRegistry|Delete Package"
msgid "PackageRegistry|Delete Package Version"
msgstr ""
 
msgid "PackageRegistry|Delete Package Version"
msgid "PackageRegistry|Delete package"
msgstr ""
 
msgid "PackageRegistry|Installation"
Loading
Loading
Loading
Loading
@@ -12,7 +12,7 @@ module QA
fill_in 'password', with: QA::Runtime::Env.github_password
click_on 'Sign in'
 
Support::Retrier.retry_until(exit_on_failure: true) do
Support::Retrier.retry_until(exit_on_failure: true, sleep_interval: 35) do
otp = OnePassword::CLI.new.otp
 
fill_in 'otp', with: otp
Loading
Loading
Loading
Loading
@@ -157,39 +157,6 @@ describe 'Commits' do
end
end
end
describe '.gitlab-ci.yml not found warning' do
before do
project.add_reporter(user)
end
context 'ci builds enabled' do
it 'does not show warning' do
visit pipeline_path(pipeline)
expect(page).not_to have_content '.gitlab-ci.yml not found in this commit'
end
it 'shows warning' do
stub_ci_pipeline_yaml_file(nil)
visit pipeline_path(pipeline)
expect(page).to have_content '.gitlab-ci.yml not found in this commit'
end
end
context 'ci builds disabled' do
it 'does not show warning' do
stub_ci_builds_disabled
stub_ci_pipeline_yaml_file(nil)
visit pipeline_path(pipeline)
expect(page).not_to have_content '.gitlab-ci.yml not found in this commit'
end
end
end
end
 
context 'viewing commits for a branch' do
Loading
Loading
Loading
Loading
@@ -57,7 +57,7 @@ describe 'Sort Issuable List' do
it 'is "last updated"' do
visit_merge_requests_with_state(project, 'merged')
 
expect(find('.issues-other-filters')).to have_content('Last updated')
expect(find('.filter-dropdown-container')).to have_content('Last updated')
expect(first_merge_request).to include(last_updated_issuable.title)
expect(last_merge_request).to include(first_updated_issuable.title)
end
Loading
Loading
@@ -69,7 +69,7 @@ describe 'Sort Issuable List' do
it 'is "last updated"' do
visit_merge_requests_with_state(project, 'closed')
 
expect(find('.issues-other-filters')).to have_content('Last updated')
expect(find('.filter-dropdown-container')).to have_content('Last updated')
expect(first_merge_request).to include(last_updated_issuable.title)
expect(last_merge_request).to include(first_updated_issuable.title)
end
Loading
Loading
@@ -81,7 +81,7 @@ describe 'Sort Issuable List' do
it 'is "created date"' do
visit_merge_requests_with_state(project, 'all')
 
expect(find('.issues-other-filters')).to have_content('Created date')
expect(find('.filter-dropdown-container')).to have_content('Created date')
expect(first_merge_request).to include(last_created_issuable.title)
expect(last_merge_request).to include(first_created_issuable.title)
end
Loading
Loading
@@ -94,7 +94,7 @@ describe 'Sort Issuable List' do
it 'supports sorting in asc and desc order' do
visit_merge_requests_with_state(project, 'open')
 
page.within('.issues-other-filters') do
page.within('.filter-dropdown-container') do
click_button('Created date')
click_link('Last updated')
end
Loading
Loading
@@ -102,7 +102,7 @@ describe 'Sort Issuable List' do
expect(first_merge_request).to include(last_updated_issuable.title)
expect(last_merge_request).to include(first_updated_issuable.title)
 
find('.issues-other-filters .filter-dropdown-container .rspec-reverse-sort').click
find('.filter-dropdown-container .rspec-reverse-sort').click
 
expect(first_merge_request).to include(first_updated_issuable.title)
expect(last_merge_request).to include(last_updated_issuable.title)
Loading
Loading
@@ -133,7 +133,7 @@ describe 'Sort Issuable List' do
it 'is "created date"' do
visit_issues project
 
expect(find('.issues-other-filters')).to have_content('Created date')
expect(find('.filter-dropdown-container')).to have_content('Created date')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
Loading
Loading
@@ -145,7 +145,7 @@ describe 'Sort Issuable List' do
it 'is "created date"' do
visit_issues_with_state(project, 'open')
 
expect(find('.issues-other-filters')).to have_content('Created date')
expect(find('.filter-dropdown-container')).to have_content('Created date')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
Loading
Loading
@@ -157,7 +157,7 @@ describe 'Sort Issuable List' do
it 'is "last updated"' do
visit_issues_with_state(project, 'closed')
 
expect(find('.issues-other-filters')).to have_content('Last updated')
expect(find('.filter-dropdown-container')).to have_content('Last updated')
expect(first_issue).to include(last_updated_issuable.title)
expect(last_issue).to include(first_updated_issuable.title)
end
Loading
Loading
@@ -169,7 +169,7 @@ describe 'Sort Issuable List' do
it 'is "created date"' do
visit_issues_with_state(project, 'all')
 
expect(find('.issues-other-filters')).to have_content('Created date')
expect(find('.filter-dropdown-container')).to have_content('Created date')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
Loading
Loading
@@ -183,7 +183,7 @@ describe 'Sort Issuable List' do
end
 
it 'shows the sort order as created date' do
expect(find('.issues-other-filters')).to have_content('Created date')
expect(find('.filter-dropdown-container')).to have_content('Created date')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
Loading
Loading
@@ -196,7 +196,7 @@ describe 'Sort Issuable List' do
it 'supports sorting in asc and desc order' do
visit_issues_with_state(project, 'open')
 
page.within('.issues-other-filters') do
page.within('.filter-dropdown-container') do
click_button('Created date')
click_link('Last updated')
end
Loading
Loading
@@ -204,7 +204,7 @@ describe 'Sort Issuable List' do
expect(first_issue).to include(last_updated_issuable.title)
expect(last_issue).to include(first_updated_issuable.title)
 
find('.issues-other-filters .filter-dropdown-container .rspec-reverse-sort').click
find('.filter-dropdown-container .rspec-reverse-sort').click
 
expect(first_issue).to include(first_updated_issuable.title)
expect(last_issue).to include(last_updated_issuable.title)
Loading
Loading
Loading
Loading
@@ -56,10 +56,6 @@ describe 'User browses commits' do
project.enable_ci
 
create(:ci_build, pipeline: pipeline)
allow_next_instance_of(Ci::Pipeline) do |instance|
allow(instance).to receive(:ci_yaml_file).and_return('')
end
end
 
it 'renders commit ci info' do
Loading
Loading
Loading
Loading
@@ -7,13 +7,11 @@ describe 'Projects > Files > User views files page' do
let(:user) { project.owner }
 
before do
stub_feature_flags(vue_file_list: false)
sign_in user
visit project_tree_path(project, project.repository.root_ref)
end
 
it 'user sees folders and submodules sorted together, followed by files' do
it 'user sees folders and submodules sorted together, followed by files', :js do
rows = all('td.tree-item-file-name').map(&:text)
tree = project.repository.tree
 
Loading
Loading
Loading
Loading
@@ -7,7 +7,6 @@ describe 'Projects > Files > Project owner creates a license file', :js do
let(:project_maintainer) { project.owner }
 
before do
stub_feature_flags(vue_file_list: false)
project.repository.delete_file(project_maintainer, 'LICENSE',
message: 'Remove LICENSE', branch_name: 'master')
sign_in(project_maintainer)
Loading
Loading
@@ -39,7 +38,7 @@ describe 'Projects > Files > Project owner creates a license file', :js do
end
 
it 'project maintainer creates a license file from the "Add license" link' do
click_link 'Add license'
click_link 'Add LICENSE'
 
expect(page).to have_content('New file')
expect(current_path).to eq(
Loading
Loading
Loading
Loading
@@ -12,7 +12,7 @@ describe 'Projects > Files > Project owner sees a link to create a license file
 
it 'project maintainer creates a license file from a template' do
visit project_path(project)
click_on 'Add license'
click_on 'Add LICENSE'
expect(page).to have_content('New file')
 
expect(current_path).to eq(
Loading
Loading
Loading
Loading
@@ -13,23 +13,22 @@ describe "User browses files" do
let(:user) { project.owner }
 
before do
stub_feature_flags(vue_file_list: false)
sign_in(user)
end
 
it "shows last commit for current directory" do
it "shows last commit for current directory", :js do
visit(tree_path_root_ref)
 
click_link("files")
 
last_commit = project.repository.last_commit_for_path(project.default_branch, "files")
 
page.within(".blob-commit-info") do
page.within(".commit-detail") do
expect(page).to have_content(last_commit.short_id).and have_content(last_commit.author_name)
end
end
 
context "when browsing the master branch" do
context "when browsing the master branch", :js do
before do
visit(tree_path_root_ref)
end
Loading
Loading
@@ -124,8 +123,7 @@ describe "User browses files" do
expect(current_path).to eq(project_tree_path(project, "markdown/doc/raketasks"))
expect(page).to have_content("backup_restore.md").and have_content("maintenance.md")
 
click_link("shop")
click_link("Maintenance")
click_link("maintenance.md")
 
expect(current_path).to eq(project_blob_path(project, "markdown/doc/raketasks/maintenance.md"))
expect(page).to have_content("bundle exec rake gitlab:env:info RAILS_ENV=production")
Loading
Loading
@@ -144,7 +142,7 @@ describe "User browses files" do
 
# rubocop:disable Lint/Void
# Test the full URLs of links instead of relative paths by `have_link(text: "...", href: "...")`.
find("a", text: /^empty$/)["href"] == project_tree_url(project, "markdown/d")
find("a", text: "..")["href"] == project_tree_url(project, "markdown/d")
# rubocop:enable Lint/Void
 
page.within(".tree-table") do
Loading
Loading
@@ -168,7 +166,7 @@ describe "User browses files" do
end
end
 
context "when browsing a specific ref" do
context "when browsing a specific ref", :js do
let(:ref) { project_tree_path(project, "6d39438") }
 
before do
Loading
Loading
@@ -180,7 +178,7 @@ describe "User browses files" do
expect(page).to have_content(".gitignore").and have_content("LICENSE")
end
 
it "shows files from a repository with apostroph in its name", :js do
it "shows files from a repository with apostroph in its name" do
first(".js-project-refs-dropdown").click
 
page.within(".project-refs-form") do
Loading
Loading
@@ -191,10 +189,10 @@ describe "User browses files" do
 
visit(project_tree_path(project, "'test'"))
 
expect(page).to have_css(".tree-commit-link").and have_no_content("Loading commit data...")
expect(page).not_to have_selector(".tree-commit .animation-container")
end
 
it "shows the code with a leading dot in the directory", :js do
it "shows the code with a leading dot in the directory" do
first(".js-project-refs-dropdown").click
 
page.within(".project-refs-form") do
Loading
Loading
@@ -203,7 +201,7 @@ describe "User browses files" do
 
visit(project_tree_path(project, "fix/.testdir"))
 
expect(page).to have_css(".tree-commit-link").and have_no_content("Loading commit data...")
expect(page).not_to have_selector(".tree-commit .animation-container")
end
 
it "does not show the permalink link" do
Loading
Loading
@@ -221,7 +219,7 @@ describe "User browses files" do
click_link(".gitignore")
end
 
it "shows a file content", :js do
it "shows a file content" do
expect(page).to have_content("*.rbc")
end
 
Loading
Loading
Loading
Loading
@@ -7,8 +7,6 @@ describe 'Projects > Files > User browses LFS files' do
let(:user) { project.owner }
 
before do
stub_feature_flags(vue_file_list: false)
sign_in(user)
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment