diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index fcc03c3e4b8e0db076152bdb894658a590cdfe95..351b446457dfdb2e0e0ec1cce1de31028e5b9bb3 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -86,10 +86,9 @@ class GitPushService
       author = commit_user(commit)
 
       if !issues_to_close.empty? && is_default_branch
-        Thread.current[:current_user] = author
-        Thread.current[:current_commit] = commit
-
-        issues_to_close.each { |i| i.close && i.save }
+        issues_to_close.each do |issue|
+          Issues::CloseService.new(project, author, {}).execute(issue, commit)
+        end
       end
 
       # Create cross-reference notes for any other references. Omit any issues that were referenced in an
diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb
index e04c1c6fb7a88fb4f9762e4a06855dfcb283f645..2e1e1f7e0f0ada3eb8e4d3937af767e84c010b49 100644
--- a/app/services/issues/base_service.rb
+++ b/app/services/issues/base_service.rb
@@ -3,11 +3,6 @@ module Issues
 
     private
 
-    # Create issue note with service comment like 'Status changed to closed'
-    def create_note(issue)
-      Note.create_status_change_note(issue, issue.project, current_user, issue.state, current_commit)
-    end
-
     def create_assignee_note(issue)
       Note.create_assignee_change_note(issue, issue.project, current_user, issue.assignee)
     end
diff --git a/app/services/issues/close_service.rb b/app/services/issues/close_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..780bc8e4130269e2d410b3ef60c8ed7a5c56eb40
--- /dev/null
+++ b/app/services/issues/close_service.rb
@@ -0,0 +1,20 @@
+module Issues
+  class CloseService < BaseService
+    def execute(issue, commit = nil)
+      if issue.close
+        notification_service.close_issue(issue, current_user)
+        event_service.close_issue(issue, current_user)
+        create_note(issue, commit)
+        execute_hooks(issue)
+      end
+
+      issue
+    end
+
+    private
+
+    def create_note(issue, current_commit)
+      Note.create_status_change_note(issue, issue.project, current_user, issue.state, current_commit)
+    end
+  end
+end
diff --git a/app/services/issues/reopen_service.rb b/app/services/issues/reopen_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..743a5d6c4a8df064b9ced35656eced8fe7e88dda
--- /dev/null
+++ b/app/services/issues/reopen_service.rb
@@ -0,0 +1,19 @@
+module Issues
+  class ReopenService < BaseService
+    def execute(issue)
+      if issue.reopen
+        event_service.reopen_issue(issue, current_user)
+        create_note(issue, commit)
+        execute_hooks(issue)
+      end
+
+      issue
+    end
+
+    private
+
+    def create_note(issue)
+      Note.create_status_change_note(issue, issue.project, current_user, issue.state, nil)
+    end
+  end
+end
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index 4db9dee11d3d6c0e49c88f983e8e2e56299b25a9..4d8d71b4c9f7b3eaff7a5dd0de13630c6bba138e 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -5,7 +5,7 @@ module Issues
         issue.reset_events_cache
 
         if issue.is_being_reassigned?
-          notification.reassigned_issue(issue, current_user)
+          notification_service.reassigned_issue(issue, current_user)
           create_assignee_note(issue)
         end