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

parent 6be81a71
......@@ -2,8 +2,13 @@ module Geo
class PushEvent < ActiveRecord::Base
include Geo::Model
REPOSITORY = 0
WIKI = 1
belongs_to :project
enum source: { repository: 0, wiki: 1 }
validates :project, presence: true
end
end
module Geo
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
@refs = refs
@changes = changes
@source = source
end
def execute
......@@ -17,7 +18,7 @@ module Geo
event_log.save!
end
rescue ActiveRecord::RecordInvalid
log('Push event could not created')
log("#{Geo::PushEvent.sources.key(source).humanize} updated event could not created")
end
private
......@@ -25,6 +26,7 @@ module Geo
def build_push_event
Geo::PushEvent.new(
project: project,
source: source,
ref: ref,
branches_affected: branches_affected,
tags_affected: tags_affected,
......
......@@ -18,10 +18,7 @@ class PostReceive
post_received = Gitlab::GitPostReceive.new(project, identifier, changes)
if is_wiki
update_wiki_es_indexes(post_received)
# Triggers repository update on secondary nodes when Geo is enabled
Gitlab::Geo.notify_wiki_update(post_received.project) if Gitlab::Geo.enabled?
process_wiki_update(post_received)
else
process_project_changes(post_received)
process_repository_update(post_received)
......@@ -44,12 +41,25 @@ class PostReceive
refs << ref
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)
SystemHooksService.new.execute_hooks(hook_data, :repository_update_hooks)
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)
post_received.changes_refs do |oldrev, newrev, ref|
@user ||= post_received.identify(newrev)
......
......@@ -10,6 +10,7 @@ class CreateGeoPushEvents < ActiveRecord::Migration
t.integer :tags_affected, null: false
t.boolean :new_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
......@@ -536,9 +536,11 @@ ActiveRecord::Schema.define(version: 20170602003304) do
t.integer "tags_affected", null: false
t.boolean "new_branch", default: false, null: false
t.boolean "remove_branch", default: false, null: false
t.integer "source", limit: 2, null: false
end
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|
t.date "date", null: false
......
......@@ -9,7 +9,7 @@ RSpec.describe Geo::PushEvent, type: :model do
it { is_expected.to validate_presence_of(:project) }
end
describe '#event_type' do
it { is_expected.to define_enum_for(:event_type).with([:repository_updated, :wiki_updated]) }
describe '#source' do
it { is_expected.to define_enum_for(:source).with([:repository, :wiki]) }
end
end
......@@ -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
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)
end
......@@ -27,70 +27,88 @@ describe Geo::PushService, services: true do
end
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)
end
it 'does not track ref name when post-receive event affect multiple refs' do
subject = described_class.new(project, refs, changes)
context 'when repository is beign udpated' do
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
end
expect(Geo::PushEvent.last.ref).to be_nil
end
it 'tracks ref name when post-receive event affect single ref' do
refs = ['refs/heads/tést']
changes = [{ before: '123456', after: blankrev, ref: 'refs/heads/tést' }]
subject = described_class.new(project, refs, changes)
it 'tracks ref name when post-receive event affect single ref' do
refs = ['refs/heads/tést']
changes = [{ before: '123456', after: blankrev, ref: 'refs/heads/tést' }]
subject = described_class.new(project, refs: refs, changes: changes)
subject.execute
subject.execute
expect(Geo::PushEvent.last.ref).to eq 'refs/heads/tést'
end
expect(Geo::PushEvent.last.ref).to eq 'refs/heads/tést'
end
it 'tracks number of branches post-receive event affects' do
subject = described_class.new(project, refs, changes)
it 'tracks number of branches post-receive event affects' do
subject = described_class.new(project, refs: refs, changes: changes)
subject.execute
subject.execute
expect(Geo::PushEvent.last.branches_affected).to eq 1
end
expect(Geo::PushEvent.last.branches_affected).to eq 1
end
it 'tracks number of tags post-receive event affects' do
subject = described_class.new(project, refs, changes)
it 'tracks number of tags post-receive event affects' do
subject = described_class.new(project, refs: refs, changes: changes)
subject.execute
subject.execute
expect(Geo::PushEvent.last.tags_affected).to eq 1
end
expect(Geo::PushEvent.last.tags_affected).to eq 1
end
it 'tracks when post-receive event create new branches' do
refs = ['refs/heads/tést', 'refs/heads/feature']
changes = [
{ before: '123456', after: '789012', ref: 'refs/heads/tést' },
{ before: blankrev, after: '210987', ref: 'refs/heads/feature' }
]
it 'tracks when post-receive event create new branches' do
refs = ['refs/heads/tést', 'refs/heads/feature']
changes = [
{ before: '123456', after: '789012', ref: 'refs/heads/tést' },
{ 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
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, changes)
context 'when wiki is beign udpated' do
it 'does not track any information' do
subject = described_class.new(project, source: Geo::PushEvent::WIKI)
subject.execute
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
......
......@@ -123,21 +123,31 @@ describe PostReceive do
end
end
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)
describe '#process_wiki_update' do
it 'triggers Geo::PushService when Geo is enabled' do
allow(Gitlab::Geo).to receive(:enabled?) { true }
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
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).and_return(project)
stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
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
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