Skip to content

Commit 0a6097a

Browse files
committed
fix: check for changelog and/or pull contents from changelog using remote origin
As it turns out, while you can use `git show {ref}:{filename}` to both test for the existing of a file at a given reference, as well as display its contents, it only works if the reference is present. When the github action starts, it _exports_ the default branch to the working directory. Our code then _fetches_ from the remote, which then sets the current branch to the _default_ branch, which may or may not be the branch we are releasing from. It's not until we do a checkout operation that the release branch can be guaranteed as a reference in the checkout. The reference _does_ exist in the `origin` remote, and since we have all history, that means the content is present in our checkout; it's just that the reference doesn't exist **IN** the checkout. As such, for idempotent operations where we are checking for the existence of a file, or pulling its contents, we need to qualify the reference with the remote name (e.g., `{remote}/1.0.x`). Since we can guarantee that the `origin` remote is present, we can use that remote name. Fiexes #51 Signed-off-by: Matthew Weier O'Phinney <[email protected]>
1 parent d22b7c1 commit 0a6097a

File tree

5 files changed

+77
-21
lines changed

5 files changed

+77
-21
lines changed

src/Changelog/ChangelogExistsViaConsole.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function __invoke(
1616
BranchName $sourceBranch,
1717
string $repositoryDirectory
1818
): bool {
19-
$process = new Process(['git', 'show', $sourceBranch->name() . ':CHANGELOG.md'], $repositoryDirectory);
19+
$process = new Process(['git', 'show', 'origin/' . $sourceBranch->name() . ':CHANGELOG.md'], $repositoryDirectory);
2020
$process->run();
2121

2222
return $process->isSuccessful();

src/Github/CreateReleaseTextViaKeepAChangelog.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ private function fetchChangelogContentsFromBranch(
7676
BranchName $sourceBranch,
7777
string $repositoryDirectory
7878
): string {
79-
$process = new Process(['git', 'show', $sourceBranch->name() . ':CHANGELOG.md'], $repositoryDirectory);
79+
$process = new Process(['git', 'show', 'origin/' . $sourceBranch->name() . ':CHANGELOG.md'], $repositoryDirectory);
8080
$process->mustRun();
8181

8282
$contents = $process->getOutput();

test/unit/Changelog/ChangelogExistsViaConsoleTest.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,24 @@ class ChangelogExistsViaConsoleTest extends TestCase
2020
{
2121
public function testReturnsFalseWhenChangelogIsNotPresentInBranch(): void
2222
{
23+
$repository = $this->createMockRepositoryWithChangelog();
24+
$workingDir = $this->checkoutMockRepositoryWithChangelog($repository);
2325
self::assertFalse(
2426
(new ChangelogExistsViaConsole())(
2527
BranchName::fromName('0.99.x'),
26-
$this->createMockRepositoryWithChangelog()
28+
$workingDir
2729
)
2830
);
2931
}
3032

3133
public function testReturnsTrueWhenChangelogIsPresentInBranch(): void
3234
{
35+
$repository = $this->createMockRepositoryWithChangelog();
36+
$workingDir = $this->checkoutMockRepositoryWithChangelog($repository);
3337
self::assertTrue(
3438
(new ChangelogExistsViaConsole())(
3539
BranchName::fromName('1.0.x'),
36-
$this->createMockRepositoryWithChangelog()
40+
$workingDir
3741
)
3842
);
3943
}
@@ -90,4 +94,19 @@ private function createMockRepositoryWithChangelog(): string
9094

9195
return $repo;
9296
}
97+
98+
/**
99+
* @psalm-param non-empty-string $origin
100+
* @psalm-return non-empty-string
101+
*/
102+
private function checkoutMockRepositoryWithChangelog(string $origin): string
103+
{
104+
$repo = tempnam(sys_get_temp_dir(), 'CreateReleaseTextViaKeepAChangelog');
105+
Assert::notEmpty($repo);
106+
unlink($repo);
107+
108+
(new Process(['git', 'clone', $origin, $repo]))->mustRun();
109+
110+
return $repo;
111+
}
93112
}

test/unit/Changelog/ReleaseChangelogViaKeepAChangelogTest.php

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,14 @@ public function testNoOpWhenChangelogFileDoesNotExist(): void
8686

8787
public function testNoOpWhenUnableToFindMatchingChangelogEntry(): void
8888
{
89-
$repo = $this->createMockRepositoryWithChangelog(self::INVALID_CHANGELOG);
90-
$branch = BranchName::fromName('1.0.x');
89+
$repo = $this->createMockRepositoryWithChangelog(self::INVALID_CHANGELOG);
90+
$checkout = $this->checkoutMockRepositoryWithChangelog($repo);
91+
$branch = BranchName::fromName('1.0.x');
9192

9293
$this->checkoutBranch
9394
->expects($this->once())
9495
->method('__invoke')
95-
->with($repo, $branch);
96+
->with($checkout, $branch);
9697

9798
$this
9899
->logger
@@ -104,7 +105,7 @@ public function testNoOpWhenUnableToFindMatchingChangelogEntry(): void
104105

105106
self::assertNull(
106107
$this->releaseChangelog->__invoke(
107-
$repo,
108+
$checkout,
108109
SemVerVersion::fromMilestoneName('1.0.0'),
109110
$branch
110111
)
@@ -113,13 +114,14 @@ public function testNoOpWhenUnableToFindMatchingChangelogEntry(): void
113114

114115
public function testNoOpWhenFailedToSetReleaseDateInChangelogEntry(): void
115116
{
116-
$repo = $this->createMockRepositoryWithChangelog(self::RELEASED_CHANGELOG);
117-
$branch = BranchName::fromName('1.0.x');
117+
$repo = $this->createMockRepositoryWithChangelog(self::RELEASED_CHANGELOG);
118+
$checkout = $this->checkoutMockRepositoryWithChangelog($repo);
119+
$branch = BranchName::fromName('1.0.x');
118120

119121
$this->checkoutBranch
120122
->expects($this->once())
121123
->method('__invoke')
122-
->with($repo, $branch);
124+
->with($checkout, $branch);
123125

124126
$this
125127
->logger
@@ -131,7 +133,7 @@ public function testNoOpWhenFailedToSetReleaseDateInChangelogEntry(): void
131133

132134
self::assertNull(
133135
$this->releaseChangelog->__invoke(
134-
$repo,
136+
$checkout,
135137
SemVerVersion::fromMilestoneName('1.0.0'),
136138
$branch
137139
)
@@ -143,12 +145,13 @@ public function testWritesCommitsAndPushesChangelogWhenFoundAndReadyToRelease():
143145
$existingChangelog = sprintf(self::READY_CHANGELOG, 'TBD');
144146
$expectedChangelog = sprintf(self::READY_CHANGELOG, $this->clock->now()->format('Y-m-d'));
145147
$repositoryPath = $this->createMockRepositoryWithChangelog($existingChangelog);
148+
$checkout = $this->checkoutMockRepositoryWithChangelog($repositoryPath);
146149
$sourceBranch = BranchName::fromName('1.0.x');
147150

148151
$this->checkoutBranch
149152
->expects($this->once())
150153
->method('__invoke')
151-
->with($repositoryPath, $sourceBranch);
154+
->with($checkout, $sourceBranch);
152155

153156
$this
154157
->logger
@@ -160,7 +163,7 @@ public function testWritesCommitsAndPushesChangelogWhenFoundAndReadyToRelease():
160163
->expects($this->once())
161164
->method('__invoke')
162165
->with(
163-
$this->equalTo($repositoryPath),
166+
$this->equalTo($checkout),
164167
$this->equalTo($sourceBranch),
165168
$this->equalTo('CHANGELOG.md'),
166169
$this->stringContains('1.0.0 readiness')
@@ -170,19 +173,19 @@ public function testWritesCommitsAndPushesChangelogWhenFoundAndReadyToRelease():
170173
->expects($this->once())
171174
->method('__invoke')
172175
->with(
173-
$this->equalTo($repositoryPath),
176+
$this->equalTo($checkout),
174177
$this->equalTo('1.0.x'),
175178
);
176179

177180
self::assertNull(
178181
$this->releaseChangelog->__invoke(
179-
$repositoryPath,
182+
$checkout,
180183
SemVerVersion::fromMilestoneName('1.0.0'),
181184
BranchName::fromName('1.0.x')
182185
)
183186
);
184187

185-
$this->assertStringEqualsFile($repositoryPath . '/CHANGELOG.md', $expectedChangelog);
188+
$this->assertStringEqualsFile($checkout . '/CHANGELOG.md', $expectedChangelog);
186189
}
187190

188191
/**
@@ -213,6 +216,21 @@ private function createMockRepositoryWithChangelog(
213216
return $repo;
214217
}
215218

219+
/**
220+
* @psalm-param non-empty-string $origin
221+
* @psalm-return non-empty-string
222+
*/
223+
private function checkoutMockRepositoryWithChangelog(string $origin): string
224+
{
225+
$repo = tempnam(sys_get_temp_dir(), 'CreateReleaseTextViaKeepAChangelog');
226+
Assert::notEmpty($repo);
227+
unlink($repo);
228+
229+
(new Process(['git', 'clone', $origin, $repo]))->mustRun();
230+
231+
return $repo;
232+
}
233+
216234
private const INVALID_CHANGELOG = <<< 'END'
217235
# NOT A CHANGELOG
218236

test/unit/Github/CreateReleaseTextViaKeepAChangelogTest.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public function testReportsCannotCreateReleaseTextIfChangelogFileIsMissing(): vo
2929
self::INVALID_CHANGELOG,
3030
'NOT-A-CHANGELOG.md'
3131
);
32+
$workingPath = $this->checkoutMockRepositoryWithChangelog($repositoryPath);
3233

3334
self::assertFalse(
3435
(new CreateReleaseTextViaKeepAChangelog(new ChangelogExistsViaConsole()))
@@ -37,7 +38,7 @@ public function testReportsCannotCreateReleaseTextIfChangelogFileIsMissing(): vo
3738
RepositoryName::fromFullName('example/repo'),
3839
SemVerVersion::fromMilestoneName('1.0.0'),
3940
BranchName::fromName('1.0.x'),
40-
$repositoryPath
41+
$workingPath
4142
)
4243
);
4344
}
@@ -48,6 +49,7 @@ public function testReportsCannotCreateReleaseTextIfChangelogFileDoesNotContainV
4849
self::INVALID_CHANGELOG,
4950
'CHANGELOG.md'
5051
);
52+
$workingPath = $this->checkoutMockRepositoryWithChangelog($repositoryPath);
5153

5254
self::assertFalse(
5355
(new CreateReleaseTextViaKeepAChangelog(new ChangelogExistsViaConsole()))
@@ -56,7 +58,7 @@ public function testReportsCannotCreateReleaseTextIfChangelogFileDoesNotContainV
5658
RepositoryName::fromFullName('example/repo'),
5759
SemVerVersion::fromMilestoneName('1.0.0'),
5860
BranchName::fromName('1.0.x'),
59-
$repositoryPath
61+
$workingPath
6062
)
6163
);
6264
}
@@ -68,6 +70,7 @@ public function testReportsCanCreateReleaseWhenChangelogWithVersionExists(): voi
6870
$changelogContents,
6971
'CHANGELOG.md'
7072
);
73+
$workingPath = $this->checkoutMockRepositoryWithChangelog($repositoryPath);
7174

