Introduce recipe for checking out luci-test CL
The luci-test recipe usese RunSteps to checkout the change during CQ
label process. GenTests is a test for the recipe and generates the
expect JSON file.
Next I will try to make it run the tests, and hook it up to the labels
in luci-test repo. After maybe similar experimenting with java/bazel,
I will do a similar recipe for `gerrit` repo and finally remove the
Jenkins labels/integrations and delete the luci-test repo.
Change-Id: I2d6501edac64b303d7b9a782e6c86278aca6b37f
diff --git a/infra/config/recipes.cfg b/infra/config/recipes.cfg
index 1ea176d..433c8d3 100644
--- a/infra/config/recipes.cfg
+++ b/infra/config/recipes.cfg
@@ -5,8 +5,13 @@
"deps": {
"recipe_engine": {
"branch": "refs/heads/main",
- "revision": "6a02d019c4b24e4412cc40003c4397320be41cae",
+ "revision": "a4e5d51c4351ab0674e264a8a360572286b04a6f",
"url": "https://chromium.googlesource.com/infra/luci/recipes-py.git"
+ },
+ "depot_tools": {
+ "branch": "refs/heads/main",
+ "revision": "e1c8efebe0a3cce42ca46d6057b6d4bd909ad203",
+ "url": "https://chromium.googlesource.com/chromium/tools/depot_tools.git"
}
},
"recipes_path": "recipes"
diff --git a/recipes/README.recipes.md b/recipes/README.recipes.md
index 40c7a41..4351976 100644
--- a/recipes/README.recipes.md
+++ b/recipes/README.recipes.md
@@ -4,6 +4,7 @@
**[Recipes](#Recipes)**
* [hello_world](#recipes-hello_world)
+ * [luci-test](#recipes-luci-test) (Python3 ✅)
## Recipes
### *recipes* / [hello\_world](/recipes/recipes/hello_world.py)
@@ -13,5 +14,17 @@
PYTHON_VERSION_COMPATIBILITY: PY2
— **def [RunSteps](/recipes/recipes/hello_world.py#11)(api):**
+### *recipes* / [luci-test](/recipes/recipes/luci-test.py)
-[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/6a02d019c4b24e4412cc40003c4397320be41cae/README.recipes.md#recipe_modules-step
+[DEPS](/recipes/recipes/luci-test.py#3): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/path][recipe_engine/recipe_modules/path]
+
+PYTHON_VERSION_COMPATIBILITY: PY3
+
+— **def [RunSteps](/recipes/recipes/luci-test.py#13)(api):**
+
+[depot_tools/recipe_modules/bot_update]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/e1c8efebe0a3cce42ca46d6057b6d4bd909ad203/recipes/README.recipes.md#recipe_modules-bot_update
+[depot_tools/recipe_modules/gclient]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/e1c8efebe0a3cce42ca46d6057b6d4bd909ad203/recipes/README.recipes.md#recipe_modules-gclient
+[recipe_engine/recipe_modules/buildbucket]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a4e5d51c4351ab0674e264a8a360572286b04a6f/README.recipes.md#recipe_modules-buildbucket
+[recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a4e5d51c4351ab0674e264a8a360572286b04a6f/README.recipes.md#recipe_modules-context
+[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a4e5d51c4351ab0674e264a8a360572286b04a6f/README.recipes.md#recipe_modules-path
+[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a4e5d51c4351ab0674e264a8a360572286b04a6f/README.recipes.md#recipe_modules-step
diff --git a/recipes/recipes/luci-test.expected/basic.json b/recipes/recipes/luci-test.expected/basic.json
new file mode 100644
index 0000000..10ab1c7
--- /dev/null
+++ b/recipes/recipes/luci-test.expected/basic.json
@@ -0,0 +1,150 @@
+[
+ {
+ "cmd": [
+ "vpython3",
+ "RECIPE_REPO[depot_tools]/gerrit_client.py",
+ "changes",
+ "--host",
+ "https://gerrit-review.googlesource.com",
+ "--json_file",
+ "/path/to/tmp/json",
+ "--limit",
+ "1",
+ "-p",
+ "change=123456",
+ "-o",
+ "ALL_REVISIONS",
+ "-o",
+ "DOWNLOAD_COMMANDS"
+ ],
+ "cwd": "[CACHE]/builder",
+ "env": {
+ "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
+ },
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "gerrit:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "gerrit fetch current CL info",
+ "timeout": 60,
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@[@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"branch\": \"main\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"owner\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"name\": \"John Doe\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"184ebe53805e102605d11f6b143486d15c23a09c\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": \"7\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"ref\": \"refs/changes/56/123456/7\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@]@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
+ "--spec-path",
+ "cache_dir = '[CACHE]/git'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': True, 'name': 'src', 'url': 'https://gerrit.googlesource.com/luci-test'}]",
+ "--patch_root",
+ "src",
+ "--revision_mapping_file",
+ "{\"got_revision\": \"src\"}",
+ "--git-cache-dir",
+ "[CACHE]/git",
+ "--cleanup-dir",
+ "[CLEANUP]/bot_update",
+ "--output_json",
+ "/path/to/tmp/json",
+ "--patch_ref",
+ "https://gerrit.googlesource.com/luci-test@refs/heads/main:refs/changes/56/123456/7",
+ "--revision",
+ "src@refs/heads/main",
+ "--refs",
+ "refs/heads/main"
+ ],
+ "cwd": "[CACHE]/builder",
+ "env": {
+ "DEPOT_TOOLS_REPORT_BUILD": "gerrit/try/builder/8945511751514863184",
+ "GIT_HTTP_LOW_SPEED_LIMIT": "102400",
+ "GIT_HTTP_LOW_SPEED_TIME": "1800"
+ },
+ "env_suffixes": {
+ "DEPOT_TOOLS_UPDATE": [
+ "0"
+ ],
+ "PATH": [
+ "RECIPE_REPO[depot_tools]"
+ ]
+ },
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "gerrit:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "bot_update",
+ "~followup_annotations": [
+ "@@@STEP_TEXT@Some step text@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"did_run\": true, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"fixed_revisions\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"src\": \"HEAD\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"manifest\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"src\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"repository\": \"https://fake.org/src.git\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"patch_failure\": false, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"patch_root\": \"src\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"properties\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"got_revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"got_revision_cp\": \"refs/heads/main@{#170242}\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"root\": \"src\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"source_manifest\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"directories\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"src\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"git_checkout\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"repo_url\": \"https://fake.org/src.git\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"version\": 0@@@",
+ "@@@STEP_LOG_LINE@json.output@ }, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"step_text\": \"Some step text\"@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@SET_BUILD_PROPERTY@got_revision@\"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
+ "@@@SET_BUILD_PROPERTY@got_revision_cp@\"refs/heads/main@{#170242}\"@@@"
+ ]
+ },
+ {
+ "name": "$result"
+ }
+]
\ No newline at end of file
diff --git a/recipes/recipes/luci-test.py b/recipes/recipes/luci-test.py
new file mode 100644
index 0000000..73a6c09
--- /dev/null
+++ b/recipes/recipes/luci-test.py
@@ -0,0 +1,57 @@
+PYTHON_VERSION_COMPATIBILITY = "PY3"
+
+DEPS = [
+ 'depot_tools/bot_update',
+ 'depot_tools/gclient',
+ 'recipe_engine/buildbucket',
+ 'recipe_engine/context',
+ 'recipe_engine/path',
+]
+
+# Check out the change and run the tests to verify the change as part of Change
+# Verification (ie. CQ label).
+def RunSteps(api):
+ cl = api.buildbucket.build.input.gerrit_changes[0]
+
+ gs_suffix = '-review.googlesource.com'
+ host = cl.host
+ if host.endswith(gs_suffix):
+ host = '%s.googlesource.com' % host[:-len(gs_suffix)]
+
+ gclient_config = api.gclient.make_config()
+ s = gclient_config.solutions.add()
+ s.url = 'https://%s/%s' % (host, cl.project)
+ # name is the subfolder under api.path['cache'].join('builder') the
+ # repo will be checked out at. For simplicity, I've picked `src`.
+ #
+ # Note that gclient (and by extension, bot_update), allow for complicated
+ # multi-repo layouts and dependency inclusion (via "DEPS" files). There are
+ # other repo management tools and techniques available, but this one is what
+ # chrome currently uses and is tuned to have reasonable performance by default
+ # via caches.
+ s.name = 'src'
+ gclient_config.got_revision_mapping[s.name] = 'got_revision'
+
+ with api.context(cwd=api.path['cache'].join('builder')):
+ update_result = api.bot_update.ensure_checkout(
+ gclient_config=gclient_config)
+
+ # At this point the code for the Gerrit CL is checked out at
+ # `api.path['cache'].join('builder')`, which by default is preserved locally
+ # on the bot machine and re-used between different builds for the same
+ # builder.
+
+ # TODO(frankborden): perform $ npm run test
+
+# Test the recipe and generate the expect json file.
+def GenTests(api):
+ yield api.test(
+ 'basic',
+ # These are just to make the JSON expectation file data look closer to
+ # reality. Project and git_repo will be filled in "for real" by the LUCI
+ # Change Verifier service when it creates your build.
+ api.buildbucket.try_build(
+ project="gerrit",
+ git_repo="https://gerrit.googlesource.com/luci-test",
+ ),
+ )