@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.

at recaptime-dev/main 206 lines 5.9 kB view raw
1<?php 2 3final class HarbormasterLeaseWorkingCopyBuildStepImplementation 4 extends HarbormasterBuildStepImplementation { 5 6 public function getName() { 7 return pht('Lease Working Copy'); 8 } 9 10 public function getGenericDescription() { 11 return pht('Build a working copy in Drydock.'); 12 } 13 14 public function getBuildStepGroupKey() { 15 return HarbormasterDrydockBuildStepGroup::GROUPKEY; 16 } 17 18 public function execute( 19 HarbormasterBuild $build, 20 HarbormasterBuildTarget $build_target) { 21 $viewer = PhabricatorUser::getOmnipotentUser(); 22 23 $settings = $this->getSettings(); 24 25 // TODO: We should probably have a separate temporary storage area for 26 // execution stuff that doesn't step on configuration state? 27 $lease_phid = $build_target->getDetail('exec.leasePHID'); 28 29 if ($lease_phid) { 30 $lease = id(new DrydockLeaseQuery()) 31 ->setViewer($viewer) 32 ->withPHIDs(array($lease_phid)) 33 ->executeOne(); 34 if (!$lease) { 35 throw new PhabricatorWorkerPermanentFailureException( 36 pht( 37 'Lease "%s" could not be loaded.', 38 $lease_phid)); 39 } 40 } else { 41 $working_copy_type = id(new DrydockWorkingCopyBlueprintImplementation()) 42 ->getType(); 43 44 $allowed_phids = $build_target->getFieldValue('blueprintPHIDs'); 45 if (!is_array($allowed_phids)) { 46 $allowed_phids = array(); 47 } 48 $authorizing_phid = $build_target->getBuildStep()->getPHID(); 49 50 $lease = DrydockLease::initializeNewLease() 51 ->setResourceType($working_copy_type) 52 ->setOwnerPHID($build_target->getPHID()) 53 ->setAuthorizingPHID($authorizing_phid) 54 ->setAllowedBlueprintPHIDs($allowed_phids); 55 56 $map = $this->buildRepositoryMap($build_target); 57 58 $lease->setAttribute('repositories.map', $map); 59 60 $task_id = $this->getCurrentWorkerTaskID(); 61 if ($task_id) { 62 $lease->setAwakenTaskIDs(array($task_id)); 63 } 64 65 // TODO: Maybe add a method to mark artifacts like this as pending? 66 67 // Create the artifact now so that the lease is always disposed of, even 68 // if this target is aborted. 69 $build_target->createArtifact( 70 $viewer, 71 $settings['name'], 72 HarbormasterWorkingCopyArtifact::ARTIFACTCONST, 73 array( 74 'drydockLeasePHID' => $lease->getPHID(), 75 )); 76 77 $lease->queueForActivation(); 78 79 $build_target 80 ->setDetail('exec.leasePHID', $lease->getPHID()) 81 ->save(); 82 } 83 84 if ($lease->isActivating()) { 85 // TODO: Smart backoff? 86 throw new PhabricatorWorkerYieldException(15); 87 } 88 89 if (!$lease->isActive()) { 90 // TODO: We could just forget about this lease and retry? 91 throw new PhabricatorWorkerPermanentFailureException( 92 pht( 93 'Lease "%s" never activated.', 94 $lease->getPHID())); 95 } 96 } 97 98 public function getArtifactOutputs() { 99 return array( 100 array( 101 'name' => pht('Working Copy'), 102 'key' => $this->getSetting('name'), 103 'type' => HarbormasterWorkingCopyArtifact::ARTIFACTCONST, 104 ), 105 ); 106 } 107 108 public function getFieldSpecifications() { 109 return array( 110 'name' => array( 111 'name' => pht('Artifact Name'), 112 'type' => 'text', 113 'required' => true, 114 ), 115 'blueprintPHIDs' => array( 116 'name' => pht('Use Blueprints'), 117 'type' => 'blueprints', 118 'required' => true, 119 ), 120 'repositoryPHIDs' => array( 121 'name' => pht('Also Clone'), 122 'type' => 'datasource', 123 'datasource.class' => 'DiffusionRepositoryDatasource', 124 ), 125 ); 126 } 127 128 private function buildRepositoryMap(HarbormasterBuildTarget $build_target) { 129 $viewer = PhabricatorUser::getOmnipotentUser(); 130 $variables = $build_target->getVariables(); 131 132 $repository_phid = idx($variables, 'repository.phid'); 133 if (!$repository_phid) { 134 throw new Exception( 135 pht( 136 'Unable to determine how to clone the repository for this '. 137 'buildable: it is not associated with a tracked repository.')); 138 } 139 140 $also_phids = $build_target->getFieldValue('repositoryPHIDs'); 141 if (!is_array($also_phids)) { 142 $also_phids = array(); 143 } 144 145 $all_phids = $also_phids; 146 $all_phids[] = $repository_phid; 147 148 $repositories = id(new PhabricatorRepositoryQuery()) 149 ->setViewer($viewer) 150 ->withPHIDs($all_phids) 151 ->execute(); 152 $repositories = mpull($repositories, null, 'getPHID'); 153 154 foreach ($all_phids as $phid) { 155 if (empty($repositories[$phid])) { 156 throw new PhabricatorWorkerPermanentFailureException( 157 pht( 158 'Unable to load repository with PHID "%s".', 159 $phid)); 160 } 161 } 162 163 $map = array(); 164 165 foreach ($also_phids as $also_phid) { 166 $also_repo = $repositories[$also_phid]; 167 $map[$also_repo->getCloneName()] = array( 168 'phid' => $also_repo->getPHID(), 169 'branch' => 'master', 170 ); 171 } 172 173 $repository = $repositories[$repository_phid]; 174 175 $commit = idx($variables, 'buildable.commit'); 176 $ref_uri = idx($variables, 'repository.staging.uri'); 177 $ref_ref = idx($variables, 'repository.staging.ref'); 178 if ($commit) { 179 $spec = array( 180 'commit' => $commit, 181 ); 182 } else if ($ref_uri && $ref_ref) { 183 $spec = array( 184 'ref' => array( 185 'uri' => $ref_uri, 186 'ref' => $ref_ref, 187 ), 188 ); 189 } else { 190 throw new Exception( 191 pht( 192 'Unable to determine how to fetch changes: this buildable does not '. 193 'identify a commit or a staging ref. You may need to configure a '. 194 'repository staging area.')); 195 } 196 197 $directory = $repository->getCloneName(); 198 $map[$directory] = array( 199 'phid' => $repository->getPHID(), 200 'default' => true, 201 ) + $spec; 202 203 return $map; 204 } 205 206}