Skip to content

Commit a841f63

Browse files
authored
Merge pull request #58 from weierophinney/feature/changelog-revisions
Feature/changelog revisions
2 parents 6d02a62 + 46c5e5a commit a841f63

19 files changed

+879
-259
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ All notable changes to this project will be documented in this file, in reverse
1010

1111
### Changed
1212

13-
- Nothing.
13+
- [#58](https://github.com/laminas/automatic-releases/pull/58) updates the "Release" step such that:
14+
- It now **always** uses jwage/changelog-generator to generate release notes.
15+
- **IF** a `CHANGELOG.md` file is present:
16+
- **IF** it contains changes for the target version, it appends the generated release notes to the changes for that version.
17+
- **OTHERWISE** it replaces the contents for the target version with the generated release notes.
18+
- And then it commits and pushes the file to the originating branch before it tags and releases.
1419

1520
### Deprecated
1621

bin/console.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
use Laminas\AutomaticReleases\Github\Api\V3\CreatePullRequestThroughApiCall;
2828
use Laminas\AutomaticReleases\Github\Api\V3\CreateReleaseThroughApiCall;
2929
use Laminas\AutomaticReleases\Github\Api\V3\SetDefaultBranchThroughApiCall;
30-
use Laminas\AutomaticReleases\Github\ConcatenateMultipleReleaseTexts;
3130
use Laminas\AutomaticReleases\Github\CreateReleaseTextThroughChangelog;
3231
use Laminas\AutomaticReleases\Github\CreateReleaseTextViaKeepAChangelog;
3332
use Laminas\AutomaticReleases\Github\Event\Factory\LoadCurrentGithubEventFromGithubActionPath;
3433
use Laminas\AutomaticReleases\Github\JwageGenerateChangelog;
34+
use Laminas\AutomaticReleases\Github\MergeMultipleReleaseNotes;
3535
use Laminas\AutomaticReleases\Gpg\ImportGpgKeyFromStringViaTemporaryFile;
3636
use Lcobucci\Clock\SystemClock;
3737
use Monolog\Handler\StreamHandler;
@@ -75,7 +75,6 @@ static function (int $errorCode, string $message = '', string $file = '', int $l
7575
$commit = new CommitFileViaConsole();
7676
$push = new PushViaConsole();
7777
$commitChangelog = new CommitReleaseChangelogViaKeepAChangelog(
78-
new SystemClock(),
7978
$changelogExists,
8079
$checkoutBranch,
8180
$commit,
@@ -86,8 +85,8 @@ static function (int $errorCode, string $message = '', string $file = '', int $l
8685
$makeRequests,
8786
$httpClient
8887
));
89-
$createReleaseText = new ConcatenateMultipleReleaseTexts([
90-
new CreateReleaseTextViaKeepAChangelog($changelogExists),
88+
$createReleaseText = new MergeMultipleReleaseNotes([
89+
new CreateReleaseTextViaKeepAChangelog($changelogExists, new SystemClock()),
9190
$createCommitText,
9291
]);
9392
$createRelease = new CreateReleaseThroughApiCall(
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
2+
3+
name: "Automatic Releases"
4+
5+
on:
6+
milestone:
7+
types:
8+
- "closed"
9+
10+
jobs:
11+
release:
12+
name: "GIT tag, release & create merge-up PR"
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: "Checkout"
17+
uses: "actions/checkout@v2"
18+
19+
- name: "Release"
20+
uses: "laminas/automatic-releases@v1"
21+
with:
22+
command-name: "laminas:automatic-releases:release"
23+
env:
24+
"GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
25+
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
26+
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
27+
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
28+
29+
- name: "Create Merge-Up Pull Request"
30+
uses: "laminas/automatic-releases@v1"
31+
with:
32+
command-name: "laminas:automatic-releases:create-merge-up-pull-request"
33+
env:
34+
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
35+
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
36+
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
37+
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
38+
39+
- name: "Create and/or Switch to new Release Branch"
40+
uses: "laminas/automatic-releases@v1"
41+
with:
42+
command-name: "laminas:automatic-releases:switch-default-branch-to-next-minor"
43+
env:
44+
"GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
45+
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
46+
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
47+
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
48+
49+
- name: "Bump Changelog Version On Originating Release Branch"
50+
uses: "laminas/automatic-releases@v1"
51+
with:
52+
command-name: "laminas:automatic-releases:bump-changelog"
53+
env:
54+
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
55+
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
56+
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
57+
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}

src/Application/Command/CreateMergeUpPullRequest.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,21 @@ public function execute(InputInterface $input, OutputInterface $output): int
9494
. uniqid('_', true) // This is to ensure that a new merge-up pull request is created even if one already exists
9595
);
9696

97+
$releaseNotes = $this->createReleaseText->__invoke(
98+
$this->getMilestone->__invoke($event->repository(), $event->milestoneNumber()),
99+
$event->repository(),
100+
$event->version(),
101+
$releaseBranch,
102+
$repositoryPath
103+
);
104+
97105
$this->push->__invoke($repositoryPath, $releaseBranch->name(), $mergeUpBranch->name());
98106
$this->createPullRequest->__invoke(
99107
$event->repository(),
100108
$mergeUpBranch,
101109
$mergeUpTarget,
102110
'Merge release ' . $releaseVersion->fullReleaseName() . ' into ' . $mergeUpTarget->name(),
103-
$this->createReleaseText->__invoke(
104-
$this->getMilestone->__invoke($event->repository(), $event->milestoneNumber()),
105-
$event->repository(),
106-
$event->version(),
107-
$releaseBranch,
108-
$repositoryPath
109-
)
111+
$releaseNotes->contents()
110112
);
111113

112114
return 0;

src/Application/Command/ReleaseCommand.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,22 +84,28 @@ public function execute(InputInterface $input, OutputInterface $output): int
8484
sprintf('No valid release branch found for version %s', $releaseVersion->fullReleaseName())
8585
);
8686

87-
($this->commitChangelog)($repositoryPath, $releaseVersion, $releaseBranch);
88-
89-
$changelog = ($this->createChangelogText)(
87+
$changelogReleaseNotes = ($this->createChangelogText)(
9088
$milestone,
9189
$repositoryName,
9290
$releaseVersion,
9391
$releaseBranch,
9492
$repositoryPath
9593
);
9694

95+
($this->commitChangelog)($changelogReleaseNotes, $repositoryPath, $releaseVersion, $releaseBranch);
96+
9797
$tagName = $releaseVersion->fullReleaseName();
9898

99-
($this->createTag)($repositoryPath, $releaseBranch, $tagName, $changelog, $this->environment->signingSecretKey());
99+
($this->createTag)(
100+
$repositoryPath,
101+
$releaseBranch,
102+
$tagName,
103+
$changelogReleaseNotes->contents(),
104+
$this->environment->signingSecretKey()
105+
);
100106
($this->push)($repositoryPath, $tagName);
101107
($this->push)($repositoryPath, $tagName, $releaseVersion->targetReleaseBranchName()->name());
102-
($this->createRelease)($repositoryName, $releaseVersion, $changelog);
108+
($this->createRelease)($repositoryName, $releaseVersion, $changelogReleaseNotes->contents());
103109

104110
return 0;
105111
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Laminas\AutomaticReleases\Changelog;
6+
7+
use Phly\KeepAChangelog\Common\ChangelogEditor;
8+
use Phly\KeepAChangelog\Common\ChangelogEntry;
9+
use RuntimeException;
10+
use Webmozart\Assert\Assert;
11+
12+
/**
13+
* @psalm-immutable
14+
*/
15+
class ChangelogReleaseNotes
16+
{
17+
private const CONCATENATION_STRING = "\n\n-----\n\n";
18+
19+
private ?ChangelogEntry $changelogEntry;
20+
21+
/** @psalm-var non-empty-string */
22+
private string $contents;
23+
24+
/**
25+
* @psalm-param non-empty-string $changelogFile
26+
*/
27+
public static function writeChangelogFile(string $changelogFile, self $releaseNotes): void
28+
{
29+
// Nothing to do
30+
if (! $releaseNotes->requiresUpdatingChangelogFile()) {
31+
return;
32+
}
33+
34+
Assert::notNull($releaseNotes->changelogEntry);
35+
36+
$editor = new ChangelogEditor();
37+
$editor->update(
38+
$changelogFile,
39+
$releaseNotes->contents,
40+
$releaseNotes->changelogEntry
41+
);
42+
}
43+
44+
/**
45+
* @psalm-param non-empty-string $contents
46+
*/
47+
public function __construct(
48+
string $contents,
49+
?ChangelogEntry $changelogEntry = null
50+
) {
51+
if ($changelogEntry) {
52+
$changelogEntry = clone $changelogEntry;
53+
}
54+
55+
$this->contents = $contents;
56+
57+
/** @psalm-suppress ImpurePropertyAssignment */
58+
$this->changelogEntry = $changelogEntry;
59+
}
60+
61+
/**
62+
* @psalm-return non-empty-string
63+
*/
64+
public function contents(): string
65+
{
66+
return $this->contents;
67+
}
68+
69+
public function merge(self $next): self
70+
{
71+
if ($this->changelogEntry && $next->changelogEntry) {
72+
throw new RuntimeException(
73+
'Aborting: Both current release notes and next contain a ChangelogEntry;'
74+
. ' only one CreateReleaseText implementation should resolve one.'
75+
);
76+
}
77+
78+
$changelogEntry = $this->changelogEntry ?: $next->changelogEntry;
79+
if ($changelogEntry) {
80+
$changelogEntry = clone $changelogEntry;
81+
}
82+
83+
$merged = clone $this;
84+
$merged->contents .= self::CONCATENATION_STRING . $next->contents;
85+
/** @psalm-suppress ImpurePropertyAssignment */
86+
$merged->changelogEntry = $changelogEntry;
87+
88+
return $merged;
89+
}
90+
91+
public function requiresUpdatingChangelogFile(): bool
92+
{
93+
if ($this->changelogEntry === null) {
94+
return false;
95+
}
96+
97+
$originalContents = (string) $this->changelogEntry->contents();
98+
99+
return $this->contents !== $originalContents;
100+
}
101+
}

src/Changelog/CommitReleaseChangelog.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface CommitReleaseChangelog
1313
* @psalm-param non-empty-string $repositoryDirectory
1414
*/
1515
public function __invoke(
16+
ChangelogReleaseNotes $releaseNotes,
1617
string $repositoryDirectory,
1718
SemVerVersion $version,
1819
BranchName $sourceBranch

0 commit comments

Comments
 (0)