18 'feature' =>
'Features',
19 'performance' =>
'Performance',
20 'documentation' =>
'Documentation',
22 'deprecated' =>
'Deprecations',
23 'breaking' =>
'Breaking Changes',
24 'removed' =>
'Removed',
37 'repository' =>
'https://github.com/Elgg/Elgg/',
40 $options = array_merge(
$defaults, $options);
41 if (empty($options[
'version'])) {
45 if (!file_exists($options[
'changelog']) || !is_writable($options[
'changelog'])) {
89 if ($first_anchor ===
false) {
114 'grep' =>
'^[a-z]+(\(.*\))?:|BREAKING',
115 'format' =>
'%H%n%h%n%s%n%b%n==END==',
119 $options = array_merge(
$defaults, $options);
121 $command = vsprintf(
'git log --grep="%s" -E --format=%s %s %s', [
126 if (str_contains(PHP_OS,
'WIN')) {
131 }, $options[
'exclude'])),
135 if (!isset($commits)) {
144 $subject_pattern =
'/^((Merge )|(Revert )|((\w*)\(([\w]+)\)\: ([^\n]*))$)/';
145 foreach ($commits as $line) {
146 if ($line ===
'==END==') {
168 preg_match($subject_pattern, $line, $matches);
170 $result[
'type'] = $matches[5] ??
'skip';
171 $result[
'component'] = $matches[6] ??
'';
172 $result[
'subject'] = $matches[7] ??
'';
180 $result[
'body'] .= $line . PHP_EOL;
188 $fixes_pattern =
'/(closes|fixes)\s+#(\d+)/i';
190 if ($result[
'type'] ===
'skip') {
195 if (str_contains(strtolower($result[
'body']),
'breaking change:')) {
196 $result[
'type'] =
'break';
201 preg_match_all($fixes_pattern, $result[
'body'], $matches);
202 if (!empty($matches) && !empty($matches[2])) {
203 $result[
'closes'] = array_map(
function (
$value) {
226 $options = array_merge(
$defaults, $options);
228 $command = vsprintf(
'git shortlog -sne %s --no-merges %s', [
231 if (str_contains(PHP_OS,
'WIN')) {
236 }, $options[
'exclude'])),
240 if (!isset($contributors)) {
244 $contributor_pattern =
'/\s+([0-9]+)\s+(.*)\s<(.*)>/';
246 foreach ($contributors as $contributor) {
248 preg_match($contributor_pattern, $contributor, $matches);
249 if (empty($matches)) {
254 'count' => (int) $matches[1],
255 'name' => $matches[2],
256 'email' => $matches[3],
261 usort(
$result,
function ($a, $b) {
262 return $b[
'count'] - $a[
'count'];
276 if (empty($commits)) {
282 foreach ($commits as $commit) {
283 $type = $commit[
'type'];
284 if (str_starts_with(
$type,
'feat')) {
289 $type =
'performance';
291 $type =
'documentation';
293 $type =
'deprecated';
302 if (!isset($types[
$type])) {
306 $component = $commit[
'component'];
307 if (!isset($types[$type][$component])) {
308 $types[
$type][$component] = [];
314 if (!empty($commit[
'closes'])) {
315 $closes .=
'closes ';
316 foreach ($commit[
'closes'] as $issue_id) {
321 $types[
$type][$component][] =
trim(vsprintf(
'%s %s %s', [
335 if (!isset($types[
$type])) {
339 $section =
"#### {$label}" . PHP_EOL . PHP_EOL;
341 foreach ($types[$type] as $component => $commits) {
342 if (
count($commits) === 1) {
343 $section .=
"* **{$component}:** {$commits[0]}" . PHP_EOL;
345 $section .=
"* **{$component}:**" . PHP_EOL;
347 foreach ($commits as $commit) {
348 $section .=
' * ' . $commit . PHP_EOL;
367 if (empty($contributors)) {
371 $section =
'#### Contributors' . PHP_EOL . PHP_EOL;
373 foreach ($contributors as $contributor) {
374 $section .=
"* {$contributor['name']} ({$contributor['count']})" . PHP_EOL;
388 $date = date(
'Y-m-d');
391 if ($parts[2] ===
'0') {
393 $section .=
"## {$version} ({$date})";
396 $section .=
"### {$version} ({$date})";
410 if (empty($commit)) {
414 return vsprintf(
'[%s](%s/commit/%s)', [
415 $commit[
'short_hash'],
429 if (empty($issue_id)) {
433 return vsprintf(
'[#%s](%s/commit/%s)', [
450 if ($first_anchor !==
false) {
470 exec($command,
$output, $result_code);
472 if ($result_code !== 0) {
488 return $this->options[$option] ??
$default;
Helper class to write the changelog during release.
static elgg()
Get the Elgg codebase path with "/".
Exception thrown if an argument is not of the expected type.
readNotes()
Read anything in the changelog before the first '' and consider this release notes.
__invoke()
Write the changelog for the current release.
formatCommits(array $commits)
Format the different commits into sections.
getGitTags()
Get the current git tags.
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is void
getGitContributors(array $options=[])
Get the contributors.
makeCommitLink(array $commit)
Get a link to a GitHub commit.
writeChangelog(string $release_notes)
Write the release notes to the changelog.
if($item instanceof\ElggEntity) elseif($item instanceof\ElggRiverItem) elseif($item instanceof\ElggRelationship) elseif(is_callable([$item, 'getType']))
formatContributors(array $contributors)
Format the contributors into a section.
getGitCommits(array $options)
Get all the commits.
formatHeader()
Format release header.
executeCommand(string $command)
Execute a command.
getOption(string $option, mixed $default=null)
Get an option.
if(!empty($title)&&!empty($icon_name)) if(!empty($title)) if(!empty($menu)) if(!empty($header)) if(!empty($body)) $contents
array __construct(array $options=[])
Constructor.
makeIssueLink(int $issue_id)
Generate a link to a GitHub issue.