@title Herald User Guide
@group userguide

Use Herald to get notified of changes you care about.

Overview
========

Herald allows you to write rules which run automatically when objects (like
tasks or commits) are created or updated. For instance, you might want to get
notified every time someone sends out a revision that affects some file you're
interested in, even if they didn't add you as a reviewer.

One way to think about Herald is that it is a lot like the mail rules you can
set up in most email clients to organize mail based on "To", "Subject", etc.
Herald works very similarly, but operates on Phabricator objects (like revisions
and commits) instead of emails.

For example, you can write a personal rule like this which triggers on tasks:

> When [ all of ] these conditions are met:
> [ Title ][ contains ][ quasar ]
> Take these actions [ every time this rule matches: ]
> [ Add me as a subscriber ]

This rule will automatically subscribe you to any newly created or updated
tasks that contain "quasar" in the title.

Herald rules are often used to: notify users, add reviewers, initiate audits,
classify objects, block commits, enforce CLAs, and run builds.


Working with Rules
==================

To create new Herald rules, navigate to the {nav Herald} application and select
{nav Create Herald Rule}.

Next, you'll choose an event that you want to write a rule for: for example,
a rule for when commits are discovered or a rule for when tasks are created or
updated.

After selecting an event, choose the type of rule to create. See "Rule Types"
below for a more detailed discussion.

Name the rule and provide conditions and actions. When events occur, the rule
will be evaluated automatically. If the conditions pass, the actions will be
taken.

To test rules, use {nav Herald > Test Console}. See "Testing Rules" below
for greater detail.

To review which rules did or did not trigger for a particular event (and why),
see {nav Herald > Transcripts}.


Rule Types
==========

You can create three kinds of Herald rules: personal rules, object rules, and
global rules.

  - **Personal Rules** are rules owned by an individual. They're often used
    to keep people informed about changes they're interested in.
  - **Object Rules** are rules associated with an object (like a repository
    or project). These are similar to global rules.
  - **Global Rules** are apply to all objects. They're often used to block
    commits or run builds.


Rule Policies
=============

All Herald rules are always visible to all users.

The edit policy for a rule depends on what type of rule it is:

  - Personal rules are owned by a particular user, and can only be created or
    edited by that user.
  - Object rules are associated with a particular object (like a repository),
    and can only be created or edited by users who can edit that object. That
    is, if you can edit a repository, you can also create object rules for it
    and edit existing object rules.
  - Global rules are administrative and can only be created or edited by users
    with the **Can Manage Global Rules** Herald application permission.

When rules are about to evaluate, they may first perform some policy tests.

  - Personal rules check if the owning user can see the object which the rule
    is about to run on. If the user can not see the object, the rule does not
    run. This prevents individuals from writing rules which give them access
    to information they don't have permission to see.
  - Object and global rules **bypass policies** and always execute. This makes
    them very powerful, and is why the **Can Manage Global Rules** policy is
    restricted by default.


Testing Rules
=============

When you've created a rule, use the {nav Herald > Test Console} to test it out.

Enter an object name (like `D123`, `rXYZabcdef`, or `T456`) and Herald will
execute a dry run against that object, showing you which rules //would// match
had it actually been updated. Dry runs executed via the test console don't take
any actions.


Action Repetition Settings
==========================

Rules can be configured to act in different ways:

**Every time the rule matches:** The rule will take actions every time the
object is updated if the rule's conditions match the current object state.

**Only the first time the rule matches:** The rule will take actions only once
per object, regardless of how many times the object is updated. After the rule
acts once, it won't run on the same object again.

**If this rule did not match the last time:** This rule will take actions the
first time it matches for an object. After that, it won't act unless the object
just changed from not matching to matching.

For example, suppose you have a rule like this:

> When:
> [ Title ][ contains ][ duck ]
> Take actions [ if this rule did not match the last time: ]
> [ Add comment ][ "Please prefer the term 'budget goose'." ]

If you set this rule to act "every time", it will leave a comment on the task
for every single update until the title is edited. This is usually pretty noisy.

If you set this rule to act "only the first time", it will only leave one
comment. This fixes the noise problem, but creates a new problem: if someone
edits the title, then a later change breaks it again, the rule won't leave
another reminder comment.

If you set this rule to act "if it did not match the last time", it will leave
one comment on matching tasks. If the task is fixed (by replacing the term
"duck" with the term "budget goose", so the object no longer matches the rule)
and then later changed to violate the rule again (by putting the term
"duck" back in the title), the rule will act again.


Advanced Herald
===============

A few features in Herald are particularly complicated or unintuitive.

Condition **matches regexp pair**: Some conditions allow you to select the
operator "matches regexp pair". For example, you can write a rule against
revisions like this one:

> When [ all of ] these conditions are met:
> [ Changed file content ][ matches regexp pair ][ ... ]

This condition allows you to specify two regexes in JSON format. The first will
be used to match the filename of the changed file; the second will be used to
match the content. You can use these together to express conditions like
"content in Javascript files".

For example, if you want to match revisions which add or remove calls to a
"muffinize" function, //but only in JS files//, you can set the value to
`["/\\.js$/", "/muffinize/"]` or similar. This condition is satisfied only
when the filename matches the first expression and the content matches the
second expression.

**Another Herald rule**: you can create Herald rules which depend on other
rules.

This can be useful if you need to express a more complicated condition
than "all" vs "any" allows, or have a common set of conditions which you want
to share between several rules.

If a rule is only being used as a group of conditions, you can set the action
to "Do Nothing".
