Commit 5454016a authored by Valery Sizov's avatar Valery Sizov

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ee into ce_upstream

parents d08b1ed8 5b46f0fd
...@@ -192,9 +192,6 @@ import initGroupAnalytics from './init_group_analytics'; ...@@ -192,9 +192,6 @@ import initGroupAnalytics from './init_group_analytics';
const filteredSearchManager = new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests'); const filteredSearchManager = new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests');
filteredSearchManager.setup(); filteredSearchManager.setup();
} }
if (page === 'projects:merge_requests:index') {
new UserCallout({ setCalloutPerProject: true });
}
const pagePrefix = page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_'; const pagePrefix = page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_';
IssuableIndex.init(pagePrefix); IssuableIndex.init(pagePrefix);
...@@ -382,7 +379,10 @@ import initGroupAnalytics from './init_group_analytics'; ...@@ -382,7 +379,10 @@ import initGroupAnalytics from './init_group_analytics';
case 'projects:show': case 'projects:show':
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
new NotificationsForm(); new NotificationsForm();
new UserCallout({ setCalloutPerProject: true }); new UserCallout({
setCalloutPerProject: true,
className: 'js-autodevops-banner',
});
if ($('#tree-slider').length) new TreeView(); if ($('#tree-slider').length) new TreeView();
if ($('.blob-viewer').length) new BlobViewer(); if ($('.blob-viewer').length) new BlobViewer();
...@@ -409,9 +409,6 @@ import initGroupAnalytics from './init_group_analytics'; ...@@ -409,9 +409,6 @@ import initGroupAnalytics from './init_group_analytics';
case 'projects:pipelines:new': case 'projects:pipelines:new':
new NewBranchForm($('.js-new-pipeline-form')); new NewBranchForm($('.js-new-pipeline-form'));
break; break;
case 'projects:pipelines:index':
new UserCallout({ setCalloutPerProject: true });
break;
case 'projects:pipelines:builds': case 'projects:pipelines:builds':
case 'projects:pipelines:failures': case 'projects:pipelines:failures':
case 'projects:pipelines:show': case 'projects:pipelines:show':
...@@ -477,7 +474,6 @@ import initGroupAnalytics from './init_group_analytics'; ...@@ -477,7 +474,6 @@ import initGroupAnalytics from './init_group_analytics';
); );
} }
new UserCallout({ setCalloutPerProject: true });
$('#tree-slider').waitForImages(function() { $('#tree-slider').waitForImages(function() {
ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath); ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
}); });
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
@import "framework/animations"; @import "framework/animations";
@import "framework/avatar"; @import "framework/avatar";
@import "framework/asciidoctor"; @import "framework/asciidoctor";
@import "framework/banner";
@import "framework/blocks"; @import "framework/blocks";
@import "framework/buttons"; @import "framework/buttons";
@import "framework/badges"; @import "framework/badges";
......
.banner-callout {
display: flex;
position: relative;
flex-wrap: wrap;
.banner-close {
position: absolute;
top: 10px;
right: 10px;
opacity: 1;
.dismiss-icon {
color: $gl-text-color;
font-size: $gl-font-size;
}
}
.banner-graphic {
margin: 20px auto;
}
&.banner-non-empty-state {
border-bottom: 1px solid $border-color;
}
}
...@@ -24,10 +24,15 @@ ...@@ -24,10 +24,15 @@
%p %p
You will need to be owner or have the master permission level for the initial push, as the master branch is automatically protected. You will need to be owner or have the master permission level for the initial push, as the master branch is automatically protected.
- if show_auto_devops_callout?(@project)
%p
- link = link_to(s_('AutoDevOps|Auto DevOps (Beta)'), project_settings_ci_cd_path(@project, anchor: 'js-general-pipeline-settings'))
= s_('AutoDevOps|You can activate %{link_to_settings} for this project.').html_safe % { link_to_settings: link }
%p
= s_('AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration.')
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
%div{ class: container_class } %div{ class: container_class }
- if show_auto_devops_callout?(@project)
= render 'shared/auto_devops_callout'
.prepend-top-20 .prepend-top-20
.empty_wrapper .empty_wrapper
%h3.page-title-empty %h3.page-title-empty
......
...@@ -13,8 +13,6 @@ ...@@ -13,8 +13,6 @@
- if @project.merge_requests.exists? - if @project.merge_requests.exists?
%div{ class: container_class } %div{ class: container_class }
- if show_auto_devops_callout?(@project)
= render 'shared/auto_devops_callout'
.top-area .top-area
= render 'shared/issuable/nav', type: :merge_requests = render 'shared/issuable/nav', type: :merge_requests
.nav-controls .nav-controls
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
= render 'shared/shared_runners_minutes_limit', project: @project = render 'shared/shared_runners_minutes_limit', project: @project
%div{ 'class' => container_class } %div{ 'class' => container_class }
- if show_auto_devops_callout?(@project)
= render 'shared/auto_devops_callout'
#pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json), #pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json),
"help-page-path" => help_page_path('ci/quick_start/README'), "help-page-path" => help_page_path('ci/quick_start/README'),
"help-auto-devops-path" => help_page_path('topics/autodevops/index.md'), "help-auto-devops-path" => help_page_path('topics/autodevops/index.md'),
......
...@@ -12,7 +12,5 @@ ...@@ -12,7 +12,5 @@
= webpack_bundle_tag 'repo' = webpack_bundle_tag 'repo'
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] } %div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
- if show_auto_devops_callout?(@project) && !show_new_repo?
= render 'shared/auto_devops_callout'
= render 'projects/last_push' = render 'projects/last_push'
= render 'projects/files', commit: @last_commit, project: @project, ref: @ref, content_url: project_tree_path(@project, @id) = render 'projects/files', commit: @last_commit, project: @project, ref: @ref, content_url: project_tree_path(@project, @id)
.user-callout{ data: { uid: 'auto_devops_settings_dismissed', project_path: project_path(@project) } } .js-autodevops-banner.banner-callout.banner-non-empty-state.append-bottom-20{ data: { uid: 'auto_devops_settings_dismissed', project_path: project_path(@project) } }
.bordered-box.landing.content-block .banner-graphic
%button.btn.btn-default.close.js-close-callout{ type: 'button', = custom_icon('icon_autodevops')
'aria-label' => 'Dismiss Auto DevOps box' }
= icon('times', class: 'dismiss-icon', 'aria-hidden' => 'true')
.svg-container
= custom_icon('icon_autodevops')
.user-callout-copy
%h4= s_('AutoDevOps|Auto DevOps (Beta)')
%p= s_('AutoDevOps|Auto DevOps can be activated for this project. It will automatically build, test, and deploy your application based on a predefined CI/CD configuration.')
%p
- link = link_to(s_('AutoDevOps|Auto DevOps documentation'), help_page_path('topics/autodevops/index.md'), target: '_blank', rel: 'noopener noreferrer')
= s_('AutoDevOps|Learn more in the %{link_to_documentation}').html_safe % { link_to_documentation: link }
= link_to s_('AutoDevOps|Enable in settings'), project_settings_ci_cd_path(@project, anchor: 'js-general-pipeline-settings'), class: 'btn btn-primary js-close-callout' .prepend-top-10.prepend-left-10.append-bottom-10
%h5= s_('AutoDevOps|Auto DevOps (Beta)')
%p= s_('AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration.')
%p
- link = link_to(s_('AutoDevOps|Auto DevOps documentation'), help_page_path('topics/autodevops/index.md'), target: '_blank', rel: 'noopener noreferrer')
= s_('AutoDevOps|Learn more in the %{link_to_documentation}').html_safe % { link_to_documentation: link }
.prepend-top-10
= link_to s_('AutoDevOps|Enable in settings'), project_settings_ci_cd_path(@project, anchor: 'js-general-pipeline-settings'), class: 'btn js-close-callout'
%button.btn-transparent.banner-close.close.js-close-callout{ type: 'button',
'aria-label' => 'Dismiss Auto DevOps box' }
= icon('times', class: 'dismiss-icon', 'aria-hidden' => 'true')
<svg xmlns="http://www.w3.org/2000/svg" width="189" height="179" viewBox="0 0 189 179"> <svg xmlns="http://www.w3.org/2000/svg" width="189" height="110" viewBox="0 0 189 179">
<g fill="none" fill-rule="evenodd"> <g fill="none" fill-rule="evenodd">
<path fill="#FFFFFF" fill-rule="nonzero" d="M110.160166,47.6956996 L160.160166,47.6956996 C165.683013,47.6956996 170.160166,52.1728521 170.160166,57.6956996 L170.160166,117.6957 C170.160166,123.218547 165.683013,127.6957 160.160166,127.6957 L110.160166,127.6957 C104.637318,127.6957 100.160166,123.218547 100.160166,117.6957 L100.160166,57.6956996 C100.160166,52.1728521 104.637318,47.6956996 110.160166,47.6956996 Z" transform="rotate(10 135.16 87.696)"/> <path fill="#FFFFFF" fill-rule="nonzero" d="M110.160166,47.6956996 L160.160166,47.6956996 C165.683013,47.6956996 170.160166,52.1728521 170.160166,57.6956996 L170.160166,117.6957 C170.160166,123.218547 165.683013,127.6957 160.160166,127.6957 L110.160166,127.6957 C104.637318,127.6957 100.160166,123.218547 100.160166,117.6957 L100.160166,57.6956996 C100.160166,52.1728521 104.637318,47.6956996 110.160166,47.6956996 Z" transform="rotate(10 135.16 87.696)"/>
<path fill="#EEEEEE" fill-rule="nonzero" d="M110.160166,51.6956996 C106.846457,51.6956996 104.160166,54.3819911 104.160166,57.6956996 L104.160166,117.6957 C104.160166,121.009408 106.846457,123.6957 110.160166,123.6957 L160.160166,123.6957 C163.473874,123.6957 166.160166,121.009408 166.160166,117.6957 L166.160166,57.6956996 C166.160166,54.3819911 163.473874,51.6956996 160.160166,51.6956996 L110.160166,51.6956996 Z M110.160166,47.6956996 L160.160166,47.6956996 C165.683013,47.6956996 170.160166,52.1728521 170.160166,57.6956996 L170.160166,117.6957 C170.160166,123.218547 165.683013,127.6957 160.160166,127.6957 L110.160166,127.6957 C104.637318,127.6957 100.160166,123.218547 100.160166,117.6957 L100.160166,57.6956996 C100.160166,52.1728521 104.637318,47.6956996 110.160166,47.6956996 Z" transform="rotate(10 135.16 87.696)"/> <path fill="#EEEEEE" fill-rule="nonzero" d="M110.160166,51.6956996 C106.846457,51.6956996 104.160166,54.3819911 104.160166,57.6956996 L104.160166,117.6957 C104.160166,121.009408 106.846457,123.6957 110.160166,123.6957 L160.160166,123.6957 C163.473874,123.6957 166.160166,121.009408 166.160166,117.6957 L166.160166,57.6956996 C166.160166,54.3819911 163.473874,51.6956996 160.160166,51.6956996 L110.160166,51.6956996 Z M110.160166,47.6956996 L160.160166,47.6956996 C165.683013,47.6956996 170.160166,52.1728521 170.160166,57.6956996 L170.160166,117.6957 C170.160166,123.218547 165.683013,127.6957 160.160166,127.6957 L110.160166,127.6957 C104.637318,127.6957 100.160166,123.218547 100.160166,117.6957 L100.160166,57.6956996 C100.160166,52.1728521 104.637318,47.6956996 110.160166,47.6956996 Z" transform="rotate(10 135.16 87.696)"/>
......
---
title: Always allow the default branch as a branch name
merge_request: 3154
author:
type: fixed
---
title: Improve autodevops banner UX and render it only in project page
merge_request:
author:
type: fixed
...@@ -445,7 +445,7 @@ Settings.cron_jobs['geo_repository_sync_worker'] ||= Settingslogic.new({}) ...@@ -445,7 +445,7 @@ Settings.cron_jobs['geo_repository_sync_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['geo_repository_sync_worker']['cron'] ||= '*/5 * * * *' Settings.cron_jobs['geo_repository_sync_worker']['cron'] ||= '*/5 * * * *'
Settings.cron_jobs['geo_repository_sync_worker']['job_class'] ||= 'Geo::RepositorySyncWorker' Settings.cron_jobs['geo_repository_sync_worker']['job_class'] ||= 'Geo::RepositorySyncWorker'
Settings.cron_jobs['geo_file_download_dispatch_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['geo_file_download_dispatch_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['geo_file_download_dispatch_worker']['cron'] ||= '5 * * * *' Settings.cron_jobs['geo_file_download_dispatch_worker']['cron'] ||= '*/5 * * * *'
Settings.cron_jobs['geo_file_download_dispatch_worker']['job_class'] ||= 'Geo::FileDownloadDispatchWorker' Settings.cron_jobs['geo_file_download_dispatch_worker']['job_class'] ||= 'Geo::FileDownloadDispatchWorker'
Settings.cron_jobs['import_export_project_cleanup_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['import_export_project_cleanup_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['import_export_project_cleanup_worker']['cron'] ||= '0 * * * *' Settings.cron_jobs['import_export_project_cleanup_worker']['cron'] ||= '0 * * * *'
......
...@@ -185,6 +185,7 @@ module Gitlab ...@@ -185,6 +185,7 @@ module Gitlab
def branch_name_allowed_by_push_rule?(push_rule) def branch_name_allowed_by_push_rule?(push_rule)
return true unless push_rule return true unless push_rule
return true if @branch_name.blank? return true if @branch_name.blank?
return true if @branch_name == @project.default_branch
push_rule.branch_name_allowed?(@branch_name) push_rule.branch_name_allowed?(@branch_name)
end end
......
...@@ -30,6 +30,17 @@ module Gitlab ...@@ -30,6 +30,17 @@ module Gitlab
RequestStore.fetch(:gitlab_git_env) { {} } RequestStore.fetch(:gitlab_git_env) { {} }
end end
def self.to_env_hash
env = {}
all.compact.each do |key, value|
value = value.join(File::PATH_SEPARATOR) if value.is_a?(Array)
env[key.to_s] = value
end
env
end
def self.[](key) def self.[](key)
all[key] all[key]
end end
......
...@@ -28,7 +28,7 @@ module Gitlab ...@@ -28,7 +28,7 @@ module Gitlab
private private
def execute(args) def execute(args)
output, status = popen(args, nil, Gitlab::Git::Env.all.stringify_keys) output, status = popen(args, nil, Gitlab::Git::Env.to_env_hash)
unless status.zero? unless status.zero?
raise "Got a non-zero exit code while calling out `#{args.join(' ')}`: #{output}" raise "Got a non-zero exit code while calling out `#{args.join(' ')}`: #{output}"
......
...@@ -266,6 +266,15 @@ describe Gitlab::Checks::ChangeAccess do ...@@ -266,6 +266,15 @@ describe Gitlab::Checks::ChangeAccess do
expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, "Branch name does not follow the pattern '^(w*)$'") expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, "Branch name does not follow the pattern '^(w*)$'")
end end
end end
context 'when the default branch does not match the push rules' do
let(:push_rule) { create(:push_rule, branch_name_regex: 'not-master') }
let(:ref) { "refs/heads/#{project.default_branch}" }
it 'allows the default branch even if it does not match push rule' do
expect { subject }.not_to raise_error
end
end
end end
context 'existing member rules' do context 'existing member rules' do
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Git::Env do describe Gitlab::Git::Env do
describe "#set" do describe ".set" do
context 'with RequestStore.store disabled' do context 'with RequestStore.store disabled' do
before do before do
allow(RequestStore).to receive(:active?).and_return(false) allow(RequestStore).to receive(:active?).and_return(false)
...@@ -34,25 +34,57 @@ describe Gitlab::Git::Env do ...@@ -34,25 +34,57 @@ describe Gitlab::Git::Env do
end end
end end
describe "#all" do describe ".all" do
context 'with RequestStore.store enabled' do context 'with RequestStore.store enabled' do
before do before do
allow(RequestStore).to receive(:active?).and_return(true) allow(RequestStore).to receive(:active?).and_return(true)
described_class.set( described_class.set(
GIT_OBJECT_DIRECTORY: 'foo', GIT_OBJECT_DIRECTORY: 'foo',
GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar') GIT_ALTERNATE_OBJECT_DIRECTORIES: ['bar'])
end end
it 'returns an env hash' do it 'returns an env hash' do
expect(described_class.all).to eq({ expect(described_class.all).to eq({
'GIT_OBJECT_DIRECTORY' => 'foo', 'GIT_OBJECT_DIRECTORY' => 'foo',
'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar' 'GIT_ALTERNATE_OBJECT_DIRECTORIES' => ['bar']
}) })
end end
end end
end end
describe "#[]" do describe ".to_env_hash" do
context 'with RequestStore.store enabled' do
using RSpec::Parameterized::TableSyntax
let(:key) { 'GIT_OBJECT_DIRECTORY' }
subject { described_class.to_env_hash }
where(:input, :output) do
nil | nil
'foo' | 'foo'
[] | ''
['foo'] | 'foo'
%w[foo bar] | 'foo:bar'
end
with_them do
before do
allow(RequestStore).to receive(:active?).and_return(true)
described_class.set(key.to_sym => input)
end
it 'puts the right value in the hash' do
if output
expect(subject.fetch(key)).to eq(output)
else
expect(subject.has_key?(key)).to eq(false)
end
end
end
end
end
describe ".[]" do
context 'with RequestStore.store enabled' do context 'with RequestStore.store enabled' do
before do before do
allow(RequestStore).to receive(:active?).and_return(true) allow(RequestStore).to receive(:active?).and_return(true)
......
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