1# Flutter's Build Infrastructure 2 3This directory exists to support building Flutter on our build infrastructure. 4 5The results of such builds are viewable at: 6* https://cirrus-ci.com/github/flutter/flutter/master 7 - Testing done on PRs and submitted changes on GitHub. 8* https://ci.chromium.org/p/flutter/ 9 - Additional testing and processing done after changes are submitted. 10 11The LUCI infra requires permissions to retrigger or schedule builds. Contact 12@kf6gpe or another Google member of the Flutter team if you need to do that. 13 14The [Cirrus](https://cirrus-ci.org)-based bots run the [`test.dart`](test.dart) 15script for each PR and submission. This does testing for the tools, for the 16framework, and (for submitted changes only) rebuilds and updates the master 17branch API docs [staging site](https://master-docs.flutter.dev/). 18For tagged dev and beta builds, it also builds and deploys the gallery app to 19the app stores. It is configured by the [.cirrus.yml](/.cirrus.yml). 20 21We also have post-commit testing with actual devices, in what we call our 22[devicelab](../devicelab/README.md). 23 24## LUCI (Layered Universal Continuous Integration) 25 26A [set of recipes](https://chromium.googlesource.com/chromium/tools/build.git/+/master/scripts/slave/recipes/flutter) 27are run on Windows, Linux, and Mac machines. The configuration for how many 28machines and what kind are managed internally by Google. Contact @kf6gpe or 29another Google member of the Flutter team if you suspect changes are needed 30there. Both of these technologies are highly specific to the [LUCI](https://github.com/luci) 31project, which is the successor to Chromium's infra. We're just borrowing some 32of their infrastructure. 33 34### Prerequisites 35 36To work on this infrastructure you will need: 37 38- [depot_tools](https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up) 39- Python package installer: `sudo apt-get install python-pip` 40- Python coverage package (only needed for `training_simulation`): `sudo pip install coverage` 41 42To run prepare_package.dart locally: 43 44- Make sure the depot_tools is in your PATH. If you're on Windows, you also need 45 an environment variable called DEPOT_TOOLS with the path to depot_tools as value. 46- Run `gsutil.py config` (or `python %DEPOT_TOOLS%\gsutil.py` on Windows) to 47 authenticate with your auth token. 48- Create a local temp directory. `cd` into it. 49- Run `dart [path to your normal Flutter repo]/dev/bots/prepare_package.dart 50 --temp_dir=. --revision=[revision to package] --branch=[branch to deploy to] 51 --publish`. 52- If you're running into gsutil permission issues, check with @Hixie to make sure 53 you have the right push permissions. 54 55### Getting the code 56 57The following will get way more than just recipe code, but it _will_ get the 58recipe code: 59 60```bash 61mkdir chrome_infra 62cd chrome_infra 63fetch infra 64``` 65 66More detailed instructions can be found [here](https://chromium.googlesource.com/infra/infra/+/master/doc/source.md). 67 68Most of the functionality for recipes comes from `recipe_modules`, which are 69unfortunately spread to many separate repositories. After checking out the code 70search for files named `api.py` or `example.py` under `infra/build`. 71 72### Editing a recipe 73 74Flutter has one recipe per repository. Currently 75[flutter/flutter](https://chromium.googlesource.com/chromium/tools/build.git/+/master/scripts/slave/recipes/flutter/flutter.py) 76and 77[flutter/engine](https://chromium.googlesource.com/chromium/tools/build.git/+/master/scripts/slave/recipes/flutter/engine.py): 78 79- build/scripts/slave/recipes/flutter/flutter.py 80- build/scripts/slave/recipes/flutter/engine.py 81 82Recipes are just Python with some limitations on what can be imported. They are 83[documented](https://github.com/luci/recipes-py/blob/master/doc/user_guide.md) 84by the [luci/recipes-py github project](https://github.com/luci/recipes-py). 85 86The typical cycle for editing a recipe is: 87 881. Make your edits (probably to files in 89 `//chrome_infra/build/scripts/slave/recipes/flutter`). 902. Update the tests. Run `build/scripts/slave/recipes.py test train` to update 91 existing expected output to match the new output. Verify completely new test 92 cases by altering the `GenTests` method of the recipe. The recipe is required 93 to have 100% test coverage. 943. Run `led get-builder 'luci.flutter.prod:BUILDER_NAME' | led edit -p 'revision="GIT_HASH"' | led edit-recipe-bundle | led launch`, where `BUILDER_NAME` is the builder name (e.g. `Linux Engine`), and 95 `GIT_HASH` is the hash to build (which is important for the engine but not 96 for the framework). 974. To submit a CL, you need a local branch first (`git checkout -b [some branch name]`). 985. Upload the patch (`git commit`, `git cl upload`) and send it to someone in 99 the `recipes/flutter/OWNERS` file for review. 100 101### The infra config repository 102 103The [flutter/infra](https://github.com/flutter/infra) repository contains 104configuration files for the dashboard, builder groups, scheduling, and 105individual builders. Edits to this may require changes other internal Google 106repositories - e.g., to change the operating system or number of machines. If 107you want to do that, reach out to @kf6gpe or another member of the Google team. 108 109Each configuration file in that repository has a link in the top comments to a 110schema that describes available properties. 111 112### Future Directions 113 114We would like to host our own recipes instead of storing them in 115[build](https://chromium.googlesource.com/chromium/tools/build.git/+/master/scripts/slave/recipes/flutter). 116Support for [cross-repository 117recipes](https://github.com/luci/recipes-py/blob/master/doc/cross_repo.md) is 118in-progress. If you view the git log of this directory, you'll see we initially 119tried, but it's not quite ready. 120 121 122### Android Tools 123 124The Android SDK and NDK used by Flutter's Chrome infra bots are stored in Google 125Cloud. During the build a bot runs the `download_android_tools.py` script that 126downloads the required version of the Android SDK into `dev/bots/android_tools`. 127 128To check which components are currently installed, download the current SDK 129stored in Google Cloud using the `download_android_tools.py` script, then 130`dev/bots/android_tools/sdk/tools/bin/sdkmanager --list`. If you find that some 131components need to be updated or installed, follow the steps below: 132 133#### How to update Android SDK on Google Cloud Storage 134 1351. Run Android SDK Manager and update packages 136 `$ dev/bots/android_tools/sdk/tools/android update sdk` 137 Use `android.bat` on Windows. 138 1392. Use the UI to choose the packages you want to install and/or update. 140 1413. Run `dev/bots/android_tools/sdk/tools/bin/sdkmanager --update`. On Windows, 142 run `sdkmanager.bat` instead. If the process fails with an error saying that 143 it is unable to move files (Windows makes files and directories read-only 144 when another process is holding them open), make a copy of the 145 `dev/bots/android_tools/sdk/tools` directory, run the `sdkmanager.bat` from 146 the copy, and use the `--sdk_root` option pointing at 147 `dev/bots/android_tools/sdk`. 148 1494. Run `dev/bots/android_tools/sdk/tools/bin/sdkmanager --licenses` and accept 150 the licenses for the newly installed components. It also helps to run this 151 command a second time and make sure that it prints "All SDK package licenses 152 accepted". 153 1545. Run upload_android_tools.py -t sdk 155 `$ dev/bots/upload_android_tools.py -t sdk` 156 157#### How to update Android NDK on Google Cloud Storage 158 1591. Download a new NDK binary (e.g. android-ndk-r10e-linux-x86_64.bin) 1602. cd dev/bots/android_tools 161 `$ cd dev/bots/android_tools` 162 1633. Remove the old ndk directory 164 `$ rm -rf ndk` 165 1664. Run the new NDK binary file 167 `$ ./android-ndk-r10e-linux-x86_64.bin` 168 1695. Rename the extracted directory to ndk 170 `$ mv android-ndk-r10e ndk` 171 1726. Run upload_android_tools.py -t ndk 173 `$ cd ../..` 174 `$ dev/bots/upload_android_tools.py -t ndk` 175 176 177## Flutter codelabs build test 178 179The Flutter codelabs exercise Material Components in the form of a 180demo application. The code for the codelabs is similar to, but 181distinct from, the code for the Shrine demo app in Flutter Gallery. 182 183The Flutter codelabs build test ensures that the final version of the 184[Material Components for Flutter 185Codelabs](https://github.com/material-components/material-components-flutter-codelabs) 186can be built. This test serves as a smoke test for the Flutter 187framework and should not fail. If it does, please address any issues 188in your PR and rerun the test. If you feel that the test failing is 189not a direct result of changes made in your PR or that breaking this 190test is absolutely necessary, escalate this issue by [submitting an 191issue](https://github.com/material-components/material-components-flutter-codelabs/issues/new?title=%5BURGENT%5D%20Flutter%20Framework%20breaking%20PR) 192to the MDC-Flutter Team. 193 194## Unpublishing published archives 195 196Flutter downloadable archives are built for each release by our continuous 197integration systems using the [`prepare_package.dart`](prepare_package.dart) 198script, but if something goes very wrong, and a release is published that wasn't 199intended to be published, the [`unpublish_package.dart`](unpublish_package.dart) 200script may be used to remove the package or packages from the channels in which 201they were published. 202 203For example To remove a published package corresponding to the git hash 204`d444a455de87a2e40b7f576dc12ffd9ab82fd491`, first do a dry run of the script to 205see what it will do: 206 207``` 208$ dart ./unpublish_package.dart --temp_dir=/tmp/foo --revision d444a455de87a2e40b7f576dc12ffd9ab82fd491 209``` 210 211And once you've verified the output of the dry run to be sure it is what you 212want to do, run: 213 214``` 215$ dart ./unpublish_package.dart --confirm --temp_dir=/tmp/foo --revision d444a455de87a2e40b7f576dc12ffd9ab82fd491 216``` 217 218and it will actually perform the actions. You will of course need to have access 219to the cloud storage server and have gsutil installed in order to perform this 220operation. Only runs on Linux or macOS systems. 221 222See `dart ./unpublish_package.dart --help` for more details. 223 224Once the package is unpublished, it will not be available from the website for 225download, and will not be rebuilt (even though there is a tagged revision in the 226repo still) unless someone forces the packaging build to run again at that 227revision to rebuild the package. 228