Page MenuHomePhabricator

Support workboard column triggers which activate when a task is dropped into a column
Closed, ResolvedPublic

Assigned To
Authored By
Jun 25 2014, 12:39 PM
Referenced Files
F6440292: image.png
May 9 2019, 6:50 PM
F1920098: dl8cf.jpg
Nov 13 2016, 8:55 PM
F1920071: demo.mp4
Nov 13 2016, 8:49 PM
"Party Time" token, awarded by mbinder."Party Time" token, awarded by spawnlt."Like" token, awarded by maxim.efremoff."Pterodactyl" token, awarded by yingshu."Love" token, awarded by MatanUbe."Like" token, awarded by siepkes."Like" token, awarded by arpagon."Love" token, awarded by G3292."Burninate" token, awarded by fumoboy007."Love" token, awarded by franjesus."Manufacturing Defect?" token, awarded by buoowl."Love" token, awarded by NDKilla."Like" token, awarded by isfs."Burninate" token, awarded by MissyTS."Burninate" token, awarded by janitorial."Like" token, awarded by vpavlushkov."Like" token, awarded by tetrapus."Love" token, awarded by danieldanciu."Like" token, awarded by n3v3rf411."Yellow Medal" token, awarded by beverly."Manufacturing Defect?" token, awarded by mreeder."Burninate" token, awarded by dmitry.shulga."Love" token, awarded by brett."Love" token, awarded by tomekj2ee."Like" token, awarded by jkrets."Love" token, awarded by Sohojoe."Like" token, awarded by Croakx."Love" token, awarded by groenroos."Like" token, awarded by zhiyuchen."Love" token, awarded by mbenua-mparticle."Like" token, awarded by brianespinosa."Like" token, awarded by jon.rimmer."Like" token, awarded by Netrics."Love" token, awarded by azurasean."Like" token, awarded by jaie.wilson."Party Time" token, awarded by edouard.kaiser."Like" token, awarded by jlap."Evil Spooky Haunted Tree" token, awarded by shandor."Like" token, awarded by carwyn."Like" token, awarded by ocrete."Like" token, awarded by rphl."Like" token, awarded by dmgarcia."Love" token, awarded by stevex."Like" token, awarded by adam93."Love" token, awarded by kontextbewusst."Love" token, awarded by st_we."Like" token, awarded by rabahmeradi."Love" token, awarded by nhitze."Love" token, awarded by demix."Pterodactyl" token, awarded by Yuriovich."Love" token, awarded by jstejada."Mountain of Wealth" token, awarded by snaik."Like" token, awarded by fbu."Love" token, awarded by apfols."Love" token, awarded by bernard.oflynn."Like" token, awarded by scott.horsley."Like" token, awarded by lgazo."Like" token, awarded by venky."Like" token, awarded by vanmeeuwen."Like" token, awarded by helenhousandi."Like" token, awarded by fschloegl."The World Burns" token, awarded by chad."Love" token, awarded by seungrye."Like" token, awarded by remusvrm."Like" token, awarded by kebe."Like" token, awarded by jonathanrseawright."Like" token, awarded by mrjoops."Like" token, awarded by AnysM."Like" token, awarded by monsdar."Like" token, awarded by gurrinder."Like" token, awarded by c.mertins."Like" token, awarded by cguenther."Like" token, awarded by dereknex."Love" token, awarded by overlordtm."Like" token, awarded by jarrod."Love" token, awarded by spiridon-alexandru."Like" token, awarded by Instinct64."Like" token, awarded by trevorsummerssmith."Love" token, awarded by ilich."Pterodactyl" token, awarded by eserrano."Like" token, awarded by dmgander."Love" token, awarded by chrisportela."Like" token, awarded by jonasoberschweiber."Like" token, awarded by wschroo."Love" token, awarded by cmmata."Love" token, awarded by utrack."Like" token, awarded by jcowgar."Love" token, awarded by manas-chaudhari."Love" token, awarded by grmbl."Like" token, awarded by mliberty."Love" token, awarded by joncalhoun."Love" token, awarded by guayosr."Like" token, awarded by franshamk."Like" token, awarded by mufid."Love" token, awarded by Luke081515.2."Like" token, awarded by frahmj."Like" token, awarded by stevenjt."Like" token, awarded by r0bbie."Like" token, awarded by phpeach."Like" token, awarded by boruchy."Mountain of Wealth" token, awarded by timor."Like" token, awarded by OCram."Like" token, awarded by nateguchi2."Pterodactyl" token, awarded by tycho.tatitscheff."Like" token, awarded by bobek."Like" token, awarded by ivh."Like" token, awarded by anda."Like" token, awarded by gerriet."Love" token, awarded by brablc."Love" token, awarded by mholden."Like" token, awarded by mjamil."Like" token, awarded by helix."Love" token, awarded by calfzhou."Like" token, awarded by TeeLicht."Like" token, awarded by lperrin."Like" token, awarded by hartman."Like" token, awarded by vgoetz."Love" token, awarded by lukasz.roth."Like" token, awarded by michaeloa."Like" token, awarded by xiaogaozi.


