Skip to content

Commit e2d591c

Browse files
authored
fix: get content hash for master on local engine branches (flutter#172792)
The content hash doesn't exist for local engine changes, except for on CI. If we detect we're on a branch with committed or uncommitted changes to engine files; use "master". towards flutter#171790
1 parent 35ebc20 commit e2d591c

File tree

4 files changed

+111
-9
lines changed

4 files changed

+111
-9
lines changed

.github/workflows/content-aware-hash.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,12 @@ jobs:
1313
- name: Checkout code
1414
uses: actions/checkout@v4
1515

16-
- name: Fetch base commit and origin/master
17-
run: |
18-
git fetch --no-tags --prune --depth=1 origin ${{ github.event.pull_request.base.sha }}
19-
2016
- name: Generate Hash
2117
run: |
22-
engine_content_hash=$(bin/internal/content_aware_hash.sh)
18+
# IMPORTANT: Keep the list of files in sync with bin/internal/content_aware_hash.sh
19+
# We call this directly here as we're expected to be in the merge queue (not master)
20+
engine_content_hash=$(git ls-tree --format "%(objectname) %(path)" HEAD -- DEPS engine bin/internal/release-candidate-branch.version | git hash-object --stdin)
2321
# test notice annotation for retrival from api
2422
echo "::notice ::{\"engine_content_hash\": \"${engine_content_hash}\"}"
2523
# test summary writing
26-
echo "{\"engine_content_hash\": \"${engine_content_hash}\"" >> $GITHUB_STEP_SUMMARY
24+
echo "{\"engine_content_hash\": \"${engine_content_hash}\"" >> $GITHUB_STEP_SUMMARY

bin/internal/content_aware_hash.ps1

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,28 @@ $flutterRoot = (Get-Item $progName).parent.parent.FullName
3636
# 3. Out-File -NoNewline -Encoding ascii outputs 8bit ascii
3737
# 4. git hash-object with stdin from a pipeline consumes UTF-16, so consume
3838
#. the contents of hash.txt
39-
(git -C "$flutterRoot" ls-tree --format "%(objectname) %(path)" HEAD DEPS engine bin/internal/release-candidate-branch.version | Out-String) -replace "`r`n", "`n" | Out-File -NoNewline -Encoding ascii hash.txt
39+
$trackedFiles = "DEPS", "engine", "bin/internal/release-candidate-branch.version"
40+
$baseRef = "HEAD"
41+
42+
$ErrorActionPreference = "Continue"
43+
# We will fallback to origin/master if upstream is not detected.
44+
git -C "$flutterRoot" remote get-url upstream *> $null
45+
$exitCode = $?
46+
$ErrorActionPreference = "Stop"
47+
if ($exitCode) {
48+
$mergeBase = (git -C "$flutterRoot" merge-base HEAD upstream/master)
49+
} else {
50+
$mergeBase = (git -C "$flutterRoot" merge-base HEAD origin/master)
51+
}
52+
53+
# Check to see if we're in a local development branch and the branch has any
54+
# changes to engine code - including non-committed changes.
55+
if ((git -C "$flutterRoot" rev-parse --abbrev-ref HEAD) -ne "master") {
56+
git -C "$flutterRoot" diff --quiet "$(git -C "$flutterRoot" merge-base $mergeBase HEAD)" -- $trackedFiles | Out-Null
57+
if ($LASTEXITCODE -ne 0) {
58+
$baseRef = "$mergeBase"
59+
}
60+
}
61+
(git -C "$flutterRoot" ls-tree --format "%(objectname) %(path)" $baseRef -- $trackedFiles | Out-String) -replace "`r`n", "`n" | Out-File -NoNewline -Encoding ascii hash.txt
4062
git hash-object hash.txt
4163
Remove-Item hash.txt

bin/internal/content_aware_hash.sh

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,24 @@ unset GIT_WORK_TREE
2525
# bin/internal/content_aware_hash.ps1: script for calculating the hash on windows
2626
# bin/internal/content_aware_hash.sh: script for calculating the hash on mac/linux
2727
# .github/workflows/content-aware-hash.yml: github action for CI/CD hashing
28-
git -C "$FLUTTER_ROOT" ls-tree --format "%(objectname) %(path)" HEAD DEPS engine bin/internal/release-candidate-branch.version | git hash-object --stdin
28+
TRACKEDFILES="DEPS engine bin/internal/release-candidate-branch.version"
29+
BASEREF="HEAD"
30+
31+
set +e
32+
# We will fallback to origin/master if upstream is not detected.
33+
git -C "$FLUTTER_ROOT" remote get-url upstream >/dev/null 2>&1
34+
exit_code=$?
35+
set -e
36+
if [[ $exit_code -eq 0 ]]; then
37+
MERGEBASE=$(git -C "$FLUTTER_ROOT" merge-base HEAD upstream/master)
38+
else
39+
MERGEBASE=$(git -C "$FLUTTER_ROOT" merge-base HEAD origin/master)
40+
fi
41+
42+
# Check to see if we're in a local development branch and the branch has any
43+
# changes to engine code - including non-committed changes.
44+
if [ "$(git -C "$FLUTTER_ROOT" rev-parse --abbrev-ref HEAD)" != "master" ] && \
45+
! git -C "$FLUTTER_ROOT" diff --quiet "$MERGEBASE" -- $TRACKEDFILES; then
46+
BASEREF="$MERGEBASE"
47+
fi
48+
git -C "$FLUTTER_ROOT" ls-tree --format "%(objectname) %(path)" $BASEREF -- $TRACKEDFILES | git hash-object --stdin

dev/tools/test/content_aware_hash_test.dart

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,21 @@ void main() {
114114
return run(executable, args);
115115
}
116116

117+
/// Sets up and fetches a [remote] (such as `upstream` or `origin`) for [testRoot.root].
118+
///
119+
/// The remote points at itself (`testRoot.root.path`) for ease of testing.
120+
void setupRemote({required String remote, String? rootPath}) {
121+
run('git', <String>[
122+
'remote',
123+
'add',
124+
remote,
125+
rootPath ?? testRoot.root.path,
126+
], workingPath: rootPath);
127+
run('git', <String>['fetch', remote], workingPath: rootPath);
128+
}
129+
117130
/// Initializes a blank git repo in [testRoot.root].
118-
void initGitRepoWithBlankInitialCommit({String? workingPath}) {
131+
void initGitRepoWithBlankInitialCommit({String? workingPath, String remote = 'upstream'}) {
119132
run('git', <String>['init', '--initial-branch', 'master'], workingPath: workingPath);
120133
// autocrlf is very important for tests to work on windows.
121134
run('git', 'config --local core.autocrlf true'.split(' '), workingPath: workingPath);
@@ -133,6 +146,8 @@ void main() {
133146
'-m',
134147
'Initial commit',
135148
], workingPath: workingPath);
149+
150+
setupRemote(remote: remote, rootPath: workingPath);
136151
}
137152

138153
void writeFileAndCommit(File file, String contents) {
@@ -141,11 +156,58 @@ void main() {
141156
run('git', <String>['commit', '--all', '-m', 'changed ${file.basename} to $contents']);
142157
}
143158

159+
void gitSwitchBranch(String branch, {bool create = true}) {
160+
run('git', <String>['switch', if (create) '-c', branch]);
161+
}
162+
144163
test('generates a hash', () async {
145164
initGitRepoWithBlankInitialCommit();
146165
expect(runContentAwareHash(), processStdout('3bbeb6a394378478683ece4f8e8663c42f8dc814'));
147166
});
148167

168+
test('generates a hash for origin', () {
169+
initGitRepoWithBlankInitialCommit(remote: 'origin');
170+
expect(runContentAwareHash(), processStdout('3bbeb6a394378478683ece4f8e8663c42f8dc814'));
171+
});
172+
173+
group('ignores local engine for', () {
174+
test('upstream', () {
175+
initGitRepoWithBlankInitialCommit();
176+
gitSwitchBranch('engineTest');
177+
testRoot.deps.writeAsStringSync('deps changed');
178+
expect(
179+
runContentAwareHash(),
180+
processStdout('3bbeb6a394378478683ece4f8e8663c42f8dc814'),
181+
reason: 'content hash from master for non-committed file',
182+
);
183+
184+
writeFileAndCommit(testRoot.deps, 'deps changed');
185+
expect(
186+
runContentAwareHash(),
187+
processStdout('3bbeb6a394378478683ece4f8e8663c42f8dc814'),
188+
reason: 'content hash from master for committed file',
189+
);
190+
});
191+
192+
test('origin', () {
193+
initGitRepoWithBlankInitialCommit(remote: 'origin');
194+
gitSwitchBranch('engineTest');
195+
testRoot.deps.writeAsStringSync('deps changed');
196+
expect(
197+
runContentAwareHash(),
198+
processStdout('3bbeb6a394378478683ece4f8e8663c42f8dc814'),
199+
reason: 'content hash from master for non-committed file',
200+
);
201+
202+
writeFileAndCommit(testRoot.deps, 'deps changed');
203+
expect(
204+
runContentAwareHash(),
205+
processStdout('3bbeb6a394378478683ece4f8e8663c42f8dc814'),
206+
reason: 'content hash from master for committed file',
207+
);
208+
});
209+
});
210+
149211
group('generates a different hash when', () {
150212
setUp(() {
151213
initGitRepoWithBlankInitialCommit();

0 commit comments

Comments
 (0)