Add support to build and deploy docs to firebase.

Change-Id: I610e01a8ba098b3149e1553e324c0e78586fa690
Bug: https://github.com/flutter/flutter/issues/60646
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/7320
Commit-Queue: Godofredo Contreras <godofredoc@google.com>
Reviewed-by: Keyong Han <keyonghan@google.com>
diff --git a/recipe_modules/adhoc_validation/__init__.py b/recipe_modules/adhoc_validation/__init__.py
index 0377a4c..73e5eed 100644
--- a/recipe_modules/adhoc_validation/__init__.py
+++ b/recipe_modules/adhoc_validation/__init__.py
@@ -1,8 +1,10 @@
 DEPS = [
     'depot_tools/osx_sdk',
+    'flutter/firebase',
     'flutter/flutter_deps',
     'flutter/kms',
     'recipe_engine/context',
+    'recipe_engine/file',
     'recipe_engine/path',
     'recipe_engine/platform',
     'recipe_engine/properties',
diff --git a/recipe_modules/adhoc_validation/api.py b/recipe_modules/adhoc_validation/api.py
index 003c3a0..2abb354 100644
--- a/recipe_modules/adhoc_validation/api.py
+++ b/recipe_modules/adhoc_validation/api.py
@@ -52,10 +52,19 @@
           self.m.flutter_deps.swift()
           checkout_path = self.m.path['start_dir'].join('flutter')
           self.m.flutter_deps.gems(
-            env, env_prefixes, checkout_path.join('dev', 'ci', 'mac')
+              env, env_prefixes, checkout_path.join('dev', 'ci', 'mac')
           )
           with self.m.context(env=env, env_prefixes=env_prefixes):
             self.m.step(validation, [resource_name])
       else:
         with self.m.context(env=env, env_prefixes=env_prefixes):
           self.m.step(validation, [resource_name])
+          if validation == 'docs':
+            docs_path = self.m.path['start_dir'].join('flutter', 'dev', 'docs')
+            project = self.m.properties.get('firebase_project')
+            self.m.firebase.deploy_docs(
+                env=env,
+                env_prefixes=env_prefixes,
+                docs_path=docs_path,
+                project=project
+            )
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/invalid_validation.json b/recipe_modules/adhoc_validation/examples/full.expected/invalid_validation.json
index 8fa766a..07cbd15 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/invalid_validation.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/invalid_validation.json
@@ -8,7 +8,7 @@
       "",
       "Traceback (most recent call last):",
       "  File \"RECIPE_REPO[flutter]/recipe_modules/adhoc_validation/examples/full.py\", line 15, in RunSteps",
-      "    api.adhoc_validation.run('dart analyze', validation, {}, {})",
+      "    api.adhoc_validation.run('Docs', validation, {}, {})",
       "  File \"RECIPE_REPO[flutter]/recipe_modules/adhoc_validation/api.py\", line 37, in run",
       "    raise AssertionError(msg)",
       "AssertionError: invalid is not listed in available_validations."
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/linux.json b/recipe_modules/adhoc_validation/examples/full.expected/linux.json
index 7c743a8..c58739d 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/linux.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/linux.json
@@ -1,29 +1,98 @@
 [
   {
     "cmd": [],
-    "name": "dart analyze"
+    "name": "Docs"
   },
   {
     "cmd": [
       "chmod",
       "755",
-      "RECIPE_MODULE[flutter::adhoc_validation]/resources/analyze.sh"
+      "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
     ],
-    "name": "dart analyze.Set execute permission",
+    "name": "Docs.Set execute permission",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
   },
   {
     "cmd": [
-      "RECIPE_MODULE[flutter::adhoc_validation]/resources/analyze.sh"
+      "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
     ],
-    "name": "dart analyze.analyze",
+    "name": "Docs.docs",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
   },
   {
+    "cmd": [
+      "luci-auth",
+      "token",
+      "-scopes",
+      "https://www.googleapis.com/auth/cloud-platform",
+      "-lifetime",
+      "3m"
+    ],
+    "infra_step": true,
+    "name": "Docs.get access token for default account",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "vpython",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "copy",
+      "extra.secret.token.should.not.be.logged",
+      "[CLEANUP]/tmp_tmp_1"
+    ],
+    "infra_step": true,
+    "name": "Docs.write token",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Docs.Deploy docs",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "chmod",
+      "755",
+      "RECIPE_MODULE[flutter::firebase]/resources/firebase_deploy.sh"
+    ],
+    "cwd": "[START_DIR]/flutter/dev/docs",
+    "env": {
+      "GCP_PROJECT": null,
+      "TOKEN_PATH": "[CLEANUP]/tmp_tmp_1"
+    },
+    "name": "Docs.Deploy docs.Set execute permission",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "RECIPE_MODULE[flutter::firebase]/resources/firebase_deploy.sh"
+    ],
+    "cwd": "[START_DIR]/flutter/dev/docs",
+    "env": {
+      "GCP_PROJECT": null,
+      "TOKEN_PATH": "[CLEANUP]/tmp_tmp_1"
+    },
+    "name": "Docs.Deploy docs.Firebase deploy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/mac.json b/recipe_modules/adhoc_validation/examples/full.expected/mac.json
index ca5dff4..b5f15b8 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/mac.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/mac.json
@@ -1,15 +1,15 @@
 [
   {
     "cmd": [],
-    "name": "dart analyze"
+    "name": "Docs"
   },
   {
     "cmd": [
       "chmod",
       "755",
-      "RECIPE_MODULE[flutter::adhoc_validation]/resources/analyze.sh"
+      "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
     ],
-    "name": "dart analyze.Set execute permission",
+    "name": "Docs.Set execute permission",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -28,7 +28,7 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "dart analyze.ensure_installed",
+    "name": "Docs.ensure_installed",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
@@ -56,7 +56,7 @@
       "[CACHE]/osx_sdk/XCode.app"
     ],
     "infra_step": true,
-    "name": "dart analyze.install xcode",
+    "name": "Docs.install xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -69,14 +69,14 @@
       "[CACHE]/osx_sdk/XCode.app"
     ],
     "infra_step": true,
