Skip to content

Commit 9e70384

Browse files
authored
Allow a release without engine cherrypicks (adds fallback logic) (flutter#172184)
Closes flutter#172179.
1 parent 81e1d5e commit 9e70384

File tree

3 files changed

+128
-6
lines changed

3 files changed

+128
-6
lines changed

bin/internal/last_engine_commit.ps1

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,48 @@ $ErrorActionPreference = "Stop"
2424

2525
$progName = Split-Path -parent $MyInvocation.MyCommand.Definition
2626
$flutterRoot = (Get-Item $progName).parent.parent.FullName
27+
$gitToplevel = (git rev-parse --show-toplevel).Trim()
28+
# 1. Determine when we diverged from master.
29+
$MERGE_BASE_COMMIT = ""
30+
try {
31+
$MERGE_BASE_COMMIT = (git merge-base HEAD master).Trim()
32+
}
33+
catch {
34+
# If git merge-base fails (e.g., master not found, no common history),
35+
# $MERGE_BASE_COMMIT will remain empty.
36+
}
2737

28-
cmd /c "git log -1 --pretty=format:%H -- ""$(git rev-parse --show-toplevel)/DEPS"" ""$(git rev-parse --show-toplevel)/engine"""
38+
# If we did not find a merge-base, fail
39+
if ([string]::IsNullOrEmpty($MERGE_BASE_COMMIT)) {
40+
Write-Error "Error: Could not determine a suitable engine commit." -ErrorAction Stop
41+
Write-Error "Current branch: $(git rev-parse --abbrev-ref HEAD).Trim()" -ErrorAction Stop
42+
Write-Error "Expected a different branch, from 'master', or a 'master' branch that exists and has history." -ErrorAction Stop
43+
exit 1
44+
}
45+
46+
# 2. Define and search history range to search within (unique to changes on this branch).
47+
$HISTORY_RANGE = "$MERGE_BASE_COMMIT..HEAD"
48+
$DEPS_PATH = Join-Path $gitToplevel "DEPS"
49+
$ENGINE_PATH = Join-Path $gitToplevel "engine"
50+
51+
$ENGINE_COMMIT = (git log -1 --pretty=format:%H --ancestry-path $HISTORY_RANGE -- "$DEPS_PATH" "$ENGINE_PATH")
52+
53+
# 3. If no engine-related commit was found within the current branch's history, fallback to the first commit on this branch.
54+
if ([string]::IsNullOrEmpty($ENGINE_COMMIT)) {
55+
# Find the oldest commit on HEAD that is *not* reachable from MERGE_BASE_COMMIT.
56+
# This is the first commit *on this branch* after it diverged from 'master'.
57+
$ENGINE_COMMIT = (git log --pretty=format:%H --reverse --ancestry-path "$MERGE_BASE_COMMIT..HEAD" | Select-Object -First 1).Trim()
58+
59+
# Final check: If even this fallback fails (which would be highly unusual if MERGE_BASE_COMMIT was found),
60+
# then something is truly wrong.
61+
if ([string]::IsNullOrEmpty($ENGINE_COMMIT)) {
62+
Write-Error "Error: Unexpected state. MERGE_BASE_COMMIT was found ($MERGE_BASE_COMMIT), but no commits found on current branch after it." -ErrorAction Stop
63+
Write-Error "Current branch: $((git rev-parse --abbrev-ref HEAD).Trim())" -ErrorAction Stop
64+
Write-Error "History range searched for fallback: $HISTORY_RANGE" -ErrorAction Stop
65+
Write-Error "All commits on current branch (for debug):" -ErrorAction Stop
66+
(git log --pretty=format:%H) | Write-Error -ErrorAction Stop
67+
exit 1
68+
}
69+
}
70+
71+
Write-Output $ENGINE_COMMIT

bin/internal/last_engine_commit.sh

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,37 @@ set -e
2626

2727
FLUTTER_ROOT="$(dirname "$(dirname "$(dirname "${BASH_SOURCE[0]}")")")"
2828

29-
git log -1 --pretty=format:%H -- "$(git rev-parse --show-toplevel)/DEPS" "$(git rev-parse --show-toplevel)/engine"
29+
# 1. Determine when we diverged from master, and prevent set -e from exiting.
30+
MERGE_BASE_COMMIT="$(git merge-base HEAD master || echo "")"
31+
32+
# If we did not find a merge-base, fail
33+
if [[ -z "$MERGE_BASE_COMMIT" ]]; then
34+
echo >&2 "Error: Could not determine a suitable engine commit."
35+
echo >&2 "Current branch: $(git rev-parse --abbrev-ref HEAD)"
36+
echo >&2 "Expected a different branch, from master"
37+
exit 1
38+
fi
39+
40+
# 2. Define and search history range to searhc within (unique to changes on this branch).
41+
HISTORY_RANGE="$MERGE_BASE_COMMIT..HEAD"
42+
ENGINE_COMMIT="$(git log -1 --pretty=format:%H --ancestry-path "$HISTORY_RANGE" -- "$(git rev-parse --show-toplevel)/DEPS" "$(git rev-parse --show-toplevel)/engine")"
43+
44+
# 3. If no engine-related commit was found within the current branch's history, fallback to the first commit on this branch.
45+
if [[ -z "$ENGINE_COMMIT" ]]; then
46+
# Find the oldest commit on HEAD that is *not* reachable from MERGE_BASE_COMMIT.
47+
# This is the first commit *on this branch* after it diverged from 'master'.
48+
ENGINE_COMMIT="$(git log --pretty=format:%H --reverse --ancestry-path "$MERGE_BASE_COMMIT"..HEAD | head -n 1)"
49+
50+
# Final check: If even this fallback fails (which would be highly unusual if MERGE_BASE_COMMIT was found),
51+
# then something is truly wrong.
52+
if [[ -z "$ENGINE_COMMIT" ]]; then
53+
echo >&2 "Error: Unexpected state. MERGE_BASE_COMMIT was found ($MERGE_BASE_COMMIT), but no commits found on current branch after it."
54+
echo >&2 "Current branch: $(git rev-parse --abbrev-ref HEAD)"
55+
echo >&2 "History range searched for fallback: $HISTORY_RANGE"
56+
echo >&2 "All commits on current branch (for debug):"
57+
git log --pretty=format:%H
58+
exit 1
59+
fi
60+
fi
61+
62+
echo "$ENGINE_COMMIT"

dev/tools/test/last_engine_commit_test.dart

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ void main() {
5353
}
5454

5555
io.ProcessResult run(String executable, List<String> args) {
56-
print('Running "$executable ${args.join(" ")}');
5756
final io.ProcessResult result = io.Process.runSync(
5857
executable,
5958
args,
@@ -76,7 +75,9 @@ void main() {
7675
setUpAll(() async {
7776
if (usePowershellOnPosix) {
7877
final io.ProcessResult result = io.Process.runSync('pwsh', <String>['--version']);
79-
print('Using Powershell (${result.stdout}) on POSIX for local debugging and testing');
78+
print(
79+
'Using Powershell (${(result.stdout as String).trim()}) on POSIX for local debugging and testing',
80+
);
8081
}
8182
});
8283

@@ -104,7 +105,7 @@ void main() {
104105

105106
if (const LocalPlatform().isWindows || usePowershellOnPosix) {
106107
// Copy a minimal set of environment variables needed to run the update_engine_version script in PowerShell.
107-
const List<String> powerShellVariables = <String>['SystemRoot', 'Path', 'PATHEXT'];
108+
const List<String> powerShellVariables = <String>['SYSTEMROOT', 'PATH', 'PATHEXT'];
108109
for (final String key in powerShellVariables) {
109110
final String? value = io.Platform.environment[key];
110111
if (value != null) {
@@ -143,7 +144,12 @@ void main() {
143144
executable = testRoot.binInternalLastEngineCommit.path;
144145
args = <String>[];
145146
}
146-
return run(executable, args).stdout as String;
147+
return (run(executable, args).stdout as String).trim();
148+
}
149+
150+
/// Gets the latest commit on the current branch.
151+
String getLastCommit() {
152+
return (run('git', <String>['rev-parse', 'HEAD']).stdout as String).trim();
147153
}
148154

149155
void writeCommit(Iterable<String> files) {
@@ -157,7 +163,12 @@ void main() {
157163
run('git', <String>['commit', '-m', 'Wrote ${files.length} files']);
158164
}
159165

166+
void changeBranch({required String newBranchName}) {
167+
run('git', <String>['checkout', '-b', newBranchName]);
168+
}
169+
160170
test('returns the last engine commit', () {
171+
changeBranch(newBranchName: 'flutter-1.2.3-candidate.0');
161172
writeCommit(<String>['DEPS', 'engine/README.md']);
162173

163174
final String lastEngine = getLastEngineCommit();
@@ -168,6 +179,7 @@ void main() {
168179
});
169180

170181
test('considers DEPS an engine change', () {
182+
changeBranch(newBranchName: 'flutter-1.2.3-candidate.0');
171183
writeCommit(<String>['DEPS', 'engine/README.md']);
172184

173185
final String lastEngineA = getLastEngineCommit();
@@ -177,6 +189,40 @@ void main() {
177189
final String lastEngineB = getLastEngineCommit();
178190
expect(lastEngineB, allOf(isNotEmpty, isNot(equals(lastEngineA))));
179191
});
192+
193+
test('if there have been no engine changes, uses the first commit since the branch point', () {
194+
final String initialStartingCommit = getLastCommit();
195+
196+
// Make an engine change *before* the branch.
197+
writeCommit(<String>['engine/README.md']);
198+
final String engineCommitPreBranch = getLastCommit();
199+
changeBranch(newBranchName: 'flutter-1.2.3-candidate.0');
200+
201+
// Make a non-engine change, but no engine changes, after branching.
202+
writeCommit(<String>['bin/internal/release-candidate-branch.version']);
203+
final String initialBranchCommit = getLastCommit();
204+
205+
// Write another commit to make sure we don't always use the latest.
206+
writeCommit(<String>['CHANGELOG.md']);
207+
final String latestCommitIgnore = getLastCommit();
208+
209+
// Get the engine commit, which should fallback to HEAD~2 (in this case).
210+
final String lastCommitToEngine = getLastEngineCommit();
211+
expect(
212+
lastCommitToEngine,
213+
initialBranchCommit,
214+
reason:
215+
'The git history for this simulation looks like this:\n'
216+
'master (intial commit) | $initialStartingCommit\n'
217+
'master (touches engine) | $engineCommitPreBranch\n'
218+
'flutter-1.2.3-candidate.0 | $initialBranchCommit\n'
219+
'flutter-1.2.3-candidate.0 | $latestCommitIgnore\n'
220+
'\n'
221+
'We expected our script to select HEAD~2, $initialBranchCommit, but '
222+
'instead it selected $lastCommitToEngine, which is incorrect. See '
223+
'the table above to help debug.',
224+
);
225+
});
180226
}
181227

182228
extension on File {

0 commit comments

Comments
 (0)