blob: fdb673a8ce4599fda2c0cfb9b40ea60829955061 [file] [log] [blame] [view]
Lukasz Anforowiczceddb032024-02-21 16:39:231# Updating Rust crates used by Chromium
2
3This document describes how Chromium updates crates.io Rust crates that Chromium
4depends on.
5
Lukasz Anforowicz121edc92024-03-20 18:24:336We have a weekly rotation (go/chromium-crates-update-rotation) of engineers
7responsible for creating and landing CLs that update Rust crates.
8
9## Initial setup
10
11The "Rust: periodic update of 3rd-party crates" rotation requires access to an
12up-to-date Chromium repo. One way to start a shift is to run `git fetch`,
13`git checkout origin/main`, and `gclient sync` (but other workflows should also
14work - e.g. ones based on `git-new-workdir`).
15
16## Automated step: `create_update_cl.py`
17
Lukasz Anforowicz561878d2024-03-22 18:30:1218The first actual step of the rotation is running the script:
Lukasz Anforowiczceddb032024-02-21 16:39:2319
Lukasz Anforowicz561878d2024-03-22 18:30:1220```
21$ tools/crates/create_update_cl.py auto
22```
23
Lukasz Anforowicz52258d12024-03-05 20:23:3624`create_update_cl.py` has to be invoked from within a Chromium repo.
Lukasz Anforowiczceddb032024-02-21 16:39:2325The script depends on `depot_tools` and `git` being present in the `PATH`.
Lukasz Anforowicz561878d2024-03-22 18:30:1226
27In `auto` mode `//tools/crates/create_update_cl.py` runs `gnrt update` to
28discover all possible minor version updates and then for each update creates a
29new local git branch (and a Gerrit CL unless invoked with `--no-upload`).
30Each branch contains an update created by `gnrt update <old crate id>`, `gnrt
31vendor`, and `gnrt gen`.
Lukasz Anforowicz121edc92024-03-20 18:24:3332Depending on how many crates are updated, the script may need 10-15 minutes to
33run.
Lukasz Anforowiczceddb032024-02-21 16:39:2334
Lukasz Anforowicz561878d2024-03-22 18:30:1235(Side-note: outside the rotation one may also use the script to update a single
36crate - e.g. `tools/crates/create_update_cl.py single <crate name>`.)
37
Lukasz Anforowicz52258d12024-03-05 20:23:3638Before the auto-generated CLs can be landed, some additional manual steps need
Lukasz Anforowicz121edc92024-03-20 18:24:3339to be done first - see the sections below.
Lukasz Anforowiczceddb032024-02-21 16:39:2340
Lukasz Anforowicz121edc92024-03-20 18:24:3341## Manual step: `run_cargo_vet.py`
Lukasz Anforowiczceddb032024-02-21 16:39:2342
43The changes in the auto-generated CL need to go through a security audit, which
44will ensure that `cargo vet` criteria (e.g. `ub-risk-0`, `safe-to-deploy`,
Lukasz Anforowicz52258d12024-03-05 20:23:3645etc.). still hold for the new versions. The CL description specifies which
Lukasz Anforowicz121edc92024-03-20 18:24:3346criteria apply to the updated crates.
47See the `//docs/rust-unsafe.md` doc for details on how to audit and certify
48the new crate versions (this may require looping in `unsafe` Rust experts
49and/or cryptography experts).
Lukasz Anforowiczceddb032024-02-21 16:39:2350
Lukasz Anforowicz121edc92024-03-20 18:24:3351For each update CL, there is a separate git branch created. An audit will most
52likely need to be recorded in
53`third_party/rust/chromium_crates_io/supply-chain/audits.toml` and committed to
54the git branch for each update CL. There are some known corner cases where
55`audits.toml` changes are not needed:
Lukasz Anforowiczceddb032024-02-21 16:39:2356
Lukasz Anforowicz121edc92024-03-20 18:24:3357* Updates of crates listed in `remove_crates` in
58 `third_party/rust/chromium_crates_io/gnrt_config.toml` (e.g. the `cc` crate
59 which is a dependency of `cxx` but is not actually used/needed in Chromium).
60 This case should be recognized by the `create_update_cl.py` script and noted
61 in the CL description.
62* Updates of grand-parented-in crates that are covered by exemptions in
63 `third_party/rust/chromium_crates_io/supply-chain/config.toml` instead of
64 being covered by real audits from `audits.toml`. For such crates, skim the
65 delta and use your best judgement on whether to bump the crate version that
66 the exemption applies to. Note that `supply-chain/config.toml` is generated
67 by `gnrt vendor` and should not be edited directly - please instead edit
68 `third_party/rust/chromium_crates_io/vet_config.toml.hbs` and then run
69 `tools/crates/run_gnrt.py vendor` to regenerate `supply-chain/config.toml`.
70* Update to a crate version that is already covered by `audits.toml` of other
71 projects that Chromium's `run_cargo_vet.py` imports. In such case (but only
72 once https://crrev.com/c/5368743 lands) you may
73 need to commit changes that `cargo vet` generates in
74 `third_party/rust/chromium_crates_io/supply-chain/imports.lock`.
Lukasz Anforowiczceddb032024-02-21 16:39:2375
Lukasz Anforowicz121edc92024-03-20 18:24:3376This step may require one or more of the commands below, for each git branch
77associated with an update CL (starting with the earliest branches - ones
78closest to `origin/main`):
Lukasz Anforowiczceddb032024-02-21 16:39:2379
Lukasz Anforowicz121edc92024-03-20 18:24:33801. `git checkout rust-crates-update--...`
81 - If this is the second or subsequent branch, then also run `git rebase` to
82 rebase it on top of the manual `audits.toml` changes in the upstream
83 branches
841. Check which crate (or crates) and which audit criteria need to be reviewed in
85 this branch / CL: `tools/crates/run_cargo_vet.py check`
86 - Note that `run_cargo_vet.py check` may list a _subset_ of the criteria
87 that the automated script has listed in the CL description (e.g. if some
88 of the criteria are already covered by `audits.toml` imported from other
89 projects).
Lukasz Anforowicz121edc92024-03-20 18:24:33901. Follow the cargo vet instructions to inspect diffs and certify the results
911. `git add third_party/rust/chromium_crates_io/supply-chain`.
92 `git commit -m 'cargo vet'`
Lukasz Anforowiczceddb032024-02-21 16:39:23931. `git cl upload -m 'cargo vet'`
94
Lukasz Anforowicz121edc92024-03-20 18:24:3395## Potential additional steps
Lukasz Anforowiczceddb032024-02-21 16:39:2396
97* If updating `cxx`, you may need to also update its version in:
98 - `build/rust/BUILD.gn`
99 - `third_party/rust/cxx/v1/cxx.h`
100
Lukasz Anforowicz121edc92024-03-20 18:24:33101* The `create_update_cl.py` script may stop early if it detects that `gnrt
102 vendor` or `gnrt gen` have reported any warnings or errors (e.g. a "License
103 file not found for crate foo" warning). In this case, manual intervention is
104 needed to finish the update CL. It's probably best to finish and land the CLs
105 created so far before trying to restart the script in order to create the
106 remaining CLs.
Lukasz Anforowicz52258d12024-03-05 20:23:36107
Lukasz Anforowicz121edc92024-03-20 18:24:33108## Landing the CL
Lukasz Anforowiczceddb032024-02-21 16:39:23109
110Other than the above, the CL can go through the normal, plain-vanilla, manual
111review and landing process.
112
1131. `git cl upload`
1141. Get a review from one of `//third_party/rust/OWNERS`
1151. Land the CL using CQ+2
Lukasz Anforowicz67783682024-03-22 16:24:49116
117## Checking for new major versions
118
119Note that `create_update_cl.py` will only handle minor version changes (e.g.
120123.1 => 123.2, or 0.123.1 => 0.123.2). Major version changes (e.g. 1.0 => 2.0,
121which may include breaking API changes and other breaking changes) need to be
122handled separately.
123
124As part of the rotation, one should attempt to check for new major versions of
125direct Chromium dependencies (i.e. dependencies directly listed in
126`third_party/rust/chromium_crates_io/Cargo.toml`). To discover direct _and_
127transitive dependencies with a new major version, you can use the command below
128(running it in the final update CL branch - after all the minor version
129updates):
130
131```
132$ tools/crates/run_cargo.py -Zunstable-options -C third_party/rust/chromium_crates_io -Zbindeps update --dry-run --verbose
133...
134 Unchanged serde_json_lenient v0.1.8 (latest: v0.2.0)
135 Unchanged syn v1.0.109 (latest: v2.0.53)
136...
137```
138
139### Workflow A: Single update CL
140
141If the updating to a new major version doesn't require lots of Chromium changes,
142then it may be possible to land the update in a single CL. This is typically
143possible when the APIs affected by the major version's breaking change either
144weren't used by Chromium, or were used only in a handful of places.
145
146**Warning**: Sometimes a new major version may be API compatible, but may
147introduce breaking changes in the _behavior_ of the existing APIs.
148
149To update:
150
1511. Edit `third_party/rust/chromium_crates_io/Cargo.toml` to change the version
152 being depended upon.
1531. Follow other steps described in
154 [`docs/rust.md`](../../docs/rust.md#importing-a-crate-from-crates_io) for
155 importing a new crate (e.g. `gnrt vendor`, `gnrt gen`, etc.)
156 - TODO(https://crbug.com/330729319): Try to automate some parts of this step
1571. Remove the old version's leftover files in `//third_party/rust/<crate>/<old
158 epoch>`
159
160### Workflow B: Incremental transition
161
162When lots of first-party code depends on the old major version, then the
163transition to the new major version may need to be done incrementally. In this
164case the transition can be split into the following steps:
165
1661. Open a new bug to track the transition
167 - TODO: Figure out how to tag/format the bug to make it easy to discover
168 in future rotations
1691. Land the new major version, so that the old and the new versions coexist.
170 To do this follow the process for importing a new crate as described in
171 [`docs/rust.md`](../../docs/rust.md#importing-a-crate-from-crates_io)
172 (i.e. edit `Cargo.toml` to add the new version, run `gnrt vendor`, and so
173 forth).
1741. Incrementally transition first-party code to the new major version
1751. Remove the old major version. To do this follow a similar process as above
176 (i.e. edit `Cargo.toml` to remove the old version, run `gnrt vendor`, and so
177 forth). Any leftover files in `//third_party/rust/<crate>/<old epoch>`
178 should also be removed.
179
180Note that the following `Cargo.toml` syntax allows two versions of a crate to
181coexist:
182
183```
184[dependencies.serde_json_lenient_old_epoch]
185package = "serde_json_lenient"
186version = "0.1"
187
188[dependencies.serde_json_lenient]
189version = "0.2"
190```