{"action":"created","comment":{"url":"https://api.github.com/repos/Dynflow/dynflow/pulls/comments/170649402","pull_request_review_id":99367177,"id":170649402,"diff_hunk":"@@ -0,0 +1,82 @@\n+require_relative 'test_helper'\n+\n+module Dynflow\n+  class ExecutionPlan\n+    describe Hooks do\n+      include PlanAssertions\n+\n+      let(:world) { WorldFactory.create_world }\n+\n+      class Flag\n+        class << self\n+          def raise!\n+            @raised = true\n+          end\n+\n+          def raised?\n+            @raised\n+          end\n+\n+          def lower!\n+            @raised = false\n+          end\n+        end\n+      end\n+\n+      class FlagHook < ::Dynflow::ExecutionPlan::Hooks::Abstract\n+        def on_success(_execution_plan, _action)\n+          Flag.raise!\n+        end\n+\n+        def on_stopped(_execution_plan, _action)\n+          Flag.raise!\n+          raise \"A controlled failure\"\n+        end\n+      end\n+\n+      class ActionWithHooks < ::Dynflow::Action\n+        execution_plan_hooks.use FlagHook, :on => :success","path":"test/execution_plan_hooks_test.rb","position":38,"original_position":38,"commit_id":"2019f135a0046302c50a38433f3581c8296baed3","original_commit_id":"2019f135a0046302c50a38433f3581c8296baed3","user":{"login":"iNecas","id":190443,"avatar_url":"https://avatars3.githubusercontent.com/u/190443?v=4","gravatar_id":"","url":"https://api.github.com/users/iNecas","html_url":"https://github.com/iNecas","followers_url":"https://api.github.com/users/iNecas/followers","following_url":"https://api.github.com/users/iNecas/following{/other_user}","gists_url":"https://api.github.com/users/iNecas/gists{/gist_id}","starred_url":"https://api.github.com/users/iNecas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iNecas/subscriptions","organizations_url":"https://api.github.com/users/iNecas/orgs","repos_url":"https://api.github.com/users/iNecas/repos","events_url":"https://api.github.com/users/iNecas/events{/privacy}","received_events_url":"https://api.github.com/users/iNecas/received_events","type":"User","site_admin":false},"body":"I wonder if we need a class here vs. just action methods. Seems a bit strange that I need to define both `on_success` in the hook and `:on => :success` here. What about something like this:\r\n\r\n```ruby\r\nexecution_plan_hooks.run :send_notification, :on => :stopped\r\n```","created_at":"2018-02-26T16:24:55Z","updated_at":"2018-02-26T16:24:55Z","html_url":"https://github.com/Dynflow/dynflow/pull/270#discussion_r170649402","pull_request_url":"https://api.github.com/repos/Dynflow/dynflow/pulls/270","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/Dynflow/dynflow/pulls/comments/170649402"},"html":{"href":"https://github.com/Dynflow/dynflow/pull/270#discussion_r170649402"},"pull_request":{"href":"https://api.github.com/repos/Dynflow/dynflow/pulls/270"}}},"pull_request":{"url":"https://api.github.com/repos/Dynflow/dynflow/pulls/270","id":168576466,"html_url":"https://github.com/Dynflow/dynflow/pull/270","diff_url":"https://github.com/Dynflow/dynflow/pull/270.diff","patch_url":"https://github.com/Dynflow/dynflow/pull/270.patch","issue_url":"https://api.github.com/repos/Dynflow/dynflow/issues/270","number":270,"state":"open","locked":false,"title":"Execution plan life cycle hooks","user":{"login":"adamruzicka","id":7326770,"avatar_url":"https://avatars0.githubusercontent.com/u/7326770?v=4","gravatar_id":"","url":"https://api.github.com/users/adamruzicka","html_url":"https://github.com/adamruzicka","followers_url":"https://api.github.com/users/adamruzicka/followers","following_url":"https://api.github.com/users/adamruzicka/following{/other_user}","gists_url":"https://api.github.com/users/adamruzicka/gists{/gist_id}","starred_url":"https://api.github.com/users/adamruzicka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamruzicka/subscriptions","organizations_url":"https://api.github.com/users/adamruzicka/orgs","repos_url":"https://api.github.com/users/adamruzicka/repos","events_url":"https://api.github.com/users/adamruzicka/events{/privacy}","received_events_url":"https://api.github.com/users/adamruzicka/received_events","type":"User","site_admin":false},"body":"This commit allows actions to hook into the life cycle of an execution plan.\r\nCurrently hooks can be triggered when the execution plan goes into:\r\n- `stopped` state (`:stop`)\r\n- `paused` state (`:pause`)\r\n- `stopped` state with `success` result (`:success`)\r\n- `stopped` state with `error`, `warning` or `cancelled` result (`:fail`)\r\n\r\nA hook can either override default `execute` method and provide the same\r\nbehavior for all events or override separate `on_success`, `on_stop`,\r\n`on_pause` and `on_fail` methods to implement the desired behavior.\r\n\r\nHooks have volatile access to the action, any changes done to the action's\r\noutput or input will be lost upon exiting the hook.\r\n\r\nHooks are enabled using the `execution_plan_hooks.use` call and are inherited\r\nwhen actions are sub-classed. Hooks from the parent action can be disabled using\r\nthe `execution_plan_hooks.do_not_use` call in the child action. The order of\r\nexecution is not guaranteed.\r\n\r\nThe hooks are executed in a begin-rescue block, so even if a hook raises an\r\nexception during its run, other hooks should still be run.","created_at":"2018-02-12T13:18:56Z","updated_at":"2018-02-26T16:24:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1a07b2abe2b8805d25d14764febad210e4442d94","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/Dynflow/dynflow/pulls/270/commits","review_comments_url":"https://api.github.com/repos/Dynflow/dynflow/pulls/270/comments","review_comment_url":"https://api.github.com/repos/Dynflow/dynflow/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Dynflow/dynflow/issues/270/comments","statuses_url":"https://api.github.com/repos/Dynflow/dynflow/statuses/2019f135a0046302c50a38433f3581c8296baed3","head":{"label":"adamruzicka:hooks","ref":"hooks","sha":"2019f135a0046302c50a38433f3581c8296baed3","user":{"login":"adamruzicka","id":7326770,"avatar_url":"https://avatars0.githubusercontent.com/u/7326770?v=4","gravatar_id":"","url":"https://api.github.com/users/adamruzicka","html_url":"https://github.com/adamruzicka","followers_url":"https://api.github.com/users/adamruzicka/followers","following_url":"https://api.github.com/users/adamruzicka/following{/other_user}","gists_url":"https://api.github.com/users/adamruzicka/gists{/gist_id}","starred_url":"https://api.github.com/users/adamruzicka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamruzicka/subscriptions","organizations_url":"https://api.github.com/users/adamruzicka/orgs","repos_url":"https://api.github.com/users/adamruzicka/repos","events_url":"https://api.github.com/users/adamruzicka/events{/privacy}","received_events_url":"https://api.github.com/users/adamruzicka/received_events","type":"User","site_admin":false},"repo":{"id":19110252,"name":"dynflow","full_name":"adamruzicka/dynflow","owner":{"login":"adamruzicka","id":7326770,"avatar_url":"https://avatars0.githubusercontent.com/u/7326770?v=4","gravatar_id":"","url":"https://api.github.com/users/adamruzicka","html_url":"https://github.com/adamruzicka","followers_url":"https://api.github.com/users/adamruzicka/followers","following_url":"https://api.github.com/users/adamruzicka/following{/other_user}","gists_url":"https://api.github.com/users/adamruzicka/gists{/gist_id}","starred_url":"https://api.github.com/users/adamruzicka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adamruzicka/subscriptions","organizations_url":"https://api.github.com/users/adamruzicka/orgs","repos_url":"https://api.github.com/users/adamruzicka/repos","events_url":"https://api.github.com/users/adamruzicka/events{/privacy}","received_events_url":"https://api.github.com/users/adamruzicka/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/adamruzicka/dynflow","description":"DYNamic workFLOW engine","fork":true,"url":"https://api.github.com/repos/adamruzicka/dynflow","forks_url":"https://api.github.com/repos/adamruzicka/dynflow/forks","keys_url":"https://api.github.com/repos/adamruzicka/dynflow/keys{/key_id}","collaborators_url":"https://api.github.com/repos/adamruzicka/dynflow/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/adamruzicka/dynflow/teams","hooks_url":"https://api.github.com/repos/adamruzicka/dynflow/hooks","issue_events_url":"https://api.github.com/repos/adamruzicka/dynflow/issues/events{/number}","events_url":"https://api.github.com/repos/adamruzicka/dynflow/events","assignees_url":"https://api.github.com/repos/adamruzicka/dynflow/assignees{/user}","branches_url":"https://api.github.com/repos/adamruzicka/dynflow/branches{/branch}","tags_url":"https://api.github.com/repos/adamruzicka/dynflow/tags","blobs_url":"https://api.github.com/repos/adamruzicka/dynflow/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/adamruzicka/dynflow/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/adamruzicka/dynflow/git/refs{/sha}","trees_url":"https://api.github.com/repos/adamruzicka/dynflow/git/trees{/sha}","statuses_url":"https://api.github.com/repos/adamruzicka/dynflow/statuses/{sha}","languages_url":"https://api.github.com/repos/adamruzicka/dynflow/languages","stargazers_url":"https://api.github.com/repos/adamruzicka/dynflow/stargazers","contributors_url":"https://api.github.com/repos/adamruzicka/dynflow/contributors","subscribers_url":"https://api.github.com/repos/adamruzicka/dynflow/subscribers","subscription_url":"https://api.github.com/repos/adamruzicka/dynflow/subscription","commits_url":"https://api.github.com/repos/adamruzicka/dynflow/commits{/sha}","git_commits_url":"https://api.github.com/repos/adamruzicka/dynflow/git/commits{/sha}","comments_url":"https://api.github.com/repos/adamruzicka/dynflow/comments{/number}","issue_comment_url":"https://api.github.com/repos/adamruzicka/dynflow/issues/comments{/number}","contents_url":"https://api.github.com/repos/adamruzicka/dynflow/contents/{+path}","compare_url":"https://api.github.com/repos/adamruzicka/dynflow/compare/{base}...{head}","merges_url":"https://api.github.com/repos/adamruzicka/dynflow/merges","archive_url":"https://api.github.com/repos/adamruzicka/dynflow/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/adamruzicka/dynflow/downloads","issues_url":"https://api.github.com/repos/adamruzicka/dynflow/issues{/number}","pulls_url":"https://api.github.com/repos/adamruzicka/dynflow/pulls{/number}","milestones_url":"https://api.github.com/repos/adamruzicka/dynflow/milestones{/number}","notifications_url":"https://api.github.com/repos/adamruzicka/dynflow/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/adamruzicka/dynflow/labels{/name}","releases_url":"https://api.github.com/repos/adamruzicka/dynflow/releases{/id}","deployments_url":"https://api.github.com/repos/adamruzicka/dynflow/deployments","created_at":"2014-04-24T13:53:55Z","updated_at":"2016-01-27T13:51:52Z","pushed_at":"2018-02-19T14:58:39Z","git_url":"git://github.com/adamruzicka/dynflow.git","ssh_url":"git@github.com:adamruzicka/dynflow.git","clone_url":"https://github.com/adamruzicka/dynflow.git","svn_url":"https://github.com/adamruzicka/dynflow","homepage":null,"size":2387,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"Dynflow:master","ref":"master","sha":"6b19fe6ffff95dcb1e62338013d7abc88f156a4d","user":{"login":"Dynflow","id":6445287,"avatar_url":"https://avatars2.githubusercontent.com/u/6445287?v=4","gravatar_id":"","url":"https://api.github.com/users/Dynflow","html_url":"https://github.com/Dynflow","followers_url":"https://api.github.com/users/Dynflow/followers","following_url":"https://api.github.com/users/Dynflow/following{/other_user}","gists_url":"https://api.github.com/users/Dynflow/gists{/gist_id}","starred_url":"https://api.github.com/users/Dynflow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Dynflow/subscriptions","organizations_url":"https://api.github.com/users/Dynflow/orgs","repos_url":"https://api.github.com/users/Dynflow/repos","events_url":"https://api.github.com/users/Dynflow/events{/privacy}","received_events_url":"https://api.github.com/users/Dynflow/received_events","type":"Organization","site_admin":false},"repo":{"id":9658764,"name":"dynflow","full_name":"Dynflow/dynflow","owner":{"login":"Dynflow","id":6445287,"avatar_url":"https://avatars2.githubusercontent.com/u/6445287?v=4","gravatar_id":"","url":"https://api.github.com/users/Dynflow","html_url":"https://github.com/Dynflow","followers_url":"https://api.github.com/users/Dynflow/followers","following_url":"https://api.github.com/users/Dynflow/following{/other_user}","gists_url":"https://api.github.com/users/Dynflow/gists{/gist_id}","starred_url":"https://api.github.com/users/Dynflow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Dynflow/subscriptions","organizations_url":"https://api.github.com/users/Dynflow/orgs","repos_url":"https://api.github.com/users/Dynflow/repos","events_url":"https://api.github.com/users/Dynflow/events{/privacy}","received_events_url":"https://api.github.com/users/Dynflow/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Dynflow/dynflow","description":"DYNamic workFLOW orchestration engine","fork":false,"url":"https://api.github.com/repos/Dynflow/dynflow","forks_url":"https://api.github.com/repos/Dynflow/dynflow/forks","keys_url":"https://api.github.com/repos/Dynflow/dynflow/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Dynflow/dynflow/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Dynflow/dynflow/teams","hooks_url":"https://api.github.com/repos/Dynflow/dynflow/hooks","issue_events_url":"https://api.github.com/repos/Dynflow/dynflow/issues/events{/number}","events_url":"https://api.github.com/repos/Dynflow/dynflow/events","assignees_url":"https://api.github.com/repos/Dynflow/dynflow/assignees{/user}","branches_url":"https://api.github.com/repos/Dynflow/dynflow/branches{/branch}","tags_url":"https://api.github.com/repos/Dynflow/dynflow/tags","blobs_url":"https://api.github.com/repos/Dynflow/dynflow/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Dynflow/dynflow/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Dynflow/dynflow/git/refs{/sha}","trees_url":"https://api.github.com/repos/Dynflow/dynflow/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Dynflow/dynflow/statuses/{sha}","languages_url":"https://api.github.com/repos/Dynflow/dynflow/languages","stargazers_url":"https://api.github.com/repos/Dynflow/dynflow/stargazers","contributors_url":"https://api.github.com/repos/Dynflow/dynflow/contributors","subscribers_url":"https://api.github.com/repos/Dynflow/dynflow/subscribers","subscription_url":"https://api.github.com/repos/Dynflow/dynflow/subscription","commits_url":"https://api.github.com/repos/Dynflow/dynflow/commits{/sha}","git_commits_url":"https://api.github.com/repos/Dynflow/dynflow/git/commits{/sha}","comments_url":"https://api.github.com/repos/Dynflow/dynflow/comments{/number}","issue_comment_url":"https://api.github.com/repos/Dynflow/dynflow/issues/comments{/number}","contents_url":"https://api.github.com/repos/Dynflow/dynflow/contents/{+path}","compare_url":"https://api.github.com/repos/Dynflow/dynflow/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Dynflow/dynflow/merges","archive_url":"https://api.github.com/repos/Dynflow/dynflow/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Dynflow/dynflow/downloads","issues_url":"https://api.github.com/repos/Dynflow/dynflow/issues{/number}","pulls_url":"https://api.github.com/repos/Dynflow/dynflow/pulls{/number}","milestones_url":"https://api.github.com/repos/Dynflow/dynflow/milestones{/number}","notifications_url":"https://api.github.com/repos/Dynflow/dynflow/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Dynflow/dynflow/labels{/name}","releases_url":"https://api.github.com/repos/Dynflow/dynflow/releases{/id}","deployments_url":"https://api.github.com/repos/Dynflow/dynflow/deployments","created_at":"2013-04-24T22:13:43Z","updated_at":"2018-02-05T05:07:41Z","pushed_at":"2018-02-26T16:15:09Z","git_url":"git://github.com/Dynflow/dynflow.git","ssh_url":"git@github.com:Dynflow/dynflow.git","clone_url":"https://github.com/Dynflow/dynflow.git","svn_url":"https://github.com/Dynflow/dynflow","homepage":"http://dynflow.github.io","size":2229,"stargazers_count":58,"watchers_count":58,"language":"Ruby","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":32,"mirror_url":null,"archived":false,"open_issues_count":20,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":32,"open_issues":20,"watchers":58,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Dynflow/dynflow/pulls/270"},"html":{"href":"https://github.com/Dynflow/dynflow/pull/270"},"issue":{"href":"https://api.github.com/repos/Dynflow/dynflow/issues/270"},"comments":{"href":"https://api.github.com/repos/Dynflow/dynflow/issues/270/comments"},"review_comments":{"href":"https://api.github.com/repos/Dynflow/dynflow/pulls/270/comments"},"review_comment":{"href":"https://api.github.com/repos/Dynflow/dynflow/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Dynflow/dynflow/pulls/270/commits"},"statuses":{"href":"https://api.github.com/repos/Dynflow/dynflow/statuses/2019f135a0046302c50a38433f3581c8296baed3"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"iNecas"}}