Name Date Size #Lines LOC

..--

analysis/H25-Apr-2025-11141

assets/H25-Apr-2025-3,7692,209

buildstats/H25-Apr-2025-457301

deps/H25-Apr-2025-307279

gen_tasks_logic/H25-Apr-2025-5,9404,540

recipe_modules/H25-Apr-2025-37,00735,381

recipes/H25-Apr-2025-17,64917,068

task_drivers/H25-Apr-2025-9,9257,985

tools/luci-go/H25-Apr-2025-1710

BUILD.bazelH A D25-Apr-20253.1 KiB5754

MakefileH A D25-Apr-202558 64

README.mdH A D25-Apr-20253 KiB9764

README.recipes.mdH A D25-Apr-202539 KiB547317

build_task_drivers.shH A D25-Apr-20251.4 KiB339

bundle_recipes.shH A D25-Apr-2025320 168

cfg.jsonH A D25-Apr-20251.1 KiB2726

check_deps.pyH A D25-Apr-20251.9 KiB7248

find_tasks.pyH A D25-Apr-20251.5 KiB6536

gen_tasks.goH A D25-Apr-2025359 197

git_utils.pyH A D25-Apr-20255.8 KiB164132

infra_tests.pyH A D25-Apr-20252 KiB9466

jobs.jsonH A D25-Apr-202556.1 KiB864863

recipes.pyH A D25-Apr-20258.9 KiB273177

run_recipe.pyH A D25-Apr-20251.2 KiB4129

tasks.jsonH A D25-Apr-20253.9 MiB87,27687,275

test_utils.pyH A D25-Apr-20252 KiB7450

utils.pyH A D25-Apr-20256.6 KiB204145

zip_utils.pyH A D25-Apr-20252.5 KiB7960

zip_utils_test.pyH A D25-Apr-20251.9 KiB7545

README.md