We plan to support triggers, which let you make columns apply behavior. For example:

  • When a task is dropped into this column, close it as "Resolved".
  • When a task is dropped into this column, require it to be assigned to a user.
  • When a task is dropped into this column, set custom field "My Special Workflow Status" to value "In Progress".

Related Objects

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

My small team & I have been using Phabricator for a year. This is the feature that we lack and that makes our day-to-day work difficult. It would be nice to have even the basics (drag & drop to a column -> update to a given status). Any advise or workaround in the meanwhile would also be nice if they are some. Sorry if I lack Phabricator knowledge and missed an obvious workaround feature.

@epriestley, @chad > The paid prioritization Chad mentionned in 2015 is apparently not a thing anymore, and the Roadmap page was not updated since 300d+. Can I guess it means users can't have more visibility on this than the entry's status itself? Or did I miss a valuable page? It's always nice to get an idea of when an expected feature will be done, even roughly.

There is no secret tracker with a different set of priorities or timelines
for features. Everything we plan is 100% open. This feature is not on any
short or medium term roadmap and you can read Planning for more
information on how we build the roadmap. We do plan to offer paid support
soon which will let installs prioritize features they need.

+1 that this is really needed.

FYI to everyone, looks like this feature is on the starmap.

The other side of the status-column relationship is also needed btw for a decent workflow: T6409

@kislinsk Is it possible to externalize your solution? I have no information about the status of Phabricator supporting extensions but when there is a way to separate your solution from the core cleanly, why not creating a repository on GitHub? I would love to use this right now! :D

Currently, you can put a task in a column in these ways:

  1. By dragging it on a workboard.
  2. As part of a bulk move via Move Tasks to Column... on a workboard.
  3. Via the Move on Workboard action in the comment area.
  4. Implicitly, by adding a project tag, to put a task in the "Backlog" column.

For now, I'm only going to make method (1) activate triggers. I'm probably going to prevent triggers from being attached to the "Backlog" column to make it more clear that method (4) does not work and does not activate triggers.

The general idea is that triggers are a convenience, not a strict workflow constraint. You can always put a task in a state which violates triggers in these ways:

  • Drag a task to a column, then edit it with the "Edit" workflow or API.
  • Drag a task to a column, then edit it by dragging it to some contradictory column on some other board which it's also on.
  • Drag a task to a column, then edit the triggers for that column to imply some other state.

That is, when you apply some kind of edit to an object, we aren't going to check that the edit conforms to all the triggers in all the columns the object is present in. I think this would often be a confusing mess with no way forward, and it would make certain flows fairly absurd, e.g.:

You can not add a "Change Status: Resolved" trigger rule to this trigger ruleset because the ruleset is used by one or more columns which have one or more tasks in that are currently also in columns on other boards which have contradictory trigger rules. For each column in conflict: change the trigger rules; or remove all the conflicting tasks from the column; or remove all conflicting tasks from other conflicting columns so that they are no longer in conflict. Resolve all conflicts to continue.

BoardColumnTaskConflicting BoardConflicting ColumnConflicting RulesetConflicting Rule
EngineDoneT123: Yorble a FlorbleEngineeringIn ProgressTriggers 38: Engineering TriggersChange Status: In Progress

