Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion feature/automated-releases.feature
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Feature: Automated releases
When I close milestone "2.0.0"
Then tag "2.0.0" should have been created on branch "2.0.x"

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

Scenario: If a minor release branch exists, when closing the minor release milestone,
the tool tags the minor release from the branch, and creates a pull request
against the next newer minor or major release branch.
Given following existing branches:
| name |
| 1.1.x |
| 2.0.x |
| master |
And following open milestones:
| name |
| 1.1.0 |
When I close milestone "1.1.0"
Then tag "1.1.0" should have been created on branch "1.1.x"
And a new pull request from branch "1.1.x" to "2.0.x" should have been created

Scenario: If no newer release branch exists, the tool will not create any pull requests
Given following existing branches:
| name |
Expand Down
15 changes: 14 additions & 1 deletion src/Application/Command/SwitchDefaultBranchToNextMinor.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

use function sprintf;

final class SwitchDefaultBranchToNextMinor extends Command
{
public function __construct(
Expand All @@ -31,7 +33,7 @@
parent::__construct('laminas:automatic-releases:switch-default-branch-to-next-minor');
}

public function execute(InputInterface $input, OutputInterface $output): int

Check warning on line 36 in src/Application/Command/SwitchDefaultBranchToNextMinor.php

View workflow job for this annotation

GitHub Actions / ci / QA Checks (Infection [8.3, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@...

Escaped Mutant for Mutator "PublicVisibility": --- Original +++ New @@ @@ { parent::__construct('laminas:automatic-releases:switch-default-branch-to-next-minor'); } - public function execute(InputInterface $input, OutputInterface $output) : int + protected function execute(InputInterface $input, OutputInterface $output) : int { $event = $this->loadGithubEvent->__invoke(); $repositoryPath = $this->variables->githubWorkspacePath();
{
$event = $this->loadGithubEvent->__invoke();
$repositoryPath = $this->variables->githubWorkspacePath();
Expand All @@ -58,9 +60,20 @@
$nextDefaultBranch = $mergeCandidates->newestFutureReleaseBranchAfter($releaseVersion);

if (! $mergeCandidates->contains($nextDefaultBranch)) {
$baseBranch = $mergeCandidates->targetBranchFor($releaseVersion);
if ($baseBranch === null) {
$output->writeln(sprintf(
'Target branch for release [%s] was not found. Expected [%s] to exist.',
$releaseVersion->fullReleaseName(),
$releaseVersion->targetReleaseBranchName()->name(),
));

return 1;
}

$this->push->__invoke(
$repositoryPath,
$newestBranch->name(),
$baseBranch->name(),
$nextDefaultBranch->name(),
);
($this->bumpChangelogVersion)(
Expand Down
6 changes: 3 additions & 3 deletions src/Git/Value/SemVerVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
final readonly class SemVerVersion
{
private function __construct(
private readonly int $major,
private readonly int $minor,
private readonly int $patch,
private int $major,
private int $minor,
private int $patch,
) {
}

Expand Down
140 changes: 140 additions & 0 deletions test/unit/Application/SwitchDefaultBranchToNextMinorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,146 @@ public function testWillSwitchToExistingNewestDefaultBranch(): void
self::assertSame(0, $this->command->run(new ArrayInput([]), new NullOutput()));
}

public function testWillSwitchToExistingNewestDefaultBranchEvenWithNewMajorBranchExist(): void
{
$event = MilestoneClosedEvent::fromEventJson(
<<<'JSON'
{
"milestone": {
"title": "1.3.0",
"number": 123
},
"repository": {
"full_name": "foo/bar"
},
"action": "closed"
}
JSON,
);

$workspace = Filesystem\create_temporary_file(Env\temp_dir(), 'workspace');

Filesystem\delete_file($workspace);
Filesystem\create_directory($workspace);
Filesystem\create_directory($workspace . '/.git');

$this->variables->method('githubWorkspacePath')
->willReturn($workspace);

$this->loadEvent->method('__invoke')
->willReturn($event);

$this->fetch->expects(self::once())
->method('__invoke')
->with(
'https://github.com/foo/bar.git',
'https://github-auth-token:x-oauth-basic@github.com/foo/bar.git',
$workspace,
);

$this->getMergeTargets->method('__invoke')
->with($workspace)
->willReturn(MergeTargetCandidateBranches::fromAllBranches(
BranchName::fromName('1.1.x'),
BranchName::fromName('1.2.x'),
BranchName::fromName('1.3.x'),
BranchName::fromName('2.0.x'),
BranchName::fromName('master'),
));

$this->push->expects(self::once())
->method('__invoke')
->with($workspace, '1.3.x', '1.4.x');

$this->bumpChangelogVersion->expects(self::once())
->method('__invoke')
->with(
BumpAndCommitChangelogVersion::BUMP_MINOR,
$workspace,
SemVerVersion::fromMilestoneName('1.3.0'),
BranchName::fromName('1.4.x'),
);

$this->setDefaultBranch->expects(self::once())
->method('__invoke')
->with(
self::equalTo(RepositoryName::fromFullName('foo/bar')),
self::equalTo(BranchName::fromName('1.4.x')),
);

self::assertSame(0, $this->command->run(new ArrayInput([]), new NullOutput()));
}

public function testWillNotSwitchToBranchWhenTargetBranchNotFound(): void
{
$event = MilestoneClosedEvent::fromEventJson(
<<<'JSON'
{
"milestone": {
"title": "1.4.0",
"number": 123
},
"repository": {
"full_name": "foo/bar"
},
"action": "closed"
}
JSON,
);

$workspace = Filesystem\create_temporary_file(Env\temp_dir(), 'workspace');

Filesystem\delete_file($workspace);
Filesystem\create_directory($workspace);
Filesystem\create_directory($workspace . '/.git');

$this->variables->method('githubWorkspacePath')
->willReturn($workspace);

$this->loadEvent->method('__invoke')
->willReturn($event);

$this->fetch->expects(self::once())
->method('__invoke')
->with(
'https://github.com/foo/bar.git',
'https://github-auth-token:x-oauth-basic@github.com/foo/bar.git',
$workspace,
);

$this->getMergeTargets->method('__invoke')
->with($workspace)
->willReturn(MergeTargetCandidateBranches::fromAllBranches(
BranchName::fromName('1.1.x'),
BranchName::fromName('1.2.x'),
BranchName::fromName('1.3.x'),
BranchName::fromName('2.0.x'),
BranchName::fromName('master'),
));

$this->push->expects(self::never())
->method('__invoke');

$this->bumpChangelogVersion->expects(self::never())
->method('__invoke');

$this->setDefaultBranch->expects(self::never())
->method('__invoke');

$output = new BufferedOutput();

self::assertSame(1, $this->command->run(new ArrayInput([]), $output));

self::assertSame(
<<<'OUTPUT'
Target branch for release [1.4.0] was not found. Expected [1.4.x] to exist.

OUTPUT
,
$output->fetch(),
);
}

public function testWillSwitchToNewlyCreatedDefaultBranchWhenNoNewerReleaseBranchExists(): void
{
$workspace = Filesystem\create_temporary_file(Env\temp_dir(), 'workspace');
Expand Down
Loading