| # Infrastructure |
| |
| Chromium DevTools has an infrastructure component that consists of |
| recipes that define how to build and test the frontend in CQ and CI |
| plus a set of rollers to automate dependency updates. |
| |
| ## Overview of the code |
| |
| The configuration for the DevTools infrastructure is in the |
| [`infra/config`](https://chromium.googlesource.com/devtools/devtools-frontend/+/refs/heads/infra/config) |
| branch. The recipes are located in the |
| [`chromium/tools/build`](https://chromium.googlesource.com/chromium/tools/build/+/refs/heads/main) |
| repository. |
| |
| [Luci-config app](https://config.luci.app) is consuming the configuration from infra/config. You can force refresh from the app. DevTools configuration is located [here](https://chrome-internal.googlesource.com/infradata/config/+/master/configs/luci-config/projects.cfg). |
| |
| ## Checking out the infra config branch |
| |
| ```bash |
| mkdir devtools-infra |
| cd devtools-infra |
| fetch devtools-frontend |
| cd devtools-frontend |
| git checkout infra/config |
| ``` |
| |
| Run `git clean -fd` and remove the rest of the remaining files from the `main` |
| branch. |
| |
| ## Submitting an infra config change |
| |
| First, create a branch for the change and set upstream to the `infra/config`: |
| |
| ```bash |
| git new-branch branch-name --upstream_current |
| ``` |
| |
| - `buckets/try.star`: configurations for default try-jobs for a CL. |
| - `buckets/try-misc.star`: configurations for additional builders that |
| can be manually added to CLs in Gerrit or via `git cl try`. |
| - `buckets/cpp_debugging_extension.star`: configurations for the C++ |
| debugging extension tests. |
| - `buckets/serving_app.star`: configurations for the DevTools server |
| app. |
| - `buckets/ci.star`: configurations to run on the main branch after a CL |
| is submitted also known as CI or Waterfall builders. |
| - `buckets/ci-hp.star`: configurations for the highly privileged |
| builders that rolls dependencies. |
| |
| After you update a `.star` file, re-generate generated files using |
| `lucicfg main.star`. |
| |
| These `.star` definitions roughly correspond to the CI console view |
| https://ci.chromium.org/ui/p/devtools-frontend. |
| |
| Run `git cl upload`. Infra changes are submitted similar to the regular |
| frontend CLs using `git cl upload`. After a review on Gerrit, the change |
| will be merged into the infra branch. |
| |
| Note that the changes made in the CL are not picked up by the bots before the |
| change is merged. After the CL is merged, the change will be deployed to the |
| bots. |
| |
| ## Submitting a recipe change |
| |
| Follow the instructions at |
| https://chromium.googlesource.com/chromium/tools/build/+/refs/heads/main/recipes/README.md |
| and upload a CL for |
| [`chromium/tools/build`](https://chromium.googlesource.com/chromium/tools/build/+/refs/heads/main). |
| |
| It's good practice to also manually test your recipes. You can test your recipe |
| changes against a build that was performed with the same recipes. To do so |
| follow these steps: |
| - authenticate with `led auth-login` |
| - select a particular build that ran with your target recipe ([example](https://ci.chromium.org/ui/p/devtools-frontend/builders/try/dtf_linux_dbg/14161)) |
| - got to Infra tab and collect the Buildbucket id (8700153319150087425 for the example above) |
| - run `led get-build --real-build 8700153319150087425 | led edit-recipe-bundle | led edit-system -p 25 | led launch` while in your local recipe checkout |
| - collect the output link to your test build and verify that you got the expected result |
| |
| ## Pin older version of DevTools recipes to a branch |
| |
| Updating a recipe that depends on DevTools repo recent changes can break the |
| build in beta/stable/extended branches. If those changes cannot be back-merged |
| into the branches you can pin the older version of the recipe to the branches in |
| infra/config. |
| |
| To do so update the `legacy_recipe` config in `definitions.star` with the number |
| of the last branch you need the old version of the recipe to run on and with the |
| revision hash of that version. Branches with number higher than the one you |
| configured will run ToT recipe version. [Example](https://crrev.com/c/7003685) |
| |
| ## Updating test commands in the infrastructure |
| |
| The DevTools recipes are defined in |
| [`chromium/tools/build`](https://chromium.googlesource.com/chromium/tools/build/+/refs/heads/main) |
| repository. Once a change is made there, the recipes are packaged |
| as a cipd package and the `infra/config` data defines how to fetch that |
| cipd package. The recipes are bundled by |
| https://ci.chromium.org/ui/p/chrome/builders/official.infra/recipe-bundler. |
| |
| DevTools recipes live at |
| https://chromium.googlesource.com/chromium/tools/build/+/refs/heads/main/recipes/recipes/devtools/. |
| |
| ## Determining if a change needs to run tests |
| |
| The |
| [`try.star`](https://chromium.googlesource.com/devtools/devtools-frontend/+/refs/heads/infra/config/buckets/try.star) |
| file in the `infra/config` branch contains the logic that determines |
| which builders are needed to verify a CQ. See `custom_locationsfilters` |
| for the current logic. |
| |
| Some of the filters currently in use are: |
| |
| - `cpp_debug_extension` builders only trigger on changes related to the extension |
| - `dtf_check_no_bundle` builder only trigger on GN changes |
| - all other builders will not trigger if only documentation files are updated |
| |
| ## Branch cutting process |
| |
| At the end of every release cycle Chromium will cut a new branch for the current release. |
| |
| The branch cut process for DevTools is as simple as updating the beta, stable |
| and extended branch numbers in infra/config (example [CL](https://crrev.com/c/6850649)): |
| |
| - checkout infra/config branch |
| - pull and create a new branch ([see](#Submitting an infra config change)) |
| - update the definitions.star file: |
| - extended number gets updated every second release: |
| - if the extended number is equal to the stable number, then update |
| extended to the current beta number |
| - otherwise update it to the current stable number |
| - stable number updates to the current beta number |
| - beta number updates to the Chromium beta brunch number ([see](https://chromiumdash.appspot.com/branches)) |
| - regenerate the cfg files (`lucicfg main.star`), commit, upload and add |
| liviurau@chromium.org as reviewer (or another infra team member) |
| |
| Changing these numbers will reconfigure the CI and CQ for [beta](https://ci.chromium.org/p/devtools-frontend/g/beta/console), |
| [stable](https://ci.chromium.org/p/devtools-frontend/g/stable/console) and |
| [extended](https://ci.chromium.org/p/devtools-frontend/g/extended/console) branches. |
| After landing the change the three branch consoles will get reset. |
| |
| ## Toggle tree closing behaviour on CI builders |
| |
| Sometimes we might need to avoid a misbehaving builder closing the tree. Or maybe |
| we need to make a FYI builder a tree closer. |
| |
| To do so find your builder buckets/ci.star file and toggle the |
| `notification_muted` property (defaults to False if not present). Setting the |
| property to True/False will remove/add the tree closer notifier for this builder. |
| Make sure you regenerated the cfg files and upload your changes. [Example](https://crrev.com/c/6903184). |
| |
| ## Toggle blocking behaviour of CQ builders |
| |
| CQ builders come in 3 flavors: |
| |
| - regular try builder: will always prevent a CL from landing when the builder |
| fails |
| - includable builder: will run only if explicitly added to a CQ run and will |
| prevent a CL from landing if the builder fails |
| - experimental builder: will run a percentage of the times it gets an |
| opportunity run and will not block the CL from landing if the builder fails |
| |
| To toggle this behaviour you need to edit `buckets/try.star` file ([example](https://crrev.com/c/6903181)): |
| |
| - all builders must be enumerated in `cq_builders.devtools_builders` list |
| - to make a builder includable add it's name `cq_builders.includable_only_builders` |
| list; remove it from the list to make it a regular builder |
| - to make a builder experimental add it's name `cq_builders.experiment_builders` |
| dictionary together with the desired experiment rate percentage; remove it |
| from the list to make it a regular builder |
| |
| ## Adding a new builder in CQ |
| |
| To add a new try-builder edit the [try.start](https://chromium.googlesource.com/devtools/devtools-frontend/+/refs/heads/infra/config/buckets/try.star) file to call one of the |
| existing functions that generate builder definitions: |
| |
| - `try_builder` used for builder with recipes that do not orchestrate other |
| builders: |
| - build only builders (`dtf_check_no_bundle`) |
| - chromium builders (`devtools_frontend_linux_blink_light_rel_fastbuild`) |
| - `try_pair` used for builders with orchestrating recipes (delegates to a |
| compilator builder before delegating testing to swarming) |
| |
| Alternatively define your own builder function and call it for the instances you |
| need (see `presubmit_builder` and `cpp_debug_extension_try`). |
| |
| You will need add your new builder to the `cq_builders.devtools_builders` list. |
| |
| To control the CL blocking behaviour of your builder see above. |
| |
| To control if the builder should be not present in the CQ for branches, add your |
| builder to `cq_builders.chromium_builders` list. |
| |
| ## Adding a new builder in CI |
| |
| To add a new try-builder edit the [ci.start](https://chromium.googlesource.com/devtools/devtools-frontend/+/refs/heads/infra/config/buckets/ci.star) file to add a new |
| `builder_descriptor` to the `builders` of `generate_ci_configs` function call. |
| |
| In your descriptor decide for the name of builder, the recipe, any other custom |
| properties you might need and for which configurations (consoles) to include |
| your builder (`ci` stands for the main waterfall console). [Example](https://chromium.googlesource.com/devtools/devtools-frontend/+/refs/heads/infra/config/buckets/ci.star#:~:text=name%20%3D%20%22-,Linux,-Compile%20Debug%22%2C). |
| |
| ## Anatomy of a CQ build |
| |
| In CQ the builders that get most attention are `dtf_*_rel` builders. These builders |
| run the devtools/trybot_tester recipe and are responsible with building DevTools |
| Frontend and running our tests. |
| |
| Below is a detailed description of what happens in such a build: |
| |
| - The recipe will perform the `bot_update` and `gclient runhooks` step where |
| the tip-of-tree for devtools-frontend gets checked out, your changes get |
| patched on top of it and dependencies get updated. |
| - The compilator bot get triggered (`initialization` step) |
| - We wait for the compilator bot to finish. This bot is responsible for |
| the actual build of devtools-frontend. |
| - It does a `bot_update` of its own |
| - Generates the GN files (`gn` step) |
| - Compiles (`compile`) the project |
| - Reads the e2e test lists |
| - Creates a CAS archive with project and the compilation output |
| - Outputs the `compilator_properties` |
| - Once the compilator is done we read the `compilator_properties` to find |
| - the `cas_digest` to be used when triggering tests on swarming |
| - the `e2e_test_list` for sharding the e2e tests execution |
| - Write the e2e test list at the location where building would have written it |
| - The default test run phase starts at `Run tests` step: |
| - We trigger all tests on swarming in parallel (`Trigger Tests`) substep. |
| - For all types of tests we calculate the command we want to run on swarming |
| and trigger a task with that command and the collected CAS digest |
| - Before calculating the command for e2e test we read the test list and |
| and split it in a number of shards. Each shard will have the allocated |
| tests specified in the command. |
| - We wait for all swarming task to complete |
| - Next we re-run the failed tests in attempt to exonerate their initial |
| failures (`Flake exoneration attempt` step): |
| - We query ResultDB for any tests that might have failed |
| - We collect the failed test names and construct new commands to re-run |
| them on new swarming tasks |
| - We wait for all swarming task to complete |
| - Finally we will stress test the tests that were added/modified by the |
| current CL in the `Detect flakes in new tests` step |
| - Run `git diff` to determine which tests were added/modified |
| - Construct the command to be run on swarming |
| - Trigger and wait for the swarming tasks to finish |
| - Calculate the outcome of the builder: |
| - fail the builder if tests failed in the default run and the exoneration |
| run was unsuccessful |
| - fail the builder if tests failed in the deflaking phase |
| - otherwise report build as passing |
| |
| ## Skip flake detection |
| |
| Test that are already flaky can end up being updated in CLs that do not deal |
| with the original flakiness nor can be blamed for introducing or increasing the |
| flakiness of the test. However CQ builder will fail in Flake Detection steps |
| because they picked up the test as it was being touched. |
| |
| You can skip Flake Detection for your tests by adding the `Skip-Flake-Detection` |
| CL footer (see example [CL](https://crrev.com/c/6994031)). Make sure you use the |
| full path to your test. |
| |
| ### Common build failures |
| |
| The first place where a build usually fails is on `bot_update` and this usually |
| happens because your changes cannot be applied on top of the current tip-of-tree. |
| Rebase your CL and solve any merge conflicts and this failure will go away. |
| |
| Another common failure is a compilation failure. You can inspect the compilator |
| builder (`dtf_*_compiler_rel`) separately by following the link next to the |
| `compilator steps` step. |
| |
| If you have too many tests failing in the default phase the exoneration phase |
| gets skipped. |
| |
| A test might not get exonerated in your build even if your CL does not touch |
| anything related to it. The exoneration phase will re-run previously failing |
| tests a number of times and at any point the test passes the tests gets |
| exonerated. Therefore a test can have a recent history of getting exonerated |
| even if it consistently failed 4 times out of 5 runs for some time. Try to |
| correlate your failure with a luci-analysis report on this test and skip it |
| until the flakiness gets resolved. |
| |
| ### Clobber a builder's cache |
| |
| Builder bots utilize caching for project checkouts to speed up updates. This |
| cache includes the build output directory (`/out`). Occasionally, stale files |
| within these directories can interfere with the build process or test execution. |
| |
| If you suspect a cache issue, you can clear (clobber) the cache for a specific |
| builder. This requires a local Chromium checkout to access the necessary utility |
| script. |
| |
| Run the following command from the root of your Chromium checkout: |
| |
| ```bash |
| ./tools/infra/builder-cache-clobber.py -S https://chromium-swarm.appspot.com/ --builder "Stand-alone Mac-arm64" --bucket ci --project devtools-frontend |
| ``` |
| |
| #### Note about caches on try bots: |
| |
| Try bots (CQ) operate in tester/compilator pairs. When clearing caches, ensure |
| you target both builders in the pair. For example, if you clear the cache for |
| `dtf_mac_arm64_rel`, you must also clear it for `dtf_mac_arm64_compile_rel`. |
| |
| ## Luci Analysis configuration |
| |
| [Luci Analysis](go/luci-analysis) is a tool that helps you understand the |
| impact of test failures. |
| |
| You can find the DevTools configuration in [luci-analysis.cfg](https://chromium.googlesource.com/devtools/devtools-frontend/+/refs/heads/infra/config/luci-analysis.cfg). |
| |
| We configure the rules for test failure clustering based on _file_/_suite_ and |
| _testcase_ names. |
| |
| A policy named `too-many-failures` is defined in the configuration with |
| activation/deactivation thresholds and a bug template to be used when creating |
| a new bug. The bugs will be automatically created in Buganizer on the configured |
| default component (or on the component specified in a `DIR_METADATA` file on the |
| ancestor path of the failing test file). |
| |
| After updating the `luci-analysis.cfg` file make sure you run `lucicfg main.star` to |
| refresh the copy of this file in the `generated/` folder. |
| |
| ## Autorollers |
| |
| ### Rolling DevTools to Chromium |
| |
| A [Skia autoroller](https://skia.googlesource.com/buildbot/+/main/autoroll/README.md) |
| is responsible for rolling DevTools to Chromium. Follow the links to inspect the |
| [status](https://autoroll.skia.org/r/devtools-frontend-chromium?tab=status) of |
| the roller. |
| |
| To update the configuration you will need to clone the skia [repo](sso://skia/skia-autoroll-internal-config) |
| and modify the `skia-infra-public/devtools-frontend-chromium.cfg` file ([example](https://review.skia.org/1014616)). |
| |
| ### Rolling dependencies to DevTools |
| |
| To roll all DevTool's dependencies we rely on the [Roll deps and chromium pin |
| into devtools-frontend](https://ci.chromium.org/ui/p/devtools-frontend/builders/ci-hp/Roll%20deps%20and%20chromium%20pin%20into%20devtools-frontend) |
| builder that runs on the [infra](https://ci.chromium.org/ui/p/devtools-frontend/g/infra/builders) |
| console. |
| |
| The builder is scheduled to run every day at 05 and 14 hours. In the [recipe](https://source.chromium.org/chromium/infra/infra_superproject/+/main:build/recipes/recipes/devtools/auto_roll_incoming.py?q=file:recipes%2Fdevtools%2Fauto_roll_incoming.py) |
| that runs on this builder you can configure dependencies that you need excluded |
| from the rolls and reviewer emails. The recipe uses the V8's autorolling rolling |
| [module](https://source.chromium.org/chromium/infra/infra_superproject/+/main:build/recipes/recipe_modules/v8_auto_roller/api.py), |
| that offers support for trusted and untrusted dependencies ([regular](https://source.chromium.org/chromium/infra/infra_superproject/+/main:build/recipes/recipe_modules/v8_auto_roller/deps_handlers.py)), [CfT](https://source.chromium.org/chromium/infra/infra_superproject/+/main:build/recipes/recipe_modules/v8_auto_roller/chrome_handler.py) pin rolling, and [script based](https://source.chromium.org/chromium/infra/infra_superproject/+/main:build/recipes/recipe_modules/v8_auto_roller/script_handlers.py) special rolls. |