Skip to content

Commit 982234b

Browse files
kdestinscbedd
andauthored
[engsys] Migrate to tox4 (Azure#30159)
* Remove references to {envbindir} tox prepends the {env_bin_dir} to $PATH, so commands will default to using the virtual environment first. See: https://tox.wiki/en/4.4.11/config.html#commands One of tox's core maintainers also discourages its use: tox-dev/tox#2909 (comment) * refactor: Write paths relative to git root, instead of package dir Uses an inline plugin (toxfile.py) to make a computed config value avaiable to tox environments. * refactor: Rename {toxinidir} to {tox_root} {toxinidir} is an alias for {tox_root}, but {tox_root} is: * More clear: {tox_root} isn't necessarily where the ini file is * Shorter * refactor: Flatten some commands that are no longer super long * refactor: Make a pytest section * refactor: Remove `changedir = {tox_root}` This is the default behavior, see: https://tox.wiki/en/4.4.11/config.html#change_dir-external * fix: {distdir} is deprecated See: https://tox.wiki/en/latest/upgrading.html#removed-tox-ini-keys * fix: Remove --ignore-installed from pip command --ignore-installed can break a python installation if multiple conflicting versions of a package are installed * refactor: Add descriptions to all tox environments * fix: Remove ineffective platform config platform = linux: linux macos: darwin windows: win32 Setting the above in the base environment has no effect: * None of the environments have {linux,macos,windows} in the name, so the platform config is always empty. * chore: Bump `tox` to `>4.4.11` and no longer install `tox-monorepo` tox4 natively solves what `tox-monorepo` was written to solve: `--root` lets you set `toxinidir` independently of the config file in use. 4.4.11 was chosen as the cutoff since it was the first release to include a fix to `--root` that prevented `{work_dir}` from being changed when `{toxinidir}` was changed by `--root`. `tox-monorepo` should no longer be needed * docs: Update CONTRIBUTING.md to use tox 4 commands * References to tox-monorepo were removed * Replaced discussion of `tox -l` with tox4's `tox list` * Updated examples to use `--root` * docs: Make `azure-media-{videoanalyzer,analytics}-edge`'s DevTips.md point to CONTRIBUTING.md for tox * docs: Remove remaining references to tox-monorepo * doc: Use `--root` throughout documentation * engsys: Make tox_harness set `{toxinidir}` when invoking tox * engsys: Set required tox version in config * docs: Use the new url for tox docs * docs: Add a callout that TOX_* environment variables control defaults * TOX_CONFIG_DIR can be used to permanently set --conf * TOX_ROOT_DIR can be used to permanently set --root * update packaging requirement everywhere it is used. * fix cspell * docs: Use `tox run` syntax throughout documentation * engsys: Use `tox run` syntax in tox_harness.py * docs: Replace – (U+2013 : EN DASH) with - (ASCII code 45) * update pytest requirements + coverage. * update virtualenv * more conflicts resolved * bringing in urllib3 restriction, aligning ci_tools.txt with test_tools.txt * check_call requires a list of type string. if we append ['blah', 'blah'] we are actually inserting another array. just use regular array concatenation * engsys: Tox uses `run` for serial execution and `run-parallel` for parallel` * azure-core: Use `@pytest_asyncio.fixture` to mark an asyncio fixture See https://pytest-asyncio.readthedocs.io/en/latest/concepts.html#strict-mode * pin coverage to newer version with no conflicts * identify issue with missing code coverage being caused by wrongly named namespace (Azure#30344) * remove fix of dotfile! * apply black formatting to resolve failing analyze step * tox installing tox. probably not a good thing :) * engsys: Remove `tox` from `azure-media-analytics-edge` dev_requirements * align regression version of ci/test_tools.txt * new coverage format requires that the package sources be present when combining .coverage files. amend our tox tree cleanup to exclude the whl directory when running coverage. * ensure that missing hidden folder can't break cleanup operation * ensure coverage isn't generated on whl_no_aio * ensure that coverage is generated without wonky package paths --------- Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>
1 parent 62bbb9f commit 982234b

File tree

31 files changed

+343
-339
lines changed

31 files changed

+343
-339
lines changed

.vscode/cspell.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,12 @@
416416
"pytestmarkparametrize"
417417
]
418418
},
419+
{
420+
"filename": "doc/dev/pylint_checking.md",
421+
"words": [
422+
"pylintrc"
423+
]
424+
},
419425
{
420426
"filename": "tools/azure-sdk-tools/devtools_testutils/proxy_startup.py",
421427
"words": [

CONTRIBUTING.md

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ If you want to contribute to a file that is generated (header contains `Code gen
1111

1212
The Azure SDK team's Python CI leverages the tool `tox` to distribute tests to virtual environments, handle test dependency installation, and coordinate tooling reporting during PR/CI builds. This means that a dev working locally can reproduce _exactly_ what the build machine is doing.
1313

14-
[A Brief Overview of Tox](https://tox.readthedocs.io/en/latest/)
14+
[A Brief Overview of Tox](https://tox.wiki/en/latest/)
1515

1616
#### A Monorepo and Tox in Harmony
1717

1818
Traditionally, the `tox.ini` file for a package sits _alongside the setup.py_ in source code. The `azure-sdk-for-python` necessarily does not adhere to this policy. There are over one-hundred packages contained here-in. That's a lot of `tox.ini` files to maintain!
1919

20-
Instead, the CI system leverages an tox plugin called `tox-monorepo`. This plugin allows `tox` to act as if the `tox.ini` is located in whatever directory you executed tox in!
20+
Instead, the CI system leverages the `--root` argument which is new to `tox4`. The `--root` argument allows `tox` to act as if the `tox.ini` is located in whatever directory you specify!
2121

2222
#### Tox Environments
2323

@@ -32,40 +32,62 @@ Internally `tox` leverages `virtualenv` to create each test environment's virtua
3232

3333
This means that once the `tox` workflow is in place, all tests will be executed _within a virtual environment._
3434

35-
To see the default environments from a specific `tox.ini` file, use the command `tox -l` in the same directory as the file itself.
36-
37-
> sdk-for-python/eng/tox> tox -l
38-
39-
```
40-
41-
whl
42-
sdist
43-
35+
You can use the command `tox list` to list all the environments provided by a `tox.ini` file. You can either use that command in the
36+
same directory as the file itself, or use the `--conf` argument to specify the path to it directly.
37+
38+
39+
Sample output of `tox list`:
40+
41+
```
42+
sdk-for-python/eng/tox> tox list
43+
default environments:
44+
whl -> Builds a wheel and runs tests
45+
sdist -> Builds a source distribution and runs tests
46+
47+
additional environments:
48+
pylint -> Lints a package with a pinned version of pylint
49+
next-pylint -> Lints a package with pylint (version 2.15.8)
50+
mypy -> Typechecks a package with mypy (version 1.0.0)
51+
next-mypy -> Typechecks a package with the latest version of mypy
52+
pyright -> Typechecks a package with pyright (version 1.1.287)
53+
next-pyright -> Typechecks a package with the latest version of static type-checker pyright
54+
verifytypes -> Verifies the "type completeness" of a package with pyright
55+
whl_no_aio -> Builds a wheel without aio and runs tests
56+
develop -> Tests a package
57+
sphinx -> Builds a package's documentation with sphinx
58+
depends -> Ensures all modules in a target package can be successfully imported
59+
verifywhl -> Verify directories included in whl and contents in manifest file
60+
verifysdist -> Verify directories included in sdist and contents in manifest file. Also ensures that py.typed configuration is correct within the setup.py
61+
devtest -> Tests a package against dependencies installed from a dev index
62+
latestdependency -> Tests a package against the released, upper-bound versions of its azure dependencies
63+
mindependency -> Tests a package against the released, lower-bound versions of its azure dependencies
64+
apistub -> Generate an api stub of a package ( for https://apiview.dev )
65+
bandit -> Runs bandit, a tool to find common security issues, against a package
66+
samples -> Runs a package's samples
67+
breaking -> Runs the breaking changes checker against a package
4468
```
4569

46-
Unfortunately, the command `tox -l` only returns the _default_ test builds. The common `tox.ini` file also supports `pylint` and `mypy` environments.
47-
4870
### Example Usage of the common Azure SDK For Python `tox.ini`
4971

5072
Basic usage of `tox` within this monorepo is:
5173

52-
1. `pip install tox<4 tox-monorepo`
53-
2. `cd` to target package folder
54-
3. run `tox -c path/to/tox.ini`
74+
1. `pip install tox<5`
75+
2. Run `tox run -e ENV_NAME -c path/to/tox.ini --root path/to/python_package`
76+
* **Note**: You can use environment variables to provide defaults for tox config values
77+
* With `TOX_CONFIG_FILE` set to the absolute path of `tox.ini`, you can avoid needing `-c path/to/tox.ini` in your tox invocations
78+
* With `TOX_ROOT_DIR` set to the absolute path to your python package, you can avoid needing `--root path/to/python_package`
5579

5680
The common `tox.ini` location is `eng/tox/tox.ini` within the repository.
5781

5882
If at any time you want to blow away the tox created virtual environments and start over, simply append `-r` to any tox invocation!
5983

6084
#### Example `azure-core` mypy
6185

62-
1. `cd` to `sdk/core/azure-core`
63-
2. Run `tox -e mypy -c ../../../eng/tox/tox.ini`
86+
1. Run `tox run -e mypy -c ../../../eng/tox/tox.ini --root sdk/core/azure-core`
6487

6588
#### Example `azure-storage-blob` tests
6689

67-
1. `cd` to `sdk/storage/azure-storage-blob`
68-
2. Execute `tox -c ../../../eng/tox/tox.ini`
90+
2. Execute `tox run -c ../../../eng/tox/tox.ini --root sdk/storage/azure-storage-blob`
6991

7092
Note that we didn't provide an `environment` argument for this example. Reason here is that the _default_ environment selected by our common `tox.ini` file is one that runs `pytest`.
7193

@@ -75,7 +97,7 @@ Used for test execution across the spectrum of all the platforms we want to supp
7597
* Installs the wheel, runs tests using the wheel
7698

7799
```
78-
\> tox -e whl -c <path to tox.ini>
100+
\> tox run -e whl -c <path to tox.ini> --root <path to python package>
79101
80102
```
81103

@@ -87,30 +109,30 @@ Used for the local dev loop.
87109

88110
```
89111
90-
\> tox -e sdist -c <path to tox.ini>
112+
\> tox run -e sdist -c <path to tox.ini> --root <path to python package>
91113
92114
```
93115

94116
#### `pylint` environment
95117
Pylint install and run.
96118

97119
```
98-
\> tox -e pylint -c <path to tox.ini>
120+
\> tox run -e pylint -c <path to tox.ini> --root <path to python package>
99121
```
100122

101123

102124
#### `mypy` environment
103125
Mypy install and run.
104126

105127
```
106-
\> tox -e mypy -c <path to tox.ini>
128+
\> tox run -e mypy -c <path to tox.ini> --root <path to python package>
107129
```
108130

109131
#### `sphinx` environment
110132
Generate sphinx doc for this package.
111133

112134
```
113-
\> tox -e sphinx -c <path to tox.ini>
135+
\> tox run -e sphinx -c <path to tox.ini> --root <path to python package>
114136
```
115137

116138
### Custom Pytest Arguments
@@ -120,7 +142,7 @@ Generate sphinx doc for this package.
120142
[Tox Documentation on Positional Arguments](https://tox.wiki/en/latest/config.html#substitutions-for-positional-arguments-in-commands)
121143

122144
**Example: Invoke tox, breaking into the debugger on failure**
123-
`tox -e whl -c ../../../eng/tox/tox.ini -- --pdb`
145+
`tox run -e whl -c <path to tox.ini> --root <path to python package> -- --pdb`
124146

125147
### Performance Testing
126148

@@ -150,7 +172,7 @@ a. cd to package root folder
150172
b. run tox environment devtest
151173

152174
```
153-
\> tox -e devtest -c <path to tox.ini>
175+
\> tox run -e devtest -c <path to tox.ini> --root <path to python package>
154176
```
155177

156178
This tox test( devtest) will fail if installed dependent packages are not dev build version.

doc/dev/dev_setup.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ or execute the various commands available in the toolbox.
3333
3434
4. Setup your development environment
3535
36-
Install the development requirements for a specific library (located in the `dev_requirements.txt` file at the root of the library), [Tox][tox], [Tox monorepo][tox_monorepo] and an editable install of your library. For example, to install requirements for `azure-ai-formrecognizer`:
36+
Install the development requirements for a specific library (located in the `dev_requirements.txt` file at the root of the library), [Tox][tox] and an editable install of your library. For example, to install requirements for `azure-ai-formrecognizer`:
3737
```
3838
azure-sdk-for-python> cd sdk/formrecognizer/azure-ai-formrecognizer
3939
azure-sdk-for-python/sdk/formrecognizer/azure-ai-formrecognizer> pip install -r dev_requirements.txt
40-
azure-sdk-for-python/sdk/formrecognizer/azure-ai-formrecognizer> pip install tox tox-monorepo
40+
azure-sdk-for-python/sdk/formrecognizer/azure-ai-formrecognizer> pip install tox<5
4141
azure-sdk-for-python/sdk/formrecognizer/azure-ai-formrecognizer> pip install -e .
4242
```
4343
@@ -58,6 +58,5 @@ Follow the instructions in the [Perform one-time test proxy setup][proxy_setup]
5858
[python_39]: https://www.microsoft.com/p/python-39/9p7qfqmjrfp7
5959
[proxy_setup]: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/tests.md#perform-one-time-test-proxy-setup
6060
[tests]: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/tests.md
61-
[tox]: https://tox.readthedocs.io/en/latest/
62-
[tox_monorepo]: https://pypi.org/project/tox-monorepo/
61+
[tox]: https://tox.wiki/en/latest/
6362
[virtual_environment]: https://docs.python.org/3/tutorial/venv.html

doc/dev/pylint_checking.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ In the Azure SDK for Python repository, in addition to the standard pylint libra
2424

2525
One way to run pylint is to run at the package level with tox:
2626

27-
.../azure-sdk-for-python/sdk/eventgrid/azure-eventgrid>tox -e pylint -c ../../../eng/tox/tox.ini
27+
.../azure-sdk-for-python/sdk/eventgrid/azure-eventgrid>tox run -e pylint -c ../../../eng/tox/tox.ini --root .
2828

2929
If you don't want to use tox, you can also install and run pylint on its own:
3030

@@ -58,9 +58,9 @@ In addition to being a part of the CI, the custom pylint checkers are also integ
5858

5959
There is now a new step on the CI pipeline called `Run Pylint Next`. This is merely a duplicate of the `Run Pylint` step with the exception that `Run Pylint Next` uses the latest version of pylint and the latest version of the custom pylint checkers.
6060

61-
This next-pylint enviornment can also be run locally through tox:
61+
This next-pylint environment can also be run locally through tox:
6262

63-
tox -e next-pylint -c ../../../eng/tox/tox.ini
63+
tox run -e next-pylint -c ../../../eng/tox/tox.ini --root <path to python package>
6464

6565
The errors generated by the `Run Pylint Next` step will not break your weekly test pipelines, but make sure to fix the warnings so that your client library is up to date for the next pylint release.
6666

doc/dev/sample_guide.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ The given `START`/`END` keywords can be used in a [sphinx literalinclude][sphinx
5252
[Literalinclude example][literalinclude]
5353

5454
The rendered code snippets are sensitive to the indentation in the sample file. Adjust the `dedent` accordingly to ensure the sample is captured accurately and not accidentally trimmed.
55-
You can preview how published reference documentation will look by running [tox][tox]: `tox -e sphinx -c ../../../eng/tox/tox.ini`.
55+
You can preview how published reference documentation will look by running [tox][tox]: `tox run -e sphinx -c ../../../eng/tox/tox.ini --root <path to python package>`.
5656

5757
## Test run samples in CI live tests
5858
Per the [Python guidelines][snippet_guidelines], sample code and snippets should be test run in CI to ensure they remain functional. Samples should be run in the package's live test pipeline which is scheduled to run daily.
5959
To ensure samples do get tested as part of regular CI runs, add these [lines][live_tests] to the package's tests.yml.
6060

61-
You can test this CI step locally first, by utilizing [tox][tox] and running `tox -e samples -c ../../../eng/tox/tox.ini` at the package-level.
61+
You can test this CI step locally first, by utilizing [tox][tox] and running `tox run -e samples -c ../../../eng/tox/tox.ini --root <path to python package>`.
6262

6363
The `Test Samples` step in CI will rely on the resources provisioned and environment variables used for running the package's tests.
6464

doc/dev/static_type_checking.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,17 @@ version of the type checker ships. All client libraries in the Python SDK repo a
175175

176176
The easiest way to install and run the type checkers locally is
177177
with [tox](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/tests.md#tox). This reproduces the exact type checking
178-
environment run in CI and brings in the third party stub packages necessary. To begin, first install `tox` and `tox-monorepo`:
178+
environment run in CI and brings in the third party stub packages necessary. To begin, first install `tox`:
179179

180-
`pip install tox tox-monorepo`
180+
`pip install tox<5`
181181

182182
### Run mypy
183183

184184
mypy is currently pinned to version [1.0.0](https://pypi.org/project/mypy/1.0.0/).
185185

186186
To run mypy on your library, run the tox mypy env at the package level:
187187

188-
`.../azure-sdk-for-python/sdk/textanalytics/azure-ai-textanalytics>tox -e mypy -c ../../../eng/tox/tox.ini`
188+
`.../azure-sdk-for-python/sdk/textanalytics/azure-ai-textanalytics>tox run -e mypy -c ../../../eng/tox/tox.ini --root .`
189189

190190
If you don't want to use `tox` you can also install and run mypy on its own:
191191

@@ -217,7 +217,7 @@ Note that pyright requires that node is installed. The command-line [wrapper pac
217217

218218
To run pyright on your library, run the tox pyright env at the package level:
219219

220-
`.../azure-sdk-for-python/sdk/textanalytics/azure-ai-textanalytics>tox -e pyright -c ../../../eng/tox/tox.ini`
220+
`.../azure-sdk-for-python/sdk/textanalytics/azure-ai-textanalytics>tox run -e pyright -c ../../../eng/tox/tox.ini --root .`
221221

222222
If you don't want to use `tox` you can also install and run pyright on its own:
223223

@@ -249,7 +249,7 @@ from the code in the PR vs. the latest release on PyPi.
249249

250250
To run verifytypes on your library, run the tox verifytypes env at the package level:
251251

252-
`.../azure-sdk-for-python/sdk/textanalytics/azure-ai-textanalytics>tox -e verifytypes -c ../../../eng/tox/tox.ini`
252+
`.../azure-sdk-for-python/sdk/textanalytics/azure-ai-textanalytics>tox run -e verifytypes -c ../../../eng/tox/tox.ini --root .`
253253

254254
If you don't want to use `tox` you can also install and run pyright/verifytypes on its own:
255255

doc/dev/tests.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,20 +123,20 @@ If you have print statements in your tests for debugging you can add the `-s` fl
123123

124124
## Tox
125125

126-
The Python SDK uses the [tox project](https://tox.readthedocs.io/en/latest/) to automate releases, run tests, run linters, and build our documentation. The `tox.ini` file is located at `azure-sdk-for-python/eng/tox/tox.ini` for reference. You do not need to make any changes to the tox file for tox to work with your project. Tox will create a directory (`.tox`) in the head of your branch. The first time you run tox commands it may take several moments, but subsequent runs will be quicker. To install tox run the following command from within your virtual environment.
127-
`(env) > pip install tox tox-monorepo`.
126+
The Python SDK uses the [tox project](https://tox.wiki/en/latest/) to automate releases, run tests, run linters, and build our documentation. The `tox.ini` file is located at `azure-sdk-for-python/eng/tox/tox.ini` for reference. You do not need to make any changes to the tox file for tox to work with your project. Tox will create a directory (`.tox`) in the head of your branch. The first time you run tox commands it may take several moments, but subsequent runs will be quicker. To install tox run the following command from within your virtual environment.
127+
`(env) > pip install tox<5`.
128128

129129
To run a tox command from your directory use the following commands:
130130
```cmd
131-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e sphinx
132-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e pylint
133-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e mypy
134-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e pyright
135-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e verifytypes
136-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e whl
137-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e sdist
138-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e samples
139-
(env) azure-sdk-for-python\sdk\my-service\my-package> tox -c ../../../eng/tox/tox.ini -e apistub
131+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e sphinx -c ../../../eng/tox/tox.ini --root .
132+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e pylint -c ../../../eng/tox/tox.ini --root .
133+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e mypy -c ../../../eng/tox/tox.ini --root .
134+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e pyright -c ../../../eng/tox/tox.ini --root .
135+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e verifytypes -c ../../../eng/tox/tox.ini --root .
136+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e whl -c ../../../eng/tox/tox.ini --root .
137+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e sdist -c ../../../eng/tox/tox.ini --root .
138+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e samples -c ../../../eng/tox/tox.ini --root .
139+
(env) azure-sdk-for-python\sdk\my-service\my-package> tox run -e apistub -c ../../../eng/tox/tox.ini --root .
140140
```
141141
A quick description of the five commands above:
142142
* sphinx: documentation generation using the inline comments written in our code

0 commit comments

Comments
 (0)