Skip to content

Commit 2b7e486

Browse files
committed
Add more checks for released branches
1 parent 47de916 commit 2b7e486

File tree

4 files changed

+131
-44
lines changed

4 files changed

+131
-44
lines changed

docs/release.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
Usage:
44

55
git-release.ps1 [-source] <string> [-target] <string>
6-
[-comment <string>] [-preserve <string[]>] [-noFetch] [-dryRun] [-quiet] [-cleanupOnly]
6+
[-comment <string>] [-preserve <string[]>] [-cleanupOnly] [-force]
7+
[-noFetch] [-dryRun] [-quiet]
78

89
## Parameters
910

@@ -31,6 +32,11 @@ A comma delimited list of branches to preserve in addition to those upstream
3132
Use this flag when the released branch (from `-branchName`) was already merged
3233
to the target branch (`-target`) to clean up the included branches.
3334

35+
### `-force` (Optional)
36+
37+
Bypasses up-to-date checks for the source, target, and all branches being
38+
removed.
39+
3440
## `-noFetch` (Optional)
3541

3642
By default, all scripts fetch the latest before processing. To skip this (which

git-release.ps1

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Param(
66
[Parameter()][Alias('message')][Alias('m')][string] $comment,
77
[Parameter()][String[]] $preserve = @(),
88
[switch] $cleanupOnly,
9+
[switch] $force,
910
[switch] $noFetch,
1011
[switch] $quiet,
1112
[switch] $dryRun
@@ -28,13 +29,15 @@ $commonParams = @{
2829
# Assert up-to-date
2930
# a) if $cleanupOnly, ensure no commits are in source that are not in target
3031
# b) otherwise, ensure no commits are in target that are not in source
31-
Invoke-LocalAction @commonParams @{
32-
type = 'assert-updated'
33-
parameters = $cleanupOnly `
34-
? @{ downstream = $target; upstream = $source }
35-
: @{ downstream = $source; upstream = $target }
32+
if (-not $force) {
33+
Invoke-LocalAction @commonParams @{
34+
type = 'assert-updated'
35+
parameters = $cleanupOnly `
36+
? @{ downstream = $target; upstream = $source }
37+
: @{ downstream = $source; upstream = $target }
38+
}
39+
Assert-Diagnostics $diagnostics
3640
}
37-
Assert-Diagnostics $diagnostics
3841

3942
# $toRemove = (git show-upstream $source -recurse) without ($target, git show-upstream $target -recurse)
4043
$sourceUpstream = Invoke-LocalAction @commonParams @{
@@ -52,6 +55,18 @@ Assert-Diagnostics $diagnostics
5255
$keep = @($target) + $targetUpstream
5356
[string[]]$toRemove = (@($source) + $sourceUpstream) | Where-Object { $_ -notin $keep -and $_ -notin $preserve }
5457

58+
# Assert all branches removed are up-to-date, unless $force is set
59+
if (-not $force) {
60+
foreach ($branch in $toRemove) {
61+
if ($branch -eq $source) { continue }
62+
Invoke-LocalAction @commonParams @{
63+
type = 'assert-updated'
64+
parameters = @{ downstream = $cleanupOnly ? $target : $source; upstream = $branch }
65+
}
66+
Assert-Diagnostics $diagnostics
67+
}
68+
}
69+
5570
# For all branches:
5671
# 1. Replace $toRemove branches with $target
5772
# 2. Simplify (new)

git-release.tests.ps1

Lines changed: 95 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ Describe 'git-release' {
1111
BeforeEach {
1212
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUserDeclaredVarsMoreThanAssignments', '', Justification='This is put in scope and used in the tests below')]
1313
$fw = Register-Framework
14+
15+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUserDeclaredVarsMoreThanAssignments', '', Justification='This is put in scope and used in the tests below')]
16+
$initialCommits = @{
17+
'rc/2022-07-14' = 'rc/2022-07-14-commitish'
18+
'main' = 'main-commitish'
19+
'feature/FOO-123' = 'feature/FOO-123-commitish'
20+
'feature/XYZ-1-services' = 'feature/XYZ-1-services-commitish'
21+
'feature/FOO-124-comment' = 'feature/FOO-124-comment-commitish'
22+
'feature/FOO-124_FOO-125' = 'feature/FOO-124_FOO-125-commitish'
23+
'feature/FOO-76' = 'feature/FOO-76-commitish'
24+
'integrate/FOO-125_XYZ-1' = 'integrate/FOO-125_XYZ-1-commitish'
25+
}
1426
}
1527

1628
function Add-StandardTests {
@@ -24,11 +36,10 @@ Describe 'git-release' {
2436
'feature/FOO-76' = @('main')
2537
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125","feature/XYZ-1-services")
2638
'main' = @()
27-
}
28-
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits @{
29-
'rc/2022-07-14' = 'result-commitish'
30-
'main' = 'old-main'
31-
}
39+
} -initialCommits $initialCommits
40+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits $initialCommits
41+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/XYZ-1-services' -initialCommits $initialCommits
42+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/FOO-123' -initialCommits $initialCommits
3243
Initialize-LocalActionSimplifyUpstreamBranchesSuccess `
3344
-from @("feature/FOO-124_FOO-125", "main") `
3445
-to @("feature/FOO-124_FOO-125")
@@ -40,7 +51,7 @@ Describe 'git-release' {
4051
} 'Release rc/2022-07-14 to main' 'new-commit'
4152
Initialize-FinalizeActionSetBranches @{
4253
'_upstream' = 'new-commit'
43-
'main' = 'result-commitish'
54+
'main' = $initialCommits['rc/2022-07-14']
4455
'feature/FOO-123' = $null
4556
'feature/XYZ-1-services' = $null
4657
'rc/2022-07-14' = $null
@@ -50,7 +61,7 @@ Describe 'git-release' {
5061
$fw.assertDiagnosticOutput | Should -BeNullOrEmpty
5162
}
5263

53-
It 'can issue a dry run' {
64+
It 'fails if an intermediate branch was not fully released' {
5465
Initialize-AllUpstreamBranches @{
5566
'rc/2022-07-14' = @("feature/FOO-123","feature/XYZ-1-services")
5667
'feature/FOO-123' = @('main')
@@ -60,11 +71,64 @@ Describe 'git-release' {
6071
'feature/FOO-76' = @('main')
6172
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125","feature/XYZ-1-services")
6273
'main' = @()
74+
} -initialCommits $initialCommits
75+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits $initialCommits
76+
Initialize-LocalActionAssertUpdatedFailure 'rc/2022-07-14' 'feature/XYZ-1-services' -initialCommits $initialCommits
77+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/FOO-123' -initialCommits $initialCommits
78+
79+
{ & $PSScriptRoot/git-release.ps1 rc/2022-07-14 main } | Should -Throw
80+
$fw.assertDiagnosticOutput | Should -Be 'ERR: The branch feature/XYZ-1-services has changes that are not in rc/2022-07-14'
81+
}
82+
83+
It 'allows forced removal even if an intermediate branches were not fully released' {
84+
Initialize-AllUpstreamBranches @{
85+
'rc/2022-07-14' = @("feature/FOO-123","feature/XYZ-1-services")
86+
'feature/FOO-123' = @('main')
87+
'feature/XYZ-1-services' = @('main')
88+
'feature/FOO-124-comment' = @('main')
89+
'feature/FOO-124_FOO-125' = @("feature/FOO-124-comment")
90+
'feature/FOO-76' = @('main')
91+
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125","feature/XYZ-1-services")
92+
'main' = @()
93+
} -initialCommits $initialCommits
94+
Initialize-LocalActionAssertUpdatedFailure 'rc/2022-07-14' 'main' -initialCommits $initialCommits
95+
Initialize-LocalActionAssertUpdatedFailure 'rc/2022-07-14' 'feature/XYZ-1-services' -initialCommits $initialCommits
96+
Initialize-LocalActionAssertUpdatedFailure 'rc/2022-07-14' 'feature/FOO-123' -initialCommits $initialCommits
97+
Initialize-LocalActionSimplifyUpstreamBranchesSuccess `
98+
-from @("feature/FOO-124_FOO-125", "main") `
99+
-to @("feature/FOO-124_FOO-125")
100+
Initialize-LocalActionSetUpstream @{
101+
'feature/FOO-123' = $null;
102+
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125");
103+
'rc/2022-07-14' = $null;
104+
'feature/XYZ-1-services' = $null;
105+
} 'Release rc/2022-07-14 to main' 'new-commit'
106+
Initialize-FinalizeActionSetBranches @{
107+
'_upstream' = 'new-commit'
108+
'main' = $initialCommits['rc/2022-07-14']
109+
'feature/FOO-123' = $null
110+
'feature/XYZ-1-services' = $null
111+
'rc/2022-07-14' = $null
63112
}
64-
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits @{
65-
'rc/2022-07-14' = 'result-commitish'
66-
'main' = 'old-main'
67-
}
113+
114+
& $PSScriptRoot/git-release.ps1 rc/2022-07-14 main -force
115+
$fw.assertDiagnosticOutput | Should -BeNullOrEmpty
116+
}
117+
118+
It 'can issue a dry run' {
119+
Initialize-AllUpstreamBranches @{
120+
'rc/2022-07-14' = @("feature/FOO-123","feature/XYZ-1-services")
121+
'feature/FOO-123' = @('main')
122+
'feature/XYZ-1-services' = @('main')
123+
'feature/FOO-124-comment' = @('main')
124+
'feature/FOO-124_FOO-125' = @("feature/FOO-124-comment")
125+
'feature/FOO-76' = @('main')
126+
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125","feature/XYZ-1-services")
127+
'main' = @()
128+
} -initialCommits $initialCommits
129+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits $initialCommits
130+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/XYZ-1-services' -initialCommits $initialCommits
131+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/FOO-123' -initialCommits $initialCommits
68132
Initialize-LocalActionSimplifyUpstreamBranchesSuccess `
69133
-from @("feature/FOO-124_FOO-125", "main") `
70134
-to @("feature/FOO-124_FOO-125")
@@ -93,11 +157,13 @@ Describe 'git-release' {
93157
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125","feature/XYZ-1-services")
94158
'main' = {}
95159
'rc/2022-07-14' = @("feature/FOO-123", "integrate/FOO-125_XYZ-1")
96-
}
97-
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits @{
98-
'rc/2022-07-14' = 'result-commitish'
99-
'main' = 'old-main'
100-
}
160+
} -initialCommits $initialCommits
161+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits $initialCommits
162+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/FOO-124-comment' -initialCommits $initialCommits
163+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/XYZ-1-services' -initialCommits $initialCommits
164+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/FOO-124_FOO-125' -initialCommits $initialCommits
165+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'integrate/FOO-125_XYZ-1' -initialCommits $initialCommits
166+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/FOO-123' -initialCommits $initialCommits
101167
Initialize-LocalActionSetUpstream @{
102168
'feature/FOO-123' = $null
103169
'integrate/FOO-125_XYZ-1' = $null
@@ -108,7 +174,7 @@ Describe 'git-release' {
108174
} -commitMessage 'Release rc/2022-07-14 to main' -commitish 'new-commit'
109175
Initialize-FinalizeActionSetBranches @{
110176
'_upstream' = 'new-commit'
111-
'main' = 'result-commitish'
177+
'main' = $initialCommits['rc/2022-07-14']
112178
'feature/FOO-123' = $null
113179
'integrate/FOO-125_XYZ-1' = $null
114180
'rc/2022-07-14' = $null
@@ -131,11 +197,11 @@ Describe 'git-release' {
131197
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125","feature/XYZ-1-services")
132198
'main' = {}
133199
'rc/2022-07-14' = @("feature/FOO-123", "integrate/FOO-125_XYZ-1")
134-
}
135-
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits @{
136-
'rc/2022-07-14' = 'result-commitish'
137-
'main' = 'old-main'
138-
}
200+
} -initialCommits $initialCommits
201+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'main' -initialCommits $initialCommits
202+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/FOO-124-comment' -initialCommits $initialCommits
203+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/XYZ-1-services' -initialCommits $initialCommits
204+
Initialize-LocalActionAssertUpdatedSuccess 'rc/2022-07-14' 'feature/FOO-123' -initialCommits $initialCommits
139205
Initialize-LocalActionSimplifyUpstreamBranchesSuccess `
140206
-from @("feature/FOO-124_FOO-125", "main") `
141207
-to @("feature/FOO-124_FOO-125")
@@ -152,7 +218,7 @@ Describe 'git-release' {
152218
} -commitMessage 'Release rc/2022-07-14 to main' -commitish 'new-commit'
153219
Initialize-FinalizeActionSetBranches @{
154220
'_upstream' = 'new-commit'
155-
'main' = 'result-commitish'
221+
'main' = $initialCommits['rc/2022-07-14']
156222
'feature/FOO-123' = $null
157223
'rc/2022-07-14' = $null
158224
'feature/FOO-124-comment' = $null
@@ -173,17 +239,14 @@ Describe 'git-release' {
173239
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125","feature/XYZ-1-services")
174240
'main' = {}
175241
'rc/2022-07-14' = @("feature/XYZ-1-services")
176-
}
177-
Initialize-LocalActionAssertUpdatedSuccess 'feature/FOO-123' 'main' -initialCommits @{
178-
'feature/FOO-123' = 'result-commitish'
179-
'main' = 'old-main'
180-
}
242+
} -initialCommits $initialCommits
243+
Initialize-LocalActionAssertUpdatedSuccess 'feature/FOO-123' 'main' -initialCommits $initialCommits
181244
Initialize-LocalActionSetUpstream @{
182245
'feature/FOO-123' = $null
183246
} -commitMessage 'Release feature/FOO-123 to main' -commitish 'new-commit'
184247
Initialize-FinalizeActionSetBranches @{
185248
'_upstream' = 'new-commit'
186-
'main' = 'result-commitish'
249+
'main' = $initialCommits['feature/FOO-123']
187250
'feature/FOO-123' = $null
188251
}
189252

@@ -208,11 +271,9 @@ Describe 'git-release' {
208271
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125","feature/XYZ-1-services")
209272
'main' = {}
210273
'rc/2022-07-14' = @("feature/XYZ-1-services")
211-
}
212-
Initialize-LocalActionAssertUpdatedSuccess 'main' 'rc/2022-07-14' -initialCommits @{
213-
'rc/2022-07-14' = 'released-rc'
214-
'main' = 'result-commitish'
215-
}
274+
} -initialCommits $initialCommits
275+
Initialize-LocalActionAssertUpdatedSuccess 'main' 'rc/2022-07-14' -initialCommits $initialCommits
276+
Initialize-LocalActionAssertUpdatedSuccess 'main' 'feature/XYZ-1-services' -initialCommits $initialCommits
216277
Initialize-LocalActionSetUpstream @{
217278
'integrate/FOO-125_XYZ-1' = @("feature/FOO-124_FOO-125")
218279
'rc/2022-07-14' = $null

utils/actions/local/Register-LocalActionAssertUpdated.mocks.psm1

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ Import-Module -Scope Local "$PSScriptRoot/../../git.mocks.psm1"
55
Import-Module -Scope Local "$PSScriptRoot/../../testing.psm1"
66
Import-Module -Scope Local "$PSScriptRoot/Register-LocalActionAssertUpdated.psm1"
77

8+
function Get-CommitsWithRemote(
9+
[Parameter()][Hashtable] $initialCommits
10+
) {
11+
return $initialCommits.Keys | ConvertTo-HashMap -getKey { Get-RemoteBranchRef $_ } -getValue { $initialCommits[$_] }
12+
}
13+
814
function Initialize-LocalActionAssertUpdatedSuccess(
915
[Parameter()][string] $downstream,
1016
[Parameter()][string] $upstream,
@@ -18,7 +24,7 @@ function Initialize-LocalActionAssertUpdatedSuccess(
1824
-allBranches @($upstream) `
1925
-successfulBranches @() `
2026
-noChangeBranches @($upstream) `
21-
-initialCommits (ConvertTo-HashMap -getKey { Get-RemoteBranchRef $_ } -input $initialCommits) `
27+
-initialCommits (Get-CommitsWithRemote $initialCommits) `
2228
-source $downstream `
2329
-messageTemplate 'Verification Only' `
2430
-resultCommitish $resultCommit
@@ -37,7 +43,7 @@ function Initialize-LocalActionAssertUpdatedFailure(
3743
$base = @{
3844
allBranches = @($upstream)
3945
noChangeBranches = @()
40-
initialCommits = (ConvertTo-HashMap -getKey { Get-RemoteBranchRef $_ } -input $initialCommits)
46+
initialCommits = (Get-CommitsWithRemote $initialCommits)
4147
source = $downstream
4248
messageTemplate = 'Verification Only'
4349
resultCommitish = $resultCommit
@@ -48,7 +54,6 @@ function Initialize-LocalActionAssertUpdatedFailure(
4854
-successfulBranches @()
4955
} else {
5056
Initialize-MergeTogether @base `
51-
-allBranches @($upstream) `
5257
-successfulBranches @($upstream)
5358
}
5459
}

0 commit comments

Comments
 (0)