Skip to content

Instantly share code, notes, and snippets.

@ArrayIterator
Created February 24, 2021 08:55
Show Gist options
  • Select an option

  • Save ArrayIterator/6eee800f8c3ae5c31e689844b2685ce2 to your computer and use it in GitHub Desktop.

Select an option

Save ArrayIterator/6eee800f8c3ae5c31e689844b2685ce2 to your computer and use it in GitHub Desktop.
<?php
// this route for git push notification and pull request
$this->post('/git_pull', function (ServerRequestInterface $request, ResponseInterface $response) {
$body = $request->getParsedBody();
$auth = $body['auth']??$request->getQueryParams()['auth']??null;
if ($auth !== null) {
$body['auth'] = $auth;
}
$payload = null;
if ($request->getHeaderLine('x-github-event') !== 'push'
|| !preg_match('/^Github/i', $request->getHeaderLine('user-agent'))
|| !preg_match(
'/^[a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9\-]+[a-f0-9]$/',
$request->getHeaderLine('x-github-delivery')
)
|| !isset($body['payload'])
|| !is_string($body['payload'])
|| !isset($body['auth'])
|| !is_array($payload = json_decode($body['payload'], true))
|| !isset($payload['ref'])
|| !isset($payload['commits'])
|| !is_array($payload['commits'])
|| !is_string($payload['ref'])
) {
return Json::errorCode(412);
}
$refBranch = preg_replace('/.+\/([^\/]+)$/', '$1', $payload['ref']);
/**
* Just For Logging (Ignore this if you want ignore logging)
*/
// root dir
$rootDir = dirname(dirname(__DIR__));
$logsDir = $rootDir.'/logs/';
if (!is_dir($logsDir)) {
@mkdir($logsDir, 0755, true);
}
$gits = [
'/usr/local/bin/git',
'/usr/bin/git',
'/usr/sbin/git',
];
$currentGit = null;
foreach ($gits as $git) {
if (@file_exists($git) && is_executable($git)) {
$currentGit = $git;
break;
}
}
if (!$currentGit) {
return Json::errorCode('No Git Installed', 417);
}
$composerBin = [
"{$rootDir}/composer.phar",
'/usr/local/bin/composer.phar',
'/usr/bin/composer.phar',
'/usr/local/bin/composer',
'/usr/bin/composer',
];
$gitHead = "{$rootDir}/.git/HEAD";
$gitInfo = "{$rootDir}/.git/info/refs";
$composerJson = "{$rootDir}/composer.json";
$origin = 'origin';
$remotes = [];
$origins = [];
$remote = [];
if (file_exists($gitHead)) {
$head = @file_get_contents($gitHead);
if ($head) {
$currentBranch = trim(preg_replace('/^.+[\/\\\](.+)$/', '$1', $head));
if ($refBranch !== $currentBranch) {
return Json::errorCode('Branch Mismatch', 412);
}
}
}
if (file_exists($gitInfo)) {
$remotes = @file_get_contents($gitInfo);
if ($remotes) {
$remotes = trim($remotes);
preg_match_all(
'/remotes[\/\\\](?P<remotes>(?P<origin>[^\n]+)[\/\\\](?<remote>[^\/\\\]+))$/sm',
$remotes,
$match
);
$remotes = array_values(array_filter($match['remotes']??[]));
$origins = array_values(array_filter($match['origin']??[]));
if (!in_array('origin', $origins)) {
$origin = reset($origins);
}
$remote = array_values(array_filter($match['remote']??[]));
}
}
$message = shell_exec(sprintf('cd %s && %s pull %s %s', $rootDir, $currentGit, $origin, $refBranch));
if (!$message) {
return Json::errorCode(sprintf('There was error for shell exec. %s', $message), 500);
}
$message = array_map('trim', explode("\n", trim($message)));
/**
* For logging
*/
// ignore this if ignore logs
if (is_dir($logsDir)) {
// log file
$logsFile = $logsDir .'/pull_request_log.log';
// check if log
if (!is_dir($logsFile) && (
! file_exists($logsFile) && is_writable($logsDir)
|| is_file($logsFile) && is_writable($logsFile)
)) {
file_put_contents(
$logsFile,
sprintf(
"[%s] - [%s:%s] > [%s] : %s\n",
gmdate('Y-m-d H:i:s \G\M\T'),
$origin,
$refBranch,
$refBranch,
json_encode($message)
),
FILE_APPEND
);
}
}
$composers = [];
if (file_exists($composerJson) && is_array(json_decode((string) @file_get_contents($composerJson), true))) {
// DOING COMPOSER
$currentComposer = null;
foreach ($composerBin as $com) {
if (@file_exists($com)) {
$comMessage = shell_exec(
sprintf('/usr/bin/env php %s --version', $com)
);
$comMessage = (string) $comMessage;
preg_match(
'~[Cc]omposer\s+version\s+(?P<version>[^\s]+)\s+(?P<date>[^\n]+[0-9]+(?:$)?)~i',
$comMessage,
$match
);
if (!empty($match['version'])) {
$composers['version'] = [
'version' => $match['version'],
'date' => $match['date'],
];
$currentComposer = $com;
break;
}
}
}
if ($currentComposer) {
//$composers['updates'] = ['SKIPPED'];
$comMessage = shell_exec(
sprintf('cd %s && /usr/bin/env php %s update --lock --no-dev -o', $rootDir, $currentComposer)
);
$comMessage = (string) $comMessage;
$composers['updates'] = array_filter(array_map('trim', explode("\n", $comMessage)));
}
}
gc_collect_cycles();
return Json::success([
'git' => $currentGit,
'branch' => $refBranch,
'origin' => $origin,
'message' => $message,
'remote' => $remote,
'remotes' => $remotes,
'composer' => $composers,
]);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment