Event Handlers

Events are everywhere in the software development and operations processes. Our source code repositories generate events. Our CI systems generate events. Our runtime platforms generate events. Our services generate events. Our issue tracking systems generate events. Everything seems to generated events.

Atomist believes that bringing all these events together so they can be connected and acted upon provides tremendous value for shipping better code faster. The mechanism for realizing this promise is to automate event responses using Rug event handlers.

Event handlers define automated responses to events. Each event handler is a program in a familiar Turing-complete language. Based on the characteristics of the event that occurred, the handler decides whether act and which actions to take.

A new issue was created? Post that in the repository’s chat channel and also add buttons to the message that let people apply labels or claim the issue without leaving chat.

A developer submits a pull request in a library? Find out whether it will to impact a service that uses the library: create a branch in the service, modify the code to update the dependency. The service build completes successfully? Update the library’s pull request (PR), and tell the developer all the news.

A person in chat asks Atomist “what did I do today?”? Respond by listing the issues they updated, the PRs they reviewed, and the commits they pushed.

Below is a basic Rug event handler which should make it clear how the above behaviours could be achieved.

A Basic Event Handler

The following event handler responds when a tag is added to or deleted from an issue. When this event occurs, the Atomist Bot sends a message to the repository’s Slack channel informing people in the channel about the tagging event.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { HandleEvent, Message } from '@atomist/rug/operations/Handlers'
import { GraphNode, Match, PathExpression } from '@atomist/rug/tree/PathExpression'
import { EventHandler, Tags } from '@atomist/rug/operations/Decorators'

@EventHandler("TagHandler", "Handles tag events", "/Tag")
@Tags("github", "tag")
export class TagHandler implements HandleEvent<GraphNode, GraphNode> {
    handle(event: Match<GraphNode, GraphNode>): Message {
        let message = new Message("Tag event!");
        return message.withNode(event.root());
    }
}
export const tagHandler = new TagHandler();

As you can see, Rug event handlers and Rug command handlers are very similar. In fact, the only significant difference is in the way they are invoked; event handlers are invoked by the Rug runtime in response to events ingested by Atomist, whereas command handlers are either invoked directly by users via the Atomist bot, or via the running of a Plan returned by a CommandHandler, EventHandler or ResponseHandler.

Declaring an event handler is done using the @EventHandler class decorator, which like @CommandHandler, requires name and description. Additionally however, it requires a Path Expression, which registers the handler as handling new new events resulting from the expression execution.