One of the most highly requested features in Stash has been commit hooks. Git has an in-built mechanism called “hooks” which allows you to hook into just before and after a push event. In Git, hooks are scripts that must be placed on the filesystem in each repository, which requires a system administrator with the appropriate access to copy scripts around manually. That’s not exactly a great user experience – we can do better! We started dreaming up ways to make Git hooks more accessible to the masses Stash. Users can create hooks without having to write bash scripts and upload them to the filesystem. Hooks will be able to harness the full power of the Altassian ecosystem. Users will be able to share and sell their hooks on the Atlassian Marketplace. Pre and Post Receive Hooks Currently there are three integration points in the recently released Stash 2.2 for hooks: Pre-receive hooks Merge checks Post-receive hooks Pre-receive mirrors the behaviour of the Git hook and will run when a client pushes a branch or branches to Stash. It’s important to note that this hook isn’t called when merging a pull-request. For that you can define a merge-check, which allows you to veto a potential merge of a pull-request until one or more conditions are met. This might include requiring a minimum number of acceptances, or that all the associated builds are green (so you don’t break master). A post-receive hook will fire when a push or merge has been successful, allowing you to notify external systems, like JIRA or Bamboo, of changes to a given repository. Doing all this in a shell script is certainly possible, but it isn’t going to make use of Stash’s powerful API and ecosystem which is perfect for building hooks. To assist in making a kick-ass developer experience, not only should you be able to create a custom hook, it should also be dead-simple to add custom settings. Currently, storing data against a repository can be done manually with plugin settings or Active Objects; for simple plugins this is too much overhead. Finally we wanted a sexy UI that would allow these hooks to be enabled/disabled and configured on a per-repository basis. Something like this. Less talk, more code As a simple example, let’s create a hook that notifies members of a team that new changes are available. A good way to broadcast that might be to use HipChat, a team-based group chat and IM client. 12345678910111213141516171819202122public class HipChatNotifyHook implements AsyncPostReceiveRepositoryHook, RepositorySettingsValidator { private static final String AUTH_TOKEN_KEY = "authToken"; private static final String ROOM_NAME_KEY = "roomName"; @Override public void postReceive(HookContext context, Collection refChanges) { String room = context.getSettings().getString(ROOM_NAME_KEY); createClient(context.getSettings()).notifyRoom(room, "Stash", HipChatTemplates.buildHtml(refChanges)); } @Override public void validate(Settings settings, SettingsValidationErrors errors, Repository repository) { if (createClient(settings).authTest()) { errors.addFieldError(AUTH_TOKEN_KEY, "Invalid authorization token"); [...]