From 063205ca833946e20a1c2235418c045895153c5c Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 8 Jun 2015 19:49:11 +0200 Subject: [PATCH] add action to post-release a pharext package --- app/Controller/Github/Hook/Receive.php | 104 ++++++++++--------------- app/Controller/Github/Release.php | 46 +++++++++++ app/Github/API.php | 27 +++++++ app/Pharext/Package.php | 35 +++++++++ app/views/github/repo.phtml | 12 ++- config/app.ini | 11 +-- config/routes.ini | 5 ++ 7 files changed, 171 insertions(+), 69 deletions(-) create mode 100644 app/Controller/Github/Release.php create mode 100644 app/Pharext/Package.php diff --git a/app/Controller/Github/Hook/Receive.php b/app/Controller/Github/Hook/Receive.php index 4af8899..fa631e2 100644 --- a/app/Controller/Github/Hook/Receive.php +++ b/app/Controller/Github/Hook/Receive.php @@ -64,18 +64,31 @@ class Receive implements Controller } } - function release($release) { + private function setTokenForUser($login) { + $relations = [ + $this->accounts->getTokens()->getRelation("accounts"), + $this->accounts->getOwners()->getRelation("accounts") + ]; + $tokens = $this->accounts->getTokens()->with($relations, [ + "login=" => $login, + "tokens.authority=" => "github", + ]); + + if (count($tokens)) { + $this->github->setToken($tokens->current()->token->get()); + } + } + + private function release($release) { + $response = $this->app->getResponse(); + if ($release->action !== "published") { - $response = $this->app->getResponse(); $response->setResponseCode(202); $response->getBody()->append("Not published"); - return; - } - if (!empty($release->release->assets)) { + } elseif (!empty($release->release->assets)) { foreach ($release->release->assets as $asset) { if ($asset->content_type === "application/phar") { /* we've already uploaded the asset when we created the release */ - $response = $this->app->getResponse(); $response->setResponseCode(202); $response->getBody()->append("Already published"); return; @@ -83,34 +96,34 @@ class Receive implements Controller } } - $this->uploadAssetForRelease($release->release, $release->repository)->send(); + $this->setTokenForUser($release->repository->owner->login); + $this->github->uploadAssetForRelease($release->release, $release->repository, function($json) use($response) { + $response->setResponseCode(201); + $response->setHeader("Location", $json->url); + })->send(); } - private function uploadAssetForRelease($release, $repo) { - $this->setTokenForUser($repo->owner->login); - return $this->github->listHooks($repo->full_name, function($hooks) use($release, $repo) { - $repo->hooks = $hooks; - $asset = $this->createReleaseAsset($release, $repo); - $name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name); - $url = uri_template($release->upload_url, compact("name")); - $this->github->createReleaseAsset($url, $asset, "application/phar", function($json) use($release, $repo) { - if ($release->draft) { - $this->github->publishRelease($repo->full_name, $release->id, $release->tag_name, function($json) { - $response = $this->app->getResponse(); - $response->setResponseCode(201); - $response->setHeader("Location", $json->url); - }); - } else { - $response = $this->app->getResponse(); - $response->setResponseCode(201); - $response->setHeader("Location", $json->url); - } - }); - }); + private function create($create) { + $response = $this->app->getResponse(); + + if ($create->ref_type !== "tag") { + $response->setResponseCode(202); + $response->getBody()->append("Not a tag"); + return; + } + + $this->setTokenForUser($create->repository->owner->login); + $this->github->createReleaseFromTag($create->repository, $create->ref, function($json) use($response) { + $response->setResponseCode(201); + $response->setHeader("Location", $json->url); + })->send(); } private function createReleaseAsset($release, $repo) { $hook = $this->github->checkRepoHook($repo); + $phar = new Pharext\Package($repo->clone_url, $release->tag_name, $repo->name, $hook->config); + return $phar->getFile(); + $dir = (new Task\GitClone($repo->clone_url, $release->tag_name))->run(); if (!empty($hook->config->pecl)) { $src = new SoureDir\Pecl($dir); @@ -127,38 +140,5 @@ class Receive implements Controller $file = (new Task\PharBuild($src, $meta))->run(); return $file; } - - function create($create) { - if ($create->ref_type !== "tag") { - $response = $this->app->getResponse(); - - $response->setResponseCode(202); - $response->getBody()->append("Not a tag"); - return; - } - - $this->createReleaseFromTag($create->ref, $create->repository)->send(); - } - - private function setTokenForUser($login) { - $relations = [ - $this->accounts->getTokens()->getRelation("accounts"), - $this->accounts->getOwners()->getRelation("accounts") - ]; - $tokens = $this->accounts->getTokens()->with($relations, [ - "login=" => $login, - "tokens.authority=" => "github", - ]); - - if (count($tokens)) { - $this->github->setToken($tokens->current()->token->get()); - } - } - - private function createReleaseFromTag($tag, $repo) { - $this->setTokenForUser($repo->owner->login); - return $this->github->createRelease($repo->full_name, $tag, function($json) use($repo) { - $this->uploadAssetForRelease($json, $repo); - }); - } + } diff --git a/app/Controller/Github/Release.php b/app/Controller/Github/Release.php new file mode 100644 index 0000000..fd35505 --- /dev/null +++ b/app/Controller/Github/Release.php @@ -0,0 +1,46 @@ +checkToken()) { + list($repo) = $this->github->readRepo("$owner/$name", function($repo, $links = null) { + call_user_func(new RepoCallback($this->github), $repo, $links); + + $this->github->listReleases($repo->full_name, null, function($releases) use($repo) { + $tag = $this->app->getRequest()->getForm("tag"); + foreach ($releases as $r) { + if ($r->tag_name === $tag) { + $this->github->uploadAssetForRelease($repo, $r, function() use($repo) { + $this->app->redirect($this->app->getBaseUrl()->mod("./github/" . $repo->full_name)); + }); + return; + } + } + + $this->github->createReleaseFromTag($repo, $tag, function() use($repo) { + $this->app->redirect($this->app->getBaseUrl()->mod("./github/" . $repo->full_name)); + }); + }); + })->send(); + + $hook = $this->github->checkRepoHook($repo); + + $this->app->getView()->addData(compact("owner", "name", "repo", "hook")); + + if (($modal = $this->app->getRequest()->getQuery("modal"))) { + $action = $this->app->getRequest()->getQuery($modal); + $this->app->getView()->addData(compact("modal", "action")); + } + + $this->app->display("github/repo"); + } + } +} diff --git a/app/Github/API.php b/app/Github/API.php index e56ada1..bd28f3a 100644 --- a/app/Github/API.php +++ b/app/Github/API.php @@ -5,6 +5,7 @@ namespace app\Github; use app\Github\API; use app\Github\Storage; use app\Github\Exception; +use app\Pharext; use merry\Config; @@ -239,4 +240,30 @@ class API $call = new API\Releases\ListReleaseAssets($this, compact("repo", "id")); return $call($callback); } + + function uploadAssetForRelease($repo, $release, callable $callback) { + return $this->listHooks($repo->full_name, function($hooks) use($release, $repo, $callback) { + $repo->hooks = $hooks; + $hook = $this->checkRepoHook($repo); + $phar = new Pharext\Package($repo->clone_url, $release->tag_name, $repo->name, $hook ? $hook->config : null); + $name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name); + $url = uri_template($release->upload_url, compact("name")); + $this->createReleaseAsset($url, $phar, "application/phar", function($json) use($release, $repo, $callback) { + if ($release->draft) { + $this->publishRelease($repo->full_name, $release->id, $release->tag_name, function($json) use($callback) { + $callback($json); + }); + } else { + $callback($json); + } + }); + }); + } + + function createReleaseFromTag($repo, $tag_name, callable $callback) { + return $this->createRelease($repo->full_name, $tag_name, function($json) use($repo, $callback) { + $this->uploadAssetForRelease($repo, $json, $callback); + }); + } + } diff --git a/app/Pharext/Package.php b/app/Pharext/Package.php new file mode 100644 index 0000000..bb0d92c --- /dev/null +++ b/app/Pharext/Package.php @@ -0,0 +1,35 @@ +run(); + $src = !empty($options->pecl) + ? new SourceDir\Pecl($dir) + : new SourceDir\Git($dir); + $meta = Metadata::all() + [ + "name" => $pkg_name, + "release" => $tag_name, + "license" => $src->getLicense(), + "stub" => "pharext_installer.php", + "type" => !empty($options->zend) ? "zend_extension" : "extension", + ]; + $this->file = (new Task\PharBuild($src, $meta))->run(); + } + + function __toString() { + return (string) $this->file; + } + + function getFile() { + return $this->file; + } +} diff --git a/app/views/github/repo.phtml b/app/views/github/repo.phtml index 2245aa9..709908c 100644 --- a/app/views/github/repo.phtml +++ b/app/views/github/repo.phtml @@ -226,8 +226,8 @@
- release->assets)) : ?> -
diff --git a/config/app.ini b/config/app.ini index 7b9ca38..24178f7 100644 --- a/config/app.ini +++ b/config/app.ini @@ -13,11 +13,12 @@ github.hook.content_type = json github.hook.insecure_ssl = 0 github.storage.token.ttl = 3600 -github.storage.cache.repo.ttl = 3600 -github.storage.cache.repos.ttl = 3600 -github.storage.cache.hooks.ttl = 3600 -github.storage.cache.tags.ttl = 3600 -github.storage.cache.releases.ttl = 3600 +github.storage.cache.readrepo.ttl = 3600 +github.storage.cache.listrepos.ttl = 3600 +github.storage.cache.listhooks.ttl = 3600 +github.storage.cache.listtags.ttl = 3600 +github.storage.cache.listreleases.ttl = 3600 +github.storage.cache.listreleaseassets.ttl = 3600 github.log = github diff --git a/config/routes.ini b/config/routes.ini index cb28b1e..9adef89 100644 --- a/config/routes.ini +++ b/config/routes.ini @@ -22,6 +22,11 @@ POST[] = /github/repo/{owner}/{name}/hook/{action} ; if the user has to re-authenticate, we'll receive a GET because of a redirect GET[] = /github/repo/{owner}/{name}/hook/{action} +[Github\Release] +POST[] = /github/repo/{owner}/{name}/release +; if the user has to re-authenticate, we'll receive a GET because of a redirect +GET[] = /github/repo/{owner}/{name}/release + [Github\Signin] GET[] = /github/signin -- 2.30.2