Skip to content

Commit d28c3bb

Browse files
Add protected branches option
This is done to allow fixup pushes to all branches except the protected ones. This way fixup and squash commits can be pushed to feature branches but not to configured ones like for example main or master branches.
1 parent c81e043 commit d28c3bb

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

src/Hook/Branch/Action/BlockFixupAndSquashCommits.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
* "action": "\\CaptainHook\\App\\Hook\\Branch\\Action\\BlockFixupAndSquashCommits",
3333
* "options": {
3434
* "blockSquashCommits": true,
35-
* "blockFixupCommits": true
35+
* "blockFixupCommits": true,
36+
* "protectedBranches": ["main", "master", "integration"]
3637
* },
3738
* "conditions": []
3839
* }
@@ -49,14 +50,23 @@ class BlockFixupAndSquashCommits implements Action
4950
*
5051
* @var bool
5152
*/
52-
private $blockFixupCommits = true;
53+
private bool $blockFixupCommits = true;
5354

5455
/**
5556
* Should squash! commits be blocked
5657
*
5758
* @var bool
5859
*/
59-
private $blockSquashCommits = true;
60+
private bool $blockSquashCommits = true;
61+
62+
/**
63+
* List of protected branches
64+
*
65+
* If not specified all branches are protected
66+
*
67+
* @var array<string>
68+
*/
69+
private array $protectedBranches;
6070

6171
/**
6272
* Return hook restriction
@@ -90,6 +100,9 @@ public function execute(Config $config, IO $io, Repository $repository, Config\A
90100
$this->handleOptions($action->getOptions());
91101

92102
foreach ($refsToPush as $range) {
103+
if (!empty($this->protectedBranches) && !in_array($range->from()->branch(), $this->protectedBranches)) {
104+
return;
105+
}
93106
$commits = $this->getBlockedCommits($repository, $range->from()->id(), $range->to()->id());
94107

95108
if (count($commits) > 0) {
@@ -108,6 +121,7 @@ private function handleOptions(Config\Options $options): void
108121
{
109122
$this->blockSquashCommits = (bool) $options->get('blockSquashCommits', true);
110123
$this->blockFixupCommits = (bool) $options->get('blockFixupCommits', true);
124+
$this->protectedBranches = $options->get('protectedBranches', []);
111125
}
112126

113127
/**

tests/unit/Hook/Branch/Action/BlockFixupAndSquashCommitsTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,29 @@ public function testExecuteSuccess(): void
5757
$this->assertTrue(true);
5858
}
5959

60+
/**
61+
* Tests BlockFixupAndSquashCommits::execute
62+
*/
63+
public function testExecuteSuccessBecauseOfUnprotectedBranch(): void
64+
{
65+
$input = ['refs/heads/foo 12345 refs/heads/foo 98765'];
66+
$io = $this->createIOMock();
67+
$repo = $this->createRepositoryMock();
68+
$config = $this->createConfigMock();
69+
$action = $this->createActionConfigMock();
70+
$operator = $this->createGitLogOperator();
71+
$options = new Options(['protectedBranches' => ['main']]);
72+
$action->expects($this->once())->method('getOptions')->willReturn($options);
73+
$io->expects($this->once())->method('getStandardInput')->willReturn($input);
74+
$operator->method('getCommitsBetween')->willReturn($this->getFakeCommits());
75+
$repo->method('getLogOperator')->willReturn($operator);
76+
77+
$blocker = new BlockFixupAndSquashCommits();
78+
$blocker->execute($config, $io, $repo, $action);
79+
80+
$this->assertTrue(true);
81+
}
82+
6083
/**
6184
* Tests BlockFixupAndSquashCommits::execute
6285
*/
@@ -78,6 +101,7 @@ public function testExecuteSuccessWithNoChangesFromLocalAndRemote(): void
78101

79102
$this->assertTrue(true);
80103
}
104+
81105
/**
82106
* Tests BlockFixupAndSquashCommits::execute
83107
*/
@@ -100,6 +124,29 @@ public function testExecuteBlockFixup(): void
100124
$blocker->execute($config, $io, $repo, $action);
101125
}
102126

127+
/**
128+
* Tests BlockFixupAndSquashCommits::execute
129+
*/
130+
public function testExecuteBlockFixupForProtectedBranch(): void
131+
{
132+
$this->expectException(Exception::class);
133+
134+
$input = ['refs/heads/main 12345 refs/heads/main 98765'];
135+
$io = $this->createIOMock();
136+
$repo = $this->createRepositoryMock();
137+
$config = $this->createConfigMock();
138+
$action = $this->createActionConfigMock();
139+
$operator = $this->createGitLogOperator();
140+
$options = new Options(['protectedBranches' => ['main']]);
141+
$action->expects($this->once())->method('getOptions')->willReturn($options);
142+
$io->expects($this->once())->method('getStandardInput')->willReturn($input);
143+
$operator->method('getCommitsBetween')->willReturn($this->getFakeCommits('fixup! Foo'));
144+
$repo->method('getLogOperator')->willReturn($operator);
145+
146+
$blocker = new BlockFixupAndSquashCommits();
147+
$blocker->execute($config, $io, $repo, $action);
148+
}
149+
103150
/**
104151
* Tests BlockFixupAndSquashCommits::execute
105152
*/

0 commit comments

Comments
 (0)