Skip to content

Commit 00473e2

Browse files
authored
Merge pull request #282 from DanielBadura/fix-creating-new-minor-branch-if-new-major-exist
Fix creating minor release if new major release branch already exist
2 parents 014f2b9 + f3687c5 commit 00473e2

File tree

4 files changed

+173
-5
lines changed

4 files changed

+173
-5
lines changed

feature/automated-releases.feature

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Feature: Automated releases
3838
When I close milestone "2.0.0"
3939
Then tag "2.0.0" should have been created on branch "2.0.x"
4040

41-
Scenario: If a new major release branch exists, the tool does not create a new minor release
41+
Scenario: If matching minor release branch exists, the tool does not create a new minor release
4242
Given following existing branches:
4343
| name |
4444
| 1.0.x |
@@ -66,6 +66,21 @@ Feature: Automated releases
6666
Then tag "1.1.0" should have been created on branch "1.1.x"
6767
And a new pull request from branch "1.1.x" to "1.2.x" should have been created
6868

69+
Scenario: If a minor release branch exists, when closing the minor release milestone,
70+
the tool tags the minor release from the branch, and creates a pull request
71+
against the next newer minor or major release branch.
72+
Given following existing branches:
73+
| name |
74+
| 1.1.x |
75+
| 2.0.x |
76+
| master |
77+
And following open milestones:
78+
| name |
79+
| 1.1.0 |
80+
When I close milestone "1.1.0"
81+
Then tag "1.1.0" should have been created on branch "1.1.x"
82+
And a new pull request from branch "1.1.x" to "2.0.x" should have been created
83+
6984
Scenario: If no newer release branch exists, the tool will not create any pull requests
7085
Given following existing branches:
7186
| name |

src/Application/Command/SwitchDefaultBranchToNextMinor.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use Symfony\Component\Console\Input\InputInterface;
1818
use Symfony\Component\Console\Output\OutputInterface;
1919

