OLD | NEW |
(Empty) | |
| 1 Bootstrapping the Chromium Infra Repo |
| 2 ===================================== |
| 3 |
| 4 The infra/infra repo uses python [wheel files][1], [virtualenv][2] and [pip][3] |
| 5 to manage dependencies. The process for bootstrapping these is contained |
| 6 entirely within the bootstrap directory. |
| 7 |
| 8 1: https://www.python.org/dev/peps/pep-0427/ |
| 9 2: https://github.com/pypa/virtualenv |
| 10 3: https://github.com/pypa/pip |
| 11 |
| 12 |
| 13 TL;DR - Workflows |
| 14 ~~~~~~~~~~~~~~~~~ |
| 15 |
| 16 Setting up the env with already-built-deps |
| 17 ++++++++++++++++++++++++++++++++++++++++++ |
| 18 |
| 19 gclient sync |
| 20 # OR |
| 21 gclient runhooks |
| 22 |
| 23 Adding a new dep |
| 24 ++++++++++++++++ |
| 25 Say we want to add a stock `my_pkg` python package at version 1.2.3: |
| 26 |
| 27 If it comes from a tarball:: |
| 28 |
| 29 $ ./bootstrap/ingest_source.py <tarball> |
| 30 ... |
| 31 deadbeefdeadbeefdeadbeefdeadbeef.tar.gz |
| 32 |
| 33 If it comes from a repo: |
| 34 |
| 35 File a ticket to have it mirrored (no matter what VCS!) |
| 36 to ``chromium.googlesource.com/external/<repo_url>`` |
| 37 |
| 38 Grab the git commit hash of the commit to build: badc0ffeebadc0ffeebadc0ffeebadc
0 |
| 39 |
| 40 Then add the actual dep:: |
| 41 |
| 42 $ edit bootstrap/deps.pyl # add a new entry (see the 'deps.pyl' section) |
| 43 ... |
| 44 'my_pkg' : { |
| 45 'version': '1.2.3', |
| 46 'build': 0, # This is the first build |
| 47 'gs': 'deadbeefdeadbeefdeadbeefdeadbeef.tar.gz', # if tarball |
| 48 'rev': 'badc0ffeebadc0ffeebadc0ffeebadc0', # if repo |
| 49 } |
| 50 ... |
| 51 |
| 52 Then build it:: |
| 53 |
| 54 $ ./bootstrap/build_deps.py |
| 55 # builds and uploads my_pkg-1.2.3-0_deadbeef...-....whl to google storage |
| 56 |
| 57 **If your dep is not pure-python, you will have to run ``build_deps.py`` for |
| 58 each platform.** |
| 59 |
| 60 |
| 61 If your dep needs special treatment |
| 62 +++++++++++++++++++++++++++++++++++ |
| 63 Do everything in the 'Adding a new dep' section, but before running |
| 64 ``build_deps.py``, add a file ``bootstrap/custom_builds/{wheel package name}.py`
`. |
| 65 This file is expected to implement:: |
| 66 |
| 67 def Build(source_path, wheelhouse_path) |
| 68 |
| 69 See `custom builds`_ below for more detail. |
| 70 |
| 71 |
| 72 ``bootstrap.py`` (a.k.a. "I just want a working infra repo!") |
| 73 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 74 |
| 75 Run ``gclient runhooks``. Under the hood, this runs:: |
| 76 |
| 77 ./bootstrap/bootstrap.py --deps_file bootstrap/deps.pyl |
| 78 |
| 79 This creates a virtualenv called ``{repo_root}/ENV`` with all the deps contained |
| 80 in ``bootstrap/deps.pyl``. You must be online, or must already have the wheels |
| 81 for your system cached in ``{repo_root}/.wheelcache``. |
| 82 |
| 83 If you already have an ``ENV``, ``bootstrap.py`` will check the manifest in |
| 84 ``ENV`` to see if it matches `deps.pyl`_ (i.e. the diff is zero). If it's not, |
| 85 then ``ENV`` will be re-created *from scratch*. |
| 86 |
| 87 ``{repo_root}/run.py`` will automatically use the environment ``ENV``. It is an |
| 88 error to use ``run.py`` without first setting up ``ENV``. |
| 89 |
| 90 |
| 91 `deps.pyl` |
| 92 ~~~~~~~~~~ |
| 93 This file is a python dictionary containing the exact versions of all Python |
| 94 module dependencies. These versions are the standard upstream package versions |
| 95 (e.g. '0.8.0'), plus the commit hash or sha1.{ext} of an ingested source bundle |
| 96 (see ``inject_source.py``). |
| 97 |
| 98 The format of this file is ``{'package_name': <values>}``. This file is a Python |
| 99 `ast literal <https://docs.python.org/2/library/ast.html#ast.literal_eval>`_, so |
| 100 comments are allowed and encouraged. |
| 101 |
| 102 Note that the ``package_name`` key is the pip-reported name (the one set in |
| 103 ``setup.py``). It may be different from the name used for import, and for the |
| 104 wheel. |
| 105 |
| 106 Values are: |
| 107 * version: The pip version of the module |
| 108 * build: An integer representing which build of this version/hash. If you |
| 109 modify the _way_ that a requirement is built, but not the source hash, you |
| 110 can bump the build number to get a new pinned dependency. |
| 111 |
| 112 And either: |
| 113 * ``rev``: The revision or sha1 of the source for this module. |
| 114 The repo is |
| 115 ``git+https://chromium.googlesource.com/infra/third_party/{package_name}`` |
| 116 * ``gs``: ``{sha1}.{ext}`` indicates file |
| 117 ``gs://chrome-infra-wheelhouse/sources/{sha1}.{ext}``. The sha1 will be |
| 118 checked against the content of the file. |
| 119 |
| 120 And optionally: |
| 121 * ``implicit``: A boolean indicating that this dep should only be installed as |
| 122 a dependency of some other dep. For example, you want package A, which |
| 123 depends on package Z, but you don't really care about Z. You should mark |
| 124 Z as ``implicit`` to allow it to be pinned correctly, but not to |
| 125 deliberately install it. |
| 126 |
| 127 |
| 128 ``ingest_source.py`` |
| 129 ~~~~~~~~~~~~~~~~~~~~ |
| 130 Some python modules don't have functional python repos (i.e. ones that pip |
| 131 can natively clone+build), and thus ship their source in tarballs. To ingest |
| 132 such a tarball into the infra google storage bucket, use |
| 133 `ingest_source.py /path/to/archive`. |
| 134 This will print the value for the 'gs' key for a `deps.pyl` entry. |
| 135 |
| 136 |
| 137 `build_deps.py` / rolling deps |
| 138 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 139 Any time a new dependency/version is introduced into ``deps.pyl``, you must run |
| 140 ``build_deps.py``. If the dependency is a pure-Python dependency (i.e. no compil
ed |
| 141 extensions), you only need to run it once on CPython 2.7. You can tell that it's |
| 142 a pure python module by looking at the name of the wheel file. For example:: |
| 143 |
| 144 requests-2.3.0-py2.py3-none-any.whl |
| 145 |
| 146 Is compatible with Python 2 and Python 3 (py2.py3) any python ABI (none), and |
| 147 any OS platform (any). |
| 148 |
| 149 If the module does contain compiled extensions, you must run ``build_deps.py`` |
| 150 on the following systems (all with CPython 2.7): |
| 151 * OS X 10.9 - ``x86_64`` |
| 152 * Windows 7 - ``x86_64`` |
| 153 * Linux - ``x86_64`` |
| 154 |
| 155 TODO(iannucci): Add job to build wheels on all appropriate systems. |
| 156 |
| 157 Once a wheel is sucessfully built, it is uploaded to |
| 158 ``gs://chrome-python-wheelhouse/wheels`` if it is not there already. |
| 159 |
| 160 Running ``build_deps.py`` will only attempt to build dependencies which are |
| 161 missing for the current platform. |
| 162 |
| 163 ``build_deps.py`` assumes that it can find ``gsutil`` on ``PATH``, so go ahead |
| 164 and install it appropriately for whichever platform you're on. You will also |
| 165 need write access to the ``chrome-python-wheelhouse`` bucket. |
| 166 |
| 167 |
| 168 custom builds |
| 169 ~~~~~~~~~~~~~ |
| 170 Sometimes building a wheel is a bit trickier than ``pip wheel {repo}@{hash}``. I
n |
| 171 order to support this, add a script named ``custom_builds/{name}.py``. This modu
le |
| 172 should have a function defined like:: |
| 173 |
| 174 def Build(source_path, wheelhouse_path) |
| 175 |
| 176 Where ``source_path`` is a string path to the checked-out / unpacked source code
, |
| 177 and ``wheelhouse_path`` is a string path where ``build_deps.py`` expects to find |
| 178 a ``.whl`` file after Build completes. |
| 179 |
| 180 Note that your Build function will actually need to invoke pip manually. |
| 181 Currently you can get the path for pip by doing: ``os.path.join(sys.prefix, |
| 182 'bin', 'pip')``, and you can invoke it with subprocess (see |
| 183 https://code.google.com/p/chromium/codesearch#chromium/infra/bootstrap/custom... |
| 184 as an example). |
| 185 |
| 186 |
| 187 rolling the version of wheel |
| 188 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 189 Since wheel is a package needed to build the wheels, it has a slightly different |
| 190 treatment. To roll wheel, bump the version in deps.pyl, and then run |
| 191 ``bootstrap_wheel_wheel.sh`` |
| 192 to build and upload the wheel for ``wheel`` pinned at the version in ``deps.pyl`
`. |
| 193 |
| 194 Once you do that, ``build_deps.py`` will continue working as expected. |
| 195 |
| 196 |
| 197 Building deps on Windows |
| 198 ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 199 TODO(iannucci): actually implement this |
| 200 |
| 201 Windows builds require a slightly more care when building, due to the |
| 202 complexities of getting a compile environment. To this effect, ``build_deps.py`` |
| 203 relies on the ``depot_tools/win_toolchain`` functionality to get a hermetic |
| 204 windows compiler toolchain. This should not be an issue for chromium devs |
| 205 working on windows, since they should already have this installed by compiling |
| 206 chromium, but it's something to be aware of. |
| 207 |
| 208 |
| 209 modified (non-upstream) deps |
| 210 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 211 If it is necessary to roll a patched version of a library, we should branch it |
| 212 in the infra googlesource mirror. This branch should be named ``{version}-cr``, |
| 213 and will build packages whose version is ``{version}.{cr_version}`` (e.g. modify |
| 214 ``setup.py`` on this branch to add an additional component to the version |
| 215 field). |
| 216 |
| 217 For example, given the package ``jane`` at version ``2.1.3``, we would create |
| 218 a branch ``2.1.3-cr``. On this branch we would commit any changes necessary to |
| 219 ``2.1.3``, and would adjust the version number in the builds to be e.g. |
| 220 ``2.1.3.0``. |
| 221 |
| 222 |
OLD | NEW |