-
-
Save exileed/68f72633709a152f4618e05eb9621ecf to your computer and use it in GitHub Desktop.
AutoDeploy и приём информации серверами , путем вызова вебхуков сервером GitHub
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php /** @noinspection PhpUndefinedMethodInspection PhpUnused */ | |
/** | |
* НЕ ИЗМЕНЯТЬ!!!!! (жене мужу и т.д., а контроллер можно но в исключительных случаях) | |
* Автор класса Александр Хакимов https://github.com/hackimov | |
* Контроллер который занимается автодеплоем на стэйджинг и продакшин. | |
* Это функционал ядра который восприимчив к изменению! | |
* Если затронуть код то автодеплой сломается, исключением является если он уже сломался по причине если сервера были перенесены или недоступны из вне! | |
*/ | |
namespace App\Http\Controllers\API\autodeploy; | |
use App\Http\Controllers\Controller; | |
use App\Services\ErgResponseService; | |
use Illuminate\Http\JsonResponse; | |
use Illuminate\Support\Facades\Config; | |
use Illuminate\Http\Request; | |
class AutoDeployController extends Controller | |
{ | |
protected static $path = '/home/bitrix/ext_www/'; | |
protected static $url_path = '@github.com/MicrosDevGroup/'; | |
protected static $reset = 'git reset --hard 2>&1'; | |
protected static $git_push = 'git push --force'; | |
protected static $build = '/home/bitrix/bin/Sencha/Cmd/sencha app build -des ./ 2>&1'; | |
protected static $cd = 'cd '; | |
protected static $and = ' && '; | |
protected static $quot = '"'; | |
protected static $protocol = 'https://'; | |
protected static $git_pull = 'git pull '; | |
protected static $git_ext = '.git'; | |
protected static $master_branch = ' master 2>&1'; | |
protected static $dev_branch = ' dev 2>&1'; | |
public static function back_production(Request $request): JsonResponse | |
{ | |
// получаем параметр payload с входными данными пул реквеста | |
$payload = $request->get('payload'); | |
if(empty($payload)){ | |
$payload = $request->getContent(); | |
} | |
// форматируем данные | |
$pull_response = self::github_pull_request_formatter($payload); | |
$return_data['request_content'] = $payload; | |
$return_data['request_response'] = $pull_response; | |
// проверяем на нужную ли ветку пришёл пул реквест | |
if(isset($pull_response['branch']) && $pull_response['branch'] === 'master' && $pull_response['branch'] !== false) { | |
$repo = Config::get('application.github.production.backend'); | |
$token = Config::get('application.github.token'); | |
$git_repo = Config::get('application.github.github_repo.backend'); | |
// git reset --hard | |
$reset_output = []; | |
$reset_command = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command, $reset_output); | |
$data['reset_output']['command'] = $reset_command; | |
$data['reset_output']['data'] = $reset_output; | |
// git pull origin master | |
$pull_output = []; | |
$pull = self::$git_pull . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$master_branch; | |
$pull_command = self::$cd . self::$path . $repo . self::$and . $pull; | |
exec($pull_command, $pull_output); | |
$data['pull_output']['command'] = $pull_command; | |
$data['pull_output']['data'] = $pull_output; | |
// сообщение об успешном принятии данных с гитхаба | |
return ErgResponseService::success('backend production git pull executed successfully', $data); | |
} | |
// сообщение о том, что это не нужный нам пулл реквест (был прислан на другую ветку или вообще не является пулл реквестом) | |
return ErgResponseService::success('get backend push response production but is not needed branch', $return_data); | |
} | |
public static function back_staging(Request $request): JsonResponse | |
{ | |
// получаем параметр payload с входными данными пул реквеста | |
$payload = $request->get('payload'); | |
if(empty($payload)){ | |
$payload = $request->getContent(); | |
} | |
// форматируем данные | |
$pull_response = self::github_pull_request_formatter($payload); | |
$return_data['request_content'] = $payload; | |
$return_data['request_response'] = $pull_response; | |
// проверяем на нужную ли ветку пришёл пул реквест | |
if(isset($pull_response['branch']) && $pull_response['branch'] === 'dev' && $pull_response['branch'] !== false) { | |
$repo = Config::get('application.github.staging.backend'); | |
$token = Config::get('application.github.token'); | |
$git_repo = Config::get('application.github.github_repo.backend'); | |
// git reset --hard | |
$reset_output = []; | |
$reset_command = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command, $reset_output); | |
$data['reset_output']['command'] = $reset_command; | |
$data['reset_output']['data'] = $reset_output; | |
// git pull origin dev | |
$pull_output = []; | |
$pull = self::$git_pull . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$dev_branch; | |
$pull_command = self::$cd . self::$path . $repo . self::$and . $pull; | |
exec($pull_command, $pull_output); | |
$data['pull_output']['command'] = $pull_command; | |
$data['pull_output']['data'] = $pull_output; | |
// сообщение об успешном принятии данных с гитхаба | |
return ErgResponseService::success('backend staging git pull executed successfully', $data); | |
} | |
// сообщение о том, что это не нужный нам пулл реквест (был прислан на другую ветку или вообще не является пулл реквестом) | |
return ErgResponseService::success('get backend push response staging but is not needed branch', $return_data); | |
} | |
public static function front_production(Request $request): JsonResponse | |
{ | |
// получаем параметр payload с входными данными пул реквеста | |
$payload = $request->get('payload'); | |
if(empty($payload)){ | |
$payload = $request->getContent(); | |
} | |
// форматируем данные | |
$pull_response = self::github_pull_request_formatter($payload); | |
$return_data['request_content'] = $payload; | |
$return_data['request_response'] = $pull_response; | |
// проверяем на нужную ли ветку пришёл пул реквест | |
if(isset($pull_response['branch']) && $pull_response['branch'] === 'master' && $pull_response['branch'] !== false) { | |
$repo = Config::get('application.github.production.frontend'); | |
$token = Config::get('application.github.token'); | |
$git_repo = Config::get('application.github.github_repo.frontend'); | |
// git reset --hard | |
$reset_output = []; | |
$reset_command = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command, $reset_output); | |
$data['reset_output']['command'] = $reset_command; | |
$data['reset_output']['data'] = $reset_output; | |
// git pull origin master | |
$pull_output = []; | |
$pull = self::$git_pull . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$master_branch; | |
$pull_command = self::$cd . self::$path . $repo . self::$and . $pull; | |
exec($pull_command, $pull_output); | |
$data['pull_output']['command'] = $pull_command; | |
$data['pull_output']['data'] = $pull_output; | |
// sencha app build -des ./ | |
$build_output = []; | |
$build_command = self::$cd . self::$path . $repo . self::$and . self::$build; | |
exec($build_command, $build_output); | |
$data['build_output']['command'] = $build_command; | |
$data['build_output']['data'] = $build_output; | |
// ищем ошибки билда | |
$build_errors = []; | |
foreach ($build_output as $build_string) { | |
if(false !== stripos($build_string, '[ERR]')) { | |
$build_errors[] = $build_string; | |
} | |
} | |
$data['build_output']['data']['errors'] = $build_errors; | |
if(empty($build_errors)){ | |
// сообщение об успешном принятии данных с гитхаба и билд прошёл без ошибок | |
return ErgResponseService::success('frontend production git pull and build executed successfully without errors', $data); | |
} | |
// обработка проблемного реквеста с ошибками в билде (откат последнего пул реквеста на основной ветке) | |
// git reset --hard | |
$reset_output_force = []; | |
$reset_command_force = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command_force, $reset_output_force); | |
$data['reset_output_force']['command'] = $reset_command_force; | |
$data['reset_output_force']['data'] = $reset_output_force; | |
// git push origin master --force | |
$push_output_force = []; | |
$push_force = self::$git_push . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$master_branch; | |
$push_command_force = self::$cd . self::$path . $repo . self::$and . $push_force; | |
exec($push_command_force, $push_output_force); | |
$data['push_output_force']['command'] = $push_command_force; | |
$data['push_output_force']['data'] = $push_output_force; | |
// sencha app build -des ./ | |
$build_output_force = []; | |
$build_command_force = self::$cd . self::$path . $repo . self::$and . self::$build; | |
exec($build_command_force, $build_output_force); | |
$data['build_output_force']['command'] = $build_command_force; | |
$data['build_output_force']['data'] = $build_output_force; | |
// сообщение о проблемном пулл реквесте, и откат на предыдущий, с выводом ошибок проблемного билда в ответе | |
return ErgResponseService::success('frontend production git pull and build executed successfully but with errors. last commit build', $data); | |
} | |
// сообщение о том, что это не нужный нам пулл реквест (был прислан на другую ветку или вообще не является пулл реквестом) | |
return ErgResponseService::success('get frontend push response production but is not needed branch', $return_data); | |
} | |
public static function front_staging(Request $request): JsonResponse | |
{ | |
// получаем параметр payload с входными данными пул реквеста | |
$payload = $request->get('payload'); | |
if(empty($payload)){ | |
$payload = $request->getContent(); | |
} | |
// форматируем данные | |
$pull_response = self::github_pull_request_formatter($payload); | |
$return_data['request_content'] = $payload; | |
$return_data['request_response'] = $pull_response; | |
// проверяем на нужную ли ветку пришёл пул реквест | |
if(isset($pull_response['branch']) && $pull_response['branch'] === 'dev' && $pull_response['branch'] !== false) { | |
$repo = Config::get('application.github.staging.frontend'); | |
$token = Config::get('application.github.token'); | |
$git_repo = Config::get('application.github.github_repo.frontend'); | |
// git reset --hard | |
$reset_output = []; | |
$reset_command = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command, $reset_output); | |
$data['reset_output']['command'] = $reset_command; | |
$data['reset_output']['data'] = $reset_output; | |
// git pull origin dev | |
$pull_output = []; | |
$pull = self::$git_pull . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$dev_branch; | |
$pull_command = self::$cd . self::$path . $repo . self::$and . $pull; | |
exec($pull_command, $pull_output); | |
$data['pull_output']['command'] = $pull_command; | |
$data['pull_output']['data'] = $pull_output; | |
// sencha app build -des ./ | |
$build_output = []; | |
$build_command = self::$cd . self::$path . $repo . self::$and . self::$build; | |
exec($build_command, $build_output); | |
$data['build_output']['command'] = $build_command; | |
$data['build_output']['data'] = $build_output; | |
// ищем ошибки билда | |
$build_errors = []; | |
foreach ($build_output as $build_string) { | |
if(false !== stripos($build_string, '[ERR]')) { | |
$build_errors[] = $build_string; | |
} | |
} | |
$data['build_output']['data']['errors'] = $build_errors; | |
if(empty($build_errors)){ | |
// сообщение об успешном принятии данных с гитхаба и билд прошёл без ошибок | |
return ErgResponseService::success('frontend staging git pull and build executed successfully without errors', $data); | |
} | |
// обработка проблемного реквеста с ошибками в билде (откат последнего пул реквеста на основной ветке) | |
// git reset --hard | |
$reset_output_force = []; | |
$reset_command_force = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command_force, $reset_output_force); | |
$data['reset_output_force']['command'] = $reset_command_force; | |
$data['reset_output_force']['data'] = $reset_output_force; | |
// git push origin dev --force | |
$push_output_force = []; | |
$push_force = self::$git_push . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$dev_branch; | |
$push_command_force = self::$cd . self::$path . $repo . self::$and . $push_force; | |
exec($push_command_force, $push_output_force); | |
$data['push_output_force']['command'] = $push_command_force; | |
$data['push_output_force']['data'] = $push_output_force; | |
// sencha app build -des ./ | |
$build_output_force = []; | |
$build_command_force = self::$cd . self::$path . $repo . self::$and . self::$build; | |
exec($build_command_force, $build_output_force); | |
$data['build_output_force']['command'] = $build_command_force; | |
$data['build_output_force']['data'] = $build_output_force; | |
// сообщение о проблемном пулл реквесте, и откат на предыдущий, с выводом ошибок проблемного билда в ответе | |
return ErgResponseService::success('frontend staging git pull and build executed successfully but with errors. last commit build', $data); | |
} | |
// сообщение о том, что это не нужный нам пулл реквест (был прислан на другую ветку или вообще не является пулл реквестом) | |
return ErgResponseService::success('get frontend push response staging but is not needed branch', $return_data); | |
} | |
public static function admin_production(Request $request): JsonResponse | |
{ | |
// получаем параметр payload с входными данными пул реквеста | |
$payload = $request->get('payload'); | |
if(empty($payload)){ | |
$payload = $request->getContent(); | |
} | |
// форматируем данные | |
$pull_response = self::github_pull_request_formatter($payload); | |
$return_data['request_content'] = $payload; | |
$return_data['request_response'] = $pull_response; | |
// проверяем на нужную ли ветку пришёл пул реквест | |
if(isset($pull_response['branch']) && $pull_response['branch'] === 'master' && $pull_response['branch'] !== false) { | |
$repo = Config::get('application.github.production.admin'); | |
$token = Config::get('application.github.token'); | |
$git_repo = Config::get('application.github.github_repo.admin'); | |
// git reset --hard | |
$reset_output = []; | |
$reset_command = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command, $reset_output); | |
$data['reset_output']['command'] = $reset_command; | |
$data['reset_output']['data'] = $reset_output; | |
// git pull origin master | |
$pull_output = []; | |
$pull = self::$git_pull . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$master_branch; | |
$pull_command = self::$cd . self::$path . $repo . self::$and . $pull; | |
exec($pull_command, $pull_output); | |
$data['pull_output']['command'] = $pull_command; | |
$data['pull_output']['data'] = $pull_output; | |
// сообщение об успешном принятии данных с гитхаба | |
return ErgResponseService::success('admin production git pull executed successfully', $data); | |
} | |
// сообщение о том, что это не нужный нам пулл реквест (был прислан на другую ветку или вообще не является пулл реквестом) | |
return ErgResponseService::success('get admin panel push response production but is not needed branch', $return_data); | |
} | |
public static function admin_staging(Request $request): JsonResponse | |
{ | |
// получаем параметр payload с входными данными пул реквеста | |
$payload = $request->get('payload'); | |
if(empty($payload)){ | |
$payload = $request->getContent(); | |
} | |
// форматируем данные | |
$pull_response = self::github_pull_request_formatter($payload); | |
$return_data['request_content'] = $payload; | |
$return_data['request_response'] = $pull_response; | |
// проверяем на нужную ли ветку пришёл пул реквест | |
if(isset($pull_response['branch']) && $pull_response['branch'] === 'dev' && $pull_response['branch'] !== false) { | |
$repo = Config::get('application.github.staging.admin'); | |
$token = Config::get('application.github.token'); | |
$git_repo = Config::get('application.github.github_repo.admin'); | |
// git reset --hard | |
$reset_output = []; | |
$reset_command = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command, $reset_output); | |
$data['reset_output']['command'] = $reset_command; | |
$data['reset_output']['data'] = $reset_output; | |
// git pull origin dev | |
$pull_output = []; | |
$pull = self::$git_pull . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$dev_branch; | |
$pull_command = self::$cd . self::$path . $repo . self::$and . $pull; | |
exec($pull_command, $pull_output); | |
$data['pull_output']['command'] = $pull_command; | |
$data['pull_output']['data'] = $pull_output; | |
// сообщение об успешном принятии данных с гитхаба | |
return ErgResponseService::success('admin staging git pull executed successfully', $data); | |
} | |
// сообщение о том, что это не нужный нам пулл реквест (был прислан на другую ветку или вообще не является пулл реквестом) | |
return ErgResponseService::success('get admin panel push response staging but is not needed branch', $return_data); | |
} | |
public static function auth_production(Request $request): JsonResponse | |
{ | |
// получаем параметр payload с входными данными пул реквеста | |
$payload = $request->get('payload'); | |
if(empty($payload)){ | |
$payload = $request->getContent(); | |
} | |
// форматируем данные | |
$pull_response = self::github_pull_request_formatter($payload); | |
$return_data['request_content'] = $payload; | |
$return_data['request_response'] = $pull_response; | |
// проверяем на нужную ли ветку пришёл пул реквест | |
if(isset($pull_response['branch']) && $pull_response['branch'] === 'master' && $pull_response['branch'] !== false) { | |
$repo = Config::get('application.github.production.auth'); | |
$token = Config::get('application.github.token'); | |
$git_repo = Config::get('application.github.github_repo.auth'); | |
// git reset --hard | |
$reset_output = []; | |
$reset_command = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command, $reset_output); | |
$data['reset_output']['command'] = $reset_command; | |
$data['reset_output']['data'] = $reset_output; | |
// git pull origin master | |
$pull_output = []; | |
$pull = self::$git_pull . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$master_branch; | |
$pull_command = self::$cd . self::$path . $repo . self::$and . $pull; | |
exec($pull_command, $pull_output); | |
$data['pull_output']['command'] = $pull_command; | |
$data['pull_output']['data'] = $pull_output; | |
// сообщение об успешном принятии данных с гитхаба | |
return ErgResponseService::success('auth production git pull executed successfully', $data); | |
} | |
// сообщение о том, что это не нужный нам пулл реквест (был прислан на другую ветку или вообще не является пулл реквестом) | |
return ErgResponseService::success('get auth repo push response production but is not needed branch', $return_data); | |
} | |
public static function auth_staging(Request $request): JsonResponse | |
{ | |
// получаем параметр payload с входными данными пул реквеста | |
$payload = $request->get('payload'); | |
if(empty($payload)){ | |
$payload = $request->getContent(); | |
} | |
// форматируем данные | |
$pull_response = self::github_pull_request_formatter($payload); | |
$return_data['request_content'] = $payload; | |
$return_data['request_response'] = $pull_response; | |
// проверяем на нужную ли ветку пришёл пул реквест | |
if(isset($pull_response['branch']) && $pull_response['branch'] === 'dev' && $pull_response['branch'] !== false) { | |
$repo = Config::get('application.github.staging.auth'); | |
$token = Config::get('application.github.token'); | |
$git_repo = Config::get('application.github.github_repo.auth'); | |
// git reset --hard | |
$reset_output = []; | |
$reset_command = self::$cd . self::$path . $repo . self::$and . self::$reset; | |
exec($reset_command, $reset_output); | |
$data['reset_output']['command'] = $reset_command; | |
$data['reset_output']['data'] = $reset_output; | |
// git pull origin dev | |
$pull_output = []; | |
$pull = self::$git_pull . self::$quot . self::$protocol . $token . self::$url_path . $git_repo . self::$git_ext . self::$quot . self::$dev_branch; | |
$pull_command = self::$cd . self::$path . $repo . self::$and . $pull; | |
exec($pull_command, $pull_output); | |
$data['pull_output']['command'] = $pull_command; | |
$data['pull_output']['data'] = $pull_output; | |
// сообщение об успешном принятии данных с гитхаба | |
return ErgResponseService::success('auth staging git pull executed successfully', $data); | |
} | |
// сообщение о том, что это не нужный нам пулл реквест (был прислан на другую ветку или вообще не является пулл реквестом) | |
return ErgResponseService::success('get auth repo push response staging but is not needed branch', $return_data); | |
} | |
/** | |
* @param $json | |
* @return array|bool | |
* функция возвращает результат форматирования входящих данных пулл реквеста и выдаёт необходимые данные | |
*/ | |
public static function github_pull_request_formatter($json) | |
{ | |
// декодируем тело реквеста | |
$request = json_decode($json, true); | |
$pull_response = []; | |
// если нам прислали подмассив с полным путем, обрабатываем и получаем название ветки | |
if(isset($request['ref'])){ | |
$branch_data = explode('/', $request['ref']); | |
$branch = end($branch_data); | |
$pull_response['branch'] = $branch; | |
} | |
// смотрим кто был инициатором пулл реквеста | |
if(isset($request['head_commit']['committer']['username'])){ | |
$pull_response['pushed_from'] = $request['head_commit']['committer']['username']; | |
} | |
// регулярное выражение которое проверяет является ли это пулл реквестом | |
$merge_pattern = '/Merge pull request/m'; | |
if(isset($request['head_commit']['message']) && preg_match($merge_pattern, $request['head_commit']['message'])){ | |
$pull_response['github_merge'] = true; | |
} else { | |
$pull_response['github_merge'] = false; | |
} | |
// если это не пул реквест возвращает пустой результат | |
if(empty($pull_response)){ | |
return false; | |
} | |
// возвращаем результат форматированны пул реквест | |
return $pull_response; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment