zip_filename = $project === self::PROJECT_MAILPOET ? self::FREE_ZIP_FILENAME : self::PREMIUM_ZIP_FILENAME; $github_path = $project === self::PROJECT_MAILPOET ? 'mailpoet' : 'mailpoet-premium'; $this->http_client = new Client([ 'auth' => [$username, $token], 'headers' => [ 'Accept' => 'application/vnd.github.v3+json', ], 'base_uri' => "https://api.github.com/repos/mailpoet/$github_path/", ]); } public function createReleasePullRequest($version) { $response = $this->http_client->post('pulls', [ 'json' => [ 'title' => 'Release ' . $version, 'head' => self::RELEASE_SOURCE_BRANCH, 'base' => 'master', ], ]); $response = json_decode($response->getBody()->getContents(), true); $pull_request_number = $response['number']; if (!$pull_request_number) { throw new \Exception('Failed to create a new release pull request'); } $this->assignPullRequest($pull_request_number); } private function assignPullRequest($pull_request_number) { $this->http_client->post("pulls/$pull_request_number/requested_reviewers", [ 'json' => ['reviewers' => [self::QA_GITHUB_LOGIN]], ]); $this->http_client->post("issues/$pull_request_number/assignees", [ 'json' => ['assignees' => [self::QA_GITHUB_LOGIN]], ]); } public function publishRelease($version, $changelog, $release_zip_path) { $this->ensureNoDraftReleaseExists(); $this->ensureReleaseDoesNotExistYet($version); $release_info = $this->createReleaseDraft($version, $changelog); // remove {?name,label} from the end of 'upload_url' $upload_url = preg_replace('/\{[^{}]+\}$/ui', '', $release_info['upload_url']); $this->uploadReleaseZip($upload_url, $release_zip_path); $this->publishDraftAsRelease($release_info['id']); } public function getLatestCommitRevisionOnBranch($branch) { try { $response = $this->http_client->get('commits/' . urlencode($branch)); $data = json_decode($response->getBody()->getContents(), true); } catch (ClientException $e) { if ($e->getCode() === 404) { return null; } throw $e; } return $data['sha']; } private function ensureNoDraftReleaseExists() { $response = $this->http_client->get('releases'); $data = json_decode($response->getBody()->getContents(), true); if (is_array($data) && count($data) > 0 && $data[0]['draft']) { throw new \Exception('There are unpublished draft releases'); } } private function ensureReleaseDoesNotExistYet($version) { try { $this->http_client->get('releases/tags/' . urlencode($version)); $existing = true; } catch (ClientException $e) { if ($e->getCode() !== 404) { throw $e; } $existing = false; } if ($existing) { throw new \Exception("Release with version '$version' already exists"); } } private function createReleaseDraft($version, $changelog) { $response = $this->http_client->post('releases', [ 'json' => [ 'draft' => true, 'name' => $version, 'tag_name' => $version, 'target_commitish' => self::RELEASE_SOURCE_BRANCH, 'body' => $changelog, ], ]); return json_decode($response->getBody()->getContents(), true); } private function uploadReleaseZip($upload_url, $release_zip_path) { $this->http_client->post($upload_url, [ 'headers' => [ 'Content-Type' => 'application/zip' ], 'query' => [ 'name' => $this->zip_filename, ], 'body' => fopen($release_zip_path, 'rb'), ]); } private function publishDraftAsRelease($release_id) { $this->http_client->patch('releases/' . urlencode($release_id), [ 'json' => [ 'draft' => false, ], ]); } }