diff --git a/content/contributing/docs.md b/content/contributing/docs.md index 8849a24..72fb5de 100644 --- a/content/contributing/docs.md +++ b/content/contributing/docs.md @@ -1,14 +1,98 @@ # Contribute to Documentation -We use [Sphinx][] and [ReStructuredText][] to write the documentation. +We use [Sphinx] to build the documentation. Historically, this has used +[reStructuredText] `.rst` as the syntax. You may see some pages written in +[Markdown] `.md` if the `myst-parser` dependency has been added to +the project. Docstrings in code must always use rST. + +[Sphinx]: https://sphinx-doc.org +[reStructuredText]: https://docutils.sourceforge.io/rst.html +[Markdown]: https://commonmark.org + +## Work on the `stable` Branch + +**If you are fixing or improving existing docs, or writing about existing +features, you want to branch off of the `stable` branch, as well as target the +`stable` branch in the PR.** + +If you use GitHub's UI to quickly edit a file, remember to select the `stable` +branch from the dropdown first. Otherwise, you'll end up submitting the fix +against `main`, and a maintainer will have to do extra work to retarget it. + +Changes to `stable` docs will show up within minutes of being merged. Changes to +`main` will be unavailable until the next feature release. You'll rarely want to +work off of `main` for docs, unless you're working on docs for a new unreleased +feature. + +## Building Docs To build the docs locally, run `tox r -e docs`. To serve the docs locally, run `python -m http.server docs/_build/dirhtml`. Then go to in your browser to view the docs. -Documentation is hosted by Read the Docs. They are built and deployed for any -changes to the `main` and `A.B.x` feature branches. Each PR also generates a -test build. +Documentation is hosted by Read the Docs. It is deployed on every change to the +`stable` branch. Each PR also generates a test build, which can be viewed by +clicking the "readthedocs" build check in the PR. -[Sphinx]: https://sphinx-doc.org -[reStructuredText]: https://docutils.sourceforge.io/rst.html +## Writing Docs + +Writing about how to write documentation is surprisingly hard! We generally like +the ideas presented in [Diátaxis], which is a way of thinking about and doing +documentation. + +[Diátaxis]: https://diataxis.fr + +It can be very hard to assess whether a change is _better_ rather than only +_different_. Keep this in mind when deciding if you want to change something. If +a sentence is clear and understandable, even if you would say it differently, +then it should probably be left as-is. + +The most common type of docs contribution is a typo fix. Check if the typo +happened in multiple places, and fix it everywhere. Don't submit typo fixes to +code comments that aren't visible in the deployed docs, unless you're also +working on that code. If you find multiple different typos, you can fix them in +separate commits to one PR, rather than multiple PRs. Make sure the typo is +really a typo, and not a correct sentence with a different meaning. + +The libraries' docs have been written by many people over more than a decade. +This has introduced inconsistencies in style, focus, and technical level across +different parts of documentation over time. We recognize that there are many +ways in which documentation can be rewritten and improved. However, avoid huge +rewrites unless you have already checked with maintainers. If you're changing +more than a few sentences of text, and haven't received prior approval, you're +probably doing too much at once. It is very hard to review such changes, +especially from unknown users who we have not established trust with. + +### Style, Spelling, and Grammar + +Avoid referring to "you" or "we" outside of tutorials. State things directly; +"to do X, use Y" rather than "if you want to do X, then you should use Y." + +Avoid phrases that might imply something is implicitly easy, such as "just do X" +or "the reason is obviously Y". Users are coming to the docs because something +wasn't obvious or easy for them at that moment. + +The documentation is in English. If you are not a native English speaker, that's +OK, learners often catch issues that native speakers overlook. However, if a +maintainer would have to alter a significant portion of your PR, that's not a +great use of time. We also have a translation project, explained in the next +section. + +Prefer [American spelling]. Use the [serial comma]; ("a, b, and c" rather than +"a, b and c"). That said, do not create a PR that tries to make everything +consistent, it's ok that existing docs use alternate spellings. + +[American spelling]: https://www.oxfordinternationalenglish.com/differences-in-british-and-american-spelling/ +[serial comma]: https://www.grammarly.com/blog/punctuation-capitalization/what-is-the-oxford-comma/ + +## Translating Docs + +Currently, the community is working on translating Flask's documentation. We may +add other projects in the future. + +You can find the translation project and instructions on how to contribute here: +. We use [Weblate] to +manage translations. You'll need an account there. Then you can use the UI to navigate +to a language and find strings to translate. + +[Weblate]: https://weblate.org diff --git a/content/contributing/features.md b/content/contributing/features.md index 89d9127..f3bdf7b 100644 --- a/content/contributing/features.md +++ b/content/contributing/features.md @@ -1 +1,32 @@ # Request a Feature + +If you feel that one of our libraries is missing something, you should request +a new feature for it on the GitHub Issues tab. For example, Flask's is here: +. + +The bar for accepting new features into many of our libraries is high. Our +general philosophy is to provide a solid base framework that other libraries can +extend, rather than blessing specific implementations in the core library. A +feature request may be more successful if: + +- If it's not possible to implement as an extension without changes to the + core. +- If there is one "correct" way to implement something. +- If the request is similar to or complements existing behavior. + +Before requesting a feature, try to determine if it has already been requested +or implemented. Search existing issues and PRs, including closed issues and +merged PRs. Requests that were previously rejected are likely to be rejected +again unless (or even if) significant new reasoning is presented. + +Click the green "New issue" button at the top right to start. Include the +following information in your post: + +- Write a short, descriptive title. + - Do not include prefixes such as "\[feature]"; maintainers will apply + real tags as needed. +- Describe what the feature should do. +- Include details such as links to relevant specs or previous discussions. +- Provide an example of a problem this feature would resolve. Consider if this + is problem solvable without changes to the library, such as by subclassing + or using an extension. diff --git a/content/contributing/index.md b/content/contributing/index.md index 96c7608..cade89d 100644 --- a/content/contributing/index.md +++ b/content/contributing/index.md @@ -6,76 +6,87 @@ contribute to an open source project, see the next section for more ideas. If you would like to ask a question or open an issue or feature request, see these guides: -1. [Ask a Question](questions.md) -2. [Report an Issue](issues.md) - * [Report a **Security** Issue](../security.md) -3. [Request a Feature](features.md) +- [Ask a Question](questions.md), which also covers how to contribute by + answering questions. +- [Report an Issue](issues.md) +- [Report a **Security** Issue](../security.md) +- [Request a Feature](features.md) If you would like to fix an issue or implement a feature, see these guides: -1. [Start Here: Development Environment Setup](setup.md) -2. [Create a Pull Request](pr.md) -3. [Edit and Build Documentation](docs.md) -4. [Write and Run Tests](tests.md) +- [Quick Reference](quick.md) If you're already familiar with contributing, + this provides an essential overview of the following guides. +- Start Here: Detailed Development Environment Setup - Coming Soon +- [Create a Pull Request](pr.md) +- Write and Run Tests - Coming Soon +- Static Type Checks - Coming Soon +- [Edit and Build Documentation](docs.md) +- Changelog Style - Coming Soon +- Linting and Formatting - Coming Soon If you're getting more involved as a community or team member, see these guides: -* [Triaging Issues](triage.md) covers many of the things the team looks for in - good issue reports and requests. -* [Environment](environment.md) gives an overview of the tools we use. +- [Triaging Issues](triage.md) covers many of the things the team looks for in + good issue reports and requests. +- Reviewing and Merging PRs - Coming Soon +- Project Layout - Coming Soon, explains our standard project structure, tools, + and configurations. +- Git Techniques - Coming Soon, talks about various git behaviors and commands. +- [Making a Release](release.md) You can also support us by [making a donation](../donate.md). ## What to Work On Anyone is welcome to work on any open ticket in any project's issue tracker, -no need to ask first. Before starting, check if anyone else is assigned to the +without asking first. Before starting, check if anyone else is assigned to the issue, or if there are any linked open pull requests. Look through the issue for that information as well as discussion and other linked issues for context. -Besides the core Pallets projects, there is an entire [ecosystem][] of -extensions built on top of them. We also have our own dependencies that we use -for our [development environment][]. Improving the ecosystem we're part of is a -great way to contribute to Pallets. +Besides the core Pallets projects, there is an entire [ecosystem] of extensions +built on top of them. We also have our own dependencies that we use for our +[development environment]. Improving the ecosystem we're part of is a great way +to contribute to Pallets. [ecosystem]: ../ecosystem.md -[development environment]: environment.md +[development environment]: layout Writing code is not the only way to contribute to an open source project. Other activities are just as helpful. Some ideas that are too broad for individual issues include: -* Improve this contributing guide! -* Improve documentation. - * Identify common and popular questions from Stack Overflow. We want users - to find official information from our documentation first. Perhaps we need - a new page for a topic, or need to mention a specific error message. - * Add or improve translations. We also want to improve the workflow around - updating and publishing translations. - * Our documentation is extensive, but it's been written over a long period - of time by many people. It could use the attention of people with - technical writing and editing skills. -* Improve how tests are organized and written to use modern pytest idioms. - * Some files have grown very large, or tests are not grouped well, or still - use `unittest` idioms. Perhaps tests can be split into more files, or use - pytest's parametrization feature. - * Improve test coverage by adding tests for lines and branches that are - not covered. -* Improve static type annotations. We target mypy primarily, but would also like - to improve compatibility with pyright. We also want to ensure we are using - types correctly, and add tests. -* Answer questions on GitHub Discussions and our Discord chat server. - Referencing canonical sources and providing explanation beyond the immediate - answer creates resources for others to find later and enables them to answer - in turn. +- Improve this contributing guide! +- Improve documentation. + - Identify common and popular questions from Stack Overflow. We want users + to find official information from our documentation first. Perhaps we + need a new page for a topic, or need to mention a specific error + message. + - Add or improve translations. We also want to improve the workflow around + updating and publishing translations. + - Our documentation is extensive, but it's been written over a long period + of time by many people. It could use the attention of people with + technical writing and editing skills. +- Improve how tests are organized and written to use modern pytest idioms. + - Some files have grown very large, or tests are not grouped well, or + still use `unittest` idioms. Perhaps tests can be split into more files, + or use pytest's parametrization feature. + - Improve test coverage by adding tests for lines and branches that are + not covered. +- Improve static type annotations. We target mypy primarily, but would also + like to improve compatibility with pyright. We also want to ensure we are + using types correctly, and add tests. +- Answer questions on GitHub Discussions and our Discord chat server. + Referencing canonical sources and providing explanation beyond the immediate + answer creates resources for others to find later and enables them to answer + in turn. ## Get Help Contributing -If you need help with the contributing process, or want to discuss an issue or -pull request you're working on, you can use the project-specific channels on -our Discord chat server: https://discord.gg/pallets. +If you need help with the contributing process beyond the guides here, or want +to discuss an issue or pull request you're working on, use the `#contributing` +channel on our Discord chat server: . -You can also use comments on the issue or pull request. After getting help or +You can also write comments on the issue or pull request. After getting help or researching about an issue, it's helpful to leave a comment there in order to keep public notes or help the next contributor. diff --git a/content/contributing/issues.md b/content/contributing/issues.md index 9925cab..5d5fc32 100644 --- a/content/contributing/issues.md +++ b/content/contributing/issues.md @@ -1,12 +1,33 @@ # Report an Issue -Include the following information in your post: +If you encounter an unexpected issue when using our libraries, you should report +it on the GitHub Issues tab. For example, Flask's is here: +. -- Describe what you expected to happen. -- Include a [minimal reproducible example][] to help us identify the issue. This - also helps check that the issue is not with your own code. -- Describe what actually happened. Include the full traceback if there was an exception. -- List the version of Python and the Pallets library you're using. Check if this - issue is already fixed in the latest release or the latest code in the repository. +If you have questions about your own code or how to use the libraries, read +[how to ask questions](questions.md). Don't use the issue tracker to ask +questions. -[minimal reproducible example]: https://stackoverflow.com/help/minimal-reproducible-example +Before reporting an issue, try to determine if it has already been reported or +fixed. Search existing issues and PRs, including closed issues and merged PRs. +Search for similar phrases, code, and errors. Check that you're using the latest +release. + +You don't need to report typos in documentation, unless you're unsure. Instead, +submitting a PR would probably be faster. This is _only_ the case for typos, for +everything else open an issue. + +Click the green "New issue" button at the top right to start. Include the +following information in your post: + +- Write a short, descriptive title. + - Do not include prefixes such as "\[bug]" or "\[docs]"; maintainers will + apply real tags as needed. + - Do not include a version number in the title. +- Describe what you expected to happen. +- Include a [minimal reproducible example] to help us identify the issue. This + also helps check that the issue is not with your own code. +- Describe what actually happened. Include the full traceback if there was an + exception. +- List the version of Python and the project you're using. Check if this issue + is already fixed in the latest release, or in `stable` or `main`. diff --git a/content/contributing/environment.md b/content/contributing/layout.md similarity index 62% rename from content/contributing/environment.md rename to content/contributing/layout.md index 7fb8172..e626d1b 100644 --- a/content/contributing/environment.md +++ b/content/contributing/layout.md @@ -3,10 +3,15 @@ Every project uses the same project layout and tools. It is helpful to be aware of them and their documentation when contributing. +Keeping every project consistent makes it easy for people to move between +projects. The more a project begins to diverge, the more likely it is to +cause an issue at an inopportune time. If something here is changed in one +project, it should be applied to all others as well. + ## Requirements Files -Each development environment uses a requirements file and the [pip-tools][] and -[pip-compile-multi][] tools to pin versions. This ensures that tests and builds +Each development environment uses a requirements file and the [pip-tools] and +[pip-compile-multi] tools to pin versions. This ensures that tests and builds are reproducible when setting up a new environment or looking at previous tags. The `requirements` folder contains `.in` files that list the direct, unpinned @@ -20,16 +25,16 @@ We do not use Dependabot to update these files as it is too noisy. ## Tests -[pytest][] is used to run the tests, found in the `tests` folder. +[pytest] is used to run the tests, found in the `tests` folder. -[tox][] is used to run different test environments, including Python versions, +[tox] is used to run different test environments, including Python versions, style checks, documentation, and typing. The `tox.ini` file configures this. -We do not currently run [coverage][]. While our test suite is fairly robust, +We do not currently run [coverage]. While our test suite is fairly robust, we don't have consistent enough coverage to make the reports useful at this time. We found that it does not impact our release quality. -[mypy][] is used for static type checking. Other tools may not give the same +[mypy] is used for static type checking. Other tools may not give the same results. See [here](tests.md) for information about writing, running, and improving @@ -42,12 +47,12 @@ tests and test coverage. ## Documentation -[Sphinx][] is used to build the documentation. The `docs` folder contains `.rst` -files, which are [ReStructuredText][]. +[Sphinx] is used to build the documentation. The `docs` folder contains `.rst` +files, which are [ReStructuredText]. -[Pallets-Sphinx-Themes][] contains the designs and extensions the projects use. +[Pallets-Sphinx-Themes] contains the designs and extensions the projects use. -The docs are built and hosted on [Read the Docs][]. It will also check that the +The docs are built and hosted on [Read the Docs]. It will also check that the docs build for pull requests. See [here](docs.md) for information about writing and building documentation. @@ -58,21 +63,21 @@ See [here](docs.md) for information about writing and building documentation. ## Code Style -Code style tools are run automatically on each commit using [pre-commit][]. +Code style tools are run automatically on each commit using [pre-commit]. The `.pre-commit-config.yaml` file pins the versions of each tool. -[pre-commit.ci][] runs these checks and commits fixes automatically on pull +[pre-commit.ci] runs these checks and commits fixes automatically on pull requests. It will also make PRs to update the pinned versions each month. See [setup](setup.md) for how to enable pre-commit. -[black][] enforces code formatting. +[black] enforces code formatting. -[flake8][] enforces style "lint" rules. [flake8-bugbear][] catches more +[flake8] enforces style "lint" rules. [flake8-bugbear] catches more opinionated rules. -[pyupgrade][] enforces using modern syntax for the Python versions we support. +[pyupgrade] enforces using modern syntax for the Python versions we support. -[reorder_python_imports][] enforces a standard format and order for all imports +[reorder_python_imports] enforces a standard format and order for all imports at the top of files. [pre-commit]: https://pre-commit.com diff --git a/content/contributing/pr.md b/content/contributing/pr.md index b703423..544d56f 100644 --- a/content/contributing/pr.md +++ b/content/contributing/pr.md @@ -1,57 +1,151 @@ # Creating a Pull Request -If there is not an open issue for what you want to submit, prefer -opening one for discussion before working on a PR. You can work on any -issue that doesn't have an open PR linked to it or a maintainer assigned -to it. These show up in the sidebar. No need to ask if you can work on -an issue that interests you. +If there is not an open issue for what you want to work on, prefer opening one +for discussion before working on a PR. See how to [Report an Issue](issues.md) +or [Request a Feature](features.md). -Include the following in your patch: +Anyone is welcome to work on any open issue without asking first. Check that the +issue is not marked as assigned (in the sidebar) and is not already linked to an +open PR. Do not ask to be assigned to an issue. Maintainers only use assignment +for themselves or during live sprints to avoid conflicting work. -- Use `Black`_ to format your code. This and other tools will run automatically - if you install `pre-commit`_ using the instructions below. -- Include tests if your patch adds or changes code. Make sure the test fails - without your patch. -- Update any relevant docs pages and docstrings. Docs pages and docstrings - should be wrapped at 80 characters. -- Add an entry in `CHANGES.rst`. Use the same style as other entries. Also - include `.. versionchanged::` inline changelogs in relevant docstrings. +Check [Environment Setup](setup.md) or [Quick Reference](quick.md) for how to +set up your development environment and run tests. This guide assumes you've +done that and used the GitHub CLI to fork and clone the repository and add the +upstream remote. -.. _Black: https://black.readthedocs.io -.. _pre-commit: https://pre-commit.com +## Create a Branch -## Start coding - -Create a branch to identify the issue you would like to work on. If you're -submitting a bug or documentation fix, branch off of the latest `A.B.x` branch. +To work on a bug or documentation fix, switch to the `stable` branch (if the +project has it), otherwise switch to the `main` branch. To update this target +branch, pull from `upstream`. Create a work branch with a short descriptive +name. The branch name does not need to include the issue number or prefixes +like `fix/` or `feature/`. ``` -$ git fetch origin -$ git checkout -b your-branch-name origin/2.0.x +$ git switch stable +$ git pull upstream +$ git switch -c short-descriptive-name ``` -If you're submitting a feature addition or change, branch off of the "main" branch. +## Investigate, Code, and Commit Changes + +Figuring out what to change can be as much of a challenge as figuring out how to +change it. If an issue includes a minimal reproducible example, you can try +running that with a debugger to track down the problem; or you may need to +formulate your own example script. Writing a test first to demonstrate the +desired behavior, then working to make the test pass, is another strategy. + +Make your changes and commit them. Committing as you work is fine, but can get +messy. Try to make each commit a logical chunk of work. If your PR includes many +commits, the maintainers may decide to squash it into a single commit when +merging. + +Commit messages should start with a short (<= 50 characters) first line. More +detail can be included, with a blank line separating it from the first line, +wrapped at 72 characters. Don't include issue numbers in the commit message, as +this makes GitHub's UI noisy and hard to follow. + +Besides the code itself, a pull request may need tests, docs, and other parts. +See the following guides for each part: + +- [Tests](tests.md) - Add tests that demonstrate that your code works, and + ensure all tests pass. Run `pytest` to run all tests. +- [Static Typing](typing.md) - Run `mypy` to check static typing. +- [Documentation](docs.md) - If behavior has changed somehow, check if any + documentation pages or docstrings need to be updated. +- [Changelog](changes.md) - Adding a change log entry is optional. A maintainer + will write one if you're not sure how to. Don't add an entry for changes that + only affect documentation or tool config. +- [Style](style.md) - pre-commit automatically applies lint and format checks. + +### Multiple Authors + +Git commit info only includes one author. If you are working with someone else, +you can add one or more `co-authored-by: name ` lines to the bottom of +each commit. GitHub will give you and all co-authors credit. + +### Syncing with Upstream + +If more changes are merged into the project while you're working, you may need +to update your branch to incorporate those changes. Remember to merge from the +same target branch you originally branched off of. You can also `rebase` instead +of `merge`, which is more complicated but produces nicer history. ``` -$ git fetch origin -$ git checkout -b your-branch-name origin/main +$ git fetch upstream +$ git merge upstream/stable +# or +$ git rebase -i upstream/stable ``` -Using your favorite editor, make your changes, [committing as you go][]. +If code you changed was also changed upstream, you'll need to resolve merge +conflicts. Many IDEs, including PyCharm and VS Code, have a UI for resolving +conflicts. There are also standalone merge tools as well. After resolving +conflicts, add and continue the merge. + +``` +$ git add -u +$ git merge --continue +# or +$ git rebase --continue +``` -If you are in a codespace, you will be prompted to [create a fork][] the first -time you make a commit. Enter `Y` to continue. +See [Help with Git](git.md) for more information about rebasing. -Include tests that cover any code changes you make. Make sure the test fails -without your patch. Run the tests as described below. +## Create the Pull Request -Push your commits to your fork on GitHub and [create a pull request][]. Link to the -issue being addressed with `fixes #123` in the pull request description. +Use the GitHub CLI to start submitting your work as a pull request. Specify the +target branch with `-B`. This is the same branch you branched off of at the +start. The `stable` branch is the target for bug and documentation fixes, +otherwise the target is `main`. ``` -$ git push --set-upstream origin your-branch-name +$ gh pr create --web --base stable ``` -[committing as you go]: https://afraid-to-commit.readthedocs.io/en/latest/git/commandlinegit.html#commit-your-changes -[create a fork]: https://docs.github.com/en/codespaces/developing-in-codespaces/using-source-control-in-your-codespace#about-automatic-forking -[create a pull request]: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request +Include the following information in your post: + +- Write a short descriptive title about the change you made. + - Do not include prefixes such as "\[fix]"; maintainers will apply real + tags as needed. + - Do not include issue numbers in the title. +- Describe the change and how it addresses the issue. +- Link to relevant issues or previous PRs, one per line. Prefix an issue with + "fixes" to close it with the PR. For example, "fixes #123", "continues + #123", etc. + +Open the PR in "draft" mode. Click the dropdown arrow on the green "Create pull +request" button and select "Create draft pull request". Changes to a draft PR +will not send notifications to everyone watching the project until it is marked +as ready. + +## Review and Merge + +Once you feel your PR is ready, click the "Ready for review" button. Maintainers +and other experienced contributors may leave review comments. You can push more +commits to address these comments. CI will run tests against the last commit; +you can click to see the logs and address any failures. + +Be aware that GitHub allows random people to leave comments and reviews, which +can often be low quality. If you're unsure about a comment, check if GitHub +shows a tag like "owner", "member", or "contributor" next to the user's name. If +not, and the suggestion doesn't seem good, you can ignore it. + +Maintainers also have the ability to push commits to your PR. They may choose to +use this for minor changes, or for changes they feel they're in a better +position to make. It's common for maintainers to add or rewrite the change log, +make style changes, and to rebase or squash commits. + +This process may take a long time, as maintainers have limited availability +across many projects. Please be patient. + +When a maintainer feels the PR is ready, they'll merge it. Or, after more review +of the issue and PR, they may decide to reject the issue or PR. It can be +discouraging to see your work unmerged, but either way doing the work gave you +experience and helped the maintainer make a decision. + +Once the PR is merged, the corresponding issue will be closed as well. Both the +issue and PR will be marked with a milestone indicating the future release +that will contain it. You can watch a repository's releases to get notified when +that happens. diff --git a/content/contributing/questions.md b/content/contributing/questions.md index 2268c4a..32f1e3b 100644 --- a/content/contributing/questions.md +++ b/content/contributing/questions.md @@ -1,14 +1,78 @@ # Asking and Answering Questions -Please don't use the issue tracker for this. The issue tracker is a tool to -address bugs and feature requests in the project itself. Use one of the -following resources for questions about using Flask or issues with your own -code: - -- First, search the web with your preferred search engine, giving the project - name and a specific search term such as an error message. -- Ask in the `#questions` channel on our Discord chat: . -- Use the project's [GitHub Discussions][] page for long term discussion or - larger questions. Each project has its own Discussions page. - -[GitHub Discussions]: https://github.com/pallets/flask/discussions +Don't use the issue tracker to ask questions. The issue tracker is a tool to +report and address bugs and feature requests in the project itself. Use one of +the following resources for questions about using our libraries or issues with +your own code: + +- First, search the web with your preferred search engine, giving the project + name and a specific search term such as an error message. +- Ask in the `#questions` channel on our Discord chat: + . +- Use the project's GitHub Discussions tab for long term discussion or + larger questions. Each project has its own Discussions tab. For example, + Flask's is here: . + +## How to Ask + +Try to keep your question focused on using our libraries, not other libraries. +For example, we'll probably be able to answer a question about integrating +SQLAlchemy with Flask, but ask questions about using SQLAlchemy itself in that +project's spaces instead. + +When using Discord, use the "Start thread" feature to create a space for your +question. Don't ping users unless you've already established a current +discussion with them. Don't ping users on every reply. Both of these behaviors +are disruptive and will not help you get answers. + +Try to keep your question specific. Asking broad questions will probably result +in broad and less helpful answers. Asking how to get started will probably +result in being pointed to existing documentation and tutorials. + +Include a [minimal reproducible example] that demonstrates the problem you're +asking about. Start from scratch and build up the minimum code necessary to show +the specific thing you're doing and its output or error. Linking to a full +project or requiring a complex setup will probably dissuade most answerers. + +[minimal reproducible example]: https://stackoverflow.com/help/minimal-reproducible-example + +Be aware of the [XY Problem][xy]. It can be easy, especially when learning +something new, to convince yourself you need to solve something a certain way, +while missing that the root problem is something else. Be open to this +possibility, as others with more familiarity with the project might point it out +to you. + +[xy]: https://en.wikipedia.org/wiki/XY_problem + +## How to Answer + +A great way to contribute is to answer questions asked on Discord or the +project's GitHub Discussions tab. The more people answer helpfully, the more +people will want to ask and participate, and our community will grow. + +Try to answer questions directly and politely. After answering the +immediate question, it's fine to suggest other improvements, or ask followup +questions. Avoid being overwhelming or judgemental. Avoid phrases like "just do this", "it's obvious", +"why would you do that", etc. Remember, everyone is at a different stage of +learning, and you were there once as well. + +Try to explain why your answer works rather than only saying what to do. Linking +to specific documentation along with your answer provides a helpful future +reference. For example, "You need to temporarily push an app context so Flask +knows what to access, here's how..." is more helpful than a plain "Use a +`with app.app_context()` block." + +If you notice that a question is asked often, that could be an indication that +we should improve our documentation about that topic. Consider reporting an +issue or writing a PR in that case. + +Remember, you're answering questions for fun, you are not obligated to perform +any amount of work. You do not need to participate in every question. If you're +not familiar with a topic, don't like how a question was asked, or don't have +time, you can leave it to someone else to pick up. + +Be aware of the "Asking" section above. If a new user doesn't provide enough +detail or isn't clear, gently point them towards that. If a user isn't getting +it, disengage rather than having a prolonged back-and-forth. If you believe +someone is being disruptive or taking up too much attention, message moderators +privately. diff --git a/content/contributing/quick.md b/content/contributing/quick.md new file mode 100644 index 0000000..a2f9d94 --- /dev/null +++ b/content/contributing/quick.md @@ -0,0 +1,109 @@ +# Contributing Quick Reference + +This document assumes you have some familiarity with Git, GitHub, and Python +virutalenvs. If you're not familiar with contributing to Python projects, you +can refer to the [Detailed Development Environment Setup](setup.md) instead. + +These instructions will work with at least Bash and PowerShell, and should work +on other shells. On Windows, use PowerShell, not CMD. + +You need Python and Git installed, as well as the [GitHub CLI]. Log in with +`gh auth login`. Choose and install an editor; we suggest [PyCharm] or +[VS Code]. + +[GitHub CLI]: https://cli.github.com/ +[PyCharm]: https://www.jetbrains.com/pycharm/ +[VS Code]: https://code.visualstudio.com/ + +## Set Up the Repository + +Fork and clone the project's repository ("pallets/flask" for example). To work +on a bug or documentation fix, switch to the "stable" branch (if the project has +it), otherwise switch to the "main" branch. To update this target branch, pull +from "upstream". Create a work branch with a short descriptive name. + +``` +$ gh repo fork --clone pallets/flask +$ cd flask +$ git switch stable +$ git pull upstream +$ git switch -c short-descriptive-name +``` + +## Install Development Dependencies + +Create a virtualenv and activate it. Install the dev dependencies, and the +project in editable mode. Install the pre-commit hooks. + +Create a virtualenv (Mac and Linux): + +``` +$ python3 -m venv .venv +$ . .venv/bin/activate +``` + +Create a virtualenv (Windows): + +``` +> py -m venv .venv +> .\.venv\Scripts\activate +``` + +Install (all platforms): + +``` +$ pip install -r requirements/dev.txt && pip install -e . +$ pre-commit install --install-hooks +``` + +Any time you open a new terminal, you need to activate the virtualenv again. If +you've pulled from upstream recently, you can re-run the `pip` command above to +get the current dev dependencies. + +## Run Tests + +These are the essential test commands you can run while developing: + +- `pytest` - Run the unit tests. +- `mypy` - Run the main type checker. +- `tox run -e docs` - Build the documentation. + +These are some more specific commands if you need them: + +- `tox parallel` - Run all test environments that will be run in CI, in + parallel. Python versions that are not installed are skipped. +- `pre-commit` - Run the linter and formatter tools. Only runs against changed + files that have been staged with `git add -u`. This will run automatically + before each commit. +- `pre-commit run --all-files` - Run the pre-commit hooks against all files, + including unchanged and unstaged. +- `tox run -e py3.11` - Run unit tests with a specific Python version. The + version must be installed. `-e pypy` will run against PyPy. +- `pyright` - A second type checker. +- `tox run -e typing` - Run all typing checks. This includes `pyright` and its + export check as well. +- `python -m http.server -b 127.0.0.1 -d docs/_build/html` - Serve the + documentation. +- `tox run` and `tox parallel` can be shortened to `tox r` and `tox p`. + +## Create a Pull Request + +Make your changes and commit them. Add tests that demonstrate that your code +works, and ensure all tests pass. Change documentation if needed to reflect your +change. Adding a changelog entry is optional, a maintainer will write one if +you're not sure how to. Add the entry to the end of the relevant section, match +the writing and formatting style of existing entries. Don't add an entry for +changes that only affect documentation or project internals. + +Use the GitHub CLI to start creating your pull request. Specify the target +branch with `-B`. The "stable" branch is the target for bug and documentation +fixes, otherwise the target is "main". + +``` +$ gh pr create --web --base stable +``` + +CI will run after you create the PR. If CI fails, you can click to see the logs +and address those failures, pushing new commits. Once you feel your PR is ready, +click the "Ready for review" button. A maintainer will review and merge the PR +when they are available. diff --git a/content/contributing/release.md b/content/contributing/release.md index b8c83ea..16b0e1f 100644 --- a/content/contributing/release.md +++ b/content/contributing/release.md @@ -1,77 +1,127 @@ # Creating a Release -This document explains the process of creating a release and everything you need to do and check along the way. Despite the length of this document, this is intended to be an easy process once you're used to it. Be sure to read it through the first time you do a release. Next time, you can use this abbreviated checklist. - -1. Decide to make a release. -2. Ensure the change log has entries for each user-facing non-docs change, with links to the related issue reports. -3. Ensure each issue and PR is in the milestone. -4. Create a `release-A.B.C` branch. -5. Change "Unreleased" to "Released YYYY-MM-DD" in `CHANGES.md`. -6. Remove the ".dev" suffix from the version in `pyproject.toml`. -7. Commit `git commit -am 'release version A.B.C'` and create a PR. -8. Tag `git tag -am 'release version A.B.C' A.B.C` and push `git push origin A.B.C`. -9. Watch the tests pass and build jobs begin. +This document explains the process of creating a release and everything you need +to do and check along the way. Despite the length of this document, this is +intended to be an easy process once you're used to it. Be sure to read it +through the first time you do a release. Next time, you can use this abbreviated +checklist. + +1. Decide to make a release. +2. Ensure the change log has entries for each user-facing non-docs change, with + links to the related issue reports. +3. Ensure each issue and PR is in the milestone. +4. Create a `release-A.B.C` branch. +5. Change "Unreleased" to "Released YYYY-MM-DD" in `CHANGES.md`. +6. Remove the ".dev" suffix from the version in `pyproject.toml`. +7. Commit `git commit -am 'release version A.B.C'` and create a PR. +8. Tag `git tag -am 'release version A.B.C' A.B.C` and push + `git push origin A.B.C`. +9. Watch the tests pass and build jobs begin. 10. Edit the generated draft release page with our standard message template. 11. Approve the upload job. 12. Merge the PR. Use "create a merge commit", not "squash" or "rebase"! 13. Close the milestone. 14. Publish the draft release page. -15. Start the next version(s), creating a change log section, bumping the version in `pyproject.toml` with the `.dev` suffix. +15. Start the next version(s), creating a change log section, bumping the + version in `pyproject.toml` with the `.dev` suffix. 16. Done! ## Decision -There is no precise way to know that it's time for a release. Ideally, fixes should be released within a few weeks (perhaps to wait and see if more bugs need to be fixed), and features should be released perhaps twice a year. We don't want to overwhelm our users with constant releases or churn, but we also don't want to delay things forever. Ultimately, it's up to a maintainer to decide that the time "feels right" for a new release and start the process. +There is no precise way to know that it's time for a release. Ideally, fixes +should be released within a few weeks (perhaps to wait and see if more bugs need +to be fixed), and features should be released perhaps twice a year. We don't +want to overwhelm our users with constant releases or churn, but we also don't +want to delay things forever. Ultimately, it's up to a maintainer to decide that +the time "feels right" for a new release and start the process. ## Preparation -Each project has two branches and milestones that represent the two upcoming releases. `main` tracks the next feature release, which should have a corresponding `A.B.0` milestone. `stable` tracks the next fix release, which should have a corresponding `A.B.C` (where `C > 0`) milestone. +Each project has two branches and milestones that represent the two upcoming +releases. `main` tracks the next feature release, which should have a +corresponding `A.B.0` milestone. `stable` tracks the next fix release, which +should have a corresponding `A.B.C` (where `C > 0`) milestone. -Each merged PR, and any issues associated with it, should be marked with the appropriate milestone. This makes it easier to review what changes are ready to be released, and what may still be blocking a release. If a PR or issue in a milestone has not been merged yet, you can make the decision to unmark it to unblock a release. +Each merged PR, and any issues associated with it, should be marked with the +appropriate milestone. This makes it easier to review what changes are ready to +be released, and what may still be blocking a release. If a PR or issue in a +milestone has not been merged yet, you can make the decision to unmark it to +unblock a release. -In each branch, the `CHANGES.md` file should have a section for the upcoming release. Each PR should have a corresponding entry in the change log (for user-facing changes only, and not docs). Each entry should link to the corresponding issue with `` {issue}`number` ``. If a PR doesn't have a corresponding issue, use `{pr}` instead of `{issue}` for the link. Ideally, this was part of the PR when it was merged, you should not be creating the entire change log at the last minute. +In each branch, the `CHANGES.md` file should have a section for the upcoming +release. Each PR should have a corresponding entry in the change log (for +user-facing changes only, and not docs). Each entry should link to the +corresponding issue with `` {issue}`number` ``. If a PR doesn't have a +corresponding issue, use `{pr}` instead of `{issue}` for the link. Ideally, this +was part of the PR when it was merged, you should not be creating the entire +change log at the last minute. -Review the milestone and change log to ensure each PR has a change entry, is in the milestone, and is linked to an issue, which is also in the milestone. +Review the milestone and change log to ensure each PR has a change entry, is in +the milestone, and is linked to an issue, which is also in the milestone. -Ensure everything from `stable` has been merged into `main` if you're creating a feature release. +Ensure everything from `stable` has been merged into `main` if you're creating a +feature release. -The tests will be run as part of the release PR, but you can also run `tox` locally to ensure everything is passing first. +The tests will be run as part of the release PR, but you can also run `tox` +locally to ensure everything is passing first. ## Start the Release Process -The release process is managed through a PR. This allows you to see that all tests pass, and that the build passes, by looking at the standard PR checks UI. - -1. Check out the `main` or `stable` branch depending on what release you're making. -2. Check out a new branch with the name `release-A.B.C`, for example `release-{3.2.0}`. -3. Update `CHANGES.md` to change `Unreleased` to `Released YYYY-MM-DD`, for example `Released 2024-08-04`. -4. Update `pyproject.toml` to change `[project].version`, removing the `.dev` suffix and ensuring the version number is correct. -5. Commit the changes with the message `release version A.B.C`. -6. Push the branch to the main repository, not a fork, and create a PR. - * The PR title will default to the commit message, and the description can be empty. - * Assign the appropriate milestone to the PR. - -After the PR is created, the normal test workflow will run. In the mean time, you start the build process by pushing a tag. - -1. Tag the release commit you just created. `git tag -am 'release version A.B.C'` - * The `-am` creates an annotated tag with a message. Don't forget the `-am`! -2. Push the tag to the main repository, not a fork. `git push origin A.B.C` - -The `publish.yaml` workflow will start to run and you'll see build-related checks show up in the PR checks UI. First, it builds the sdist and wheel. Then it generates an SLSA attestation for those files. Then it creates a draft release and uploads the build and attestation file to it. Finally, you'll see it waiting for approval to upload to PyPI. Don't approve it yet, there's more to do first. +The release process is managed through a PR. This allows you to see that all +tests pass, and that the build passes, by looking at the standard PR checks UI. + +1. Check out the `main` or `stable` branch depending on what release you're + making. +2. Check out a new branch with the name `release-A.B.C`, for example + `release-{3.2.0}`. +3. Update `CHANGES.md` to change `Unreleased` to `Released YYYY-MM-DD`, for + example `Released 2024-08-04`. +4. Update `pyproject.toml` to change `[project].version`, removing the `.dev` + suffix and ensuring the version number is correct. +5. Commit the changes with the message `release version A.B.C`. +6. Push the branch to the main repository, not a fork, and create a PR. + - The PR title will default to the commit message, and the description can + be empty. + - Assign the appropriate milestone to the PR. + +After the PR is created, the normal test workflow will run. In the meantime, you +start the build process by pushing a tag. + +1. Tag the release commit you just created. `git tag -am 'release version A.B.C'` + - The `-am` creates an annotated tag with a message. Don't forget the `-am`! +2. Push the tag to the main repository, not a fork. `git push origin A.B.C` + +The `publish.yaml` workflow will start to run and you'll see build-related +checks show up in the PR checks UI. First, it builds the sdist and wheel. Then +it generates an SLSA attestation for those files. Then it creates a draft +release and uploads the build and attestation file to it. Finally, you'll see it +waiting for approval to upload to PyPI. Don't approve it yet, there's more to do +first. ## Prepare the Release Message -Go to the releases for the project, and find the draft release at the top of the list. Click edit. While editing, you can click "Save draft", but do not click "Publish" until after the release is complete. +Go to the releases for the project, and find the draft release at the top of the +list. Click edit. While editing, you can click "Save draft", but do not click +"Publish" until after the release is complete. -The uploaded files from the previous step will be listed at the bottom. Do they look right? Do they have the right version? If you're really worried, you can also download the file and check if the contents look right, but this shouldn't be needed +The uploaded files from the previous step will be listed at the bottom. Do they +look right? Do they have the right version? If you're really worried, you can +also download the file and check if the contents look right, but this shouldn't +be needed -Currently, the workflow does not populate the release message, so you'll need to fill it in. This will be automated in the future. The message has the following format: +Currently, the workflow does not populate the release message, so you'll need to +fill it in. This will be automated in the future. The message has the following +format: For feature releases, the explanation is: ```markdown -This is the {project} {version} feature release. A feature release may include new features, remove previously deprecated code, add new deprecations, or introduce potentially breaking changes. +This is the {project} {version} feature release. A feature release may include +new features, remove previously deprecated code, add new deprecations, or +introduce potentially breaking changes. -We encourage everyone to upgrade. You can read more about our [Version Support Policy][version] on our website. +We encourage everyone to upgrade. You can read more about our +[Version Support Policy][version] on our website. [version]: https://palletsprojects.com/versions @@ -81,13 +131,18 @@ Milestone https://github.com/pallets-eco/{project}/milestones/{milestone}?closed {change entries, markdown, replace links} -Please remember, applications _must_ lock their full dependency tree to control when updates are installed and ensure reproducible deployments. Use one of the various project management or lock tools available in the Python ecosystem. Test with warnings treated as errors to be able to adapt to deprecation warnings early. +Please remember, applications _must_ lock their full dependency tree to control +when updates are installed and ensure reproducible deployments. Use one of the +various project management or lock tools available in the Python ecosystem. Test +with warnings treated as errors to be able to adapt to deprecation warnings early. ``` For fix releases, the explanation is: ```markdown -This is the {project} {version} fix release, which fixes bugs but does not otherwise change behavior and should not result in breaking changes compared to the latest feature release. +This is the {project} {version} fix release, which fixes bugs but does not +otherwise change behavior and should not result in breaking changes compared to +the latest feature release. PyPI: https://pypi.org/project/{pypi name}/{version}/ Changes: https://{project}.readthedocs.io/en/stable/changes/#version-{A-B-C} @@ -96,52 +151,75 @@ Milestone https://github.com/pallets-eco/{project}/milestones/{milestone}?closed {change entries, markdown, replace links} ``` -Copy and paste the change log entries from the version's section. You'll need to replace the `` {issue}`number` `` markup with `#number`. If the change log is still in `.rst` format, you'll need to make sure it renders correctly in Markdown, or use a tool like `rst2myst` to convert them. Over time, we plan to make all change log files Markdown to avoid this issue. +Copy and paste the change log entries from the version's section. You'll need to +replace the `` {issue}`number` `` markup with `#number`. If the change log is +still in `.rst` format, you'll need to make sure it renders correctly in +Markdown, or use a tool like `rst2myst` to convert them. Over time, we plan to +make all change log files Markdown to avoid this issue. -**Never use GitHub's "Generate release notes" feature.** Copying each commit message/PR title is not helpful compared to the curated change log we produce. Additionally, the pings it adds for each contribtor can become spammy, especially if mirrors/bots pick up the release and copy it into other issues/commits, which _has_ happened in the past. +**Never use GitHub's "Generate release notes" feature.** Copying each commit +message/PR title is not helpful compared to the curated change log we produce. +Additionally, the pings it adds for each contribtor can become spammy, +especially if mirrors/bots pick up the release and copy it into other +issues/commits, which _has_ happened in the past. ## Finalize the Release -Approve the upload job. In the PR check status window, click to view the "pypi-publish" job. You should see a link to "Review pending deployments", clicking it will open a confirmation window. Select the "publish" item and click "Approve". You'll see the publish workflow begin. Wait for it to complete successfully. +Approve the upload job. In the PR check status window, click to view the +"pypi-publish" job. You should see a link to "Review pending deployments", +clicking it will open a confirmation window. Select the "publish" item and click +"Approve". You'll see the publish workflow begin. Wait for it to complete +successfully. -Close the milestone. Click the link to the milestone from the PR, click "Edit", then click "Close". +Close the milestone. Click the link to the milestone from the PR, click "Edit", +then click "Close". -Merge the PR. **Make sure the "create a merge commit" strategy is selected.** Using the "sqaush" or "rebase" strategies will cause the tagged commit to be out of sync with the repo. Remember, you tagged the _specific_ commit in the PR, squashing or rebasing would re-create that commit so the tag would no longer be valid. This is recoverable with difficulty, but don't let it happen. +Merge the PR. **Make sure the "create a merge commit" strategy is selected.** +Using the "sqaush" or "rebase" strategies will cause the tagged commit to be out +of sync with the repo. Remember, you tagged the _specific_ commit in the PR, +squashing or rebasing would re-create that commit so the tag would no longer be +valid. This is recoverable with difficulty, but don't let it happen. -Publish the release page. Go back to the draft release page and click "Publish". Anyone watching the repository for releases will get a notification. +Publish the release page. Go back to the draft release page and click "Publish". +Anyone watching the repository for releases will get a notification. ## Start the Next Version ### After a Fix Release -Optimistically, there won't be another fix release after a fix release, so you can defer doing all this until at least one issue is reported. - -1. Create a milestone for `A.B.C+1`. -2. Start the next fix version. - 1. `git switch stable && git pull` - 2. Update `CHANGES.md` to add a new section at the top: +Optimistically, there won't be another fix release after a fix release, so you +can defer doing all this until at least one issue is reported. +1. Create a milestone for `A.B.C+1`. +2. Start the next fix version. + 1. `git switch stable && git pull` + 2. Update `CHANGES.md` to add a new section at the top: ```markdown ## Version A.B.C+1 Unreleased ``` - - 3. Update `pyproject.toml` to change `[project].version`. Set it to `A.B.C+1.dev`, note the `.dev` suffix. - 4. Commit the changes with the message `start version A.B.C+1` - 5. Push this commit, no need to create a PR. -3. Merge `stable` into `main`. Make sure the new change log section is merged _below_ the section for the next feature relase, and that the version isn't overwritten. -4. Push `main`. + 3. Update `pyproject.toml` to change `[project].version`. Set it to + `A.B.C+1.dev`, note the `.dev` suffix. + 4. Commit the changes with the message `start version A.B.C+1` + 5. Push this commit, no need to create a PR. +3. Merge `stable` into `main`. Make sure the new change log section is merged + _below_ the section for the next feature relase, and that the version isn't + overwritten. +4. Push `main`. ### After a Feature Release -Realistically, there will be at least one fix release after a feature release, and there will be the next feature release as well. +Realistically, there will be at least one fix release after a feature release, +and there will be the next feature release as well. -1. Create a milestone for `A.B+1.0`, the next feature release. -2. Create a milestone for `A.B.1`, the first fix release. -3. Fast forward `stable` to point at `main`. From `stable`: `git merge --ff-only main`. -3. Start the next fix version, as described in the previous section. -4. Start the next feature version, using the same steps describe in the previous section, except on `main`. +1. Create a milestone for `A.B+1.0`, the next feature release. +2. Create a milestone for `A.B.1`, the first fix release. +3. Fast-forward `stable` to point at `main`. From `stable`: + `git merge --ff-only main`. +4. Start the next fix version, as described in the previous section. +5. Start the next feature version, using the same steps describe in the + previous section, except on `main`. ## Done! diff --git a/content/contributing/setup.md b/content/contributing/setup.md index b17342c..12477e7 100644 --- a/content/contributing/setup.md +++ b/content/contributing/setup.md @@ -1,44 +1,52 @@ # Development Environment Setup -## GitHub Codespaces +This is a detailed guide on how to set up Python, Git, and a development +environment for our projects. Each of our projects uses the same layout, making +it easier to move between projects. Following these instructions will ensure +that every contributor has the same tools installed at the same versions in the +same way, which makes it easier for everyone to help each other. -[GitHub Codespaces][] creates a development environment that is already set up -for the project. By default it opens in Visual Studio Code for the Web, but this -can be changed in your GitHub profile settings to use Visual Studio Code or -JetBrains PyCharm on your local computer. +If you're already familiar with contributing to Python projects, you can refer +to the [Quick Reference](quick.md) instead. -- Make sure you have a [GitHub account][]. -- From the project's repository page, click the green "Code" button and then - "Create codespace on main". -- The codespace will be set up, then Visual Studio Code will open. However, - you'll need to wait a bit longer for the Python extension to be installed. - You'll know it's ready when the terminal at the bottom shows that the - virtualenv was activated. -- Check out a new branch and start coding. +[venv]: https://docs.python.org/3/library/venv.html +[pip]: https://pip.pypa.io -## Local Environment +## GitHub and Git -- Make sure you have a [GitHub account][]. -- Download and install the [latest version of git][]. -- Configure git with your [username][] and [email][]. GitHub provides everyone - a placeholder email if you don't want to publish yours. +- Make sure you have a [GitHub account][github]. +- Download and install the [latest version of Git][git]. +- Configure Git with your [name] and [email]. ``` $ git config --global user.name 'your name' $ git config --global user.email 'your email' ``` -- [Fork][] the project to your GitHub account by clicking the "Fork" button. + - +- [Fork] the project to your GitHub account by clicking the "Fork" button. - Clone your fork locally, replacing `your-username` and `project` in the - command below with your actual username and the actual project name. + command below with your actual username and the actual project name. Change + directory into the cloned project. ``` $ git clone https://github.com/your-username/project $ cd project ``` -- Create a virtualenv. Use the latest version of Python. +- Install the latest version of Python. + - Linux: `python3` is likely already installed, otherwise use your + system's package manager to install it. + - macOS/Windows: Download and run the appropriate installer from + https://python.org/downloads/. The yellow "Download" button near the top + left of the page will download the latest stable version. +- Create and activate a virtualenv. Use the latest version of Python. - Linux/macOS ``` $ python3 -m venv .venv $ . .venv/bin/activate ``` + - On Ubuntu or Debian, you'll need to install `venv` first, otherwise + the above command will fail. + ``` + $ sudo apt install python3-venv + ``` - Windows ``` > py -3 -m venv .venv @@ -49,14 +57,24 @@ JetBrains PyCharm on your local computer. ``` $ pip install -r requirements/dev.txt && pip install -e . ``` + - On Windows CMD, `&&` doesn't work, so run the two commands separately. - Install the pre-commit hooks. ``` $ pre-commit install --install-hooks ``` -[GitHub Codespaces]: https://docs.github.com/en/codespaces -[GitHub account]: https://github.com/join -[latest version of git]: https://git-scm.com/downloads -[username]: https://docs.github.com/en/github/using-git/setting-your-username-in-git -[email]: https://docs.github.com/en/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address +[github]: https://github.com +[git]: https://git-scm.com/downloads +[name]: https://docs.github.com/en/get-started/getting-started-with-git/setting-your-username-in-git +[email]: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-email-preferences/setting-your-commit-email-address [Fork]: https://docs.github.com/en/get-started/quickstart/fork-a-repo + +## Debugger + +Many IDEs, including [PyCharm] and [VS Code], include a debugger UI. There are also +standalone debuggers such as [pudb], [pdbp], [ipdb], and [bpdb]. + +[pudb]: https://github.com/inducer/pudb#readme +[pdbp]: https://github.com/mdmintz/pdbp#readme +[ipdb]: https://github.com/gotcha/ipdb#readme +[bpdb]: https://docs.bpython-interpreter.org/en/latest/bpdb.html diff --git a/content/contributing/tests.md b/content/contributing/tests.md index 00c7439..c548552 100644 --- a/content/contributing/tests.md +++ b/content/contributing/tests.md @@ -18,7 +18,17 @@ $ tox ## Coverage -Generating a report of lines that do not have test coverage can indicate +Most projects do not actively check code coverage percentage. It can be checked +by running pytest with coverage. + +``` +$ coverage run -m pytest +$ coverage report +$ coverage html # open htmlcov/index.html in your browser +``` + +This generates a report of lines that do not have test coverage. You can use +this to confirmcan indicate where to start contributing. Run `pytest` using `coverage` and generate a report. @@ -34,3 +44,24 @@ $ coverage html Open `htmlcov/index.html` in your browser to explore the report. Read more about [coverage](https://coverage.readthedocs.io). + + +## Writing + + +Add tests that demonstrate that your code works, and ensure all tests pass. +Tests are located in the `tests` directory. We use [pytest] as our test runner. +Run `pytest` to run all the tests with the current Python version. + +[pytest]: https://pytest.org + +Tests are generally organized by topic in `test_{topic}.py` files, and within +each file each test is a `test_{specific}` function. The test function name +should be unique, somewhat descriptive without being too long. + +Each test should test one thing, using `assert` statements to check expected +properties of that one thing. If you have multiple test cases, use the +[`@pytest.mark.parametrize`][parametrize] decorator to run the same test with +different arguments. + +[parametrize]: https://docs.pytest.org/en/stable/how-to/parametrize.html#pytest-mark-parametrize-parametrizing-test-functions diff --git a/content/contributing/triage.md b/content/contributing/triage.md index d0b6bd1..d30b028 100644 --- a/content/contributing/triage.md +++ b/content/contributing/triage.md @@ -7,10 +7,10 @@ make; this page is a loose collection of guidelines to keep in mind. Close issues or ask for clarification as needed. Determine if the issue is with the Pallets library. Issues with the user's own -code should be asked as [questions][] instead, use the "Convert to -discussion" link at the bottom of the sidebar. Issues with another library, -often indicated by a traceback pointing to other code, should be reported to -that library instead. +code should be asked as [questions] instead, use the "Convert to discussion" +link at the bottom of the sidebar. Issues with another library, often indicated +by a traceback pointing to other code, should be reported to that library +instead. [questions]: questions.md @@ -30,9 +30,9 @@ succinctly and directly, without "tags" like `[feature]`, and without versions. Search for existing issues. Searching excludes closed issues by default, and users often miss this, especially when reporting bugs after new releases. Close duplicate issues with a link to the duplicate. If an issue should remain open, -it's still useful to link to relevant prior discussions and PRs. If the issue -is with another library, try check if it's already been reported there and link -that, or suggest that the user does so. +it's still useful to link to relevant prior discussions and PRs. If the issue is +with another library, check if it's already been reported there and link that, +or suggest that the user does so. Add tags to indicate what component the issue is related to. We don't use a "bug" or "feature" tag, but we do use tags like "docs", "debugger", "windows", @@ -45,9 +45,9 @@ once it is known make sure it is recorded. If a milestone does not exist for the next version yet, create one. Some issues may be closed by our policies published on this site. Issues with -deprecations and removals should be linked to [Version Policy][]. Issues asking -for a new release should be linked to [Release Policy][]. If a user posts a -security issue publicly, link to [Security Policy][] and ping a core maintainer. +deprecations and removals should be linked to [Version Policy]. Issues asking +for a new release should be linked to [Release Policy]. If a user posts a +security issue publicly, link to [Security Policy] and ping a core maintainer. [Version Policy]: ../versions.md [Release Policy]: ../releases.md diff --git a/src/pallets/templates/layout.html b/src/pallets/templates/layout.html index fe8768a..b14dd62 100644 --- a/src/pallets/templates/layout.html +++ b/src/pallets/templates/layout.html @@ -19,6 +19,7 @@