@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Create revisions into "Draft", publish them when builds finish

Summary:
Ref T2543. This doesn't stand alone since mail still goes out normally, but gets this piece working: new revisions start as "Draft", then after updates if there are no builds they go into "Needs Review".

This should work in general because builds update revisions when they complete, to publish a "Harbormaster finished build yada yada" transaction. So either we'll un-draft immediately, or un-draft after the last build finishes.

I'll hold this until the mail and some other stuff (like UI hints) are in slightly better shape since I think it's probably too rough on its own.

Test Plan: Created revisions locally, saw them un-draft after builds.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T2543

Differential Revision: https://secure.phabricator.com/D18628

+104 -4
+3 -1
src/applications/config/editor/PhabricatorConfigEditor.php
··· 107 107 return parent::transactionHasEffect($object, $xaction); 108 108 } 109 109 110 - protected function didApplyTransactions(array $xactions) { 110 + protected function didApplyTransactions($object, array $xactions) { 111 111 // Force all the setup checks to run on the next page load. 112 112 PhabricatorSetupCheck::deleteSetupCheckCache(); 113 + 114 + return $xactions; 113 115 } 114 116 115 117 public static function storeNewValue(
+98
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 1528 1528 return array_reverse($xactions); 1529 1529 } 1530 1530 1531 + 1532 + protected function didApplyTransactions($object, array $xactions) { 1533 + // If a draft revision has no outstanding builds and we're automatically 1534 + // making drafts public after builds finish, make the revision public. 1535 + $auto_undraft = true; 1536 + 1537 + if ($object->isDraft() && $auto_undraft) { 1538 + $active_builds = $this->hasActiveBuilds($object); 1539 + if (!$active_builds) { 1540 + $xaction = $object->getApplicationTransactionTemplate() 1541 + ->setTransactionType( 1542 + DifferentialRevisionRequestReviewTransaction::TRANSACTIONTYPE) 1543 + ->setOldValue(false) 1544 + ->setNewValue(true); 1545 + 1546 + $xaction = $this->populateTransaction($object, $xaction); 1547 + 1548 + // If we're creating this revision and immediately moving it out of 1549 + // the draft state, mark this as a create transaction so it gets 1550 + // hidden in the timeline and mail, since it isn't interesting: it 1551 + // is as though the draft phase never happened. 1552 + if ($this->getIsNewObject()) { 1553 + $xaction->setIsCreateTransaction(true); 1554 + } 1555 + 1556 + $object->openTransaction(); 1557 + $object 1558 + ->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW) 1559 + ->save(); 1560 + 1561 + $xaction->save(); 1562 + $object->saveTransaction(); 1563 + 1564 + $xactions[] = $xaction; 1565 + } 1566 + } 1567 + 1568 + return $xactions; 1569 + } 1570 + 1571 + private function hasActiveBuilds($object) { 1572 + $viewer = $this->requireActor(); 1573 + $diff = $object->getActiveDiff(); 1574 + 1575 + $buildables = id(new HarbormasterBuildableQuery()) 1576 + ->setViewer($viewer) 1577 + ->withContainerPHIDs(array($object->getPHID())) 1578 + ->withBuildablePHIDs(array($diff->getPHID())) 1579 + ->withManualBuildables(false) 1580 + ->execute(); 1581 + if (!$buildables) { 1582 + return false; 1583 + } 1584 + 1585 + $builds = id(new HarbormasterBuildQuery()) 1586 + ->setViewer($viewer) 1587 + ->withBuildablePHIDs(mpull($buildables, 'getPHID')) 1588 + ->withBuildStatuses( 1589 + array( 1590 + HarbormasterBuildStatus::STATUS_INACTIVE, 1591 + HarbormasterBuildStatus::STATUS_PENDING, 1592 + HarbormasterBuildStatus::STATUS_BUILDING, 1593 + HarbormasterBuildStatus::STATUS_FAILED, 1594 + HarbormasterBuildStatus::STATUS_ABORTED, 1595 + HarbormasterBuildStatus::STATUS_ERROR, 1596 + HarbormasterBuildStatus::STATUS_PAUSED, 1597 + HarbormasterBuildStatus::STATUS_DEADLOCKED, 1598 + )) 1599 + ->needBuildTargets(true) 1600 + ->execute(); 1601 + if (!$builds) { 1602 + return false; 1603 + } 1604 + 1605 + $active = array(); 1606 + foreach ($builds as $key => $build) { 1607 + foreach ($build->getBuildTargets() as $target) { 1608 + if ($target->isAutotarget()) { 1609 + // Ignore autotargets when looking for active of failed builds. If 1610 + // local tests fail and you continue anyway, you don't need to 1611 + // double-confirm them. 1612 + continue; 1613 + } 1614 + 1615 + // This build has at least one real target that's doing something. 1616 + $active[$key] = $build; 1617 + break; 1618 + } 1619 + } 1620 + 1621 + if (!$active) { 1622 + return false; 1623 + } 1624 + 1625 + return true; 1626 + } 1627 + 1628 + 1531 1629 }
+3 -3
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 1105 1105 $this->heraldForcedEmailPHIDs = $adapter->getForcedEmailPHIDs(); 1106 1106 } 1107 1107 1108 - $this->didApplyTransactions($xactions); 1108 + $xactions = $this->didApplyTransactions($object, $xactions); 1109 1109 1110 1110 if ($object instanceof PhabricatorCustomFieldInterface) { 1111 1111 // Maybe this makes more sense to move into the search index itself? For ··· 1234 1234 return $xactions; 1235 1235 } 1236 1236 1237 - protected function didApplyTransactions(array $xactions) { 1237 + protected function didApplyTransactions($object, array $xactions) { 1238 1238 // Hook for subclasses. 1239 - return; 1239 + return $xactions; 1240 1240 } 1241 1241 1242 1242