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 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
|
# HOW TO CONTRIBUTE TO TQDM
**TL;DR: Skip to [QUICK DEV SUMMARY]**
This file describes how to
- contribute changes to the project, and
- upload released to the PyPI repository.
Most of the management commands have been directly placed inside the
Makefile:
```
make [<alias>] # on UNIX-like environments
python -m pymake [<alias>] # if make is unavailable
```
The latter depends on [`py-make>=0.1.0`](https://github.com/tqdm/py-make).
Use the alias `help` (or leave blank) to list all available aliases.
## HOW TO COMMIT CONTRIBUTIONS
Contributions to the project are made using the "Fork & Pull" model. The
typical steps would be:
1. create an account on [github](https://github.com)
2. fork [`tqdm`](https://github.com/tqdm/tqdm)
3. make a local clone: `git clone https://github.com/your_account/tqdm.git`
4. make changes on the local copy
5. test (see below) and commit changes `git commit -a -m "my message"`
6. `push` to your GitHub account: `git push origin`
7. create a Pull Request (PR) from your GitHub fork
(go to your fork's webpage and click on "Pull Request."
You can then add a message to describe your proposal.)
## WHAT CODE LAYOUT SHOULD I FOLLOW?
Don't worry too much - maintainers can help reorganise contributions.
However it would be helpful to bear in mind:
- The standard core of `tqdm`, i.e. [`tqdm.std.tqdm`](tqdm/std.py)
+ must have no dependencies apart from pure python built-in standard libraries
+ must have negligible impact on performance
+ should have 100% coverage by unit tests
+ should be appropriately commented
+ should have well-formatted docstrings for functions
* under 76 chars (incl. initial spaces) to avoid linebreaks in terminal pagers
* use two spaces between variable name and colon, specify a type, and most likely state that it's optional: `VAR<space><space>:<space>TYPE[, optional]`
* use [default: ...] for default values of keyword arguments
+ will not break backward compatibility unless there is a very good reason
* e.g. breaking py26 compatibility purely in favour of minor readability changes (such as converting `dict(a=1)` to `{'a': 1}`) is not a good enough reason
+ API changes should be discussed carefully
+ remember, with millions of downloads per month, `tqdm` must be extremely fast and reliable
- Any other kind of change may be included in a (possibly new) submodule
+ submodules are likely single python files under the main [tqdm/](tqdm/) directory
+ submodules extending `tqdm.std.tqdm` or any other module (e.g. [`tqdm.notebook.tqdm`](tqdm/notebook.py), [`tqdm.gui.tqdm`](tqdm/gui.py))
+ CLI wrapper `tqdm.cli`
* if a newly added `tqdm.std.tqdm` option is not supported by the CLI, append to `tqdm.cli.UNSUPPORTED_OPTS`
+ can implement anything from experimental new features to support for third-party libraries such as `pandas`, `numpy`, etc.
+ submodule maturity
* alpha: experimental; missing unit tests, comments, and/or feedback; raises `tqdm.TqdmExperimentalWarning`
* beta: well-used; commented, perhaps still missing tests
* stable: >10 users; commented, 80% coverage
- `.meta/`
+ A "hidden" folder containing helper utilities not strictly part of the `tqdm` distribution itself
## TESTING
Once again, don't worry too much - tests are automated online, and maintainers
can also help.
To test functionality (such as before submitting a Pull
Request), there are a number of unit tests.
### Standard unit tests
The standard way to run the tests:
- install `tox`
- `cd` to the root of the `tqdm` directory (in the same folder as this file)
- run the following command:
```
[python -m py]make test
# or:
tox --skip-missing-interpreters
```
This will build the module and run the tests in a virtual environment.
Errors and coverage rates will be output to the console/log. (Ignore missing
interpreters errors - these are due to the local machine missing certain
versions of Python.)
Note: to install all versions of the Python interpreter that are specified
in [tox.ini](https://github.com/tqdm/tqdm/blob/master/tox.ini),
you can use `MiniConda` to install a minimal setup. You must also ensure
that each distribution has an alias to call the Python interpreter
(e.g. `python312` for Python 3.12's interpreter).
### Alternative unit tests with pytest
Alternatively, use `pytest` to run the tests just for the current Python version:
- install test requirements: `[python -m py]make install_test`
- run the following command:
```
[python -m py]make alltests
```
# MANAGE A NEW RELEASE
This section is intended for the project's maintainers and describes
how to build and upload a new release. Once again,
`[python -m py]make [<alias>]` will help.
Also consider `pip install`ing development utilities:
`[python -m py]make install_build` at a minimum, or a more thorough `conda env create`.
## Pre-commit Hook
It's probably a good idea to use the `pre-commit` (`pip install pre-commit`) helper.
Run `pre-commit install` for convenient local sanity-checking.
## Semantic Versioning
The `tqdm` repository managers should:
- follow the [Semantic Versioning](https://semver.org) convention for tagging
## Checking `pyproject.toml`
To check that the `pyproject.toml` file is compliant with PyPI
requirements (e.g. version number; reStructuredText in `README.rst`) use:
```
[python -m py]make testsetup
```
To upload just metadata (including overwriting mistakenly uploaded metadata)
to PyPI, use:
```
[python -m py]make pypimeta
```
## Merging Pull Requests
This section describes how to cleanly merge PRs.
### 1 Rebase
From your project repository, merge and test
(replace `pr-branch-name` as appropriate):
```
git fetch origin
git checkout -b pr-branch-name origin/pr-branch-name
git rebase master
```
If there are conflicts:
```
git mergetool
git rebase --continue
```
### 2 Push
Update branch with the rebased history:
```
git push origin pr-branch-name --force
```
Non maintainers can stop here.
Note: NEVER just `git push --force` (this will push all local branches,
overwriting remotes).
### 3 Merge
```
git checkout master
git merge --no-ff pr-branch-name
```
### 4 Test
```
[python -m py]make alltests
```
### 5 Push to master
```
git push origin master
```
## Building a Release and Uploading to PyPI
Formally publishing requires additional steps: testing and tagging.
### Test
Ensure that all online CI tests have passed.
### Tag
- ensure the version has been tagged.
The tag format is `v{major}.{minor}.{patch}`, for example: `v4.4.1`.
The current commit's tag is used in the version checking process.
If the current commit is not tagged appropriately, the version will
display as `v{major}.{minor}.{patch}.dev{N}+g{commit_hash}`.
### Upload
GitHub Actions (GHA) CI should automatically do this after pushing tags.
Manual instructions are given below in case of failure.
Build `tqdm` into a distributable python package:
```
[python -m py]make build
```
This will generate several builds in the `dist/` folder. On non-windows
machines the windows `exe` installer may fail to build. This is normal.
Finally, upload everything to PyPI. This can be done easily using the
[twine](https://github.com/pypa/twine) module:
```
[python -m py]make pypi
```
Also, the new release can (should) be added to GitHub by creating a new
release from the [web interface](https://github.com/tqdm/tqdm/releases);
uploading packages from the `dist/` folder
created by `[python -m py]make build`.
The [wiki] can be automatically updated with GitHub release notes by
running `make` within the wiki repository.
[wiki]: https://github.com/tqdm/tqdm/wiki
Docker images may be uploaded to <https://hub.docker.com/r/tqdm/tqdm>.
Assuming `docker` is
[installed](https://docs.docker.com/install/linux/docker-ce/ubuntu/):
```
make -B docker
docker login
docker push tqdm/tqdm:latest
docker push tqdm/tqdm:$(docker run -i --rm tqdm/tqdm -v)
```
Snaps may be uploaded to <https://snapcraft.io/tqdm>.
Assuming `snapcraft` is installed (`snap install snapcraft --classic --beta`):
```
make snap
snapcraft login
snapcraft push tqdm*.snap --release stable
```
### Notes
- you can also test on the PyPI test servers `test.pypi.org`
before the real deployment
- in case of a mistake, you can delete an uploaded release on PyPI, but you
cannot re-upload another with the same version number
- in case of a mistake in the metadata on PyPI (e.g. bad README),
updating just the metadata is possible: `[python -m py]make pypimeta`
## Updating Websites
The most important file is `.readme.rst`, which should always be kept up-to-date
and in sync with the in-line source documentation. This will affect all of the
following:
- `README.rst` (generated by `mkdocs.py` during `make build`)
- The [main repository site](https://github.com/tqdm/tqdm) which automatically
serves the latest `README.rst` as well as links to all of GitHub's features.
This is the preferred online referral link for `tqdm`.
- The [PyPI mirror](https://pypi.org/project/tqdm) which automatically
serves the latest release built from `README.rst` as well as links to past
releases.
- Many external web crawlers.
Additionally (less maintained), there exists:
- A [wiki] which is publicly editable.
- The [gh-pages project] which is built from the
[gh-pages branch](https://github.com/tqdm/tqdm/tree/gh-pages), which is
built using [asv](https://github.com/airspeed-velocity/asv).
- The [gh-pages root] which is built from a separate
[github.io repo](https://github.com/tqdm/tqdm.github.io).
[gh-pages project]: https://tqdm.github.io/tqdm/
[gh-pages root]: https://tqdm.github.io/
## Helper Bots
There are some helpers in
[.github/workflows](https://github.com/tqdm/tqdm/tree/master/.github/workflows)
to assist with maintenance.
- Comment Bot
+ allows maintainers to write `/tag vM.m.p commit_hash` in an issue/PR to create a tag
- Post Release
+ automatically updates the [wiki]
+ automatically updates the [gh-pages root]
- Benchmark
+ automatically updates the [gh-pages project]
## QUICK DEV SUMMARY
For experienced devs, once happy with local master, follow the steps below.
Much is automated so really it's steps 1-5, then 11(a).
1. test (`[python -m py]make alltests` or rely on `pre-commit`)
2. `git commit [--amend] # -m "bump version"`
3. `git push`
4. wait for tests to pass
a) in case of failure, fix and go back to (1)
5. `git tag vM.m.p && git push --tags` or comment `/tag vM.m.p commit_hash`
6. **`[AUTO:GHA]`** `[python -m py]make distclean`
7. **`[AUTO:GHA]`** `[python -m py]make build`
8. **`[AUTO:GHA]`** upload to PyPI. either:
a) `[python -m py]make pypi`, or
b) `twine upload -s -i $(git config user.signingkey) dist/tqdm-*`
9. **`[AUTO:GHA]`** upload to docker hub:
a) `make -B docker`
b) `docker push tqdm/tqdm:latest`
c) `docker push tqdm/tqdm:$(docker run -i --rm tqdm/tqdm -v)`
10. **`[AUTO:GHA]`** upload to snapcraft:
a) `make snap`, and
b) `snapcraft push tqdm*.snap --release stable`
11. Wait for GHA to draft a new release on <https://github.com/tqdm/tqdm/releases>
a) replace the commit history with helpful release notes, and click publish
b) **`[AUTO:GHA]`** attach `dist/tqdm-*` binaries
(usually only `*.whl*`)
12. **`[SUB][AUTO:GHA-rel]`** run `make` in the `wiki` submodule to update release notes
13. **`[SUB][AUTO:GHA-rel]`** run `make deploy` in the `docs` submodule to update website
14. **`[SUB][AUTO:GHA-rel]`** accept the automated PR in the `feedstock` submodule to update conda
15. **`[AUTO:GHA-rel]`** update the [gh-pages project] benchmarks
a) `[python -m py]make testasvfull`
b) `asv gh-pages`
Key:
- **`[AUTO:GHA]`**: GitHub Actions CI should automatically do this after `git push --tags` (5)
- **`[AUTO:GHA-rel]`**: GitHub Actions CI should automatically do this after release (11a)
- **`[SUB]`**: Requires one-time `make submodules` to clone `docs`, `wiki`, and `feedstock`
|