I want to avoid having this kind of state in the product. I think users making reasonable use of this feature will never really hit this (tasks won't be on multiple boards with multiple conflicting states), and users who do hit this are likely to prefer that the operation just works over being handed a quest to slay 90 state conflicts.

Strict constraints would also make it easy to set things up so that a particular drag is impossible, by putting a task in a "Change Status: X" column on board A, then trying to drag it to a "Change Status: Y" column on board B.

In the future, we could improve the ability of triggers to act as a soft constraint by highlighting cards that are not in a state consistent with the column trigger while you're looking at the board. For example:

  • You drag a task to a "Change Status: Resolved" column, which resolves it.
  • You manually edit it to reopen it.
  • On the board, it shows in red to indicate that the task state is currently inconsistent with the column triggers.

At least for the moment, I'm not planning to make methods (2) or (3) apply triggers, although method (2) probably should. I'm less sure about method (3). A naive implementation seems bad and an integration integrated with the action stack seems complex.

I'm currently planning to store trigger rulesets as a separate object with a PHID. I think there are probably two reasonable ways to bind triggers to columns, and we may implement either one or both:

  • Each column has its own TriggerRuleset object. When you copy columns from an existing workboard, the triggers are also copied into a new TriggerRuleset. Although these are separate objects, they mostly act as though they are properties of the column.
  • Each column references an external TriggerRuleset. Multiple columns can reference the same ruleset. When you edit a ruleset referenced by multiple columns, all referenced columns have their behavior updated. A "Copy and Edit Ruleset" option allows you to edit a copy of a ruleset.

These are both pretty similar in terms of what we have to implement. The former approach is probably generally better if rules are simple (e.g., close tasks dropped here) since it means fewer clicks when managing ad-hoc rules. The latter approach is probably better if rules are complex, since it means fewer clicks when managing rules shared across multiple columns.

I could imagine that 95% of usage might go either way. We could simplify the implementation somewhat if I was confident that the simple approach is sufficient (e.g., rulesets would only need to know about one parent column, not multiple potential parent columns), but I strongly suspect (?) it probably (?) isn't.

I think I'll probably implement the complex case first, and then expect to implement the simple case unless feedback suggests that the complex case covers 95% of things already.

Under the complex case, rulesets need their own "Editable By" policy. (In the simple case, we could bind them to the edit policy of the project, since we know they are bound to only one column.) This is fairly straightforward, although we may need to adjust it when copying a ruleset.

I'm inclined to make them globally visible, similar to Herald rules. Users who can see any project a rule is used in must be able to see the rule, and hiding rules selectively means that transaction records sometimes become more mysterious (we can't "Explain Why" and link to a trigger rule if the user can't see the triggers).

This harms use cases like naming a ruleset "My Boss is A Big Jerk Who I Do Not Like Very Much" or putting a lot of sensitive operational details in a "Show Instructions: ..." rule, but these seem like a small loss, and we've survived a similar change from semi-private to public in Herald uneventfully.

Very happy to see that you guys are working on this, thank you. 👍

Wouldn't it detangle a lot of complexity to handle triggers more like actual triggers compared to continuous states, though? If I understand the text above correctly, it seems like you try to continuously ensure a certain task state that is expressed by a trigger rule while the task is in the column. That's something I would be surprised when editing tasks and suddenly there is some "invalid state". My personal natural understanding of triggers is a one-shot action instead of a continuous state. Something that happens *when changing* the column of a task and I can forget about this afterwards. I guess that would also unify the handling of at least (1) and (3).

epriestley claimed this task.

This more or less exists, now. See T13269 for followups and T13074 for additional context.

It looks like these triggers don't run when you move tasks via "Move on Workboard" (instead of drag and drop).

image.png (57×374 px, 8 KB)

Is this expected / intentional?

It looks like these triggers don't run when you move tasks via "Move on Workboard" (instead of drag and drop). Is this expected / intentional?


Currently, you can put a task in a column in these ways:

  1. ...
  2. As part of a bulk move via Move Tasks to Column... on a workboard.
  3. Via the Move on Workboard action in the comment area.
  4. ...


At least for the moment, I'm not planning to make methods (2) or (3) apply triggers, although method (2) probably should. I'm less sure about method (3). A naive implementation seems bad and an integration integrated with the action stack seems complex.

Got it, thanks for clarifying.