[recipe_engine/path] Make use of checkout based Paths a hard error.

This changes config_types.NamedBasePath to raise a ValueError if
anything, anywhere, attempts to 'resolve' (i.e. render to string)
a Path using a 'checkout' dynamic path.

All downstream repos tracked by the try builders on the recipes-py
repo ( and which have autorollers set up) should already be
compatible with this change.

Practically, this is a tests-only impact - attempts to use checkout
based Paths in production flows would end up with nonsense paths
such as "None/path/to/thing".

If any other recipe repos are impacted by this, the options for
remedy are as follows:

  1. (Preferred) Stop using checkout based paths - they are
     effectively a magical global variable and are more trouble than
     they are worth. Instead, just construct, and pass around, Path
     objects (which are always absolute paths). However, this
     suggestion is not always practical for established codebases,
     which leads to the second remedy.

  2. If dropping use of checkout based paths is too hard in the
     short term (which is likely), you can add something like the
     following to the top of your test recipe's RunSteps method:

        api.path['checkout'] = api.path['start_dir']

     This will cause all uses of e.g. `api.path['checkout']` to
     resolve to `api.path['start_dir']`, and you will no longer see
     ValueErrors (or invalid paths starting with 'None').

Reland: The original CL landed and exposed a bug in the build repo
where checkout-based paths were, in fact, being used in production
without assigning to api.path['checkout'] first. They were un-caught
because they were were added to the $PATH environment variable,
meaning that they were effectively no-ops because they rendered to
"None/something/something", and only became a visible error once
this CL landed. We're adding tests and fixing the build code prior
to relanding this CL.

R=bpastene, bryner, sshrimp, gbeaty

Bug: 329113288
Change-Id: Iff86f758317c2816522a4ef6c82e093b94377600
Reviewed-on: https://chromium-review.googlesource.com/c/infra/luci/recipes-py/+/5388750
Reviewed-by: Brian Ryner <bryner@google.com>
Commit-Queue: Robbie Iannucci <iannucci@chromium.org>
3 files changed
tree: a823e4a73fae8b739ddd6593ec9bb3c308b79894
  1. doc/
  2. infra/
  3. misc/
  4. recipe_engine/
  5. recipe_modules/
  6. recipe_proto/
  7. recipes/
  8. unittests/
  9. .editorconfig
  10. .gitattributes
  11. .gitignore
  12. .pycharm.vpython3
  13. .style.yapf
  14. .vpython3
  15. .vscode.vpython3
  17. codereview.settings
  20. OWNERS
  21. PRESUBMIT.py
  22. pyproject.toml
  23. README.md
  24. README.recipes.md
  25. recipe.warnings
  26. recipes.py


Recipes are a domain-specific language (embedded in Python) for specifying sequences of subprocess calls in a cross-platform and testable way.

They allow writing build flows which integrate with the rest of LUCI.

Documentation for the recipe engine (including this file!). Take a look at the user guide for some hints on how to get started. See the implementation details doc for more detailed implementation information about the recipe engine.


  • Sign the Google CLA.
  • Make sure your user.email and user.name are configured in git config.

Run the following to setup the code review tool and create your first review:

# Get `depot_tools` in $PATH if you don't have it
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $HOME/src/depot_tools
export PATH="$PATH:$HOME/src/depot_tools"

# Check out the recipe engine repo
git clone https://chromium.googlesource.com/infra/luci/recipes-py $HOME/src/recipes-py

# make your change
cd $HOME/src/recipes-py
git new-branch cool_feature
# hack hack
git commit -a -m "This is awesome"

# This will ask for your Google Account credentials.
git cl upload -s -r joe@example.com
# Wait for approval over email.
# Click "Submit to CQ" button or ask reviewer to do it for you.
# Wait for the change to be tested and landed automatically.

Use git cl help and git cl help <cmd> for more details.