7275
self::assertTrue(
7376
(new CreateReleaseTextViaKeepAChangelog(new ChangelogExistsViaConsole()))
@@ -76,7 +79,7 @@ public function testReportsCanCreateReleaseWhenChangelogWithVersionExists(): voi
7679
RepositoryName::fromFullName('example/repo'),
7780
SemVerVersion::fromMilestoneName('1.0.0'),
7881
BranchName::fromName('1.0.x'),
79-
$repositoryPath
82+
$workingPath
8083
)
8184
);
8285
}
@@ -89,6 +92,7 @@ public function testExtractsReleaseTextViaChangelogFile(): void
8992
$changelogContents,
9093
'CHANGELOG.md'
9194
);
95+
$workingPath = $this->checkoutMockRepositoryWithChangelog($repositoryPath);
9296

9397
$expected = sprintf(<<< 'END'
9498
### Added
@@ -120,7 +124,7 @@ public function testExtractsReleaseTextViaChangelogFile(): void
120124
RepositoryName::fromFullName('example/repo'),
121125
SemVerVersion::fromMilestoneName('1.0.0'),
122126
BranchName::fromName('1.0.x'),
123-
$repositoryPath
127+
$workingPath
124128
)
125129
);
126130
}
@@ -170,6 +174,21 @@ private function createMockRepositoryWithChangelog(
170174
return $repo;
171175
}
172176

177+
/**
178+
* @psalm-param non-empty-string $origin
179+
* @psalm-return non-empty-string
180+
*/
181+
private function checkoutMockRepositoryWithChangelog(string $origin): string
182+
{
183+
$repo = tempnam(sys_get_temp_dir(), 'CreateReleaseTextViaKeepAChangelog');
184+
Assert::notEmpty($repo);
185+
unlink($repo);
186+
187+
(new Process(['git', 'clone', $origin, $repo]))->mustRun();
188+
189+
return $repo;
190+
}
191+
173192
private const INVALID_CHANGELOG = <<< 'END'
174193
# NOT A CHANGELOG
175194

0 commit comments

Comments
 (0)