public function applyOperation(DrydockRepositoryOperation $operation, DrydockInterface $interface) { $viewer = $this->getViewer(); $repository = $operation->getRepository(); $cmd = array(); $arg = array(); $object = $operation->getObject(); if ($object instanceof DifferentialRevision) { $revision = $object; $diff_phid = $operation->getProperty('differential.diffPHID'); $diff = id(new DifferentialDiffQuery())->setViewer($viewer)->withPHIDs(array($diff_phid))->executeOne(); if (!$diff) { throw new Exception(pht('Unable to load diff "%s".', $diff_phid)); } $diff_revid = $diff->getRevisionID(); $revision_id = $revision->getID(); if ($diff_revid != $revision_id) { throw new Exception(pht('Diff ("%s") has wrong revision ID ("%s", expected "%s").', $diff_phid, $diff_revid, $revision_id)); } $cmd[] = 'git fetch --no-tags -- %s +%s:%s'; $arg[] = $repository->getStagingURI(); $arg[] = $diff->getStagingRef(); $arg[] = $diff->getStagingRef(); $merge_src = $diff->getStagingRef(); $dict = $diff->getDiffAuthorshipDict(); $author_name = idx($dict, 'authorName'); $author_email = idx($dict, 'authorEmail'); $api_method = 'differential.getcommitmessage'; $api_params = array('revision_id' => $revision->getID()); $commit_message = id(new ConduitCall($api_method, $api_params))->setUser($viewer)->execute(); } else { throw new Exception(pht('Invalid or unknown object ("%s") for land operation, expected ' . 'Differential Revision.', $operation->getObjectPHID())); } $target = $operation->getRepositoryTarget(); list($type, $name) = explode(':', $target, 2); switch ($type) { case 'branch': $push_dst = 'refs/heads/' . $name; $merge_dst = 'refs/remotes/origin/' . $name; break; default: throw new Exception(pht('Unknown repository operation target type "%s" (in target "%s").', $type, $target)); } $committer_info = $this->getCommitterInfo($operation); $cmd[] = 'git checkout %s'; $arg[] = $merge_dst; $cmd[] = 'git merge --no-stat --squash --ff-only -- %s'; $arg[] = $merge_src; $cmd[] = 'git -c user.name=%s -c user.email=%s commit --author %s -m %s'; $arg[] = $committer_info['name']; $arg[] = $committer_info['email']; $arg[] = "{$author_name} <{$author_email}>"; $arg[] = $commit_message; $cmd[] = 'git push origin -- %s:%s'; $arg[] = 'HEAD'; $arg[] = $push_dst; $cmd = implode(' && ', $cmd); $argv = array_merge(array($cmd), $arg); $result = call_user_func_array(array($interface, 'execx'), $argv); }
private function loadWorkingCopyLease(DrydockRepositoryOperation $operation) { $viewer = $this->getViewer(); // TODO: This is very similar to leasing in Harbormaster, maybe we can // share some of the logic? $lease_phid = $operation->getProperty('exec.leasePHID'); if ($lease_phid) { $lease = id(new DrydockLeaseQuery())->setViewer($viewer)->withPHIDs(array($lease_phid))->executeOne(); if (!$lease) { throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" could not be loaded.', $lease_phid)); } } else { $working_copy_type = id(new DrydockWorkingCopyBlueprintImplementation())->getType(); $repository = $operation->getRepository(); $allowed_phids = $repository->getAutomationBlueprintPHIDs(); $authorizing_phid = $repository->getPHID(); $lease = DrydockLease::initializeNewLease()->setResourceType($working_copy_type)->setOwnerPHID($operation->getPHID())->setAuthorizingPHID($authorizing_phid)->setAllowedBlueprintPHIDs($allowed_phids); $map = $this->buildRepositoryMap($operation); $lease->setAttribute('repositories.map', $map); $task_id = $this->getCurrentWorkerTaskID(); if ($task_id) { $lease->setAwakenTaskIDs(array($task_id)); } $operation->setProperty('exec.leasePHID', $lease->getPHID())->save(); $lease->queueForActivation(); } if ($lease->isActivating()) { throw new PhabricatorWorkerYieldException(15); } if (!$lease->isActive()) { throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" never activated.', $lease->getPHID())); } return $lease; }
private function loadDiff(DrydockRepositoryOperation $operation) { $viewer = $this->getViewer(); $revision = $operation->getObject(); $diff_phid = $operation->getProperty('differential.diffPHID'); $diff = id(new DifferentialDiffQuery())->setViewer($viewer)->withPHIDs(array($diff_phid))->executeOne(); if (!$diff) { throw new Exception(pht('Unable to load diff "%s".', $diff_phid)); } $diff_revid = $diff->getRevisionID(); $revision_id = $revision->getID(); if ($diff_revid != $revision_id) { throw new Exception(pht('Diff ("%s") has wrong revision ID ("%s", expected "%s").', $diff_phid, $diff_revid, $revision_id)); } return $diff; }