-    "name": "dart analyze.select XCode",
+    "name": "Docs.select XCode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
   },
   {
     "cmd": [],
-    "name": "dart analyze.Swift deps",
+    "name": "Docs.Swift deps",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -94,7 +94,7 @@
       "-json-output",
       "/path/to/tmp/json"
     ],
-    "name": "dart analyze.Swift deps.ensure_installed",
+    "name": "Docs.Swift deps.ensure_installed",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
@@ -122,7 +122,7 @@
       "[CACHE]/osx_sdk/XCode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift"
     ],
     "infra_step": true,
-    "name": "dart analyze.Swift deps.Copy swift",
+    "name": "Docs.Swift deps.Copy swift",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@2@@@"
     ]
@@ -139,7 +139,7 @@
       "[CACHE]/osx_sdk/XCode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0"
     ],
     "infra_step": true,
-    "name": "dart analyze.Swift deps.Copy swift-5.0",
+    "name": "Docs.Swift deps.Copy swift-5.0",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@2@@@"
     ]
@@ -155,7 +155,7 @@
       "[CACHE]/osx_sdk/XCode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib"
     ],
     "infra_step": true,
-    "name": "dart analyze.Swift deps.List directory",
+    "name": "Docs.Swift deps.List directory",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_END@listdir@@@"
@@ -163,9 +163,9 @@
   },
   {
     "cmd": [
-      "RECIPE_MODULE[flutter::adhoc_validation]/resources/analyze.sh"
+      "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
     ],
-    "name": "dart analyze.analyze",
+    "name": "Docs.docs",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -177,7 +177,7 @@
       "--reset"
     ],
     "infra_step": true,
