Skip to content

Instantly share code, notes, and snippets.

@BenMorel
Last active June 25, 2022 21:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BenMorel/bd2ff5ea3b3eb7cfd0efad6731bbb8bc to your computer and use it in GitHub Desktop.
Save BenMorel/bd2ff5ea3b3eb7cfd0efad6731bbb8bc to your computer and use it in GitHub Desktop.
<?php
/**
* This script downloads the list of releases of a project via the GitHub API,
* and generates a changelog out of it.
*
* Example, to generate a changelog for brick/math:
*
* php changelog-from-github-api.php brick/math > CHANGELOG.md
*/
(function(int $argc, array $argv) {
if ($argc !== 2) {
echo "Usage: {$argv[0]} <owner/repo>\n";
exit(1);
}
$repo = $argv[1];
$download = function(string $url): string {
$options = [
'http' => [
'header' => 'User-Agent: changelog-from-github-api'
]
];
$context = stream_context_create($options);
$attempts = 5;
for ($attempt = 1; $attempt <= $attempts; $attempt++) {
$data = file_get_contents($url, false, $context);
if ($data !== false) {
return $data;
}
sleep(1);
}
echo "Could not download $url after $attempts attempts\n";
exit(1);
};
$releases = [];
for ($page = 1; ; $page++) {
$url = 'https://api.github.com/repos/' . $repo . '/releases?page=' . $page;
$json = $download($url);
$data = json_decode($json, true);
if ($data === null) {
echo "Could not decode JSON data at $url\n";
exit(1);
}
assert(is_array($data));
if (! $data) {
break;
}
foreach ($data as $release) {
$releases[] = $release;
}
}
usort($releases, function (array $a, array $b): int {
return strnatcmp($b['name'], $a['name']);
});
echo "# Changelog\n\n";
foreach ($releases as $release) {
printf("## [%s](%s) - %s\n\n", $release['name'], $release['html_url'], substr($release['published_at'], 0, 10));
echo trim($release['body']), "\n\n";
}
})($argc, $argv);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment