[cloud functions] Change staging database to support different branch

This change allows the branch of the staging database to be configured
using the environment variable 'BRANCH'.

Change-Id: Ib031fab8134ef799bf1057ffd398cfa9d1220f9e
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/153780
Commit-Queue: Karl Klose <karlklose@google.com>
Reviewed-by: William Hesse <whesse@google.com>
diff --git a/functions/node/commits_cache.dart b/functions/node/commits_cache.dart
index 5f89630..ae5b634 100644
--- a/functions/node/commits_cache.dart
+++ b/functions/node/commits_cache.dart
@@ -9,7 +9,7 @@
 import 'firestore.dart';
 import 'result.dart';
 
-/// Contains data about the commits on the master branch of the sdk repo.
+/// Contains data about the commits on the tracked branch of the SDK repo.
 /// An instance of this class is stored in a top-level variable, and is
 /// shared between cloud function invocations.
 ///
@@ -97,6 +97,13 @@
     return commit;
   }
 
+  Future<String> get branchName async {
+    if (await firestore.isStaging()) {
+      return String.fromEnvironment('BRANCH') ?? 'master';
+    }
+    return 'master';
+  }
+
   Future<Map<String, dynamic>> _fetchByIndex(int index) => firestore
       .getCommitByIndex(index)
       .then((commit) => _fetchByHash(commit['hash']));
@@ -110,9 +117,10 @@
     final lastHash = lastCommit['hash'];
     final lastIndex = lastCommit['index'];
 
+    final branch = await branchName;
     final logUrl = 'https://dart.googlesource.com/sdk/+log/';
-    final range = '$lastHash..master';
-    final parameters = ['format=JSON', 'topo-order', 'n=1000'];
+    final range = '$lastHash..$branch';
+    final parameters = ['format=JSON', 'topo-order', 'first-parent', 'n=1000'];
     final url = '$logUrl$range?${parameters.join('&')}';
     final response = await httpClient.get(url);
     final protectedJson = response.body;
@@ -121,13 +129,13 @@
     final commits = jsonDecode(protectedJson.substring(prefix.length))['log']
         as List<dynamic>;
     if (commits.isEmpty) {
-      print('Found no new commits between $lastHash and master');
+      print('Found no new commits between $lastHash and $branch');
       return;
     }
     print('Fetched new commits from Gerrit (gitiles): $commits');
     final first = commits.last as Map<String, dynamic>;
     if (first['parents'].first != lastHash) {
-      throw 'First new commit ${first['parents'].first} is not'
+      throw 'First new commit ${first['commit']} is not'
           ' a child of last known commit $lastHash when fetching new commits';
     }
     var index = lastIndex + 1;
diff --git a/functions/node/test/fakes.dart b/functions/node/test/fakes.dart
index 79df1dc..ed7e688 100644
--- a/functions/node/test/fakes.dart
+++ b/functions/node/test/fakes.dart
@@ -49,6 +49,8 @@
       List.from(fakeFirestoreTryResults);
   int addedResultIdCounter = 1;
 
+  Future<bool> isStaging() async => false;
+
   Future<Map<String, dynamic>> getCommit(String hash) =>
       Future.value(commits[hash]);
 
diff --git a/results_feed/doc/results_feed.proto b/results_feed/doc/results_feed.proto
index 0dfc0d7..b3953b3 100644
--- a/results_feed/doc/results_feed.proto
+++ b/results_feed/doc/results_feed.proto
@@ -38,7 +38,7 @@
   // The configurations that produced this changed result when tested.
   repeated string configurations = 6;
 
-  // Commits to sdk/master are indexed consecutively in the table 'commits'.
+  // Commits to the SDK branch are indexed consecutively in the table 'commits'.
   int32 blamelist_start_index = 7;
   int32 blamelist_end_index = 8;  // Inclusive: this commit is in the blamelist.
   reserved 9;  // Unused
@@ -130,7 +130,7 @@
   // Stored as the document ID, not a field.
   string id = 1;
 
-  // The position of the commit in the sdk master branch, only considering
+  // The position of the commit in the SDK branch, only considering
   // the first parent of each commit, a linear chain.
   int32 index = 2;
   string author = 3; // The author of the commit, as an email address.