hoopoe/chirp.php

247 lines
6.6 KiB
PHP

<?php
$user = getenv('GITEA_USER');
$pass = getenv('GITEA_PASS');
$gitea_url = 'https://git.bit5.ru';
$auth_token = gitea_login($gitea_url, $user, $pass);
if(!$auth_token)
throw new Exception("Could not login to gitea");
gitea_check_repo($auth_token, $gitea_url, 'bit/skeletik',
array(
'check_forks' => true,
'check_composer' => true,
'check_upm' => false
)
);
gitea_check_repo($auth_token, $gitea_url, 'bit/skeletor',
array(
'check_forks' => true,
'check_composer' => true,
'check_upm' => true
)
);
gitea_check_repo($auth_token, $gitea_url, 'bit/skeletor-rnd',
array(
'check_forks' => true,
'check_composer' => true,
'check_upm' => true
)
);
gitea_check_repo($auth_token, $gitea_url, 'game/gymmania',
array(
'check_forks' => false,
'check_composer' => true,
'check_upm' => false
)
);
//////////////////////////////////
function gitea_login($gitea_url, $user, $pass)
{
$token_field = "test_".time();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://git.bit5.ru/api/v1/users/$user/tokens");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array("name" => $token_field)));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $pass);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$json = curl_exec($ch);
curl_close($ch);
$res = json_decode($json, true);
if(!isset($res['sha1']))
throw new Exception("Could not login to gitea");
return $res['sha1'];
}
function gitea_api_call($auth_token, $gitea_url, $api_path)
{
$api_url = "$gitea_url/api/v1/$api_path";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
array(
'Accept: application/json',
"Authorization: token $auth_token"
)
);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$json = substr($response, $header_size);
$info = curl_getinfo($ch);
curl_close($ch);
if($info['http_code'] != 200)
return $info['http_code'];
return json_decode($json, true);
}
function gitea_get_tags($auth_token, $gitea_url, $repo)
{
$res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/tags");
if($res === 404)
return array();
else if(is_numeric($res))
throw new Exception("Bad response: $res");
return $res;
}
function gitea_get_source($auth_token, $gitea_url, $repo, $path)
{
$res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/contents/$path");
if(is_numeric($res))
throw new Exception("Bad response: $res");
if(!isset($res['content']))
throw new Exception("Could not get file at path '$path'");
return base64_decode($res['content']);
}
function gitea_get_forks($auth_token, $gitea_url, $repo)
{
$res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/forks");
if(is_numeric($res))
throw new Exception("Bad response: $res");
return $res;
}
function gitea_get_commits($auth_token, $gitea_url, $repo)
{
$res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/commits");
if(is_numeric($res))
throw new Exception("Bad response: $res");
return $res;
}
function gitea_get_commit($auth_token, $gitea_url, $repo, $sha)
{
$res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/git/commits/$sha");
if($res === 404)
return null;
else if(is_numeric($res))
throw new Exception("Bad response: $res");
else
return $res;
}
function _is_composer_git_repo(array $repos, $repo)
{
foreach($repos as $item)
{
if($item['type'] == 'git' && $item['url'] == $repo)
return true;
}
return false;
}
function gitea_check_repo(
$auth_token,
$gitea_url,
$base_repo,
array $opts
)
{
echo "************************* Checking repo '$base_repo' *************************\n";
$commits = gitea_get_commits($auth_token, $gitea_url, $base_repo);
if($opts['check_forks'])
{
$forks = gitea_get_forks($auth_token, $gitea_url, $base_repo);
$behind_forks = array();
echo "== Checking forks ==\n";
foreach($forks as $fork)
{
$repo_fork = $fork['full_name'];
foreach($commits as $commit)
{
$status = gitea_get_commit($auth_token, $gitea_url, $repo_fork, $commit['sha']);
if($status === null)
{
$behind_forks[] = $repo_fork;
break;
}
//early exit if commit exists
else if(isset($status['sha']))
{
break;
}
}
}
echo "Behind forks: " . implode(", ", $behind_forks) . "\n";
}
if($opts['check_composer'])
{
echo "== Checking Composer manifest ==\n";
$composer_json = gitea_get_source($auth_token, $gitea_url, $base_repo, "composer/composer.json");
$composer_arr = json_decode($composer_json, true);
foreach($composer_arr['require'] as $repo => $version)
{
if(strpos($repo, "bit/") !== 0)
continue;
if(!_is_composer_git_repo($composer_arr['repositories'], "$gitea_url/$repo"))
continue;
$tags = gitea_get_tags($auth_token, $gitea_url, $repo);
if(isset($tags[0]))
{
$last_tag_info = $tags[0];
if(ltrim($last_tag_info["name"], 'v') != ltrim($version, 'v'))
echo "Package '$repo': current $version, latest {$last_tag_info["name"]}\n";
}
else
echo "Could not fetch tags for $repo\n";
}
}
if($opts['check_upm'])
{
echo "== Checking UPM manifest ==\n";
$upm_json = gitea_get_source($auth_token, $gitea_url, $base_repo, "unity/Packages/manifest.json");
$upm_arr = json_decode($upm_json, true);
foreach($upm_arr['dependencies'] as $name => $version)
{
if(strpos($name, "com.bitgames.") !== 0)
continue;
$name = str_replace("com.bitgames.ecs", "com.bitgames.leoecs", $name);
$name = str_replace("com.bitgames.", "", $name);
$name = str_replace(".", "-", $name);
$repo = 'bit-upm/' . $name;
$tags = gitea_get_tags($auth_token, $gitea_url, $repo);
if(isset($tags[0]))
{
$last_tag_info = $tags[0];
if(ltrim($last_tag_info["name"], 'v') != ltrim($version, 'v'))
echo "Package '$repo': current $version, latest {$last_tag_info["name"]}\n";
}
else
echo "Could not fetch tags for $repo\n";
}
}
}