public function getMethodDescription()
 {
     $types = HarbormasterArtifact::getAllArtifactTypes();
     $types = msort($types, 'getArtifactTypeName');
     $head_key = pht('Key');
     $head_type = pht('Type');
     $head_desc = pht('Description');
     $head_atype = pht('Artifact Type');
     $head_name = pht('Name');
     $head_summary = pht('Summary');
     $out = array();
     $out[] = pht('Use this method to attach artifacts to build targets while running ' . 'builds. Artifacts can be used to carry data through a complex build ' . 'workflow, provide extra information to users, or store build results.');
     $out[] = null;
     $out[] = pht('When creating an artifact, you will choose an `artifactType` from ' . 'this table. These types of artifacts are supported:');
     $out[] = "| {$head_atype} | {$head_name} | {$head_summary} |";
     $out[] = '|-------------|--------------|--------------|';
     foreach ($types as $type) {
         $type_name = $type->getArtifactTypeName();
         $type_const = $type->getArtifactConstant();
         $type_summary = $type->getArtifactTypeSummary();
         $out[] = "| `{$type_const}` | **{$type_name}** | {$type_summary} |";
     }
     $out[] = null;
     $out[] = pht('Each artifact also needs an `artifactKey`, which names the artifact. ' . 'Finally, you will provide some `artifactData` to fill in the content ' . 'of the artifact. The data you provide depends on what type of artifact ' . 'you are creating.');
     foreach ($types as $type) {
         $type_name = $type->getArtifactTypeName();
         $type_const = $type->getArtifactConstant();
         $out[] = $type_name;
         $out[] = '--------------------------';
         $out[] = null;
         $out[] = $type->getArtifactTypeDescription();
         $out[] = null;
         $out[] = pht('Create an artifact of this type by passing `%s` as the ' . '`artifactType`. When creating an artifact of this type, provide ' . 'these parameters as a dictionary to `artifactData`:', $type_const);
         $spec = $type->getArtifactParameterSpecification();
         $desc = $type->getArtifactParameterDescriptions();
         $out[] = "| {$head_key} | {$head_type} | {$head_desc} |";
         $out[] = '|-------------|--------------|--------------|';
         foreach ($spec as $key => $key_type) {
             $key_desc = idx($desc, $key);
             $out[] = "| `{$key}` | //{$key_type}// | {$key_desc} |";
         }
         $example = $type->getArtifactDataExample();
         if ($example !== null) {
             $json = new PhutilJSON();
             $rendered = $json->encodeFormatted($example);
             $out[] = pht('For example:');
             $out[] = '```lang=json';
             $out[] = $rendered;
             $out[] = '```';
         }
     }
     return implode("\n", $out);
 }
 public function getArtifactImplementation()
 {
     if ($this->artifactImplementation === null) {
         $type = $this->getArtifactType();
         $impl = HarbormasterArtifact::getArtifactType($type);
         if (!$impl) {
             return null;
         }
         $impl = clone $impl;
         $impl->setBuildArtifact($this);
         $this->artifactImplementation = $impl;
     }
     return $this->artifactImplementation;
 }
 public function createArtifact(PhabricatorUser $actor, $artifact_key, $artifact_type, array $artifact_data)
 {
     $impl = HarbormasterArtifact::getArtifactType($artifact_type);
     if (!$impl) {
         throw new Exception(pht('There is no implementation available for artifacts of type "%s".', $artifact_type));
     }
     $impl->validateArtifactData($artifact_data);
     $artifact = HarbormasterBuildArtifact::initializeNewBuildArtifact($this)->setArtifactKey($artifact_key)->setArtifactType($artifact_type)->setArtifactData($artifact_data);
     $impl = $artifact->getArtifactImplementation();
     $impl->willCreateArtifact($actor);
     return $artifact->save();
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $build_target_phid = $request->getValue('buildTargetPHID');
     $build_target = id(new HarbormasterBuildTargetQuery())->setViewer($viewer)->withPHIDs(array($build_target_phid))->executeOne();
     if (!$build_target) {
         throw new Exception(pht('No such build target "%s"!', $build_target_phid));
     }
     $artifact_type = $request->getValue('artifactType');
     // Cast "artifactData" parameters to acceptable types if this request
     // is submitting raw HTTP parameters. This is not ideal. See T11887 for
     // discussion.
     $artifact_data = $request->getValue('artifactData');
     if (!$request->getIsStrictlyTyped()) {
         $impl = HarbormasterArtifact::getArtifactType($artifact_type);
         if ($impl) {
             foreach ($artifact_data as $key => $value) {
                 $artifact_data[$key] = $impl->readArtifactHTTPParameter($key, $value);
             }
         }
     }
     $artifact = $build_target->createArtifact($viewer, $request->getValue('artifactKey'), $artifact_type, $artifact_data);
     return array('data' => $this->returnArtifactList(array($artifact)));
 }