diff --git a/docs/en/environments.md b/docs/en/environments.md index 7609cbba..2c46d583 100644 --- a/docs/en/environments.md +++ b/docs/en/environments.md @@ -47,3 +47,18 @@ deploy: mage: env: %ENVIRONMENT% ``` + + +Webhooks to include branches in the environment +----------------------------------------------- + +### GOGS + +Prepare project in GOGS web-admin: + +* Create webhook +* Set "Payload URL" to php-censor webhook URL `http://domain.tld/webhook/gogs/project` +* Enable triggering "Pull request" +* Create labels for your environments in the format: "env:environment-name", for example "env:test" + +After creating the pull request, to include the branch in the environment, add the appropriate labels. diff --git a/src/PHPCensor/Controller/WebhookController.php b/src/PHPCensor/Controller/WebhookController.php index f37120ab..b8bc33aa 100644 --- a/src/PHPCensor/Controller/WebhookController.php +++ b/src/PHPCensor/Controller/WebhookController.php @@ -15,6 +15,7 @@ use PHPCensor\Store\ProjectStore; use b8\Controller; use b8\Config; use b8\Exception\HttpException\NotFoundException; +use b8\Store\Factory; /** * Webhook Controller - Processes webhook pings from BitBucket, Github, Gitlab, Gogs, etc. @@ -590,6 +591,10 @@ class WebhookController extends Controller return $this->gogsCommitRequest($project, $payload); } + if (array_key_exists('pull_request', $payload)) { + return $this->gogsPullRequest($project, $payload); + } + return ['status' => 'ignored', 'message' => 'Unusable payload.']; } @@ -632,6 +637,100 @@ class WebhookController extends Controller return ['status' => 'ignored', 'message' => 'Unusable payload.']; } + /** + * Handle the payload when Gogs sends a pull request webhook. + * + * @param Project $project + * @param array $payload + * + * @return array + */ + protected function gogsPullRequest(Project $project, array $payload) + { + $pull_request = $payload['pull_request']; + $head_branch = $pull_request['head_branch']; + + $action = $payload['action']; + $active_actions = ['opened', 'reopened', 'label_updated', 'label_cleared']; + $inactive_actions = ['closed']; + + $state = $pull_request['state']; + $active_states = ['open']; + $inactive_states = ['closed']; + + if (!in_array($action, $active_actions) and !in_array($action, $inactive_actions)) { + return ['status' => 'ignored', 'message' => 'Action ' . $action . ' ignored']; + } + if (!in_array($state, $active_states) and !in_array($state, $inactive_states)) { + return ['status' => 'ignored', 'message' => 'State ' . $state . ' ignored']; + } + + $envs = []; + + // Get environment form labels + if (in_array($action, $active_actions) and in_array($state, $active_states)) { + if (isset($pull_request['labels']) && is_array($pull_request['labels'])) { + foreach ($pull_request['labels'] as $label) { + if (strpos($label['name'], 'env:') === 0) { + $envs[] = substr($label['name'], 4); + } + } + } + } + + $envs_updated = []; + $env_objs = $project->getEnvironmentsObjects(); + $store = Factory::getStore('Environment', 'PHPCensor');; + foreach ($env_objs['items'] as $environment) { + $branches = $environment->getBranches(); + if (in_array($environment->getName(), $envs)) { + if (!in_array($head_branch, $branches)) { + // Add branch to environment + $branches[] = $head_branch; + $environment->setBranches($branches); + $store->save($environment); + $envs_updated[] = $environment->getName(); + } + } else { + if (in_array($head_branch, $branches)) { + // Remove branch from environment + $branches = array_diff($branches, [$head_branch]); + $environment->setBranches($branches); + $store->save($environment); + $envs_updated[] = $environment->getName(); + } + } + } + + if (($state == 'closed') and $pull_request['merged']) { + // update base branch enviroments + $environment_names = $project->getEnvironmentsNamesByBranch($pull_request['base_branch']); + $envs_updated = array_merge($envs_updated, $environment_names); + } + + $envs_updated = array_unique($envs_updated); + if (!empty($envs_updated)) { + foreach ($envs_updated as $environment_name) { + $this->buildService->createBuild( + $project, + $environment_name, + '', + $project->getBranch(), + null, + null, + null, + Build::SOURCE_WEBHOOK, + 0, + null + ); + } + + return ['status' => 'ok', 'message' => 'Branch environments updated ' . join(', ', $envs_updated)]; + } + + return ['status' => 'ignored', 'message' => 'Branch environments not changed']; + } + /** * Wrapper for creating a new build. *