diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1483,7 +1483,6 @@ 'HarbormasterBuildkiteHookHandler' => 'applications/harbormaster/integration/buildkite/HarbormasterBuildkiteHookHandler.php', 'HarbormasterBuiltinBuildStepGroup' => 'applications/harbormaster/stepgroup/HarbormasterBuiltinBuildStepGroup.php', 'HarbormasterCircleCIBuildStepImplementation' => 'applications/harbormaster/integration/circleci/HarbormasterCircleCIBuildStepImplementation.php', - 'HarbormasterCircleCIBuildableInterface' => 'applications/harbormaster/interface/HarbormasterCircleCIBuildableInterface.php', 'HarbormasterCircleCIHookHandler' => 'applications/harbormaster/integration/circleci/HarbormasterCircleCIHookHandler.php', 'HarbormasterConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterConduitAPIMethod.php', 'HarbormasterControlBuildStepGroup' => 'applications/harbormaster/stepgroup/HarbormasterControlBuildStepGroup.php', @@ -1496,6 +1495,7 @@ 'HarbormasterDrydockLeaseArtifact' => 'applications/harbormaster/artifact/HarbormasterDrydockLeaseArtifact.php', 'HarbormasterExecFuture' => 'applications/harbormaster/future/HarbormasterExecFuture.php', 'HarbormasterExternalBuildStepGroup' => 'applications/harbormaster/stepgroup/HarbormasterExternalBuildStepGroup.php', + 'HarbormasterExternalBuildableInterface' => 'applications/harbormaster/interface/HarbormasterExternalBuildableInterface.php', 'HarbormasterFileArtifact' => 'applications/harbormaster/artifact/HarbormasterFileArtifact.php', 'HarbormasterHTTPRequestBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php', 'HarbormasterHookController' => 'applications/harbormaster/controller/HarbormasterHookController.php', @@ -6615,8 +6615,7 @@ 'DifferentialDAO', 'PhabricatorPolicyInterface', 'PhabricatorExtendedPolicyInterface', - 'HarbormasterBuildableInterface', - 'HarbormasterCircleCIBuildableInterface', + 'HarbormasterExternalBuildableInterface', 'HarbormasterBuildkiteBuildableInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorDestructibleInterface', @@ -7744,6 +7743,7 @@ 'HarbormasterDrydockLeaseArtifact' => 'HarbormasterArtifact', 'HarbormasterExecFuture' => 'Future', 'HarbormasterExternalBuildStepGroup' => 'HarbormasterBuildStepGroup', + 'HarbormasterExternalBuildableInterface' => 'HarbormasterBuildableInterface', 'HarbormasterFileArtifact' => 'HarbormasterArtifact', 'HarbormasterHTTPRequestBuildStepImplementation' => 'HarbormasterBuildStepImplementation', 'HarbormasterHookController' => 'HarbormasterController', @@ -11316,8 +11316,7 @@ 'PhabricatorTokenReceiverInterface', 'PhabricatorSubscribableInterface', 'PhabricatorMentionableInterface', - 'HarbormasterBuildableInterface', - 'HarbormasterCircleCIBuildableInterface', + 'HarbormasterExternalBuildableInterface', 'HarbormasterBuildkiteBuildableInterface', 'PhabricatorCustomFieldInterface', 'PhabricatorApplicationTransactionInterface', diff --git a/src/applications/differential/storage/DifferentialDiff.php b/src/applications/differential/storage/DifferentialDiff.php --- a/src/applications/differential/storage/DifferentialDiff.php +++ b/src/applications/differential/storage/DifferentialDiff.php @@ -5,8 +5,7 @@ implements PhabricatorPolicyInterface, PhabricatorExtendedPolicyInterface, - HarbormasterBuildableInterface, - HarbormasterCircleCIBuildableInterface, + HarbormasterExternalBuildableInterface, HarbormasterBuildkiteBuildableInterface, PhabricatorApplicationTransactionInterface, PhabricatorDestructibleInterface, @@ -565,70 +564,25 @@ return new DifferentialBuildableEngine(); } + public function getExternalBuildableRef() { + $ref = $this->getStagingRef(); + $ref = preg_replace('(^refs/tags/)', '', $ref); + return array( + HarbormasterExternalBuildableInterface::TAG, + $ref, + ); + } -/* -( HarbormasterCircleCIBuildableInterface )----------------------------- */ - - - public function getCircleCIGitHubRepositoryURI() { - $diff_phid = $this->getPHID(); + public function getRepository() { $repository_phid = $this->getRepositoryPHID(); if (!$repository_phid) { - throw new Exception( - pht( - 'This diff ("%s") is not associated with a repository. A diff '. - 'must belong to a tracked repository to be built by CircleCI.', - $diff_phid)); + return null; } - $repository = id(new PhabricatorRepositoryQuery()) + return id(new PhabricatorRepositoryQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withPHIDs(array($repository_phid)) ->executeOne(); - if (!$repository) { - throw new Exception( - pht( - 'This diff ("%s") is associated with a repository ("%s") which '. - 'could not be loaded.', - $diff_phid, - $repository_phid)); - } - - $staging_uri = $repository->getStagingURI(); - if (!$staging_uri) { - throw new Exception( - pht( - 'This diff ("%s") is associated with a repository ("%s") that '. - 'does not have a Staging Area configured. You must configure a '. - 'Staging Area to use CircleCI integration.', - $diff_phid, - $repository_phid)); - } - - $path = HarbormasterCircleCIBuildStepImplementation::getGitHubPath( - $staging_uri); - if (!$path) { - throw new Exception( - pht( - 'This diff ("%s") is associated with a repository ("%s") that '. - 'does not have a Staging Area ("%s") that is hosted on GitHub. '. - 'CircleCI can only build from GitHub, so the Staging Area for '. - 'the repository must be hosted there.', - $diff_phid, - $repository_phid, - $staging_uri)); - } - - return $staging_uri; - } - - public function getCircleCIBuildIdentifierType() { - return 'tag'; - } - - public function getCircleCIBuildIdentifier() { - $ref = $this->getStagingRef(); - $ref = preg_replace('(^refs/tags/)', '', $ref); - return $ref; } diff --git a/src/applications/harbormaster/integration/circleci/HarbormasterCircleCIBuildStepImplementation.php b/src/applications/harbormaster/integration/circleci/HarbormasterCircleCIBuildStepImplementation.php --- a/src/applications/harbormaster/integration/circleci/HarbormasterCircleCIBuildStepImplementation.php +++ b/src/applications/harbormaster/integration/circleci/HarbormasterCircleCIBuildStepImplementation.php @@ -79,6 +79,91 @@ } } + public static function loadRepository( + HarbormasterExternalBuildableInterface $buildable) { + + $repository = $buildable->getRepository(); + if (!$repository) { + throw new Exception( + pht( + 'Object ("%s") is not associated with a repository or the '. + 'repository could not be loaded.', + $buildable->getPHID())); + } + + return $repository; + } + + public static function searchGitHubPathForRevision( + HarbormasterExternalBuildableInterface $buildable) { + + $repository = self::loadRepository($buildable); + + $buildable_phid = $buildable->getPHID(); + $repository_phid = $repository->getPHID(); + + if ($repository->isHosted()) { + throw new Exception( + pht( + 'This commit ("%s") is associated with a hosted repository '. + '("%s"). Repositories must be imported from GitHub to be built '. + 'with CircleCI.', + $buildable_phid, + $repository_phid)); + } + + $remote_uri = $repository->getRemoteURI(); + $path = self::getGitHubPath($remote_uri); + if (!$path) { + throw new Exception( + pht( + 'This commit ("%s") is associated with a repository ("%s") '. + 'with a remote URI ("%s") that does not appear to be hosted on '. + 'GitHub. Repositories must be hosted on GitHub to be built with '. + 'CircleCI.', + $buildable_phid, + $repository_phid, + $remote_uri)); + } + + return $remote_uri; + } + + public static function searchGitHubPathForTag( + HarbormasterExternalBuildableInterface $buildable) { + + $repository = self::loadRepository($buildable); + + $buildable_phid = $buildable->getPHID(); + $repository_phid = $repository->getPHID(); + + $staging_uri = $repository->getStagingURI(); + if (!$staging_uri) { + throw new Exception( + pht( + 'This diff ("%s") is associated with a repository ("%s") that '. + 'does not have a Staging Area configured. You must configure a '. + 'Staging Area to use CircleCI integration.', + $buildable_phid, + $repository_phid)); + } + + $path = self::getGitHubPath($staging_uri); + if (!$path) { + throw new Exception( + pht( + 'This diff ("%s") is associated with a repository ("%s") that '. + 'does not have a Staging Area ("%s") that is hosted on GitHub. '. + 'CircleCI can only build from GitHub, so the Staging Area for '. + 'the repository must be hosted there.', + $buildable_phid, + $repository_phid, + $staging_uri)); + } + + return $staging_uri; + } + public function execute( HarbormasterBuild $build, HarbormasterBuildTarget $build_target) { @@ -93,18 +178,37 @@ $object = $buildable->getBuildableObject(); $object_phid = $object->getPHID(); - if (!($object instanceof HarbormasterCircleCIBuildableInterface)) { + if (!($object instanceof HarbormasterExternalBuildableInterface)) { throw new Exception( pht( 'Object ("%s") does not implement interface "%s". Only objects '. 'which implement this interface can be built with CircleCI.', $object_phid, - 'HarbormasterCircleCIBuildableInterface')); + 'HarbormasterExternalBuildableInterface')); } - $github_uri = $object->getCircleCIGitHubRepositoryURI(); - $build_type = $object->getCircleCIBuildIdentifierType(); - $build_identifier = $object->getCircleCIBuildIdentifier(); + list($type, $ref) = $object->getExternalBuildableRef(); + switch ($type) { + case HarbormasterExternalBuildableInterface::COMMIT: + $build_type = 'revision'; + $build_identifier = $ref; + $github_uri = self::searchGitHubPathForRevision($object); + break; + + case HarbormasterExternalBuildableInterface::TAG: + $build_type = 'tag'; + $build_identifier = $ref; + $github_uri = self::searchGitHubPathForTag($object); + break; + + default: + throw new Exception( + pht( + 'Object ("%s") use ref %s of type %d, which is not supported.', + $object_phid, + $ref, + $type)); + } $path = self::getGitHubPath($github_uri); if ($path === null) { diff --git a/src/applications/harbormaster/interface/HarbormasterCircleCIBuildableInterface.php b/src/applications/harbormaster/interface/HarbormasterCircleCIBuildableInterface.php deleted file mode 100644 --- a/src/applications/harbormaster/interface/HarbormasterCircleCIBuildableInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -getRepository(); - - $commit_phid = $this->getPHID(); - $repository_phid = $repository->getPHID(); - - if ($repository->isHosted()) { - throw new Exception( - pht( - 'This commit ("%s") is associated with a hosted repository '. - '("%s"). Repositories must be imported from GitHub to be built '. - 'with CircleCI.', - $commit_phid, - $repository_phid)); - } - - $remote_uri = $repository->getRemoteURI(); - $path = HarbormasterCircleCIBuildStepImplementation::getGitHubPath( - $remote_uri); - if (!$path) { - throw new Exception( - pht( - 'This commit ("%s") is associated with a repository ("%s") that '. - 'with a remote URI ("%s") that does not appear to be hosted on '. - 'GitHub. Repositories must be hosted on GitHub to be built with '. - 'CircleCI.', - $commit_phid, - $repository_phid, - $remote_uri)); - } - - return $remote_uri; - } - - public function getCircleCIBuildIdentifierType() { - return 'revision'; - } - - public function getCircleCIBuildIdentifier() { - return $this->getCommitIdentifier(); + public function getExternalBuildableRef() { + return array( + HarbormasterExternalBuildableInterface::COMMIT, + $this->getCommitIdentifier(), + ); }