Commit 3a2aa432 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge remote-tracking branch 'ee/master' into ce-to-ee-2017-10-13

* ee/master:
  Port of fl-autodevops-fix to EE
  Port Git alternate dirs fix to EE
  Fix default crontab for Geo::FileDownloadDispatchWorker
  Allow the default branch as branch name
  Geo: Don't sync disabled project wikis
parents d08b1ed8 03208c31
...@@ -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;
}
}
...@@ -20,19 +20,29 @@ class Geo::ProjectRegistry < Geo::BaseRegistry ...@@ -20,19 +20,29 @@ class Geo::ProjectRegistry < Geo::BaseRegistry
.where(resync_repository: false, resync_wiki: false) .where(resync_repository: false, resync_wiki: false)
end end
def resync_repository? def repository_sync_due?(scheduled_time)
resync_repository || last_repository_successful_sync_at.nil? never_synced_repository? || repository_sync_needed?(scheduled_time)
end end
def resync_wiki? def wiki_sync_due?(scheduled_time)
resync_wiki || last_wiki_successful_sync_at.nil? project.wiki_enabled? && (never_synced_wiki? || wiki_sync_needed?(scheduled_time))
end end
def repository_synced_since?(timestamp) private
last_repository_synced_at && last_repository_synced_at > timestamp
def never_synced_repository?
last_repository_successful_sync_at.nil?
end
def never_synced_wiki?
last_wiki_successful_sync_at.nil?
end
def repository_sync_needed?(timestamp)
resync_repository? && (last_repository_synced_at.nil? || timestamp > last_repository_synced_at)
end end
def wiki_synced_since?(timestamp) def wiki_sync_needed?(timestamp)
last_wiki_synced_at && last_wiki_synced_at > timestamp resync_wiki? && (last_wiki_synced_at.nil? || timestamp > last_wiki_synced_at)
end end
end end
...@@ -10,7 +10,7 @@ module Geo ...@@ -10,7 +10,7 @@ module Geo
repository_storage_name: project.repository.storage, repository_storage_name: project.repository.storage,
repository_storage_path: project.repository_storage_path, repository_storage_path: project.repository_storage_path,
repo_path: project.disk_path, repo_path: project.disk_path,
wiki_path: "#{project.disk_path}.wiki", wiki_path: ("#{project.disk_path}.wiki" if project.wiki_enabled?),
project_name: project.name project_name: project.name
) )
end end
......
...@@ -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',
'aria-label' => 'Dismiss Auto DevOps box' }
= icon('times', class: 'dismiss-icon', 'aria-hidden' => 'true')
.svg-container
= custom_icon('icon_autodevops') = custom_icon('icon_autodevops')
.user-callout-copy
%h4= s_('AutoDevOps|Auto DevOps (Beta)') .prepend-top-10.prepend-left-10.append-bottom-10
%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.') %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 %p
- link = link_to(s_('AutoDevOps|Auto DevOps documentation'), help_page_path('topics/autodevops/index.md'), target: '_blank', rel: 'noopener noreferrer') - 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 } = 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'
= 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' %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)"/>
......
...@@ -11,30 +11,16 @@ module Geo ...@@ -11,30 +11,16 @@ module Geo
end end
def perform(project_id, scheduled_time) def perform(project_id, scheduled_time)
project = Project.find(project_id)
registry = Geo::ProjectRegistry.find_or_initialize_by(project_id: project_id) registry = Geo::ProjectRegistry.find_or_initialize_by(project_id: project_id)
project = registry.project
Geo::RepositorySyncService.new(project).execute if sync_repository?(registry, scheduled_time) if project.nil?
Geo::WikiSyncService.new(project).execute if sync_wiki?(registry, scheduled_time) Gitlab::Geo::Logger.error(class: self.class.name, message: "Couldn't find project, skipping syncing", project_id: project_id)
rescue ActiveRecord::RecordNotFound => e return
Gitlab::Geo::Logger.error(
class: self.class.name,
message: "Couldn't find project, skipping syncing",
project_id: project_id,
error: e
)
end end
private Geo::RepositorySyncService.new(project).execute if registry.repository_sync_due?(scheduled_time)
Geo::WikiSyncService.new(project).execute if registry.wiki_sync_due?(scheduled_time)
def sync_repository?(registry, scheduled_time)
!registry.repository_synced_since?(scheduled_time) &&
registry.resync_repository?
end
def sync_wiki?(registry, scheduled_time)
!registry.wiki_synced_since?(scheduled_time) &&
registry.resync_wiki?
end end
end end
end end
---
title: 'Geo: Don''t sync disabled project wikis'
merge_request: 3109
author:
type: fixed
---
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
......
...@@ -19,9 +19,7 @@ module Gitlab ...@@ -19,9 +19,7 @@ module Gitlab
full_scan! if options[:full_scan] full_scan! if options[:full_scan]
until exit? until exit?
Events.fetch_in_batches do |batch| run_once!
handle_events(batch)
end
return if exit? return if exit?
...@@ -30,6 +28,10 @@ module Gitlab ...@@ -30,6 +28,10 @@ module Gitlab
end end
end end
def run_once!
Events.fetch_in_batches { |batch| handle_events(batch) }
end
# Execute routines to verify the required initial data is available # Execute routines to verify the required initial data is available
# and mark non-replicated data as requiring replication. # and mark non-replicated data as requiring replication.
def full_scan! def full_scan!
......
...@@ -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}"
......
...@@ -24,7 +24,7 @@ FactoryGirl.define do ...@@ -24,7 +24,7 @@ FactoryGirl.define do
repository_storage_path { project.repository_storage_path } repository_storage_path { project.repository_storage_path }
add_attribute(:repo_path) { project.disk_path } add_attribute(:repo_path) { project.disk_path }
project_name { project.name } project_name { project.name }
wiki_path { "{project.disk_path}.wiki" } wiki_path { "#{project.disk_path}.wiki" }
end end
factory :geo_repository_updated_event, class: Geo::RepositoryUpdatedEvent do factory :geo_repository_updated_event, class: Geo::RepositoryUpdatedEvent do
......
...@@ -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)
......
require 'spec_helper' require 'spec_helper'
describe Geo::ProjectRegistry do describe Geo::ProjectRegistry do
subject { create(:geo_project_registry) } using RSpec::Parameterized::TableSyntax
set(:project) { create(:project) }
set(:registry) { create(:geo_project_registry, project_id: project.id) }
subject { registry }
describe 'relationships' do describe 'relationships' do
it { is_expected.to belong_to(:project) } it { is_expected.to belong_to(:project) }
...@@ -33,85 +38,79 @@ describe Geo::ProjectRegistry do ...@@ -33,85 +38,79 @@ describe Geo::ProjectRegistry do
end end
end end
describe '#resync_repository?' do describe '#repository_sync_due?' do
it 'returns true when resync_repository is true' do where(:resync_repository, :last_successful_sync, :last_sync, :expected) do
subject.resync_repository = true now = Time.now
past = now - 1.year
future = now + 1.year
expect(subject.resync_repository).to be true true | nil | nil | true
end true | now | nil | true
false | nil | nil | true
false | now | nil | false
it 'returns true when last_repository_successful_sync_at is nil' do true | nil | past | true
subject.last_repository_successful_sync_at = nil true | now | past | true
false | nil | past | true
false | now | past | false
expect(subject.resync_repository).to be true true | nil | future | true
true | now | future | false
false | nil | future | true
false | now | future | false
end end
it 'returns false when resync_repository is false and last_repository_successful_sync_at is present' do with_them do
subject.resync_repository = false before do
subject.last_repository_successful_sync_at = Time.now registry.update!(resync_repository: resync_repository, last_repository_successful_sync_at: last_successful_sync, last_repository_synced_at: last_sync)
expect(subject.resync_repository).to be false
end
end end
describe '#resync_wiki?' do subject { registry.repository_sync_due?(Time.now) }
it 'returns true when resync_wiki is true' do
subject.resync_wiki = true
expect(subject.resync_wiki).to be true it { is_expected.to eq(expected) }
end end
it 'returns true when last_wiki_successful_sync_at is nil' do
subject.last_wiki_successful_sync_at = nil
expect(subject.resync_wiki).to be true
end end
it 'returns false when resync_wiki is false and last_wiki_successful_sync_at is present' do describe '#wiki_sync_due?' do
subject.resync_wiki = false where(:resync_wiki, :last_successful_sync, :last_sync, :expected) do
subject.last_wiki_successful_sync_at = Time.now now = Time.now
past = now - 1.year
future = now + 1.year
expect(subject.resync_wiki).to be false true | nil | nil | true
end true | now | nil | true
end false | nil | nil | true
false | now | nil | false
describe '#repository_synced_since?' do true | nil | past | true
it 'returns false when last_repository_synced_at is nil' do true | now | past | true
subject.last_repository_synced_at = nil false | nil | past | true
false | now | past | false
expect(subject.repository_synced_since?(Time.now)).to be_nil true | nil | future | true
true | now | future | false
false | nil | future | true
false | now | future | false
end end
it 'returns false when last_repository_synced_at before timestamp' do with_them do
subject.last_repository_synced_at = Time.now - 2.hours before do
registry.update!(resync_wiki: resync_wiki, last_wiki_successful_sync_at: last_successful_sync, last_wiki_synced_at: last_sync)
expect(subject.repository_synced_since?(Time.now)).to be false
end end
it 'returns true when last_repository_synced_at after timestamp' do subject { registry.wiki_sync_due?(Time.now) }
subject.last_repository_synced_at = Time.now + 2.hours
expect(subject.repository_synced_since?(Time.now)).to be true context 'wiki enabled' do
it { is_expected.to eq(expected) }
end end
end
describe '#wiki_synced_since?' do
it 'returns false when last_wiki_synced_at is nil' do
subject.last_wiki_synced_at = nil
expect(subject.wiki_synced_since?(Time.now)).to be_nil context 'wiki disabled' do
before do
project.update!(wiki_enabled: false)
end end
it 'returns false when last_wiki_synced_at before timestamp' do it { is_expected.to be_falsy }
subject.last_wiki_synced_at = Time.now - 2.hours
expect(subject.wiki_synced_since?(Time.now)).to be false
end end
it 'returns true when last_wiki_synced_at after timestamp' do
subject.last_wiki_synced_at = Time.now + 2.hours
expect(subject.wiki_synced_since?(Time.now)).to be true
end end
end end
end end
require 'spec_helper' require 'spec_helper'
describe Geo::RepositoryCreatedEventStore do describe Geo::RepositoryCreatedEventStore do
let(:project) { create(:project) } set(:project) { create(:project) }
subject(:event) { described_class.new(project) } subject(:create!) { described_class.new(project).create }
describe '#create' do describe '#create' do
it 'does not create an event when not running on a primary node' do it 'does not create an event when not running on a primary node' do
allow(Gitlab::Geo).to receive(:primary?) { false } allow(Gitlab::Geo).to receive(:primary?) { false }
expect { event.create }.not_to change(Geo::RepositoryCreatedEvent, :count) expect { create! }.not_to change(Geo::RepositoryCreatedEvent, :count)
end end
context 'when running on a primary node' do context 'running on a primary node' do
before do before do
allow(Gitlab::Geo).to receive(:primary?) { true } allow(Gitlab::Geo).to receive(:primary?) { true }
end end
it 'creates a created event' do it 'creates a created event' do
expect { event.create }.to change(Geo::RepositoryCreatedEvent, :count).by(1) expect { create! }.to change(Geo::RepositoryCreatedEvent, :count).by(1)
end end
it 'tracks information for the created project' do it 'tracks information for the created project' do
event.create create!
event = Geo::RepositoryCreatedEvent.last event = Geo::RepositoryCreatedEvent.last
...@@ -35,6 +35,15 @@ describe Geo::RepositoryCreatedEventStore do ...@@ -35,6 +35,15 @@ describe Geo::RepositoryCreatedEventStore do
repository_storage_path: project.repository_storage_path repository_storage_path: project.repository_storage_path
) )
end end
it 'does not set a wiki path if the wiki is disabled' do
project.update!(wiki_enabled: false)
create!
event = Geo::RepositoryCreatedEvent.last
expect(event.wiki_path).to be_nil
end
end end
end end
end end
...@@ -102,6 +102,23 @@ RSpec.describe Geo::ProjectSyncWorker do ...@@ -102,6 +102,23 @@ RSpec.describe Geo::ProjectSyncWorker do
end end
end end
context 'wiki is not enabled for project' do
let!(:registry) { create(:geo_project_registry, resync_repository: true, resync_wiki: true, project: project) }
before do
project.update!(wiki_enabled: false)
subject.perform(project.id, Time.now)
end
it 'syncs the project repository' do
expect(repository_sync_service).to have_received(:execute)
end
it 'does not sync the project wiki' do
expect(wiki_sync_service).not_to have_received(:execute)
end
end
context 'when project repository was synced after the time the job was scheduled in' do context 'when project repository was synced after the time the job was scheduled in' do
it 'does not perform Geo::RepositorySyncService for the given project' do it 'does not perform Geo::RepositorySyncService for the given project' do
create(:geo_project_registry, :synced, :repository_dirty, project: project, last_repository_synced_at: Time.now) create(:geo_project_registry, :synced, :repository_dirty, project: project, last_repository_synced_at: Time.now)
......
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