1Skia Infrastructure
2===================
3
4This directory contains infrastructure elements.
5
6
7Tasks and Jobs
8--------------
9
10Files in this directory define a DAG of tasks which run at every Skia commit. A
11task is a small, self-contained unit which runs via Swarming on a machine in the
12pool. Tasks may be chained together, eg. one task to compile test binaries and
13another to actually run them.
14
15Jobs are collections of related tasks which help define sub-sections of the DAG,
16for example, to be used as try jobs. Each job is defined as an entry point into
17the DAG.
18
19The tasks.json file in this directory is the list of tasks and jobs for
20the repo. Note that tasks.json is NEVER edited by hand but generated via
21gen_task.go and the input files enumerated below. The
22[Task Scheduler](https://skia.googlesource.com/buildbot/+/main/task_scheduler/README.md)
23reads the tasks.json file at each commit to determine which jobs to run. For
24convenience, gen_tasks.go is provided to generate tasks.json and also to test it
25for correct syntax and detecting cycles and orphaned tasks. Always edit
26gen_tasks.go or one of the following input JSON files, rather than tasks.json
27itself:
28
29  * cfg.json - Basic configuration information for gen_tasks.go.
30  * jobs.json - The list of all jobs to run. Edit this to add or remove
31      bots.
32
33Whenever gen_tasks.go, any of the above JSON files, or assets are changed, you
34need to run gen_tasks.go to regenerate tasks.json:
35
36	$ go run infra/bots/gen_tasks.go
37
38Or:
39
40	$ make -C infra/bots train
41
42There is also a test mode which performs consistency checks and verifies that
43tasks.json is unchanged:
44
45	$ go run infra/bots/gen_tasks.go --test
46
47Or:
48
49	$ make -C infra/bots test
50
51
52Recipes
53-------
54
55Recipes are the framework used by Skia's infrastructure to perform work inside
56of Swarming tasks. The main elements are:
57
58  * recipes.py - Used for running and testing recipes.
59  * recipes - These are the entry points for each type of task, eg. compiling
60      or running tests.
61  * recipe_modules - Shared modules which are used by recipes.
62  * .recipe_deps - Recipes and modules may depend on modules from other repos.
63      The recipes.py script automatically syncs those dependencies in this
64      directory.
65
66
67Isolate Files
68-------------
69
70These files determine which parts of the repository are transferred to the bot
71when a Swarming task is triggered. The
72[Isolate tool](https://github.com/luci/luci-py/tree/main/appengine/isolate/doc)
73hashes each file and will upload any new/changed files. Bots maintain a cache so
74that they can efficiently download only the files they don't have.
75
76
77Assets
78------
79
80Artifacts used by the infrastructure are versioned here, along with scripts for
81recreating/uploading/downloading them. See the README in that directory for more
82information. Any time an asset used by the bots changes, you need to re-run
83gen_tasks.go.
84
85
86Tools
87-----
88
89Assorted other infrastructure-related tools, eg. isolate and CIPD binaries.
90
91
92CT
93--
94
95Helpers for running Skia tasks in Cluster Telemetry.
96
97

README.recipes.md

1<!--- AUTOGENERATED BY `./recipes.py test train` -->
2# Repo documentation for [skia]()
3## Table of Contents
4
5**[Recipe Modules](#Recipe-Modules)**
6  * [build](#recipe_modules-build) &mdash; Build Skia for various platforms.
7  * [builder_name_schema](#recipe_modules-builder_name_schema)
8  * [checkout](#recipe_modules-checkout)
9  * [docker](#recipe_modules-docker)
10  * [doxygen](#recipe_modules-doxygen)
11  * [env](#recipe_modules-env)
12  * [flavor](#recipe_modules-flavor)
13  * [git](#recipe_modules-git)
14  * [gold_upload](#recipe_modules-gold_upload)
15  * [gsutil](#recipe_modules-gsutil)
16  * [infra](#recipe_modules-infra)
17  * [run](#recipe_modules-run)
18  * [vars](#recipe_modules-vars)
19
20**[Recipes](#Recipes)**
21  * [build:examples/full](#recipes-build_examples_full)
22  * [builder_name_schema:examples/full](#recipes-builder_name_schema_examples_full)
23  * [checkout:examples/full](#recipes-checkout_examples_full)
24  * [compile](#recipes-compile)
25  * [compute_buildstats](#recipes-compute_buildstats)
26  * [docker:examples/full](#recipes-docker_examples_full)
27  * [doxygen:examples/full](#recipes-doxygen_examples_full)
28  * [env:examples/full](#recipes-env_examples_full)
29  * [flavor:examples/full](#recipes-flavor_examples_full)
30  * [git:examples/full](#recipes-git_examples_full)
31  * [gold_upload:examples/full](#recipes-gold_upload_examples_full)
32  * [gsutil:examples/full](#recipes-gsutil_examples_full)
33  * [housekeeper](#recipes-housekeeper)
34  * [infra](#recipes-infra)
35  * [infra:examples/full](#recipes-infra_examples_full)
36  * [perf](#recipes-perf)
37  * [perf_pathkit](#recipes-perf_pathkit)
38  * [perf_skottietrace](#recipes-perf_skottietrace)
39  * [perf_skottiewasm_lottieweb](#recipes-perf_skottiewasm_lottieweb)
40  * [run:examples/full](#recipes-run_examples_full)
41  * [sync_and_compile](#recipes-sync_and_compile)
42  * [test](#recipes-test)
43  * [test_canvaskit](#recipes-test_canvaskit)
44  * [test_lottie_web](#recipes-test_lottie_web)
45  * [test_pathkit](#recipes-test_pathkit)
46  * [upload_buildstats_results](#recipes-upload_buildstats_results)
47  * [upload_dm_results](#recipes-upload_dm_results)
48  * [upload_nano_results](#recipes-upload_nano_results)
49  * [vars:examples/full](#recipes-vars_examples_full)
50## Recipe Modules
51
52### *recipe_modules* / [build](/infra/bots/recipe_modules/build)
53
54[DEPS](/infra/bots/recipe_modules/build/__init__.py#7): [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/step][recipe_engine/recipe_modules/step], [docker](#recipe_modules-docker), [env](#recipe_modules-env), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
55
56
57Build Skia for various platforms.
58
59#### **class [BuildApi](/infra/bots/recipe_modules/build/api.py#20)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
60
61&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/build/api.py#47)(self, checkout_root, out_dir):**
62
63Compile the code.
64
65&mdash; **def [copy\_build\_products](/infra/bots/recipe_modules/build/api.py#51)(self, out_dir, dst):**
66
67Copy selected build products to dst.
68### *recipe_modules* / [builder\_name\_schema](/infra/bots/recipe_modules/builder_name_schema)
69
70
71#### **class [BuilderNameSchemaApi](/infra/bots/recipe_modules/builder_name_schema/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
72
73&mdash; **def [DictForBuilderName](/infra/bots/recipe_modules/builder_name_schema/api.py#32)(self, \*args, \*\*kwargs):**
74
75&mdash; **def [MakeBuilderName](/infra/bots/recipe_modules/builder_name_schema/api.py#29)(self, \*\*kwargs):**
76### *recipe_modules* / [checkout](/infra/bots/recipe_modules/checkout)
77
78[DEPS](/infra/bots/recipe_modules/checkout/__init__.py#7): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [depot\_tools/git][depot_tools/recipe_modules/git], [depot\_tools/tryserver][depot_tools/recipe_modules/tryserver], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
79
80
81#### **class [CheckoutApi](/infra/bots/recipe_modules/checkout/api.py#13)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
82
83&mdash; **def [assert\_git\_is\_from\_cipd](/infra/bots/recipe_modules/checkout/api.py#20)(self):**
84
85Fail if git is not obtained from CIPD.
86
87&mdash; **def [bot\_update](/infra/bots/recipe_modules/checkout/api.py#39)(self, checkout_root, gclient_cache=None, skip_patch=False, override_revision=None):**
88
89Run the steps to obtain a checkout using bot_update.
90
91Args:
92  checkout_root: Root directory where the code will be synced.
93  gclient_cache: Optional, directory of the gclient cache.
94  skip_patch: Ignore changelist/patchset when syncing the Skia repo.
95
96&emsp; **@property**<br>&mdash; **def [default\_checkout\_root](/infra/bots/recipe_modules/checkout/api.py#15)(self):**
97
98The default location for cached persistent checkouts.
99
100&mdash; **def [git](/infra/bots/recipe_modules/checkout/api.py#26)(self, checkout_root):**
101
102Run the steps to perform a pure-git checkout without DEPS.
103### *recipe_modules* / [docker](/infra/bots/recipe_modules/docker)
104
105[DEPS](/infra/bots/recipe_modules/docker/__init__.py#8): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [run](#recipe_modules-run)
106
107
108#### **class [DockerApi](/infra/bots/recipe_modules/docker/api.py#15)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
109
110&mdash; **def [mount\_out](/infra/bots/recipe_modules/docker/api.py#27)(self):**
111
112&mdash; **def [mount\_src](/infra/bots/recipe_modules/docker/api.py#24)(self):**
113
114&mdash; **def [run](/infra/bots/recipe_modules/docker/api.py#32)(self, name, docker_image, src_dir, out_dir, script, args=None, docker_args=None, copies=None, recursive_read=None, attempts=1, match_directory_structure=False):**
115### *recipe_modules* / [doxygen](/infra/bots/recipe_modules/doxygen)
116
117[DEPS](/infra/bots/recipe_modules/doxygen/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run)
118
119
120#### **class [DoxygenApi](/infra/bots/recipe_modules/doxygen/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
121
122&mdash; **def [generate\_and\_upload](/infra/bots/recipe_modules/doxygen/api.py#10)(self, skia_dir):**
123### *recipe_modules* / [env](/infra/bots/recipe_modules/env)
124
125[DEPS](/infra/bots/recipe_modules/env/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context]
126
127
128#### **class [EnvApi](/infra/bots/recipe_modules/env/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
129### *recipe_modules* / [flavor](/infra/bots/recipe_modules/flavor)
130
131[DEPS](/infra/bots/recipe_modules/flavor/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
132
133
134#### **class [SkiaFlavorApi](/infra/bots/recipe_modules/flavor/api.py#54)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
135
136&mdash; **def [cleanup\_steps](/infra/bots/recipe_modules/flavor/api.py#122)(self):**
137
138&mdash; **def [copy\_directory\_contents\_to\_device](/infra/bots/recipe_modules/flavor/api.py#80)(self, host_dir, device_dir):**
139
140&mdash; **def [copy\_directory\_contents\_to\_host](/infra/bots/recipe_modules/flavor/api.py#83)(self, device_dir, host_dir):**
141
142&mdash; **def [copy\_file\_to\_device](/infra/bots/recipe_modules/flavor/api.py#86)(self, host_path, device_path):**
143
144&mdash; **def [create\_clean\_device\_dir](/infra/bots/recipe_modules/flavor/api.py#92)(self, path):**
145
146&mdash; **def [create\_clean\_host\_dir](/infra/bots/recipe_modules/flavor/api.py#89)(self, path):**
147
148&mdash; **def [device\_path\_join](/infra/bots/recipe_modules/flavor/api.py#77)(self, \*args):**
149
150&mdash; **def [get\_flavor](/infra/bots/recipe_modules/flavor/api.py#55)(self, vars_api, app_name):**
151
152Return a flavor utils object specific to the given builder.
153
154&mdash; **def [install](/infra/bots/recipe_modules/flavor/api.py#101)(self, skps=False, images=False, lotties=False, svgs=False, resources=False, texttraces=False):**
155
156&mdash; **def [read\_file\_on\_device](/infra/bots/recipe_modules/flavor/api.py#95)(self, path, \*\*kwargs):**
157
158&mdash; **def [remove\_file\_on\_device](/infra/bots/recipe_modules/flavor/api.py#98)(self, path):**
159
160&mdash; **def [setup](/infra/bots/recipe_modules/flavor/api.py#68)(self, app_name):**
161
162&mdash; **def [step](/infra/bots/recipe_modules/flavor/api.py#74)(self, name, cmd, \*\*kwargs):**
163### *recipe_modules* / [git](/infra/bots/recipe_modules/git)
164
165[DEPS](/infra/bots/recipe_modules/git/__init__.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [env](#recipe_modules-env)
166
167
168#### **class [GitApi](/infra/bots/recipe_modules/git/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
169
170&mdash; **def [env](/infra/bots/recipe_modules/git/api.py#10)(self):**
171
172Add Git to PATH
173
174Requires the infra/git and infra/tools/git CIPD packages to be installed
175in the 'git' relative path.
176### *recipe_modules* / [gold\_upload](/infra/bots/recipe_modules/gold_upload)
177
178[DEPS](/infra/bots/recipe_modules/gold_upload/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [flavor](#recipe_modules-flavor), [gsutil](#recipe_modules-gsutil), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
179
180
181#### **class [GoldUploadApi](/infra/bots/recipe_modules/gold_upload/api.py#11)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
182
183&mdash; **def [upload](/infra/bots/recipe_modules/gold_upload/api.py#12)(self):**
184
185Attempt to upload files to Gold.
186This module assumes setup has occurred for the vars and flavor modules.
187### *recipe_modules* / [gsutil](/infra/bots/recipe_modules/gsutil)
188
189[DEPS](/infra/bots/recipe_modules/gsutil/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
190
191
192#### **class [GSUtilApi](/infra/bots/recipe_modules/gsutil/api.py#10)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
193
194&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/gsutil/api.py#11)(self, step_name, \*args):**
195
196Run gsutil with the given args.
197
198This assumes there exists an executable called gsutil on the PATH.
199This probably only works for Linux/Mac, but those are the only
200hosts that we try to upload to GCS from anyway.
201
202&mdash; **def [cp](/infra/bots/recipe_modules/gsutil/api.py#20)(self, name, src, dst, extra_gsutil_args=None, extra_args=None, multithread=False):**
203
204Attempt to upload or download files to/from Google Cloud Storage (GCS).
205
206Args:
207  name: string. Will be used to fill out the step name.
208  src: string. Absolute path for a local file or gcs file (e.g. gs://...)
209  dst: string. Same as src.
210  extra_gsutil_args: optional list of args to be passed to gsutil before the
211    cp command.
212  extra_args: optional list of args to be passed to gsutil cp. e.g. [-Z]
213    asks all files be compressed with gzip after upload and before download.
214  multi_thread: if the -m argument should be used to copy multiple items
215    at once (e.g. gsutil -m cp foo* gs://bar/dir)
216
217If the operation fails, it will be retried multiple times.
218### *recipe_modules* / [infra](/infra/bots/recipe_modules/infra)
219
220[DEPS](/infra/bots/recipe_modules/infra/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
221
222
223#### **class [InfraApi](/infra/bots/recipe_modules/infra/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
224
225&emsp; **@property**<br>&mdash; **def [go\_bin](/infra/bots/recipe_modules/infra/api.py#46)(self):**
226
227&emsp; **@property**<br>&mdash; **def [go\_env](/infra/bots/recipe_modules/infra/api.py#50)(self):**
228
229&emsp; **@property**<br>&mdash; **def [gopath](/infra/bots/recipe_modules/infra/api.py#60)(self):**
230
231&emsp; **@property**<br>&mdash; **def [goroot](/infra/bots/recipe_modules/infra/api.py#15)(self):**
232### *recipe_modules* / [run](/infra/bots/recipe_modules/run)
233
234[DEPS](/infra/bots/recipe_modules/run/__init__.py#7): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [vars](#recipe_modules-vars)
235
236
237#### **class [SkiaStepApi](/infra/bots/recipe_modules/run/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
238
239&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/run/api.py#69)(self, steptype, name, abort_on_failure=True, fail_build_on_failure=True, \*\*kwargs):**
240
241Run a step. If it fails, keep going but mark the build status failed.
242
243&mdash; **def [\_\_init\_\_](/infra/bots/recipe_modules/run/api.py#16)(self, \*args, \*\*kwargs):**
244
245Initialize the recipe module.
246
247&mdash; **def [asset\_version](/infra/bots/recipe_modules/run/api.py#54)(self, asset_name, skia_dir, test_data=None):**
248
249Return the contents of VERSION for the given asset as a string.
250
251If test_data is not specified, reads the property
252'test_<asset_name>_version' or if not present, uses
253TEST_DEFAULT_ASSET_VERSION.
254
255&mdash; **def [check\_failure](/infra/bots/recipe_modules/run/api.py#25)(self):**
256
257Raise an exception if any step failed.
258
259&emsp; **@property**<br>&mdash; **def [failed\_steps](/infra/bots/recipe_modules/run/api.py#31)(self):**
260
261&mdash; **def [readfile](/infra/bots/recipe_modules/run/api.py#40)(self, filename, \*args, \*\*kwargs):**
262
263Convenience function for reading files.
264
265&mdash; **def [rmtree](/infra/bots/recipe_modules/run/api.py#50)(self, path):**
266
267Wrapper around api.file.rmtree.
268
269&mdash; **def [run\_once](/infra/bots/recipe_modules/run/api.py#35)(self, fn, \*args, \*\*kwargs):**
270
271&mdash; **def [with\_retry](/infra/bots/recipe_modules/run/api.py#81)(self, steptype, name, attempts, between_attempts_fn=None, abort_on_failure=True, fail_build_on_failure=True, \*\*kwargs):**
272
273&mdash; **def [writefile](/infra/bots/recipe_modules/run/api.py#45)(self, filename, contents):**
274
275Convenience function for writing files.
276### *recipe_modules* / [vars](/infra/bots/recipe_modules/vars)
277
278[DEPS](/infra/bots/recipe_modules/vars/__init__.py#7): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [builder\_name\_schema](#recipe_modules-builder_name_schema)
279
280
281#### **class [SkiaVarsApi](/infra/bots/recipe_modules/vars/api.py#16)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
282
283&emsp; **@property**<br>&mdash; **def [is\_linux](/infra/bots/recipe_modules/vars/api.py#87)(self):**
284
285&mdash; **def [setup](/infra/bots/recipe_modules/vars/api.py#18)(self):**
286
287Prepare the variables.
288
289&emsp; **@property**<br>&mdash; **def [swarming\_bot\_id](/infra/bots/recipe_modules/vars/api.py#95)(self):**
290
291&emsp; **@property**<br>&mdash; **def [swarming\_task\_id](/infra/bots/recipe_modules/vars/api.py#106)(self):**
292## Recipes
293
294### *recipes* / [build:examples/full](/infra/bots/recipe_modules/build/examples/full.py)
295
296[DEPS](/infra/bots/recipe_modules/build/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [build](#recipe_modules-build), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
297
298
299&mdash; **def [RunSteps](/infra/bots/recipe_modules/build/examples/full.py#18)(api):**
300### *recipes* / [builder\_name\_schema:examples/full](/infra/bots/recipe_modules/builder_name_schema/examples/full.py)
301
302[DEPS](/infra/bots/recipe_modules/builder_name_schema/examples/full.py#7): [builder\_name\_schema](#recipe_modules-builder_name_schema)
303
304
305&mdash; **def [RunSteps](/infra/bots/recipe_modules/builder_name_schema/examples/full.py#12)(api):**
306### *recipes* / [checkout:examples/full](/infra/bots/recipe_modules/checkout/examples/full.py)
307
308[DEPS](/infra/bots/recipe_modules/checkout/examples/full.py#7): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [checkout](#recipe_modules-checkout), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
309
310
311&mdash; **def [RunSteps](/infra/bots/recipe_modules/checkout/examples/full.py#18)(api):**
312### *recipes* / [compile](/infra/bots/recipes/compile.py)
313
314[DEPS](/infra/bots/recipes/compile.py#11): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [build](#recipe_modules-build), [checkout](#recipe_modules-checkout), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
315
316
317&mdash; **def [RunSteps](/infra/bots/recipes/compile.py#26)(api):**
318### *recipes* / [compute\_buildstats](/infra/bots/recipes/compute_buildstats.py)
319
320[DEPS](/infra/bots/recipes/compute_buildstats.py#12): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [env](#recipe_modules-env), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
321
322
323&mdash; **def [RunSteps](/infra/bots/recipes/compute_buildstats.py#34)(api):**
324
325&mdash; **def [add\_binary\_size\_output\_property](/infra/bots/recipes/compute_buildstats.py#30)(result, source, binary_size):**
326
327&mdash; **def [analyze\_cpp\_lib](/infra/bots/recipes/compute_buildstats.py#166)(api, checkout_root, out_dir, files):**
328
329&mdash; **def [analyze\_flutter\_lib](/infra/bots/recipes/compute_buildstats.py#194)(api, checkout_root, out_dir, files):**
330
331&mdash; **def [analyze\_wasm\_file](/infra/bots/recipes/compute_buildstats.py#233)(api, checkout_root, out_dir, files):**
332
333&mdash; **def [analyze\_web\_file](/infra/bots/recipes/compute_buildstats.py#139)(api, checkout_root, out_dir, files):**
334
335&mdash; **def [keys\_and\_props](/infra/bots/recipes/compute_buildstats.py#115)(api):**
336
337&mdash; **def [make\_treemap](/infra/bots/recipes/compute_buildstats.py#265)(api, checkout_root, out_dir, files):**
338### *recipes* / [docker:examples/full](/infra/bots/recipe_modules/docker/examples/full.py)
339
340[DEPS](/infra/bots/recipe_modules/docker/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [docker](#recipe_modules-docker), [vars](#recipe_modules-vars)
341
342
343&mdash; **def [RunSteps](/infra/bots/recipe_modules/docker/examples/full.py#16)(api):**
344### *recipes* / [doxygen:examples/full](/infra/bots/recipe_modules/doxygen/examples/full.py)
345
346[DEPS](/infra/bots/recipe_modules/doxygen/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [doxygen](#recipe_modules-doxygen), [vars](#recipe_modules-vars)
347
348
349&mdash; **def [RunSteps](/infra/bots/recipe_modules/doxygen/examples/full.py#15)(api):**
350### *recipes* / [env:examples/full](/infra/bots/recipe_modules/env/examples/full.py)
351
352[DEPS](/infra/bots/recipe_modules/env/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env)
353
354
355&mdash; **def [RunSteps](/infra/bots/recipe_modules/env/examples/full.py#14)(api):**
356### *recipes* / [flavor:examples/full](/infra/bots/recipe_modules/flavor/examples/full.py)
357
358[DEPS](/infra/bots/recipe_modules/flavor/examples/full.py#7): [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
359
360
361&mdash; **def [RunSteps](/infra/bots/recipe_modules/flavor/examples/full.py#32)(api):**
362
363&mdash; **def [test\_exceptions](/infra/bots/recipe_modules/flavor/examples/full.py#17)(api):**
364### *recipes* / [git:examples/full](/infra/bots/recipe_modules/git/examples/full.py)
365
366[DEPS](/infra/bots/recipe_modules/git/examples/full.py#7): [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step], [git](#recipe_modules-git)
367
368
369&mdash; **def [RunSteps](/infra/bots/recipe_modules/git/examples/full.py#14)(api):**
370### *recipes* / [gold\_upload:examples/full](/infra/bots/recipe_modules/gold_upload/examples/full.py)
371
372[DEPS](/infra/bots/recipe_modules/gold_upload/examples/full.py#10): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
373
374
375&mdash; **def [RunSteps](/infra/bots/recipe_modules/gold_upload/examples/full.py#22)(api):**
376### *recipes* / [gsutil:examples/full](/infra/bots/recipe_modules/gsutil/examples/full.py)
377
378[DEPS](/infra/bots/recipe_modules/gsutil/examples/full.py#10): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [gsutil](#recipe_modules-gsutil), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
379
380
381&mdash; **def [RunSteps](/infra/bots/recipe_modules/gsutil/examples/full.py#20)(api):**
382### *recipes* / [housekeeper](/infra/bots/recipes/housekeeper.py)
383
384[DEPS](/infra/bots/recipes/housekeeper.py#13): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [checkout](#recipe_modules-checkout), [doxygen](#recipe_modules-doxygen), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
385
386
387&mdash; **def [RunSteps](/infra/bots/recipes/housekeeper.py#24)(api):**
388### *recipes* / [infra](/infra/bots/recipes/infra.py)
389
390[DEPS](/infra/bots/recipes/infra.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [infra](#recipe_modules-infra), [vars](#recipe_modules-vars)
391
392
393&mdash; **def [RunSteps](/infra/bots/recipes/infra.py#28)(api):**
394
395&mdash; **def [git\_init](/infra/bots/recipes/infra.py#20)(api, repo_root, env):**
396### *recipes* / [infra:examples/full](/infra/bots/recipe_modules/infra/examples/full.py)
397
398[DEPS](/infra/bots/recipe_modules/infra/examples/full.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
399
400
401&mdash; **def [RunSteps](/infra/bots/recipe_modules/infra/examples/full.py#22)(api):**
402### *recipes* / [perf](/infra/bots/recipes/perf.py)
403
404[DEPS](/infra/bots/recipes/perf.py#15): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
405
406
407&mdash; **def [RunSteps](/infra/bots/recipes/perf.py#104)(api):**
408
409&mdash; **def [perf\_steps](/infra/bots/recipes/perf.py#31)(api):**
410
411Run Skia benchmarks.
412### *recipes* / [perf\_pathkit](/infra/bots/recipes/perf_pathkit.py)
413
414[DEPS](/infra/bots/recipes/perf_pathkit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
415
416
417&mdash; **def [RunSteps](/infra/bots/recipes/perf_pathkit.py#27)(api):**
418### *recipes* / [perf\_skottietrace](/infra/bots/recipes/perf_skottietrace.py)
419
420[DEPS](/infra/bots/recipes/perf_skottietrace.py#17): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [flavor](#recipe_modules-flavor), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
421
422
423&mdash; **def [RunSteps](/infra/bots/recipes/perf_skottietrace.py#191)(api):**
424
425&mdash; **def [get\_trace\_match](/infra/bots/recipes/perf_skottietrace.py#147)(lottie_filename, is_android):**
426
427Returns the DM regex to match the specified lottie file name.
428
429&mdash; **def [parse\_trace](/infra/bots/recipes/perf_skottietrace.py#162)(trace_json, lottie_filename, api):**
430
431parse_trace parses the specified trace JSON.
432
433Parses the trace JSON and calculates the time of a single frame. Frame time is
434considered the same as seek time + render time.
435Note: The first seek is ignored because it is a constructor call.
436
437A dictionary is returned that has the following structure:
438{
439  'frame_max_us': 100,
440  'frame_min_us': 90,
441  'frame_avg_us': 95,
442}
443
444&mdash; **def [perf\_steps](/infra/bots/recipes/perf_skottietrace.py#37)(api):**
445
446Run DM on lottie files with tracing turned on and then parse the output.
447### *recipes* / [perf\_skottiewasm\_lottieweb](/infra/bots/recipes/perf_skottiewasm_lottieweb.py)
448
449[DEPS](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#14): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [checkout](#recipe_modules-checkout), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
450
451
452&mdash; **def [RunSteps](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#85)(api):**
453
454&mdash; **def [parse\_trace](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#206)(trace_json, lottie_filename, api, renderer):**
455
456parse_trace parses the specified trace JSON.
457
458Parses the trace JSON and calculates the time of a single frame.
459A dictionary is returned that has the following structure:
460{
461  'frame_max_us': 100,
462  'frame_min_us': 90,
463  'frame_avg_us': 95,
464}
465### *recipes* / [run:examples/full](/infra/bots/recipe_modules/run/examples/full.py)
466
467[DEPS](/infra/bots/recipe_modules/run/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
468
469
470&mdash; **def [RunSteps](/infra/bots/recipe_modules/run/examples/full.py#22)(api):**
471
472&mdash; **def [myfunc](/infra/bots/recipe_modules/run/examples/full.py#18)(api, i):**
473### *recipes* / [sync\_and\_compile](/infra/bots/recipes/sync_and_compile.py)
474
475[DEPS](/infra/bots/recipes/sync_and_compile.py#10): [depot\_tools/gitiles][depot_tools/recipe_modules/gitiles], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [build](#recipe_modules-build), [checkout](#recipe_modules-checkout), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
476
477
478&mdash; **def [RunSteps](/infra/bots/recipes/sync_and_compile.py#27)(api):**
479### *recipes* / [test](/infra/bots/recipes/test.py)
480
481[DEPS](/infra/bots/recipes/test.py#13): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
482
483
484&mdash; **def [RunSteps](/infra/bots/recipes/test.py#136)(api):**
485
486&mdash; **def [test\_steps](/infra/bots/recipes/test.py#30)(api):**
487
488Run the DM test.
489### *recipes* / [test\_canvaskit](/infra/bots/recipes/test_canvaskit.py)
490
491[DEPS](/infra/bots/recipes/test_canvaskit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
492
493
494&mdash; **def [RunSteps](/infra/bots/recipes/test_canvaskit.py#28)(api):**
495### *recipes* / [test\_lottie\_web](/infra/bots/recipes/test_lottie_web.py)
496
497[DEPS](/infra/bots/recipes/test_lottie_web.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
498
499
500&mdash; **def [RunSteps](/infra/bots/recipes/test_lottie_web.py#29)(api):**
501### *recipes* / [test\_pathkit](/infra/bots/recipes/test_pathkit.py)
502
503[DEPS](/infra/bots/recipes/test_pathkit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
504
505
506&mdash; **def [RunSteps](/infra/bots/recipes/test_pathkit.py#29)(api):**
507### *recipes* / [upload\_buildstats\_results](/infra/bots/recipes/upload_buildstats_results.py)
508
509[DEPS](/infra/bots/recipes/upload_buildstats_results.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [vars](#recipe_modules-vars)
510
511
512&mdash; **def [RunSteps](/infra/bots/recipes/upload_buildstats_results.py#21)(api):**
513### *recipes* / [upload\_dm\_results](/infra/bots/recipes/upload_dm_results.py)
514
515[DEPS](/infra/bots/recipes/upload_dm_results.py#13): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [gsutil](#recipe_modules-gsutil), [vars](#recipe_modules-vars)
516
517
518&mdash; **def [RunSteps](/infra/bots/recipes/upload_dm_results.py#29)(api):**
519### *recipes* / [upload\_nano\_results](/infra/bots/recipes/upload_nano_results.py)
520
521[DEPS](/infra/bots/recipes/upload_nano_results.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [vars](#recipe_modules-vars)
522
523
524&mdash; **def [RunSteps](/infra/bots/recipes/upload_nano_results.py#21)(api):**
525### *recipes* / [vars:examples/full](/infra/bots/recipe_modules/vars/examples/full.py)
526
527[DEPS](/infra/bots/recipe_modules/vars/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [vars](#recipe_modules-vars)
528
529
530&mdash; **def [RunSteps](/infra/bots/recipe_modules/vars/examples/full.py#16)(api):**
531
532[depot_tools/recipe_modules/bot_update]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/858263702e7d753140c34b47b0625374e36fe535/recipes/README.recipes.md#recipe_modules-bot_update
533[depot_tools/recipe_modules/gclient]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/858263702e7d753140c34b47b0625374e36fe535/recipes/README.recipes.md#recipe_modules-gclient
534[depot_tools/recipe_modules/git]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/858263702e7d753140c34b47b0625374e36fe535/recipes/README.recipes.md#recipe_modules-git
535[depot_tools/recipe_modules/gitiles]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/858263702e7d753140c34b47b0625374e36fe535/recipes/README.recipes.md#recipe_modules-gitiles
536[depot_tools/recipe_modules/tryserver]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/858263702e7d753140c34b47b0625374e36fe535/recipes/README.recipes.md#recipe_modules-tryserver
537[recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-context
538[recipe_engine/recipe_modules/file]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-file
539[recipe_engine/recipe_modules/json]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-json
540[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-path
541[recipe_engine/recipe_modules/platform]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-platform
542[recipe_engine/recipe_modules/properties]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-properties
543[recipe_engine/recipe_modules/raw_io]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-raw_io
544[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-step
545[recipe_engine/recipe_modules/time]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-time
546[recipe_engine/wkt/RecipeApi]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/recipe_engine/recipe_api.py#433
547