Create a push event on Geo event log when wiki is being updated

parent 6be81a71
...@@ -2,8 +2,13 @@ module Geo ...@@ -2,8 +2,13 @@ module Geo
class PushEvent < ActiveRecord::Base class PushEvent < ActiveRecord::Base
include Geo::Model include Geo::Model
REPOSITORY = 0
WIKI = 1
belongs_to :project belongs_to :project
enum source: { repository: 0, wiki: 1 }
validates :project, presence: true validates :project, presence: true
end end
end end
module Geo module Geo
class PushService class PushService
attr_reader :project, :refs, :changes attr_reader :project, :source, :refs, :changes
def initialize(project, refs, changes) def initialize(project, refs: [], changes: [], source: Geo::PushEvent::REPOSITORY)
@project = project @project = project
@refs = refs @refs = refs
@changes = changes @changes = changes
@source = source
end end
def execute def execute
...@@ -17,7 +18,7 @@ module Geo ...@@ -17,7 +18,7 @@ module Geo
event_log.save! event_log.save!
end end
rescue ActiveRecord::RecordInvalid rescue ActiveRecord::RecordInvalid
log('Push event could not created') log("#{Geo::PushEvent.sources.key(source).humanize} updated event could not created")
end end
private private
...@@ -25,6 +26,7 @@ module Geo ...@@ -25,6 +26,7 @@ module Geo
def build_push_event def build_push_event
Geo::PushEvent.new( Geo::PushEvent.new(
project: project, project: project,
source: source,
ref: ref, ref: ref,
branches_affected: branches_affected, branches_affected: branches_affected,
tags_affected: tags_affected, tags_affected: tags_affected,
......
...@@ -18,10 +18,7 @@ class PostReceive ...@@ -18,10 +18,7 @@ class PostReceive
post_received = Gitlab::GitPostReceive.new(project, identifier, changes) post_received = Gitlab::GitPostReceive.new(project, identifier, changes)
if is_wiki if is_wiki
update_wiki_es_indexes(post_received) process_wiki_update(post_received)
# Triggers repository update on secondary nodes when Geo is enabled
Gitlab::Geo.notify_wiki_update(post_received.project) if Gitlab::Geo.enabled?
else else
process_project_changes(post_received) process_project_changes(post_received)
process_repository_update(post_received) process_repository_update(post_received)
...@@ -44,12 +41,25 @@ class PostReceive ...@@ -44,12 +41,25 @@ class PostReceive
refs << ref refs << ref
end end
Geo::PushService.new(post_received.project, changes, refs.to_a).execute # Generate repository update event on Geo event log when Geo is enabled
Geo::PushService.new(post_received.project, refs: refs.to_a, changes: changes).execute
hook_data = Gitlab::DataBuilder::Repository.update(post_received.project, @user, changes, refs.to_a) hook_data = Gitlab::DataBuilder::Repository.update(post_received.project, @user, changes, refs.to_a)
SystemHooksService.new.execute_hooks(hook_data, :repository_update_hooks) SystemHooksService.new.execute_hooks(hook_data, :repository_update_hooks)
end end
def process_wiki_update(post_received)
update_wiki_es_indexes(post_received)
if Gitlab::Geo.enabled?
# Generate wiki update event on Geo event log
Geo::PushService.new(post_received.project, source: Geo::PushEvent::WIKI).execute
# Triggers repository update on secondary nodes
Gitlab::Geo.notify_wiki_update(post_received.project)
end
end
def process_project_changes(post_received) def process_project_changes(post_received)
post_received.changes_refs do |oldrev, newrev, ref| post_received.changes_refs do |oldrev, newrev, ref|
@user ||= post_received.identify(newrev) @user ||= post_received.identify(newrev)
......
...@@ -10,6 +10,7 @@ class CreateGeoPushEvents < ActiveRecord::Migration ...@@ -10,6 +10,7 @@ class CreateGeoPushEvents < ActiveRecord::Migration
t.integer :tags_affected, null: false t.integer :tags_affected, null: false
t.boolean :new_branch, default: false, null: false t.boolean :new_branch, default: false, null: false
t.boolean :remove_branch, default: false, null: false t.boolean :remove_branch, default: false, null: false
t.integer :source, limit: 2, index: true, null: false
end end
end end
end end
...@@ -536,9 +536,11 @@ ActiveRecord::Schema.define(version: 20170602003304) do ...@@ -536,9 +536,11 @@ ActiveRecord::Schema.define(version: 20170602003304) do
t.integer "tags_affected", null: false t.integer "tags_affected", null: false
t.boolean "new_branch", default: false, null: false t.boolean "new_branch", default: false, null: false
t.boolean "remove_branch", default: false, null: false t.boolean "remove_branch", default: false, null: false
t.integer "source", limit: 2, null: false
end end
add_index "geo_push_events", ["project_id"], name: "index_geo_push_events_on_project_id", using: :btree add_index "geo_push_events", ["project_id"], name: "index_geo_push_events_on_project_id", using: :btree
add_index "geo_push_events", ["source"], name: "index_geo_push_events_on_source", using: :btree
create_table "historical_data", force: :cascade do |t| create_table "historical_data", force: :cascade do |t|
t.date "date", null: false t.date "date", null: false
......
...@@ -9,7 +9,7 @@ RSpec.describe Geo::PushEvent, type: :model do ...@@ -9,7 +9,7 @@ RSpec.describe Geo::PushEvent, type: :model do
it { is_expected.to validate_presence_of(:project) } it { is_expected.to validate_presence_of(:project) }
end end
describe '#event_type' do describe '#source' do
it { is_expected.to define_enum_for(:event_type).with([:repository_updated, :wiki_updated]) } it { is_expected.to define_enum_for(:source).with([:repository, :wiki]) }
end end
end end
...@@ -16,7 +16,7 @@ describe Geo::PushService, services: true do ...@@ -16,7 +16,7 @@ describe Geo::PushService, services: true do
it 'does not create a push event when not running on a primary node' do it 'does not create a push event when not running on a primary node' do
allow(Gitlab::Geo).to receive(:primary?) { false } allow(Gitlab::Geo).to receive(:primary?) { false }
subject = described_class.new(project, refs, changes) subject = described_class.new(project, refs: refs, changes: changes)
expect { subject.execute }.not_to change(Geo::PushEvent, :count) expect { subject.execute }.not_to change(Geo::PushEvent, :count)
end end
...@@ -27,70 +27,88 @@ describe Geo::PushService, services: true do ...@@ -27,70 +27,88 @@ describe Geo::PushService, services: true do
end end
it 'creates a push event' do it 'creates a push event' do
subject = described_class.new(project, refs, changes) subject = described_class.new(project, refs: refs, changes: changes)
expect { subject.execute }.to change(Geo::PushEvent, :count).by(1) expect { subject.execute }.to change(Geo::PushEvent, :count).by(1)
end end
it 'does not track ref name when post-receive event affect multiple refs' do context 'when repository is beign udpated' do
subject = described_class.new(project, refs, changes) it 'does not track ref name when post-receive event affect multiple refs' do
subject = described_class.new(project, refs: refs, changes: changes)
subject.execute subject.execute
expect(Geo::PushEvent.last.ref).to be_nil expect(Geo::PushEvent.last.ref).to be_nil
end end
it 'tracks ref name when post-receive event affect single ref' do it 'tracks ref name when post-receive event affect single ref' do
refs = ['refs/heads/tést'] refs = ['refs/heads/tést']
changes = [{ before: '123456', after: blankrev, ref: 'refs/heads/tést' }] changes = [{ before: '123456', after: blankrev, ref: 'refs/heads/tést' }]
subject = described_class.new(project, refs, changes) subject = described_class.new(project, refs: refs, changes: changes)
subject.execute subject.execute
expect(Geo::PushEvent.last.ref).to eq 'refs/heads/tést' expect(Geo::PushEvent.last.ref).to eq 'refs/heads/tést'
end end
it 'tracks number of branches post-receive event affects' do it 'tracks number of branches post-receive event affects' do
subject = described_class.new(project, refs, changes) subject = described_class.new(project, refs: refs, changes: changes)
subject.execute subject.execute
expect(Geo::PushEvent.last.branches_affected).to eq 1 expect(Geo::PushEvent.last.branches_affected).to eq 1
end end
it 'tracks number of tags post-receive event affects' do it 'tracks number of tags post-receive event affects' do
subject = described_class.new(project, refs, changes) subject = described_class.new(project, refs: refs, changes: changes)
subject.execute subject.execute
expect(Geo::PushEvent.last.tags_affected).to eq 1 expect(Geo::PushEvent.last.tags_affected).to eq 1
end end
it 'tracks when post-receive event create new branches' do it 'tracks when post-receive event create new branches' do
refs = ['refs/heads/tést', 'refs/heads/feature'] refs = ['refs/heads/tést', 'refs/heads/feature']
changes = [ changes = [
{ before: '123456', after: '789012', ref: 'refs/heads/tést' }, { before: '123456', after: '789012', ref: 'refs/heads/tést' },
{ before: blankrev, after: '210987', ref: 'refs/heads/feature' } { before: blankrev, after: '210987', ref: 'refs/heads/feature' }
] ]
subject = described_class.new(project, refs, changes) subject = described_class.new(project, refs: refs, changes: changes)
subject.execute subject.execute
expect(Geo::PushEvent.last.new_branch).to eq true expect(Geo::PushEvent.last.new_branch).to eq true
end
it 'tracks when post-receive event remove branches' do
refs = ['refs/heads/tést', 'refs/heads/feature']
changes = [
{ before: '123456', after: '789012', ref: 'refs/heads/tést' },
{ before: '654321', after: blankrev, ref: 'refs/heads/feature' }
]
subject = described_class.new(project, refs: refs, changes: changes)
subject.execute
expect(Geo::PushEvent.last.remove_branch).to eq true
end
end end
it 'tracks when post-receive event remove branches' do context 'when wiki is beign udpated' do
refs = ['refs/heads/tést', 'refs/heads/feature'] it 'does not track any information' do
changes = [ subject = described_class.new(project, source: Geo::PushEvent::WIKI)
{ before: '123456', after: '789012', ref: 'refs/heads/tést' },
{ before: '654321', after: blankrev, ref: 'refs/heads/feature' } subject.execute
]
subject = described_class.new(project, refs, changes)
subject.execute push_event = Geo::PushEvent.last
expect(Geo::PushEvent.last.remove_branch).to eq true expect(push_event.ref).to be_nil
expect(push_event.branches_affected).to be_zero
expect(push_event.tags_affected).to be_zero
expect(push_event.new_branch).to eq false
expect(push_event.remove_branch).to eq false
end
end end
end end
end end
......
...@@ -123,21 +123,31 @@ describe PostReceive do ...@@ -123,21 +123,31 @@ describe PostReceive do
end end
end end
context "webhook" do describe '#process_wiki_update' do
it "fetches the correct project" do it 'triggers Geo::PushService when Geo is enabled' do
expect(Project).to receive(:find_by).with(id: project.id.to_s) allow(Gitlab::Geo).to receive(:enabled?) { true }
described_class.new.perform(project_identifier, key_id, base64_changes)
expect(Geo::PushService).to receive(:new).with(instance_of(Project), source: Geo::PushEvent::WIKI).and_call_original
expect_any_instance_of(Geo::PushService).to receive(:execute)
described_class.new.perform("#{pwd(project)}.wiki", key_id, base64_changes)
end end
it "triggers wiki index update" do it 'triggers wiki index update when ElasticSearch is enabled' do
expect(Project).to receive(:find_by_full_path).with("#{project.full_path}.wiki").and_return(nil) expect(Project).to receive(:find_by_full_path).with("#{project.full_path}.wiki").and_return(nil)
expect(Project).to receive(:find_by_full_path).with(project.full_path).and_return(project) expect(Project).to receive(:find_by_full_path).with(project.full_path).and_return(project)
stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
expect_any_instance_of(ProjectWiki).to receive(:index_blobs) expect_any_instance_of(ProjectWiki).to receive(:index_blobs)
repo_path = "#{pwd(project)}.wiki" described_class.new.perform("#{pwd(project)}.wiki", key_id, base64_changes)
end
end
described_class.new.perform(repo_path, key_id, base64_changes) context "webhook" do
it "fetches the correct project" do
expect(Project).to receive(:find_by).with(id: project.id.to_s)
described_class.new.perform(project_identifier, key_id, base64_changes)
end end
it "does not run if the author is not in the project" do it "does not run if the author is not in the project" do
......
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