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'])) {
49 $options[
'repository'] =
rtrim($options[
'repository'],
'/');
91 if ($first_anchor ===
false) {
116 'grep' =>
'^[a-z]+(\(.*\))?:|BREAKING',
117 'format' =>
'%H%n%h%n%s%n%b%n==END==',
121 $options = array_merge(
$defaults, $options);
123 $command = vsprintf(
'git log --grep="%s" -E --format=%s %s %s', [
128 if (str_contains(PHP_OS,
'WIN')) {
133 }, $options[
'exclude'])),
137 if (!isset($commits)) {
146 $subject_pattern =
'/^((Merge )|(Revert )|((\w*)\(([\w]+)\)\: ([^\n]*))$)/';
147 foreach ($commits as $line) {
148 if ($line ===
'==END==') {
170 preg_match($subject_pattern, $line, $matches);
172 $result[
'type'] = $matches[5] ??
'skip';
173 $result[
'component'] = $matches[6] ??
'';
174 $result[
'subject'] = $matches[7] ??
'';
182 $result[
'body'] .= $line . PHP_EOL;
190 $fixes_pattern =
'/(closes|fixes)\s+#(\d+)/i';
192 if ($result[
'type'] ===
'skip') {
197 if (str_contains(strtolower($result[
'body']),
'breaking change:')) {
198 $result[
'type'] =
'break';
203 preg_match_all($fixes_pattern, $result[
'body'], $matches);
204 if (!empty($matches) && !empty($matches[2])) {
205 $result[
'closes'] = array_map(
function (
$value) {
228 $options = array_merge(
$defaults, $options);
230 $command = vsprintf(
'git shortlog -sne %s --no-merges %s', [
233 if (str_contains(PHP_OS,
'WIN')) {
238 }, $options[
'exclude'])),
242 if (!isset($contributors)) {
246 $contributor_pattern =
'/\s+([0-9]+)\s+(.*)\s<(.*)>/';
248 foreach ($contributors as $contributor) {
250 preg_match($contributor_pattern, $contributor, $matches);
251 if (empty($matches)) {
256 'count' => (int) $matches[1],
257 'name' => $matches[2],
258 'email' => $matches[3],
263 usort(
$result,
function ($a, $b) {
264 return $b[
'count'] - $a[
'count'];
278 if (empty($commits)) {
284 foreach ($commits as $commit) {
285 $type = $commit[
'type'];
286 if (str_starts_with(
$type,
'feat')) {
291 $type =
'performance';
293 $type =
'documentation';
295 $type =
'deprecated';
304 if (!isset($types[
$type])) {
308 $component = $commit[
'component'];
309 if (!isset($types[$type][$component])) {
310 $types[
$type][$component] = [];
316 if (!empty($commit[
'closes'])) {
317 $closes .=
'closes ';
318 foreach ($commit[
'closes'] as $issue_id) {
323 $types[
$type][$component][] =
trim(vsprintf(
'%s %s %s', [
337 if (!isset($types[
$type])) {
341 $section =
"#### {$label}" . PHP_EOL . PHP_EOL;
343 foreach ($types[$type] as $component => $commits) {
344 if (
count($commits) === 1) {
345 $section .=
"* **{$component}:** {$commits[0]}" . PHP_EOL;
347 $section .=
"* **{$component}:**" . PHP_EOL;
349 foreach ($commits as $commit) {
350 $section .=
' * ' . $commit . PHP_EOL;
369 if (empty($contributors)) {
373 $section =
'#### Contributors' . PHP_EOL . PHP_EOL;
375 foreach ($contributors as $contributor) {
376 $section .=
"* {$contributor['name']} ({$contributor['count']})" . PHP_EOL;
390 $date = date(
'Y-m-d');
393 if ($parts[2] ===
'0') {
395 $section .=
"## {$version} ({$date})";
398 $section .=
"### {$version} ({$date})";
412 if (empty($commit)) {
416 return vsprintf(
'[%s](%s/commit/%s)', [
417 $commit[
'short_hash'],
431 if (empty($issue_id)) {
435 return vsprintf(
'[#%s](%s/issues/%s)', [
452 if ($first_anchor !==
false) {
472 exec($command,
$output, $result_code);
474 if ($result_code !== 0) {
490 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.