20+
use function sprintf;
21+
2022
final class SwitchDefaultBranchToNextMinor extends Command
2123
{
2224
public function __construct(
@@ -58,9 +60,20 @@ public function execute(InputInterface $input, OutputInterface $output): int
5860
$nextDefaultBranch = $mergeCandidates->newestFutureReleaseBranchAfter($releaseVersion);
5961

6062
if (! $mergeCandidates->contains($nextDefaultBranch)) {
63+
$baseBranch = $mergeCandidates->targetBranchFor($releaseVersion);
64+
if ($baseBranch === null) {
65+
$output->writeln(sprintf(
66+
'Target branch for release [%s] was not found. Expected [%s] to exist.',
67+
$releaseVersion->fullReleaseName(),
68+
$releaseVersion->targetReleaseBranchName()->name(),
69+
));
70+
71+
return 1;
72+
}
73+
6174
$this->push->__invoke(
6275
$repositoryPath,
63-
$newestBranch->name(),
76+
$baseBranch->name(),
6477
$nextDefaultBranch->name(),
6578
);
6679
($this->bumpChangelogVersion)(

src/Git/Value/SemVerVersion.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
final readonly class SemVerVersion
1212
{
1313
private function __construct(
14-
private readonly int $major,
15-
private readonly int $minor,
16-
private readonly int $patch,
14+
private int $major,
15+
private int $minor,
16+
private int $patch,
1717
) {
1818
}
1919

test/unit/Application/SwitchDefaultBranchToNextMinorTest.php

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,146 @@ public function testWillSwitchToExistingNewestDefaultBranch(): void
145145
self::assertSame(0, $this->command->run(new ArrayInput([]), new NullOutput()));
146146
}
147147

148+
public function testWillSwitchToExistingNewestDefaultBranchEvenWithNewMajorBranchExist(): void
149+
{
150+
$event = MilestoneClosedEvent::fromEventJson(
151+
<<<'JSON'
152+
{
153+
"milestone": {
154+
"title": "1.3.0",
155+
"number": 123
156+
},
157+
"repository": {
158+
"full_name": "foo/bar"
159+
},
160+
"action": "closed"
161+
}
162+
JSON,
163+
);
164+
165+
$workspace = Filesystem\create_temporary_file(Env\temp_dir(), 'workspace');
166+
167+
Filesystem\delete_file($workspace);
168+
Filesystem\create_directory($workspace);
169+
Filesystem\create_directory($workspace . '/.git');
170+
171+
$this->variables->method('githubWorkspacePath')
172+
->willReturn($workspace);
173+
174+
$this->loadEvent->method('__invoke')
175+
->willReturn($event);
176+
177+
$this->fetch->expects(self::once())
178+
->method('__invoke')
179+
->with(
180+
'https://github.com/foo/bar.git',
181+
'https://github-auth-token:x-oauth-basic@github.com/foo/bar.git',
182+
$workspace,
183+
);
184+
185+
$this->getMergeTargets->method('__invoke')
186+
->with($workspace)
187+
->willReturn(MergeTargetCandidateBranches::fromAllBranches(
188+
BranchName::fromName('1.1.x'),
189+
BranchName::fromName('1.2.x'),
190+
BranchName::fromName('1.3.x'),
191+
BranchName::fromName('2.0.x'),
192+
BranchName::fromName('master'),
193+
));
194+
195+
$this->push->expects(self::once())
196+
->method('__invoke')
197+
->with($workspace, '1.3.x', '1.4.x');
198+
199+
$this->bumpChangelogVersion->expects(self::once())
200+
->method('__invoke')
201+
->with(
202+
BumpAndCommitChangelogVersion::BUMP_MINOR,
203+
$workspace,
204+
SemVerVersion::fromMilestoneName('1.3.0'),
205+
BranchName::fromName('1.4.x'),
206+
);
207+
208+
$this->setDefaultBranch->expects(self::once())
209+
->method('__invoke')
210+
->with(
211+
self::equalTo(RepositoryName::fromFullName('foo/bar')),
212+
self::equalTo(BranchName::fromName('1.4.x')),
213+
);
214+
215+
self::assertSame(0, $this->command->run(new ArrayInput([]), new NullOutput()));
216+
}
217+
218+
public function testWillNotSwitchToBranchWhenTargetBranchNotFound(): void
219+
{
220+
$event = MilestoneClosedEvent::fromEventJson(
221+
<<<'JSON'
222+
{
223+
"milestone": {
224+
"title": "1.4.0",
225+
"number": 123
226+
},
227+
"repository": {
228+
"full_name": "foo/bar"
229+
},
230+
"action": "closed"
231+
}
232+
JSON,
233+
);
234+
235+
$workspace = Filesystem\create_temporary_file(Env\temp_dir(), 'workspace');
236+
237+
Filesystem\delete_file($workspace);
238+
Filesystem\create_directory($workspace);
239+
Filesystem\create_directory($workspace . '/.git');
240+
241+
$this->variables->method('githubWorkspacePath')
242+
->willReturn($workspace);
243+
244+
$this->loadEvent->method('__invoke')
245+
->willReturn($event);
246+
247+
$this->fetch->expects(self::once())
248+
->method('__invoke')
249+
->with(
250+
'https://github.com/foo/bar.git',
251+
'https://github-auth-token:x-oauth-basic@github.com/foo/bar.git',
252+
$workspace,
253+
);
254+
255+
$this->getMergeTargets->method('__invoke')
256+
->with($workspace)
257+
->willReturn(MergeTargetCandidateBranches::fromAllBranches(
258+
BranchName::fromName('1.1.x'),
259+
BranchName::fromName('1.2.x'),
260+
BranchName::fromName('1.3.x'),
261+
BranchName::fromName('2.0.x'),
262+
BranchName::fromName('master'),
263+
));
264+
265+
$this->push->expects(self::never())
266+
->method('__invoke');
267+
268+
$this->bumpChangelogVersion->expects(self::never())
269+
->method('__invoke');
270+
271+
$this->setDefaultBranch->expects(self::never())
272+
->method('__invoke');
273+
274+
$output = new BufferedOutput();
275+
276+
self::assertSame(1, $this->command->run(new ArrayInput([]), $output));
277+
278+
self::assertSame(
279+
<<<'OUTPUT'
280+
Target branch for release [1.4.0] was not found. Expected [1.4.x] to exist.
281+
282+
OUTPUT
283+
,
284+
$output->fetch(),
285+
);
286+
}
287+
148288
public function testWillSwitchToNewlyCreatedDefaultBranchWhenNoNewerReleaseBranchExists(): void
149289
{
150290
$workspace = Filesystem\create_temporary_file(Env\temp_dir(), 'workspace');

0 commit comments

Comments
 (0)