Differential D20467 Diff 48843 src/applications/repository/worker/PhabricatorRepositoryCommitPublishWorker.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/repository/worker/PhabricatorRepositoryCommitPublishWorker.php
- This file was moved from src/applications/repository/worker/PhabricatorRepositoryCommitOwnersWorker.php.
| <?php | <?php | ||||
| final class PhabricatorRepositoryCommitOwnersWorker | final class PhabricatorRepositoryCommitPublishWorker | ||||
| extends PhabricatorRepositoryCommitParserWorker { | extends PhabricatorRepositoryCommitParserWorker { | ||||
| protected function getImportStepFlag() { | protected function getImportStepFlag() { | ||||
| return PhabricatorRepositoryCommit::IMPORTED_OWNERS; | return PhabricatorRepositoryCommit::IMPORTED_PUBLISH; | ||||
| } | |||||
| public function getRequiredLeaseTime() { | |||||
| // Herald rules may take a long time to process. | |||||
| return phutil_units('4 hours in seconds'); | |||||
amckinley: I can see that this comes from `PhabricatorRepositoryCommitHeraldWorker`, but maybe it's a good… | |||||
| } | } | ||||
| protected function parseCommit( | protected function parseCommit( | ||||
| PhabricatorRepository $repository, | PhabricatorRepository $repository, | ||||
| PhabricatorRepositoryCommit $commit) { | PhabricatorRepositoryCommit $commit) { | ||||
| if (!$this->shouldSkipImportStep()) { | if (!$this->shouldSkipImportStep()) { | ||||
| $this->triggerOwnerAudits($repository, $commit); | $this->publishCommit($repository, $commit); | ||||
| $commit->writeImportStatusFlag($this->getImportStepFlag()); | $commit->writeImportStatusFlag($this->getImportStepFlag()); | ||||
| } | } | ||||
| if ($this->shouldQueueFollowupTasks()) { | // This is the last task in the sequence, so we don't need to queue any | ||||
| $this->queueTask( | // followup workers. | ||||
| 'PhabricatorRepositoryCommitHeraldWorker', | |||||
| array( | |||||
| 'commitID' => $commit->getID(), | |||||
| )); | |||||
| } | |||||
| } | } | ||||
| private function triggerOwnerAudits( | private function publishCommit( | ||||
| PhabricatorRepository $repository, | PhabricatorRepository $repository, | ||||
| PhabricatorRepositoryCommit $commit) { | PhabricatorRepositoryCommit $commit) { | ||||
| $viewer = PhabricatorUser::getOmnipotentUser(); | $viewer = PhabricatorUser::getOmnipotentUser(); | ||||
| $publisher = $repository->newPublisher(); | $publisher = $repository->newPublisher(); | ||||
| if (!$publisher->shouldPublishCommit($commit)) { | if (!$publisher->shouldPublishCommit($commit)) { | ||||
| return; | return; | ||||
| } | } | ||||
| $commit_phid = $commit->getPHID(); | |||||
| // Reload the commit to get the commit data, identities, and any | |||||
| // outstanding audit requests. | |||||
| $commit = id(new DiffusionCommitQuery()) | |||||
| ->setViewer($viewer) | |||||
| ->withPHIDs(array($commit_phid)) | |||||
| ->needCommitData(true) | |||||
| ->needIdentities(true) | |||||
| ->needAuditRequests(true) | |||||
| ->executeOne(); | |||||
| if (!$commit) { | |||||
| throw new PhabricatorWorkerPermanentFailureException( | |||||
| pht( | |||||
| 'Failed to reload commit "%s".', | |||||
| $commit_phid)); | |||||
| } | |||||
| $xactions = array( | |||||
| $this->newAuditTransactions($commit), | |||||
| $this->newPublishTransactions($commit), | |||||
| ); | |||||
| $xactions = array_mergev($xactions); | |||||
| $acting_phid = $this->getPublishAsPHID($commit); | |||||
| $content_source = $this->newContentSource(); | |||||
| $editor = $commit->getApplicationTransactionEditor() | |||||
| ->setActor($viewer) | |||||
| ->setActingAsPHID($acting_phid) | |||||
| ->setContinueOnNoEffect(true) | |||||
| ->setContinueOnMissingFields(true) | |||||
| ->setContentSource($content_source); | |||||
| try { | |||||
| $raw_patch = $this->loadRawPatchText($repository, $commit); | |||||
| } catch (Exception $ex) { | |||||
| $raw_patch = pht('Unable to generate patch: %s', $ex->getMessage()); | |||||
| } | |||||
| $editor->setRawPatch($raw_patch); | |||||
| $editor->applyTransactions($commit, $xactions); | |||||
| } | |||||
| private function getPublishAsPHID(PhabricatorRepositoryCommit $commit) { | |||||
| if ($commit->hasCommitterIdentity()) { | |||||
| return $commit->getCommitterIdentity()->getIdentityDisplayPHID(); | |||||
| } | |||||
| if ($commit->hasAuthorIdentity()) { | |||||
| return $commit->getAuthorIdentity()->getIdentityDisplayPHID(); | |||||
| } | |||||
| return id(new PhabricatorDiffusionApplication())->getPHID(); | |||||
| } | |||||
| private function newPublishTransactions(PhabricatorRepositoryCommit $commit) { | |||||
| $data = $commit->getCommitData(); | |||||
| $xactions = array(); | |||||
| $xactions[] = $commit->getApplicationTransactionTemplate() | |||||
| ->setTransactionType(PhabricatorAuditTransaction::TYPE_COMMIT) | |||||
| ->setDateCreated($commit->getEpoch()) | |||||
| ->setNewValue( | |||||
| array( | |||||
| 'description' => $data->getCommitMessage(), | |||||
| 'summary' => $data->getSummary(), | |||||
| 'authorName' => $data->getAuthorName(), | |||||
| 'authorPHID' => $commit->getAuthorPHID(), | |||||
| 'committerName' => $data->getCommitDetail('committer'), | |||||
| 'committerPHID' => $data->getCommitDetail('committerPHID'), | |||||
| )); | |||||
| return $xactions; | |||||
| } | |||||
| private function newAuditTransactions(PhabricatorRepositoryCommit $commit) { | |||||
| $viewer = PhabricatorUser::getOmnipotentUser(); | |||||
| $repository = $commit->getRepository(); | |||||
| $affected_paths = PhabricatorOwnerPathQuery::loadAffectedPaths( | $affected_paths = PhabricatorOwnerPathQuery::loadAffectedPaths( | ||||
| $repository, | $repository, | ||||
| $commit, | $commit, | ||||
| PhabricatorUser::getOmnipotentUser()); | PhabricatorUser::getOmnipotentUser()); | ||||
| $affected_packages = PhabricatorOwnersPackage::loadAffectedPackages( | $affected_packages = PhabricatorOwnersPackage::loadAffectedPackages( | ||||
| $repository, | $repository, | ||||
| $affected_paths); | $affected_paths); | ||||
| $commit->writeOwnersEdges(mpull($affected_packages, 'getPHID')); | $commit->writeOwnersEdges(mpull($affected_packages, 'getPHID')); | ||||
| if (!$affected_packages) { | if (!$affected_packages) { | ||||
| return; | return array(); | ||||
| } | |||||
| $commit = id(new DiffusionCommitQuery()) | |||||
| ->setViewer($viewer) | |||||
| ->withPHIDs(array($commit->getPHID())) | |||||
| ->needCommitData(true) | |||||
| ->needAuditRequests(true) | |||||
| ->executeOne(); | |||||
| if (!$commit) { | |||||
| return; | |||||
| } | } | ||||
| $data = $commit->getCommitData(); | $data = $commit->getCommitData(); | ||||
| $author_phid = $data->getCommitDetail('authorPHID'); | $author_phid = $data->getCommitDetail('authorPHID'); | ||||
| $revision_id = $data->getCommitDetail('differential.revisionID'); | $revision_id = $data->getCommitDetail('differential.revisionID'); | ||||
| if ($revision_id) { | if ($revision_id) { | ||||
| $revision = id(new DifferentialRevisionQuery()) | $revision = id(new DifferentialRevisionQuery()) | ||||
| Show All 25 Lines | foreach ($affected_packages as $package) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| $auditor_phids[] = $package->getPHID(); | $auditor_phids[] = $package->getPHID(); | ||||
| } | } | ||||
| // If none of the packages are triggering audits, we're all done. | // If none of the packages are triggering audits, we're all done. | ||||
| if (!$auditor_phids) { | if (!$auditor_phids) { | ||||
| return; | return array(); | ||||
| } | } | ||||
| $audit_type = DiffusionCommitAuditorsTransaction::TRANSACTIONTYPE; | $audit_type = DiffusionCommitAuditorsTransaction::TRANSACTIONTYPE; | ||||
| $owners_phid = id(new PhabricatorOwnersApplication()) | |||||
| ->getPHID(); | |||||
| $content_source = $this->newContentSource(); | |||||
| $xactions = array(); | $xactions = array(); | ||||
| $xactions[] = $commit->getApplicationTransactionTemplate() | $xactions[] = $commit->getApplicationTransactionTemplate() | ||||
| ->setTransactionType($audit_type) | ->setTransactionType($audit_type) | ||||
| ->setNewValue( | ->setNewValue( | ||||
| array( | array( | ||||
| '+' => array_fuse($auditor_phids), | '+' => array_fuse($auditor_phids), | ||||
| )); | )); | ||||
| $editor = $commit->getApplicationTransactionEditor() | return $xactions; | ||||
| ->setActor($viewer) | |||||
| ->setActingAsPHID($owners_phid) | |||||
| ->setContinueOnNoEffect(true) | |||||
| ->setContinueOnMissingFields(true) | |||||
| ->setContentSource($content_source); | |||||
| $editor->applyTransactions($commit, $xactions); | |||||
| } | } | ||||
| private function shouldTriggerAudit( | private function shouldTriggerAudit( | ||||
| PhabricatorRepositoryCommit $commit, | PhabricatorRepositoryCommit $commit, | ||||
| PhabricatorOwnersPackage $package, | PhabricatorOwnersPackage $package, | ||||
| $author_phid, | $author_phid, | ||||
| $revision) { | $revision) { | ||||
| ▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | private function isOwnerInvolved( | ||||
| if ($found_accept) { | if ($found_accept) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| private function loadRawPatchText( | |||||
| PhabricatorRepository $repository, | |||||
| PhabricatorRepositoryCommit $commit) { | |||||
| $viewer = PhabricatorUser::getOmnipotentUser(); | |||||
| $identifier = $commit->getCommitIdentifier(); | |||||
| $drequest = DiffusionRequest::newFromDictionary( | |||||
| array( | |||||
| 'user' => $viewer, | |||||
| 'repository' => $repository, | |||||
| )); | |||||
| $time_key = 'metamta.diffusion.time-limit'; | |||||
| $byte_key = 'metamta.diffusion.byte-limit'; | |||||
| $time_limit = PhabricatorEnv::getEnvConfig($time_key); | |||||
| $byte_limit = PhabricatorEnv::getEnvConfig($byte_key); | |||||
| $diff_info = DiffusionQuery::callConduitWithDiffusionRequest( | |||||
| $viewer, | |||||
| $drequest, | |||||
| 'diffusion.rawdiffquery', | |||||
| array( | |||||
| 'commit' => $identifier, | |||||
| 'linesOfContext' => 3, | |||||
| 'timeout' => $time_limit, | |||||
| 'byteLimit' => $byte_limit, | |||||
| )); | |||||
| if ($diff_info['tooSlow']) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Patch generation took longer than configured limit ("%s") of '. | |||||
| '%s second(s).', | |||||
| $time_key, | |||||
| new PhutilNumber($time_limit))); | |||||
| } | |||||
| if ($diff_info['tooHuge']) { | |||||
| $pretty_limit = phutil_format_bytes($byte_limit); | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Patch size exceeds configured byte size limit ("%s") of %s.', | |||||
| $byte_key, | |||||
| $pretty_limit)); | |||||
| } | |||||
| $file_phid = $diff_info['filePHID']; | |||||
| $file = id(new PhabricatorFileQuery()) | |||||
| ->setViewer($viewer) | |||||
| ->withPHIDs(array($file_phid)) | |||||
| ->executeOne(); | |||||
| if (!$file) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Failed to load file ("%s") returned by "%s".', | |||||
| $file_phid, | |||||
| 'diffusion.rawdiffquery')); | |||||
| } | |||||
| return $file->loadFileData(); | |||||
| } | |||||
| } | } | ||||
I can see that this comes from PhabricatorRepositoryCommitHeraldWorker, but maybe it's a good reason to separate these workers?