|
| 1 | +# Managing Python dependencies |
| 2 | + |
| 3 | +1. All pip dependency files stored in `.config` |
| 4 | +2. All dependency file names must match this `requirements.(txt|in)`. Needed for dependabot compatibility. |
| 5 | + |
| 6 | +### Recommended filenames: |
| 7 | + |
| 8 | +- `.config/requirements.in` - runtime deps |
| 9 | +- `.config/requirements-test.in` - test requirements |
| 10 | +- `.config/requirements-docs.in` - docs requirements |
| 11 | +- `.config/requirements-lock.txt` - locked (pinned) runtime requirements for projects having `lock` extra. |
| 12 | +- `.config/constraints.txt` - unified testing constraint file to use as `PIP_CONSTRAINTS`. Is named like this for Dependabot compatibility. It also pins all extras. |
| 13 | + |
| 14 | +### Upgrading dependencies |
| 15 | + |
| 16 | +To upgrade dependencies, it's recommended to use `pip-tools` as part of the `pre-commit` hook and invoke manually via a tox profile named `deps`. |
| 17 | + |
| 18 | +Example `.pre-commit-config.yaml` |
| 19 | + |
| 20 | +``` |
| 21 | +- repo: https://github.com/jazzband/pip-tools |
| 22 | + rev: 7.3.0 |
| 23 | + hooks: |
| 24 | + - id: pip-compile |
| 25 | + name: deps |
| 26 | + alias: deps |
| 27 | + stages: [manual] |
| 28 | + entry: pip-compile .config/requirements.in --upgrade --all-extras --no-annotate --strip-extras --output-file=.config/constraints.txt pyproject.toml |
| 29 | + files: ^.config\/.*requirements.*$ |
| 30 | + language_version: "3.10" # minimal we support officially |
| 31 | +``` |
| 32 | + |
| 33 | +Example `tox.ini` |
| 34 | + |
| 35 | +``` |
| 36 | +[testenv:deps] |
| 37 | +description = Bump all dependencies |
| 38 | +base_python = python3.10 |
| 39 | +skip_install = true |
| 40 | +deps = |
| 41 | + {[testenv:lint]deps} |
| 42 | +extras = |
| 43 | +set_env = |
| 44 | + PIP_CONSTRAINT = /dev/null |
| 45 | +commands_pre = |
| 46 | +commands = |
| 47 | + -pre-commit run --all-files --show-diff-on-failure --hook-stage manual deps |
| 48 | + -pre-commit autoupdate |
| 49 | + git diff --exit-code |
| 50 | +env_dir = {toxworkdir}/lint |
| 51 | +``` |
| 52 | + |
| 53 | +To upgrade dependencies, execute `tox -e deps` in the local project. |
| 54 | + |
| 55 | +### Dependabot Github configuration |
| 56 | + |
| 57 | +To minimise the amount of PRs Dependabot would create, it is recommended to group all dependencies updates together. This can be accomplish with the following config file: |
| 58 | + |
| 59 | +Example `.github/dependabot.yml` |
| 60 | + |
| 61 | +``` |
| 62 | +--- |
| 63 | +version: 2 |
| 64 | +updates: |
| 65 | + - package-ecosystem: pip |
| 66 | + directory: /.config/ |
| 67 | + schedule: |
| 68 | + day: sunday |
| 69 | + interval: weekly |
| 70 | + labels: |
| 71 | + - dependabot-deps-updates |
| 72 | + - skip-changelog |
| 73 | + groups: |
| 74 | + dependencies: |
| 75 | + patterns: |
| 76 | + - "*" |
| 77 | +``` |
| 78 | + |
| 79 | +### Dependabot quirks |
| 80 | + |
| 81 | +As Dependabot has very limited configurability, filenames matter and we can only make it work well if they match. |
| 82 | + |
| 83 | +If you have a pair of `requirements.in` and `requirements.txt` in a folder, dependabot always rewrite the `.txt` file as being the lock for the `.in` file. This means that if we use the txt as a constraint and we also have some extras, the lock file will not be correct. Dependabot will attempt to mess the file. |
| 84 | + |
| 85 | +Dependabot parses requirements files and tries executing the same command specified in the header as a comment. Please take a look at an example header below. |
| 86 | + |
| 87 | +``` |
| 88 | +# |
| 89 | +# This file is autogenerated by pip-compile with Python 3.11 |
| 90 | +# by the following command: |
| 91 | +# |
| 92 | +# pip-compile --no-annotate --output-file=.config/requirements.txt --strip-extras .config/requirements.in pyproject.toml |
| 93 | +# |
| 94 | +``` |
| 95 | + |
| 96 | +The actual `pip-compile` command executed by Dependbadot won't be the same as it parses arguments and only uses known ones, giving possible different results. |
| 97 | +Dependabot does not support `--extra` when running pip-compile based on requirements files. See https://github.com/dependabot/dependabot-core/issues/6406 |
0 commit comments