commit d75deea8842472ac52ea7a02d485fa8f616df70f Author: Pavel Shevaev Date: Fri Aug 26 15:36:01 2022 +0300 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..f267101 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Execute as follows: + + GITEA_USER= GITEA_PASS= php chirp.php diff --git a/chirp.php b/chirp.php new file mode 100644 index 0000000..f30394e --- /dev/null +++ b/chirp.php @@ -0,0 +1,209 @@ + $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_base_repo($auth_token, $gitea_url, $base_repo, $check_upm = true) +{ + echo "=== Checking base repo '$base_repo' ===\n"; + + $commits = gitea_get_commits($auth_token, $gitea_url, $base_repo); + + $forks = gitea_get_forks($auth_token, $gitea_url, $base_repo); + 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) + { + echo "Fork '$repo_fork' is behind '$base_repo' at ({$commit['sha']}, {$commit['commit']['author']['date']} by {$commit['commit']['author']['name']})\n"; + break; + } + //early exit if commit exists + else if(isset($status['sha'])) + { + break; + } + } + } + + 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 "Newer version in $repo: current $version, latest {$last_tag_info["name"]}\n"; + } + else + echo "Could not fetch tags for $repo\n"; + } + + if($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 "Newer version in $repo: current $version, latest {$last_tag_info["name"]}\n"; + } + else + echo "Could not fetch tags for $repo\n"; + } + } +}