File: development.rst

package info (click to toggle)
tox 4.49.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,612 kB
  • sloc: python: 26,672; javascript: 114; sh: 22; makefile: 15
file content (352 lines) | stat: -rw-r--r-- 16,092 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#############
 Development
#############

.. toctree::
    :hidden:

    onboarding

************
 Key points
************

If you're already experienced with submitting GitHub PRs to open-source Python projects, the following are the key
points you need to know about this project. (If you're not, you should carefully read all the documentation after this
section. This section contains only highlights; it's not a substitute for reading this entire file.)

- Check the `style guide <#code-style-guide>`_ below. Note that ``tox -e fix`` will not catch the following:

  - Lines wrapped at less than 120 characters. Lines should be wrapped at 120 characters, not the PEP-8 standard of 79.
  - Variable names should be at least two characters long.

- Documentation is in `RST <https://docutils.sourceforge.io/docs/user/rst/quickref.html>`_ format; beware the
  differences from GitHub Markdown. The tox ``docs`` and ``fix`` targets will catch only some RST errors; documentation
  changes *must* be checked visually (see below).
- All PRs that make changes visible to an end user require a changelog entry. This should reference an issue if it
  closes that issue, otherwise reference the PR. Create one or more (if there's more than one issue)
  ``docs/changelog/####.{breaking,deprecation,feature,bugfix,doc,packaging,contrib,misc}.rst`` per the `changelog entry
  <#changelog-entries>`_ section below.
- GitHub Actions will do a full set of `tests and checks <#automated-testing>`_ when the PR is submitted. For local
  testing you'll need to install your own "top-level" tox (using pipx_ or similar is fine) and use the following targets
  (tox environments):

  - :samp:`tox -e py [-- {pytest-arg ...}]` to `test code changes <#running-tests>`_. This will skip tests for which you
    are missing dependencies, but those tests will still be run by GitHub Actions.
  - ``tox -e type`` to typecheck changes. (All new code should have complete type annotations.)
  - ``tox -e docs`` to build documentation changes and update the changelog, followed by viewing (with a browser) the
    generated HTML files under :file:`.tox/docs_out/html/`. The required changelog entry can be viewed at the "Release
    History" link at the left.
  - ``tox -e fix`` to lint code, documentation and any other changes to the repo. This will also fix the code and write
    out the changed files; you can update your commit with `git commit --amend`.

*****************
 Getting started
*****************

``tox`` is a volunteer maintained open source project and we welcome contributions of all forms. The sections below will
help you get started with development, testing, and documentation. We’re pleased that you are interested in working on
tox. This document is meant to get you setup to work on tox and to act as a guide and reference to the development
setup. If you face any issues during this process, please :issue:`open an issue
<new?title=Trouble+with+development+environment>` about it on the issue tracker.

Setup
=====

tox is a command line application written in Python. To work on it, you'll need:

- **Source code**: available on :gh_repo:`GitHub <tox-dev/tox>`. You can use ``git`` to clone the repository:

  .. code-block:: shell

      git clone https://github.com/tox-dev/tox
      cd tox

- **Python interpreter**: We recommend using ``CPython``. You can use `this guide
  <https://realpython.com/installing-python/>`_ to set it up.
- :pypi:`tox`: to automatically get the projects development dependencies and run the test suite. We recommend
  installing it using `pipx <https://pipxproject.github.io/pipx/>`_.

Running from source tree
========================

The easiest way to do this is to generate the development tox environment, and then invoke tox from under the
``.tox/dev`` folder

.. code-block:: shell

    tox -e dev
    .tox/dev/bin/tox  # on Linux
    .tox/dev/Scripts/tox  # on Windows

Running tests
=============

tox's tests are written using the :pypi:`pytest` test framework. :pypi:`tox` is used to automate the setup and execution
of tox's tests.

To run tests locally execute:

.. code-block:: shell

    tox -e py

This will run the test suite for the same Python version as under which ``tox`` is installed. Alternatively you can
specify a specific version of Python by using the ``pyNN`` format, such as: ``py38``, ``pypy3``, etc.

``tox`` has been configured to forward any additional arguments it is given to ``pytest``. This enables the use of
pytest's `rich CLI <https://docs.pytest.org/en/latest/how-to/usage.html#specifying-which-tests-to-run>`_. As an example,
you can select tests using the various ways that pytest provides:

.. code-block:: shell

    # Using markers
    tox -e py -- -m "not slow"
    # Using keywords
    tox -e py -- -k "test_extra"

Some tests require additional dependencies to be run, such is the various shell activators (``bash``, ``fish``,
``powershell``, etc). The tests will be skipped automatically if the dependencies are not present. Please note however
that in CI all tests are run; so even if all tests succeed locally for you, they may still fail in the CI.

Running linters
===============

tox uses :pypi:`pre-commit` for managing linting of the codebase. ``pre-commit`` performs various checks on all files in
tox and uses tools that help following a consistent code style within the codebase. To use linters locally, run:

.. code-block:: shell

    tox -e fix

.. note::

    Avoid using ``# noqa`` comments to suppress linter warnings - wherever possible, warnings should be fixed instead.
    ``# noqa`` comments are reserved for rare cases where the recommended style causes severe readability problems or
    sidestep bugs within the linters.

Code style guide
================

- First and foremost, the linters configured for the project must pass; this generally means following PEP-8 rules, as
  codified by ``ruff`` (which replaces the previously used ``flake8``, ``black``, ``isort``, and ``pyupgrade``).
- The supported Python versions (and the code syntax to use) are listed in the ``pyproject.toml`` file in the
  ``project/requires-python`` entry.
- All code (tests too) must be type annotated as much as required by ``mypy``.
- We use a line length of 120.
- Exception messages should only be capitalized (and ended with a period/exclamation mark) if they are multi-sentenced,
  which should be avoided. Otherwise, use statements that start with lowercase.
- All function (including test) names must follow PEP-8, so they must be fully snake cased. All classes are upper
  camel-cased.
- Prefer f-strings instead of the ``str.format`` method.
- Tests should contain as little information as possible but do use descriptive variable names within it.

Building documentation
======================

tox's documentation is built using :pypi:`Sphinx`. The documentation is written in reStructuredText. To build it
locally, run:

.. code-block:: shell

    tox -e docs

The built documentation can be found in the ``.tox/docs_out/html`` folder and may be viewed by opening ``index.html``
within that folder.

**************
 Contributing
**************

Submitting pull requests
========================

Submit pull requests (PRs) against the ``main`` branch, providing a good description of what you're doing and why. You
must have legal permission to distribute any code you contribute to tox and it must be available under the MIT License.
Provide tests that cover your changes and run the tests locally first. tox :ref:`supports <compatibility-requirements>`
multiple Python versions and operating systems. Any pull request must consider and work on all these platforms.

Pull requests should be small to facilitate review. Keep them self-contained, and limited in scope. Studies have shown
that review quality falls off as patch size grows. In particular, pull requests must not be treated as "feature
branches", with ongoing development work happening within the PR. Instead, the feature should be broken up into smaller,
independent parts which can be reviewed and merged individually.

Additionally, avoid including "cosmetic" changes to code that is unrelated to your change, as these make reviewing the
PR more difficult. Examples include re-flowing text in comments or documentation, or addition or removal of blank lines
or whitespace within lines. Such changes can be made separately, as a "formatting cleanup" PR, if needed.

Automated testing
=================

All pull requests and merges to the ``main`` branch are tested using :gh:`GitHub Actions <features/actions>` (configured
by ``check.yaml`` file inside the ``.github/workflows`` directory). You can find the status and the results to the CI
runs for your PR on GitHub's Web UI for the pull request. You can also find links to the CI services' pages for the
specific builds in the form of "Details" links, in case the CI run fails and you wish to view the output.

To trigger CI to run again for a pull request, you can close and open the pull request or submit another change to the
pull request. If needed, project maintainers can manually trigger a restart of a job/build.

Changelog entries
=================

The ``changelog.rst`` file is managed using :pypi:`towncrier` and all changes must be accompanied by a changelog entry.
To add an entry to the changelog, first you need to have created an issue describing the change you want to make. A pull
request itself *may* function as such, but it is preferred to have a dedicated issue (for example, in case the PR ends
up rejected due to code quality reasons).

There is no need to create an issue for trivial changes, e.g. for typo fixes.

Once you have an issue or pull request, you take the number and you create a file inside of the ``docs/changelog``
directory named after that issue number with an extension of:

- ``breaking.rst`` - backward incompatible changes,
- ``deprecation.rst`` - deprecations (removal in next major release),
- ``feature.rst`` - new features,
- ``bugfix.rst`` - bug fixes,
- ``doc.rst`` - documentation improvements,
- ``packaging.rst`` - packaging updates and notes for downstreams,
- ``contrib.rst`` - contributor-facing changes,
- ``misc.rst`` - miscellaneous internal changes.

Thus if your issue or PR number is ``1234`` and this change is fixing a bug, then you would create a file
``docs/changelog/1234.bugfix.rst``. PRs can span multiple categories by creating multiple files (for instance, if you
added a feature and deprecated/removed the old feature at the same time, you would create
``docs/changelog/1234.bugfix.rst`` and ``docs/changelog/1234.deprecation.rst``). Likewise if a PR touches multiple
issues/PRs you may create a file for each of them with the same contents and :pypi:`towncrier` will deduplicate them.

Contents of a changelog entry
-----------------------------

The content of this file is reStructuredText formatted text that will be used as the content of the changelog entry. You
do not need to reference the issue or PR numbers here as towncrier will automatically add a reference to all of the
affected issues when rendering the changelog. You may append ``- by :user:USERNAME``, with a GitHub username in
backticks, if you wish.

In order to maintain a consistent style in the ``changelog.rst`` file, it is preferred to keep the entries to the point,
in sentence case, shorter than 120 characters and in an imperative tone -- an entry should complete the sentence ``This
change will …``. In rare cases, where one line is not enough, use a summary line in an imperative tone followed by a
blank line separating it from a description of the feature/change in one or more paragraphs, each wrapped at 120
characters. Remember that a changelog entry is meant for end users and should only contain details relevant to an end
user.

An example of ``docs/changelog/####.bugfix.rst`` contents is:

.. code-block::

    Instead of raising ``UnicodeDecodeError`` when command output includes non-utf-8 bytes, ``tox`` will now use
    ``surrogateescape`` error handling to convert the unrecognized bytes to escape sequences according to :pep:`383`
    - by :user:`masenf`

Becoming a maintainer
=====================

If you want to become an official maintainer, start by helping out. As a first step, we welcome you to triage issues on
tox's issue tracker. tox maintainers provide triage abilities to contributors once they have been around for some time
and contributed positively to the project. This is optional and highly recommended for becoming a tox maintainer. Later,
when you think you're ready, get in touch with one of the maintainers and they will initiate a vote among the existing
maintainers.

.. note::

    Upon becoming a maintainer, a person should be given access to various tox-related tooling across multiple
    platforms. These are noted here for future reference by the maintainers:

    - GitHub Push Access (provides also CI administration capabilities)
    - PyPI Publishing Access
    - ReadTheDocs Administration capabilities (the root domain `tox.wiki <https://tox.wiki/en/latest/>`_ is currently
      owned and maintained by the primary maintainer and author ``Bernat Gabor``; bought via `Porkbun
      <https://porkbun.com/>`_ -- reach out to him directly for any changes).

Creating a new release
======================

tox supports two methods for preparing releases:

Method 1: Local release (requires git access)
---------------------------------------------

.. code-block:: shell

    tox r -e release -- <version>

Example:

.. code-block:: shell

    tox r -e release -- 4.27.0

This will:

1. Create a ``release-<version>`` branch from upstream/main.
2. Generate changelog using towncrier.
3. Commit changes with message "release <version>".
4. Tag the commit with the version number.
5. Force-push to main and push the tag.
6. Clean up local branches.

Requirements:

- Write access to tox-dev/tox repository.
- Configured git remote pointing to tox-dev/tox (typically named ``upstream``).

  .. code-block:: shell

      git remote add upstream git@github.com:tox-dev/tox.git

- Local dependencies installed via tox.

Method 2: GitHub Actions workflow dispatch
------------------------------------------

Navigate to `Actions > Prepare Release <https://github.com/tox-dev/tox/actions/workflows/prepare-release.yaml>`_ and:

1. Click "Run workflow".
2. Select the branch (usually ``main``).
3. Choose the version bump type:

   - ``auto`` (default) - Automatically bump minor if feature changelogs exist, otherwise bump patch.
   - ``major`` - Bump major version (e.g., 4.0.0 → 5.0.0).
   - ``minor`` - Bump minor version (e.g., 4.27.0 → 4.28.0).
   - ``patch`` - Bump patch version (e.g., 4.27.0 → 4.27.1).

4. Click "Run workflow".

The workflow executes the same ``tasks/release.py`` script in a clean CI environment.

Requirements:

- Write access to tox-dev/tox repository (workflow permissions).
- For repositories with branch protection on ``main``, a ``RELEASE_PAT`` secret must be configured in the
  ``release-auth`` environment with a fine-grained Personal Access Token that has permissions to bypass branch
  protection rules.
- Maintainer approval is required to trigger the workflow (configured via environment protection rules).

After release preparation
-------------------------

Both methods push a tag to the repository. The tag push automatically triggers the ``release.yaml`` workflow which:

1. Builds Python packages (sdist + wheel).
2. Publishes to PyPI via trusted publishing.

.. note::

    - Both methods force-push to main (ensure no concurrent work).
    - The release process is atomic and should not be interrupted.
    - Failed releases can be retried with the same version number.

.. _current-maintainers:

Current maintainers
-------------------

- :user:`Bernát Gábor <gaborbernat>`
- :user:`Jürgen Gmach <jugmac00>`
- :user:`Rahul Devikar <rahuldevikar>`

Previous maintainers
--------------------

- :user:`Anthony Sottile <asottile>`
- :user:`Masen Furer <masenf>`
- :user:`Oliver Bestwalter <obestwalter>`