-    "name": "dart analyze.reset XCode",
+    "name": "Docs.reset XCode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/mac_nodeps.json b/recipe_modules/adhoc_validation/examples/full.expected/mac_nodeps.json
index 7c743a8..c58739d 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/mac_nodeps.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/mac_nodeps.json
@@ -1,29 +1,98 @@
 [
   {
     "cmd": [],
-    "name": "dart analyze"
+    "name": "Docs"
   },
   {
     "cmd": [
       "chmod",
       "755",
-      "RECIPE_MODULE[flutter::adhoc_validation]/resources/analyze.sh"
+      "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
     ],
-    "name": "dart analyze.Set execute permission",
+    "name": "Docs.Set execute permission",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
   },
   {
     "cmd": [
-      "RECIPE_MODULE[flutter::adhoc_validation]/resources/analyze.sh"
+      "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
     ],
-    "name": "dart analyze.analyze",
+    "name": "Docs.docs",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
   },
   {
+    "cmd": [
+      "luci-auth",
+      "token",
+      "-scopes",
+      "https://www.googleapis.com/auth/cloud-platform",
+      "-lifetime",
+      "3m"
+    ],
+    "infra_step": true,
+    "name": "Docs.get access token for default account",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "vpython",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "copy",
+      "extra.secret.token.should.not.be.logged",
+      "[CLEANUP]/tmp_tmp_1"
+    ],
+    "infra_step": true,
+    "name": "Docs.write token",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Docs.Deploy docs",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "chmod",
+      "755",
+      "RECIPE_MODULE[flutter::firebase]/resources/firebase_deploy.sh"
+    ],
+    "cwd": "[START_DIR]/flutter/dev/docs",
+    "env": {
+      "GCP_PROJECT": null,
+      "TOKEN_PATH": "[CLEANUP]/tmp_tmp_1"
+    },
+    "name": "Docs.Deploy docs.Set execute permission",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "RECIPE_MODULE[flutter::firebase]/resources/firebase_deploy.sh"
+    ],
+    "cwd": "[START_DIR]/flutter/dev/docs",
+    "env": {
+      "GCP_PROJECT": null,
+      "TOKEN_PATH": "[CLEANUP]/tmp_tmp_1"
+    },
+    "name": "Docs.Deploy docs.Firebase deploy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/win.json b/recipe_modules/adhoc_validation/examples/full.expected/win.json
index a393a32..707642a 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/win.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/win.json
@@ -1,18 +1,87 @@
 [
   {
     "cmd": [],
-    "name": "dart analyze"
+    "name": "Docs"
   },
   {
     "cmd": [
-      "RECIPE_MODULE[flutter::adhoc_validation]\\resources\\analyze.bat"
+      "RECIPE_MODULE[flutter::adhoc_validation]\\resources\\docs.bat"
     ],
-    "name": "dart analyze.analyze",
+    "name": "Docs.docs",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
   },
   {
+    "cmd": [
+      "luci-auth",
+      "token",
+      "-scopes",
+      "https://www.googleapis.com/auth/cloud-platform",
+      "-lifetime",
+      "3m"
+    ],
+    "infra_step": true,
+    "name": "Docs.get access token for default account",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "vpython",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "copy",
+      "extra.secret.token.should.not.be.logged",
+      "[CLEANUP]\\tmp_tmp_1"
+    ],
+    "infra_step": true,
+    "name": "Docs.write token",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Docs.Deploy docs",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "chmod",
+      "755",
+      "RECIPE_MODULE[flutter::firebase]\\resources\\firebase_deploy.sh"
+    ],
+    "cwd": "[START_DIR]\\flutter\\dev\\docs",
+    "env": {
+      "GCP_PROJECT": null,
+      "TOKEN_PATH": "[CLEANUP]\\tmp_tmp_1"
+    },
+    "name": "Docs.Deploy docs.Set execute permission",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "RECIPE_MODULE[flutter::firebase]\\resources\\firebase_deploy.sh"
+    ],
+    "cwd": "[START_DIR]\\flutter\\dev\\docs",
+    "env": {
+      "GCP_PROJECT": null,
+      "TOKEN_PATH": "[CLEANUP]\\tmp_tmp_1"
+    },
+    "name": "Docs.Deploy docs.Firebase deploy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/adhoc_validation/examples/full.py b/recipe_modules/adhoc_validation/examples/full.py
index fa77392..a91307e 100644
--- a/recipe_modules/adhoc_validation/examples/full.py
+++ b/recipe_modules/adhoc_validation/examples/full.py
@@ -11,8 +11,8 @@
 
 
 def RunSteps(api):
-  validation = api.properties.get('validation', 'analyze')
-  api.adhoc_validation.run('dart analyze', validation, {}, {})
+  validation = api.properties.get('validation', 'docs')
+  api.adhoc_validation.run('Docs', validation, {}, {})
 
 
 def GenTests(api):
diff --git a/recipe_modules/adhoc_validation/resources/docs.sh b/recipe_modules/adhoc_validation/resources/docs.sh
index 9ac6937..095ec72 100644
--- a/recipe_modules/adhoc_validation/resources/docs.sh
+++ b/recipe_modules/adhoc_validation/resources/docs.sh
@@ -3,9 +3,9 @@
 # Copyright 2020 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+#
+# Script to generate and upload flutter docs.
 
 set -e
 
-export FIREBASE_MASTER_TOKEN=`cat $FIREBASE_MASTER_TOKEN`
-export FIREBASE_PUBLIC_TOKEN=`cat $FIREBASE_PUBLIC_TOKEN`
 ./dev/bots/docs.sh