snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
This commit is contained in:
51
docs/contributing/asking-great-questions.md
Normal file
51
docs/contributing/asking-great-questions.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Asking great questions
|
||||
|
||||
A well-formed question helps you learn, respects the person answering, and makes
|
||||
efficient use of time for everyone involved. Asking the right question, to the
|
||||
right person, in the right way, at the right time, is a skill that requires a
|
||||
lifetime of fine-tuning. This page offers some guidelines and resources the
|
||||
[Zulip community](https://zulip.com/development-community/) has found helpful in this pursuit.
|
||||
|
||||
## Where to ask your question
|
||||
|
||||
It is almost always best to ask questions and have a conversation in a public
|
||||
channel, rather than in direct messages. You’ll get better and faster answers
|
||||
since many people can help, and it makes it possible for others to benefit from
|
||||
the discussion.
|
||||
|
||||
The [Zulip community
|
||||
guide](https://zulip.com/development-community/#where-do-i-send-my-message)
|
||||
offers guidelines on how the major public channels in the community are used.
|
||||
Don’t stress too much about picking the right place if you’re not sure, as
|
||||
moderators can [move your question thread to a different
|
||||
channel](https://zulip.com/help/move-content-to-another-channel) if needed.
|
||||
|
||||
## How to ask a great question
|
||||
|
||||
Spending some extra time and effort to carefully formulate your question is well
|
||||
worthwhile, as it makes it much more likely that you'll get the information you
|
||||
need to move forward. There are a few wonderfully thoughtful blog posts that
|
||||
explain what it means to ask a good question:
|
||||
|
||||
- [Try, Then Ask](https://www.mattringel.com/2013/09/30/you-must-try-and-then-you-must-ask/)
|
||||
- [We Aren’t Just Making Code, We’re Making History](https://www.harihareswara.net/sumana/2016/10/12/0)
|
||||
- [How to Ask Good Questions](https://jvns.ca/blog/good-questions/)
|
||||
|
||||
In brief, to formulate a great question, you should:
|
||||
|
||||
- Try to solve your own problem first, including reading through relevant
|
||||
documentation and code.
|
||||
- Identify the precise point on which you feel stuck.
|
||||
- Formulate a clear question that includes an appropriate amount of context
|
||||
and a specific request for help.
|
||||
|
||||
When your question is answered, follow through on the advice you receive, and (when
|
||||
appropriate) summarize the resolution of your problem so that others can learn
|
||||
from your experience.
|
||||
|
||||
## Follow the community guidelines
|
||||
|
||||
As always, be sure to follow the [Zulip community
|
||||
norms](https://zulip.com/development-community/). In particular, check out [the
|
||||
section on getting help](https://zulip.com/development-community/#getting-help)
|
||||
before you post.
|
||||
429
docs/contributing/code-reviewing.md
Normal file
429
docs/contributing/code-reviewing.md
Normal file
@@ -0,0 +1,429 @@
|
||||
# Reviewing Zulip code
|
||||
|
||||
Code review is a key part of how Zulip does development. It's an essential
|
||||
aspect of our process to build a high-quality product with a maintainable
|
||||
codebase. See the [pull request review process](../contributing/review-process.md)
|
||||
guide for a detailed overview of Zulip's PR review process.
|
||||
|
||||
## Principles of code review
|
||||
|
||||
Zulip has an active contributor community, and just a small handful
|
||||
of maintainers who can do the final rounds of code review. As such, we would
|
||||
love for contributors to help each other with making pull requests that are not
|
||||
only correct, but easy to review. Doing so ensures that PRs can be finalized and
|
||||
merged more quickly, and accelerates the pace of progress for the entire
|
||||
project.
|
||||
|
||||
If you're new to open source, this may be the first time you do a code review of
|
||||
anyone's changes! We have therefore written this step-by-step guide to be
|
||||
accessible to all Zulip contributors.
|
||||
|
||||
### Reviewing your own code
|
||||
|
||||
One of the best ways to improve the quality of your own work as a software
|
||||
engineer is to do a code review of your own work before submitting it to others for
|
||||
review. We thus strongly encourage you to get into the habit of reviewing your
|
||||
own code. You can often find things you missed by taking a step back to look
|
||||
over your work before asking others to do so, and this guide will walk you
|
||||
through the process. Catching mistakes yourself will help your PRs be merged
|
||||
faster, and folks will appreciate the quality and professionalism of your
|
||||
work.
|
||||
|
||||
### Reviewing other contributors' code
|
||||
|
||||
Doing code reviews is a valuable contribution to the Zulip project.
|
||||
It's also an important skill to develop for participating in
|
||||
open-source projects and working in the industry in general. If
|
||||
you're contributing to Zulip and have been working in our code for a
|
||||
little while, we would love for you to start doing code reviews!
|
||||
|
||||
Anyone can do a code review -- you don't have to have a ton of experience, and
|
||||
you don't have to have the power to ultimately merge the PR. The sections below
|
||||
offer accessible, step-by-step guidance for how to go about reviewing Zulip PRs.
|
||||
|
||||
For students participating in Google Summer of Code or a similar
|
||||
program, we expect you to spend a chunk of your time each week (after
|
||||
the first couple of weeks as you're getting going) doing code reviews.
|
||||
|
||||
## How to review code
|
||||
|
||||
Whether you are reviewing your own code or somebody else's, this section
|
||||
describes how to go about it.
|
||||
|
||||
If you are reviewing somebody else's code, you will likely need to first fetch
|
||||
it so that you can play around with the new functionality. If you're working in
|
||||
the Zulip server codebase, use our [Git tool][git-tool]
|
||||
`tools/fetch-rebase-pull-request` to check out a pull request locally and rebase
|
||||
it onto `main`.
|
||||
|
||||
### Code review checklist
|
||||
|
||||
The following review steps apply to the majority of PRs.
|
||||
|
||||
**Think about the issue:**
|
||||
|
||||
1. Start by **rereading the issue** the PR is intended to solve. Are you
|
||||
confident that you **understand everything the issue is asking for**? If not,
|
||||
try exploring the relevant parts of the Zulip app and reading any linked
|
||||
discussions on the [development community server][czo] to see if the
|
||||
additional context helps. If any part is still confusing, post a GitHub
|
||||
comment or a message on the [development community server][czo] explaining
|
||||
precisely what points you find confusing.
|
||||
|
||||
2. Now that you're confident that you understand the issue, **does the PR
|
||||
address all the points described in the issue**? If not, is it easy to tell
|
||||
without reading the code which points are not addressed and why? Here is a
|
||||
handful of good ways for the author to communicate why the issue as written
|
||||
might not be fully solved by the PR:
|
||||
|
||||
- The issue explicitly notes that it's fine for some parts to be completed
|
||||
separately, and the PR clearly indicates which parts are solved.
|
||||
- After discussion of initial prototypes (in GitHub comments or on the
|
||||
[development community server][czo]), it was decided to change some part of
|
||||
the specification, and the PR notes this.
|
||||
- The author explains why the PR is a better way to solve the issue than what
|
||||
was described.
|
||||
- The solution changed because of changes in the project or application since
|
||||
the issue was written, and the author explains the adjustments that were
|
||||
made.
|
||||
|
||||
**Think about the code:**
|
||||
|
||||
1. Make sure the PR uses **clear function, argument, variable, and test names.**
|
||||
Every new piece of Zulip code will be read many times by other developers, and
|
||||
future developers will `grep` for relevant terms when researching a problem, so
|
||||
it's important that variable names communicate clearly the purpose of each
|
||||
piece of the codebase.
|
||||
|
||||
1. Make sure the PR **avoids duplicated code.** Code duplication is a huge
|
||||
source of bugs in large projects and makes the codebase difficult to
|
||||
understand, so we avoid significant code duplication wherever possible.
|
||||
Sometimes avoiding code duplication involves some refactoring of existing
|
||||
code; if so, that should usually be done as its own series of commits (not
|
||||
squashed into other changes or left as a thing to do later). That series of
|
||||
commits can be in the same pull request as the feature that they support, and
|
||||
we recommend ordering the history of commits so that the refactoring comes
|
||||
_before_ the feature. That way, it's easy to merge the refactoring (and
|
||||
minimize risk of merge conflicts) if there are still user experience issues
|
||||
under discussion for the feature itself.
|
||||
|
||||
1. **Good comments** help. It's often worth thinking about whether explanation
|
||||
in a commit message or pull request discussion should be included in
|
||||
a comment, `/docs`, or other documentation. But it's better yet if
|
||||
verbose explanation isn't needed. We prefer writing code that is
|
||||
readable without explanation over a heavily commented codebase using
|
||||
lots of clever tricks.
|
||||
|
||||
1. Make sure the PR follows Zulip's **coding style**. See the Zulip [coding
|
||||
style documentation][code-style] for details. Our goal is to have as much of
|
||||
this as possible verified via the linters and tests, but there will always be
|
||||
unusual forms of Python/JavaScript style that our tools don't check for.
|
||||
|
||||
1. If you can, step back and think about the **technical design**. There are a
|
||||
lot of considerations here: security, migration paths/backwards compatibility,
|
||||
cost of new dependencies, interactions with features, speed of performance,
|
||||
API changes. Security is especially important and worth thinking about
|
||||
carefully with any changes to security-sensitive code like views.
|
||||
|
||||
**Think about testing:**
|
||||
|
||||
1. **The CI build tests need to pass.** One can investigate
|
||||
any failures and figure out what to fix by clicking on a red X next
|
||||
to the commit hash or the Detail links on a pull request. (Example:
|
||||
in [#17584](https://github.com/zulip/zulip/pull/17584),
|
||||
click the red X before `49b10a3` to see the build jobs
|
||||
for that commit. You can see that there are 7 build jobs in total.
|
||||
All the 7 jobs run in GitHub Actions. You can see what caused
|
||||
the job to fail by clicking on the failed job. This will open
|
||||
up a page in the CI that has more details on why the job failed.
|
||||
For example [this](https://github.com/zulip/zulip/actions/runs/15362225042/job/43230810881)
|
||||
is the page of an "Ubuntu 22.04 (Python 3.10, backend + frontend)" job.
|
||||
See our docs on [continuous integration](../testing/continuous-integration.md)
|
||||
to learn more.
|
||||
|
||||
2. Make sure **the code is well-tested**; see below for details. The PR should
|
||||
summarize any [manual testing](#manual-testing) that was done to validate
|
||||
that the feature is working as expected.
|
||||
|
||||
**Think about the commits:**
|
||||
|
||||
1. Does the PR follow the principle that “**Each commit is a minimal coherent
|
||||
idea**”? See the [commit discipline guide][commit-discipline] to learn more
|
||||
about commit structure in Zulip.
|
||||
|
||||
2. Does each commit have a **clear commit message**? Check for content, format,
|
||||
spelling and grammar. See the [Zulip commit discipline][commit-messages]
|
||||
documentation for details on what we look for.
|
||||
|
||||
You should also go through any of the following checks that are applicable:
|
||||
|
||||
- _Error handling._ The code should always check for invalid user
|
||||
input. User-facing error messages should be clear and when possible
|
||||
be actionable (it should be obvious to the user what they need to do
|
||||
in order to correct the problem).
|
||||
|
||||
- _Translation._ Make sure that the strings are marked for
|
||||
[translation].
|
||||
|
||||
- _Completeness of refactoring._ When reviewing a refactor, verify that the changes are
|
||||
complete. Usually, one can check that efficiently using `git grep`,
|
||||
and it's worth it, as we very frequently find issues by doing so.
|
||||
|
||||
- _Documentation updates._ If this changes how something works, does it
|
||||
update the documentation in a corresponding way? If it's a new
|
||||
feature, is it documented, and documented in the right place?
|
||||
|
||||
- _mypy annotations in Python code._ New functions should be annotated using
|
||||
[mypy] and existing annotations should be updated. Use of `Any`, `ignore`, and
|
||||
unparameterized containers should be limited to cases where a more precise
|
||||
type cannot be specified.
|
||||
|
||||
### Automated testing
|
||||
|
||||
- The tests should **validate that the feature works correctly**, and
|
||||
specifically test for common error conditions, bad user input, and potential
|
||||
bugs that are likely for the type of change being made. Tests that exclude
|
||||
whole classes of potential bugs are preferred when possible (e.g., the common
|
||||
test suite `test_markdown.py` between the Zulip server's [frontend and backend
|
||||
Markdown processors](../subsystems/markdown.md), or the `GetEventsTest` test
|
||||
for buggy race condition handling). See the [test writing][test-writing]
|
||||
documentation to learn more.
|
||||
|
||||
- We are trying to maintain ~100% test coverage on the backend, so backend
|
||||
changes should have negative tests for the various error conditions. See
|
||||
[backend testing documentation][backend-testing] for details.
|
||||
|
||||
- If the feature involves frontend changes, there should be frontend tests. See
|
||||
[frontend testing documentation][frontend-testing] for details.
|
||||
|
||||
### Manual testing
|
||||
|
||||
If the PR makes any user-facing changes, make sure to play with the part
|
||||
of the app being changed to validate that things look and work as expected.
|
||||
While not all of the situations below will apply, here are some ideas for things
|
||||
that should be tested if they are applicable. Use the [development
|
||||
environment][development-environment] to test any web app changes.
|
||||
|
||||
This might seem like a long process, but you can go through it quite quickly
|
||||
once you get the hang of it. Trust us, it will save time and review round-trips
|
||||
down the line!
|
||||
|
||||
Testing a PR is a great opportunity to discover pre-existing bugs or usability
|
||||
issues. Please verify that the issue you observed is pre-existing by replicating
|
||||
the behavior on `main`, and [report it](./reporting-bugs.md)!
|
||||
|
||||
Describe the manual testing you did in the PR description (for your own work),
|
||||
or in a comment (as a reviewer), so that the next reviewer knows how thoroughly
|
||||
the changes were exercised, and can catch any testing gaps.
|
||||
|
||||
**Visual appearance:**
|
||||
|
||||
- Open up the parts of the UI that were changed, and make sure they look as
|
||||
you were expecting.
|
||||
- Is the new UI consistent with similar UI elements? Think about fonts, colors,
|
||||
sizes, etc. If a new or modified element has multiple states (e.g., "on" and
|
||||
"off"), consider all of them.
|
||||
- Is the new UI aligned correctly with the elements around it, both vertically and
|
||||
horizontally?
|
||||
- If the PR adds or modifies a clickable element, does it have a hover behavior
|
||||
that's consistent with similar UI elements?
|
||||
- If the PR adds or modifies an element (e.g., a button or checkbox) that is
|
||||
sometimes disabled, is the disabled version of the UI consistent with similar
|
||||
UI elements?
|
||||
- Did the PR accidentally affect any other parts of the UI? E.g., if the PR
|
||||
modifies some CSS, look for other elements that may have been altered
|
||||
unintentionally. Are you using a shared function or component? Use `git grep`
|
||||
to see if the code you modified is being used elsewhere. Compare carefully
|
||||
with the state in `main` to make sure you haven't introduced any incidental
|
||||
changes.
|
||||
- Now check all of the above in the other theme (light/dark).
|
||||
- Now check all of the above at small and large [font
|
||||
sizes](https://zulip.com/help/font-size).
|
||||
|
||||
**Responsiveness and internationalization:**
|
||||
|
||||
- Check the new UI at different window sizes, including mobile sizes (you can
|
||||
use Chrome DevTools if you like). Does it look good in both wide and narrow
|
||||
windows?
|
||||
- To simulate what will happen when the UI is translated to different languages,
|
||||
try changing any new strings, or ones that are now displayed differently, to
|
||||
make them 1.5x longer, and check if anything breaks. What would happen if the
|
||||
strings were half as long as in English?
|
||||
- Are any [plurals and
|
||||
lists](../translating/internationalization.md#plurals-and-lists)
|
||||
internationalized correctly?
|
||||
|
||||
**Strings (text):**
|
||||
If the PR adds or modifies strings, check the following:
|
||||
|
||||
- Does the wording seem consistent with similar features (similar style, level
|
||||
of detail, etc.)?
|
||||
- Are strings appropriate in all situations (e.g., user vs. admin, other users
|
||||
vs. yourself)?
|
||||
|
||||
**Tooltips:**
|
||||
|
||||
- Do elements that require tooltips have them? Check similar elements to see
|
||||
whether a tooltip is needed, and what information it should contain.
|
||||
|
||||
**Functionality:**
|
||||
We're finally getting to the part where you actually use the new/updated
|
||||
feature. :) Test to see if it works as expected, trying a variety of scenarios.
|
||||
If it works as described in the issue but seems awkward in some way, note this
|
||||
on the PR.
|
||||
|
||||
If relevant, be sure to check that:
|
||||
|
||||
- Live updates are working as expected, in all the places that should be updated.
|
||||
- Keyboard navigation, including tabbing to the interactive elements, is working
|
||||
as expected.
|
||||
|
||||
Some scenarios to consider:
|
||||
|
||||
- Try clicking on any interactive elements, multiple times, in a variety of orders.
|
||||
- If the feature affects the **message view**, try it out in different types of
|
||||
narrows: topic, channel, Combined feed, direct messages.
|
||||
- If the feature affects the **compose box** in the web app, try both ways of
|
||||
[resizing the compose box](https://zulip.com/help/resize-the-compose-box).
|
||||
Test both channel messages and direct messages.
|
||||
- If the feature might require **elevated permissions**, check it out as a user who has
|
||||
permissions to use it and one who does not.
|
||||
- If the feature takes user input, check input edge cases (e.g., empty, invalid,
|
||||
or very long).
|
||||
- Think about how the feature might **interact with other features**, and try out
|
||||
such scenarios. For example:
|
||||
- If the PR adds a banner, is it possible that it would be shown at the same
|
||||
time as other banners? Does something reasonable happen?
|
||||
- If the feature has to do with topic editing, do you need to think
|
||||
about what happens when a topic is resolved/unresolved?
|
||||
- If it's a message view feature, would anything go wrong if the message was
|
||||
collapsed or muted? If it was colored like an `@`-mention or a direct message?
|
||||
|
||||
**Logged out view:** When appropriate, test as a logged out user. For example,
|
||||
was a new message menu item correctly added or skipped? If the item was skipped,
|
||||
did your changes introduce an extraneous separator in the menu?
|
||||
|
||||
## Review process and communication
|
||||
|
||||
### Asking for a code review
|
||||
|
||||
The [pull request review process](../contributing/review-process.md) guide
|
||||
provides a detailed overview of Zulip's PR review process. Your reviewers and
|
||||
Zulip's maintainers will help shepherd your PR through the process. There are
|
||||
also some additional ways to ask for a code review:
|
||||
|
||||
- Are there folks who have been working on similar things, or a loosely related
|
||||
area? If so, they might be a good person to review your PR. `@`-mention them
|
||||
with something like "`@person`, would you be up for reviewing this?" If
|
||||
you're not sure whether they are familiar with how Zulip code reviews work, you
|
||||
can also include a link to this guide.
|
||||
|
||||
- If you're not sure who to ask, you can post a message in
|
||||
[#code-review](https://chat.zulip.org/#narrow/channel/91-code-review) on [the Zulip
|
||||
development community server](https://zulip.com/development-community/) to reach
|
||||
out to a wider group of potential reviewers.
|
||||
|
||||
Please be patient and mindful of the fact that it isn't always possible to
|
||||
provide a quick reply. Going through the [review process](#how-to-review-code)
|
||||
described above for your own PR will make your code easier and faster to review,
|
||||
which makes it much more likely that it will be reviewed quickly and require
|
||||
fewer review cycles.
|
||||
|
||||
### Reviewing someone else's code
|
||||
|
||||
#### Fast replies are key
|
||||
|
||||
For the author of a PR, getting feedback quickly is really important
|
||||
for making progress quickly and staying productive. That means that
|
||||
if you get @-mentioned on a PR with a request for you to review it,
|
||||
it helps the author a lot if you reply promptly.
|
||||
|
||||
A reply doesn't even have to be a full review; if a PR is big or if
|
||||
you're pressed for time, then just getting some kind of reply in
|
||||
quickly -- initial thoughts, feedback on the general direction, or
|
||||
just saying you're busy and when you'll have time to look harder -- is
|
||||
still really valuable for the author and for anyone else who might
|
||||
review the PR.
|
||||
|
||||
People in the Zulip project live and work in many time zones, and code
|
||||
reviewers also need focused chunks of time to write code and do other
|
||||
things, so an immediate reply isn't always possible. But a good
|
||||
benchmark is to try to always reply **within one workday**, at least
|
||||
with a short initial reply, if you're working regularly on Zulip. And
|
||||
sooner is better.
|
||||
|
||||
#### Communication style
|
||||
|
||||
Any time you leave a code review, be sure to treat the author with respect.
|
||||
Remember that they are generously spending their time on an effort to improve
|
||||
the Zulip project. Thank them for their work, and express your appreciation for
|
||||
anything the author did especially well, whether it's a nice commit message, a
|
||||
prompt response to earlier feedback, or a well-written test.
|
||||
|
||||
Be as clear and direct as you can when describing requested changes. There is no
|
||||
need to apologize when asking for a change; you're collaborating with the
|
||||
author to make the PR as good as you can together.
|
||||
|
||||
Be sure to explain the motivation for the changes you're requesting if it's not
|
||||
obvious, so that the author can learn for next time. It may be helpful to point
|
||||
to developer documentation, such as the [commit discipline
|
||||
guide][commit-discipline].
|
||||
|
||||
#### Fixing up the PR
|
||||
|
||||
If a pull request just needs a little fixing to make it mergeable,
|
||||
feel free to do that in a new commit, then push your branch to GitHub
|
||||
and mention the branch in a comment on the pull request. That'll save
|
||||
the maintainer time and get the PR merged quicker.
|
||||
|
||||
### Responding to review feedback
|
||||
|
||||
Once you've received a review and resolved any feedback, it's critical
|
||||
to update the GitHub thread to reflect that. Best practices are to:
|
||||
|
||||
- Make sure that CI passes and the PR is rebased onto recent `main`.
|
||||
- Post comments on each feedback thread explaining at least how you
|
||||
resolved the feedback, as well as any other useful information
|
||||
(problems encountered, reasoning for why you picked one of several
|
||||
options, a test you added to make sure the bug won't recur, etc.).
|
||||
- Post a summary comment in the main feed for the PR, explaining that
|
||||
this is ready for another review, and summarizing any changes from
|
||||
the previous version, details on how you tested the changes, new
|
||||
screenshots/etc. More detail is better than less, as long as you
|
||||
take the time to write clearly.
|
||||
|
||||
If you resolve the feedback, but the PR has merge conflicts, CI
|
||||
failures, or the most recent comment is the reviewer asking you to fix
|
||||
something, it's very likely that a potential reviewer skimming your PR
|
||||
will assume it isn't ready for review and move on to other work.
|
||||
|
||||
If you need help or think an open discussion topic requires more
|
||||
feedback or a more complex discussion, move the discussion to a topic
|
||||
in the [Zulip development community server][czo]. Be sure to provide links
|
||||
from the GitHub PR to the conversation (and vice versa) so that it's
|
||||
convenient to read both conversations together.
|
||||
|
||||
## Additional resources
|
||||
|
||||
We also recommend the following resources on code reviews.
|
||||
|
||||
- [The Gentle Art of Patch Review](https://sage.thesharps.us/2014/09/01/the-gentle-art-of-patch-review/)
|
||||
article by Sarah Sharp
|
||||
- [Zulip & Good Code Review](https://www.harihareswara.net/sumana/2016/05/17/0)
|
||||
article by Sumana Harihareswara
|
||||
- [Code Review - A consolidation of advice and stuff from the
|
||||
internet](https://gist.github.com/porterjamesj/002fb27dd70df003646df46f15e898de)
|
||||
article by James J. Porter
|
||||
- [Zulip code of conduct](../code-of-conduct.md)
|
||||
|
||||
[code-style]: code-style.md
|
||||
[commit-discipline]: commit-discipline.md
|
||||
[commit-messages]: commit-discipline.md#commit-messages
|
||||
[test-writing]: ../testing/testing.md
|
||||
[backend-testing]: ../testing/testing-with-django.md
|
||||
[frontend-testing]: ../testing/testing-with-node.md
|
||||
[mypy]: ../testing/mypy.md
|
||||
[git-tool]: ../git/zulip-tools.md#fetch-a-pull-request-and-rebase
|
||||
[translation]: ../translating/translating.md
|
||||
[czo]: https://zulip.com/development-community/
|
||||
[development-environment]: ../development/overview.md
|
||||
369
docs/contributing/code-style.md
Normal file
369
docs/contributing/code-style.md
Normal file
@@ -0,0 +1,369 @@
|
||||
# Code style and conventions
|
||||
|
||||
This page documents code style policies that every Zulip developer
|
||||
should understand. We aim for this document to be short and focused
|
||||
only on details that cannot be easily enforced in another way (e.g.,
|
||||
through linters, automated tests, or subsystem design that makes classes
|
||||
of mistakes unlikely). This approach minimizes the cognitive
|
||||
load of ensuring a consistent coding style for both contributors and
|
||||
maintainers.
|
||||
|
||||
One can summarize Zulip's coding philosophy as a relentless focus on
|
||||
making the codebase easy to understand and difficult to make dangerous
|
||||
mistakes in (see the sections on [dangerous constructs](#dangerous-constructs-in-django)
|
||||
at the end of this page). The majority of work in any large software
|
||||
development project is understanding the existing code so one can debug
|
||||
or modify it, and investments in code readability usually end up paying
|
||||
for themselves when someone inevitably needs to debug or improve the code.
|
||||
|
||||
When there's something subtle or complex to explain or ensure in the
|
||||
implementation, we try hard to make it clear through a combination of
|
||||
clean and intuitive interfaces, well-named variables and functions,
|
||||
comments/docstrings, and commit messages (roughly in that order of
|
||||
priority -- if you can make something clear with a good interface,
|
||||
that's a lot better than writing a comment explaining how the bad
|
||||
interface works).
|
||||
|
||||
After an introduction to our lint tools and test suites, this document
|
||||
outlines some general
|
||||
[conventions and practices](#follow-zulip-conventions-and-practices)
|
||||
applicable to all languages used in the codebase, as well as specific
|
||||
guidance on [Python](#python-specific-conventions-and-practices) and
|
||||
[JavaScript and TypeScript](#javascript-and-typescript-conventions-and-practices).
|
||||
([HTML and CSS](../subsystems/html-css.md) are outlined in their own
|
||||
documentation.)
|
||||
|
||||
At the end of the document, you can read about
|
||||
[dangerous constructs in Django](#dangerous-constructs-in-django) and
|
||||
[JavaScript and TypeScript](#dangerous-constructs-in-javascript-and-typescript)
|
||||
that you should absolutely avoid.
|
||||
|
||||
## Be consistent with existing code
|
||||
|
||||
Look at the surrounding code, or a similar part of the project, and try
|
||||
to do the same thing. If you think the other code has actively bad
|
||||
style, fix it (in a separate commit).
|
||||
|
||||
When in doubt, ask in
|
||||
[#development help](https://chat.zulip.org/#narrow/channel/49-development-help).
|
||||
|
||||
### Use the linters
|
||||
|
||||
You can run all of the linters at once:
|
||||
|
||||
```bash
|
||||
$ ./tools/lint
|
||||
```
|
||||
|
||||
But, doing that will take a little time, because `./tools/lint`
|
||||
runs many lint checks in parallel, including:
|
||||
|
||||
- JavaScript ([ESLint](https://eslint.org/),
|
||||
[Prettier](https://prettier.io/))
|
||||
- Python ([mypy](http://mypy-lang.org/),
|
||||
[Ruff](https://docs.astral.sh/ruff/))
|
||||
- templates
|
||||
- Puppet configuration
|
||||
- custom checks (e.g., trailing whitespace and spaces-not-tabs)
|
||||
|
||||
To speed things up, you can [pass specific files or directories
|
||||
to the linter](../testing/linters.md):
|
||||
|
||||
```
|
||||
$ ./tools/lint web/src/compose.ts
|
||||
```
|
||||
|
||||
If you'd like, you can also set up a local Git commit hook that
|
||||
will lint only your changed files each time you commit:
|
||||
|
||||
```bash
|
||||
$ ./tools/setup-git-repo
|
||||
```
|
||||
|
||||
### Use tests to verify your logic
|
||||
|
||||
Clear, readable code is important for [tests](../testing/testing.md);
|
||||
familiarize yourself with our
|
||||
[testing frameworks](../testing/testing.md#major-test-suites) and
|
||||
[testing philosophy](../testing/philosophy.md) so that you can write
|
||||
clean, readable tests. In-test comments about anything subtle that is
|
||||
being verified are appreciated.
|
||||
|
||||
You can run all of the tests like this:
|
||||
|
||||
```
|
||||
$ ./tools/test-all
|
||||
```
|
||||
|
||||
But consult [our documentation on running tests](../testing/testing.md#running-tests),
|
||||
which covers more targeted approaches to commanding the test-runners.
|
||||
|
||||
## Follow Zulip conventions and practices
|
||||
|
||||
What follows is language-neutral advice that is beyond the bounds of
|
||||
linters and automated tests.
|
||||
|
||||
### Observe a reasonable line length
|
||||
|
||||
We have an absolute hard limit on line length only for some files, but
|
||||
we should still avoid extremely long lines. A general guideline is:
|
||||
refactor stuff to get it under 85 characters, unless that makes the
|
||||
code a lot uglier, in which case it's fine to go up to 120 or so.
|
||||
|
||||
### Tag user-facing strings for translation
|
||||
|
||||
Remember to
|
||||
[tag all user-facing strings for translation](../translating/translating.md),
|
||||
whether the strings are in HTML templates or output by JavaScript/TypeScript
|
||||
that injects or modifies HTML (e.g., error messages).
|
||||
|
||||
### Correctly prepare paths destined for state or log files
|
||||
|
||||
When writing out state or log files, always pass an absolute path
|
||||
through `zulip_path` (found in `zproject/computed_settings.py`), which
|
||||
will do the right thing in both development and production.
|
||||
|
||||
### Never include secrets inline with code
|
||||
|
||||
Please don't put any passwords, secret access keys, etc. inline in the
|
||||
code. Instead, use the `get_secret` function or the `get_mandatory_secret`
|
||||
function in `zproject/config.py` to read secrets from `/etc/zulip/secrets.conf`.
|
||||
|
||||
### Familiarize yourself with rules about third-party code
|
||||
|
||||
See [our docs on dependencies](../subsystems/dependencies.md) for discussion of
|
||||
rules about integrating third-party projects.
|
||||
|
||||
## Python-specific conventions and practices
|
||||
|
||||
- Our Python code is formatted with
|
||||
[Ruff](https://docs.astral.sh/ruff/). The [linter
|
||||
tool](../testing/linters.md) enforces this by running Ruff in check
|
||||
mode, or in write mode with
|
||||
`tools/lint --only=ruff,ruff-format --fix`. You may find it helpful
|
||||
to [integrate Ruff](https://docs.astral.sh/ruff/integrations/) with
|
||||
your editor.
|
||||
- Don't put a shebang line on a Python file unless it's meaningful to
|
||||
run it as a script. (Some libraries can also be run as scripts, e.g.,
|
||||
to run a test suite.)
|
||||
- Scripts should be executed directly (`./script.py`), so that the
|
||||
interpreter is implicitly found from the shebang line, rather than
|
||||
explicitly overridden (`python script.py`).
|
||||
- Put all imports together at the top of the file, absent a compelling
|
||||
reason to do otherwise.
|
||||
- Unpacking sequences doesn't require list brackets:
|
||||
```python
|
||||
[x, y] = xs # unnecessary
|
||||
x, y = xs # better
|
||||
```
|
||||
- For string formatting, use `x % (y,)` rather than `x % y`, to avoid
|
||||
ambiguity if `y` happens to be a tuple.
|
||||
|
||||
## JavaScript and TypeScript conventions and practices
|
||||
|
||||
Our JavaScript and TypeScript code is formatted with
|
||||
[Prettier](https://prettier.io/). You can ask Prettier to reformat
|
||||
all code via our [linter tool](../testing/linters.md) with
|
||||
`tools/lint --only=prettier --fix`. You can also [integrate it with your
|
||||
editor](https://prettier.io/docs/en/editors.html).
|
||||
|
||||
### Build DOM elements in Handlebars
|
||||
|
||||
The best way to build complicated DOM elements is a Handlebars template
|
||||
like `web/templates/message_reactions.hbs`. For simpler things you can
|
||||
use jQuery DOM-building APIs like this:
|
||||
|
||||
```js
|
||||
const $new_tr = $('<tr />').attr('id', object.id);
|
||||
```
|
||||
|
||||
### Attach behaviors to event listeners
|
||||
|
||||
Attach callback functions to events using jQuery code. For example:
|
||||
|
||||
```js
|
||||
$("body").on("click", ".move_message_button", function (e) {
|
||||
// message-moving UI logic
|
||||
}
|
||||
```
|
||||
|
||||
That approach has multiple benefits:
|
||||
|
||||
- Potential huge performance gains by using delegated events where
|
||||
possible
|
||||
- When calling a function from an `onclick` attribute, `this` is not
|
||||
bound to the element like you might think
|
||||
- jQuery does event normalization
|
||||
|
||||
Do not use `onclick` attributes in the HTML.
|
||||
|
||||
### Declare variables using `const` and `let`
|
||||
|
||||
Always declare JavaScript variables using `const` or `let` rather than
|
||||
`var`.
|
||||
|
||||
### Manipulate objects and arrays with modern methods
|
||||
|
||||
For functions that operate on arrays or JavaScript objects, you should
|
||||
generally use modern
|
||||
[ECMAScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Language_Resources)
|
||||
primitives such as [`for … of`
|
||||
loops](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of),
|
||||
[`Array.prototype.{entries, every, filter, find, indexOf, map, some}`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array),
|
||||
[`Object.{assign, entries, keys, values}`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object),
|
||||
[spread
|
||||
syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax),
|
||||
and so on. Our Babel configuration automatically transpiles and
|
||||
polyfills these using [`core-js`](https://github.com/zloirock/core-js)
|
||||
when necessary. We used to use the
|
||||
[Underscore](https://underscorejs.org/) library, but that should be
|
||||
avoided in new code.
|
||||
|
||||
## HTML and CSS
|
||||
|
||||
See the documentation on [HTML and CSS](../subsystems/html-css.md)
|
||||
for guidance on conventions in those languages.
|
||||
|
||||
## Dangerous constructs in Django
|
||||
|
||||
### Avoid excessive database queries
|
||||
|
||||
Look out for Django code like this:
|
||||
|
||||
```python
|
||||
bars = Bar.objects.filter(...)
|
||||
for bar in bars:
|
||||
foo = bar.foo
|
||||
# Make use of foo
|
||||
```
|
||||
|
||||
...because it equates to:
|
||||
|
||||
```python
|
||||
bars = Bar.objects.filter(...)
|
||||
for bar in bars:
|
||||
foo = Foo.objects.get(id=bar.foo.id)
|
||||
# Make use of foo
|
||||
```
|
||||
|
||||
...which makes a database query for every `Bar`. While this may be fast
|
||||
locally in development, it may be quite slow in production! Instead,
|
||||
tell Django's [QuerySet
|
||||
API](https://docs.djangoproject.com/en/5.0/ref/models/querysets/) to
|
||||
_prefetch_ the data in the initial query:
|
||||
|
||||
```python
|
||||
bars = Bar.objects.filter(...).select_related()
|
||||
for bar in bars:
|
||||
foo = bar.foo # This doesn't take another query, now!
|
||||
# Make use of foo
|
||||
```
|
||||
|
||||
If you can't rewrite it as a single query, that's a sign that something
|
||||
is wrong with the database schema. So don't defer this optimization when
|
||||
performing schema changes, or else you may later find that it's
|
||||
impossible.
|
||||
|
||||
### Never do direct database queries (`UserProfile.objects.get()`, `Client.objects.get()`, etc.)
|
||||
|
||||
In our Django code, never do direct `UserProfile.objects.get(email=foo)`
|
||||
database queries. Instead always use `get_user_profile_by_{email,id}`.
|
||||
There are 3 reasons for this:
|
||||
|
||||
1. It's guaranteed to correctly do a case-insensitive lookup
|
||||
2. It fetches the user object from remote cache, which is faster
|
||||
3. It always fetches a UserProfile object which has been queried
|
||||
using `.select_related()` ([see above](#avoid-excessive-database-queries)!),
|
||||
and thus will perform well when one later accesses related models
|
||||
like the Realm.
|
||||
|
||||
Similarly we have `get_client` and `access_stream_by_id` /
|
||||
`access_stream_by_name` functions to fetch those commonly accessed
|
||||
objects via remote cache.
|
||||
|
||||
### Don't use Django model objects as keys in sets/dicts
|
||||
|
||||
Don't use Django model objects as keys in sets/dictionaries -- you will
|
||||
get unexpected behavior when dealing with objects obtained from
|
||||
different database queries:
|
||||
|
||||
For example, the following will, surprisingly, fail:
|
||||
|
||||
```python
|
||||
# Bad example -- will raise!
|
||||
obj: UserProfile = get_user_profile_by_id(17)
|
||||
some_objs = UserProfile.objects.get(id=17)
|
||||
assert obj in set([some_objs])
|
||||
```
|
||||
|
||||
You should work with the IDs instead:
|
||||
|
||||
```python
|
||||
obj: UserProfile = get_user_profile_by_id(17)
|
||||
some_objs = UserProfile.objects.get(id=17)
|
||||
assert obj.id in set([o.id for o in some_objs])
|
||||
```
|
||||
|
||||
### Don't call user_profile.save() without `update_fields`
|
||||
|
||||
You should always pass the `update_fields` keyword argument to `.save()`
|
||||
when modifying an existing Django model object. By default, `.save()`
|
||||
updates all of the model object fields in the database, which results
|
||||
in lots of race conditions where unrelated changes made by one thread can be
|
||||
accidentally overwritten by another thread that fetched its `UserProfile`
|
||||
object before the first thread wrote out its change.
|
||||
|
||||
### Don't update important model objects with raw saves
|
||||
|
||||
In most cases, we already have a function in `zerver.actions` with
|
||||
a name like `do_activate_user` that will correctly handle lookups,
|
||||
caching, and notifying running browsers via the event system about your
|
||||
change. So please check whether such a function exists before writing
|
||||
new code to modify a model object, since your new code has a good chance
|
||||
of getting at least one of these things wrong.
|
||||
|
||||
### Don't use naive datetime objects
|
||||
|
||||
Python allows datetime objects to not have an associated time zone, which can
|
||||
cause time-related bugs that are hard to catch with a test suite, or bugs
|
||||
that only show up during daylight saving time.
|
||||
|
||||
Good ways to make time-zone-aware datetimes are below. We import time zone
|
||||
libraries as `from datetime import datetime, timezone` and
|
||||
`from django.utils.timezone import now as timezone_now`.
|
||||
|
||||
Use:
|
||||
|
||||
- `timezone_now()` to get a datetime when Django is available, such as
|
||||
in `zerver/`.
|
||||
- `datetime.now(tz=timezone.utc)` when Django is not available, such as
|
||||
for bots and scripts.
|
||||
- `datetime.fromtimestamp(timestamp, tz=timezone.utc)` if creating a
|
||||
datetime from a timestamp. This is also available as
|
||||
`zerver.lib.timestamp.timestamp_to_datetime`.
|
||||
- `datetime.strptime(date_string, format).replace(tzinfo=timezone.utc)` if
|
||||
creating a datetime from a formatted string that is in UTC.
|
||||
|
||||
Idioms that result in time-zone-naive datetimes, and should be avoided, are
|
||||
`datetime.now()` and `datetime.fromtimestamp(timestamp)` without a `tz`
|
||||
parameter, `datetime.utcnow()` and `datetime.utcfromtimestamp()`, and
|
||||
`datetime.strptime(date_string, format)` without replacing the `tzinfo` at
|
||||
the end.
|
||||
|
||||
Additional notes:
|
||||
|
||||
- Especially in scripts and puppet configuration where Django is not
|
||||
available, using `time.time()` to get timestamps can be cleaner than
|
||||
dealing with datetimes.
|
||||
- All datetimes on the backend should be in UTC, unless there is a good
|
||||
reason to do otherwise.
|
||||
|
||||
## Dangerous constructs in JavaScript and TypeScript
|
||||
|
||||
### Do not use `for...in` statements to traverse arrays
|
||||
|
||||
That construct pulls in properties inherited from the prototype chain.
|
||||
Don't use it:
|
||||
[[1]](https://stackoverflow.com/questions/500504/javascript-for-in-with-arrays),
|
||||
[[2]](https://google.github.io/styleguide/javascriptguide.xml#for-in_loop),
|
||||
[[3]](https://www.jslint.com/help.html#forin)
|
||||
345
docs/contributing/commit-discipline.md
Normal file
345
docs/contributing/commit-discipline.md
Normal file
@@ -0,0 +1,345 @@
|
||||
# Commit discipline
|
||||
|
||||
We follow the Git project's own commit discipline practice of "Each
|
||||
commit is a minimal coherent idea". This discipline takes a bit of work,
|
||||
but it makes it much easier for code reviewers to spot bugs, and
|
||||
makes the commit history a much more useful resource for developers
|
||||
trying to understand why the code works the way it does, which also
|
||||
helps a lot in preventing bugs.
|
||||
|
||||
Use `git rebase -i` as much as you need to shape your commit structure. See the
|
||||
[Git guide](../git/overview.md) for useful resources on mastering Git.
|
||||
|
||||
**Tip**: Check out how to use [`git log -p` to study the commit
|
||||
history](../git/reading-history.md) of the project.
|
||||
|
||||
## Each commit must be coherent
|
||||
|
||||
- It should pass tests (so test updates needed by a change should be
|
||||
in the same commit as the original change, not a separate "fix the
|
||||
tests that were broken by the last commit" commit).
|
||||
- It should not make Zulip worse. For example, it is fine to add backend
|
||||
capabilities without adding a frontend to access them. It's not fine to add a
|
||||
frontend component with no backend to make it work.
|
||||
- It should be safe to deploy individually, or explain in detail in
|
||||
the commit message as to why it isn't (maybe with a [manual] tag).
|
||||
So implementing a new API endpoint in one commit and then adding the
|
||||
security checks in a future commit should be avoided -- the security
|
||||
checks should be there from the beginning.
|
||||
- Error handling should generally be included along with the code that
|
||||
might trigger the error.
|
||||
- TODO comments should be in the commit that introduces the issue or
|
||||
the functionality with further work required.
|
||||
|
||||
## Commits should generally be minimal
|
||||
|
||||
Whenever possible, find chunks of complexity that you can separate from the
|
||||
rest of the project.
|
||||
|
||||
- If you need to refactor code, add tests for existing functionality,
|
||||
rename variables or functions, or make other changes that do not
|
||||
change the functionality of the product, make those changes into a
|
||||
series of preparatory commits that can be merged independently of
|
||||
building the feature itself.
|
||||
- Moving code from one file to another should be done in separate
|
||||
commits from functional changes or even refactoring within a file.
|
||||
- 2 different refactorings should be done in different commits.
|
||||
- 2 different features should be done in different commits.
|
||||
- If you find yourself writing a commit message that reads like a list
|
||||
of somewhat dissimilar things that you did, you probably should have
|
||||
just done multiple commits.
|
||||
|
||||
### When not to be overly minimal
|
||||
|
||||
- For completely new features, you don't necessarily need to split out
|
||||
new commits for each little subfeature of the new feature. E.g., if
|
||||
you're writing a new tool from scratch, it's fine to have the
|
||||
initial tool have plenty of options/features without doing separate
|
||||
commits for each one. That said, reviewing a 2000-line giant blob of
|
||||
new code isn't fun, so please be thoughtful about submitting things
|
||||
in reviewable units.
|
||||
- Don't bother to split backend commits from frontend commits, even
|
||||
though the backend can often be coherent on its own.
|
||||
|
||||
## Write a clean commit history
|
||||
|
||||
- Overly fine commits are easy to squash later, but not vice versa.
|
||||
So err toward small commits, and the code reviewer can advise on
|
||||
squashing.
|
||||
- If a commit you write doesn't pass tests, you should usually fix
|
||||
that by amending the commit to fix the bug, not writing a new "fix
|
||||
tests" commit on top of it.
|
||||
|
||||
Zulip expects you to structure the commits in your pull requests to form
|
||||
a clean history before we will merge them. It's best to write your
|
||||
commits following these guidelines in the first place, but if you don't,
|
||||
you can always fix your history using `git rebase -i` (more on that
|
||||
[here](../git/fixing-commits.md)).
|
||||
|
||||
Never mix multiple changes together in a single commit, but it's great
|
||||
to include several related changes, each in their own commit, in a
|
||||
single pull request. If you notice an issue that is only somewhat
|
||||
related to what you were working on, but you feel that it's too minor
|
||||
to create a dedicated pull request, feel free to append it as an
|
||||
additional commit in the pull request for your main project (that
|
||||
commit should have a clear explanation of the bug in its commit
|
||||
message). This way, the bug gets fixed, but this independent change
|
||||
is highlighted for reviewers. Or just create a dedicated pull request
|
||||
for it. Whatever you do, don't squash unrelated changes together in a
|
||||
single commit; the reviewer will ask you to split the changes out into
|
||||
their own commits.
|
||||
|
||||
It can take some practice to get used to writing your commits with a
|
||||
clean history so that you don't spend much time doing interactive
|
||||
rebases. For example, often you'll start adding a feature, and discover
|
||||
you need to do a refactoring partway through writing the feature. When that
|
||||
happens, we recommend you stash your partial feature, do the refactoring,
|
||||
commit it, and then unstash and finish implementing your feature.
|
||||
|
||||
For additional guidance on how to structure your commits (and why it matters!),
|
||||
check out GitHub's excellent [blog post](https://github.blog/2022-06-30-write-better-commits-build-better-projects).
|
||||
|
||||
## Commit messages
|
||||
|
||||
Commit messages have two parts:
|
||||
|
||||
1. A **summary**, which is a brief one-line overview of the changes.
|
||||
2. A **description**, which provides further details on the changes,
|
||||
the motivation behind them, and why they improve the project.
|
||||
|
||||
In Zulip, commit summaries have a two-part structure:
|
||||
|
||||
1. A one or two word description of the part of the codebase changed
|
||||
by the commit.
|
||||
2. A short sentence summarizing your changes.
|
||||
|
||||
Here is an
|
||||
[example](https://github.com/zulip/zulip/commit/084dd216f017c32e15c1b13469bcbc928cd0bce9)
|
||||
of a good commit message:
|
||||
|
||||
> tests: Remove ignored realm_str parameter from message send test.
|
||||
>
|
||||
> In commit
|
||||
> [8181ec4](https://github.com/zulip/zulip/commit/8181ec4b56abf598223112e7bc65ce20f3a6236b),
|
||||
> we removed the `realm_str` as a parameter for `send_message_backend`. This
|
||||
> removes a missed test that included this as a parameter for that
|
||||
> endpoint/function.
|
||||
|
||||
The commit message is a key piece of how you communicate with reviewers and
|
||||
future contributors, and is no less important than the code you write. This
|
||||
section provides detailed guidance on how to write an excellent commit message.
|
||||
|
||||
**Tip:** You can set up [Zulip's Git pre-commit hook][commit-hook] to
|
||||
automatically catch common commit message mistakes.
|
||||
|
||||
[commit-hook]: ../git/zulip-tools.md#set-up-git-repo-script
|
||||
|
||||
### Commit summary, part 1
|
||||
|
||||
The first part of the commit summary should only be 1-2 **lower-case**
|
||||
words, followed by a `:`, describing what the part of the product the
|
||||
commit changes. These prefixes are essential for maintainers to
|
||||
efficiently skim commits when doing release management or
|
||||
investigating regressions.
|
||||
|
||||
Common examples include: settings, message feed, compose, left
|
||||
sidebar, right sidebar, recent (for **Recent conversations**), search,
|
||||
markdown, tooltips, popovers, drafts, integrations, email, docs, help,
|
||||
and api docs.
|
||||
|
||||
When it's possible to do so concisely, it's helpful to be a little more
|
||||
specific, e.g., emoji, spoilers, polls. However, a simple `settings:` is better
|
||||
than a lengthy description of a specific setting.
|
||||
|
||||
If your commit doesn't cleanly map to a part of the product, you might
|
||||
use something like "css" for CSS-only changes, or the name of the file
|
||||
or technical subsystem principally being modified (not the full path,
|
||||
so `realm_icon`, not `zerver/lib/realm_icon.py`).
|
||||
|
||||
There is no need to be creative here! If one of the examples above
|
||||
fits your commit, use it. Consistency makes it easier for others to
|
||||
scan commit messages to find what they need.
|
||||
|
||||
Additional tips:
|
||||
|
||||
- Use lowercase (e.g., "settings", not "Settings").
|
||||
- If it's hard to find a 1-2 word description of the part of the codebase
|
||||
affected by your commit, consider again whether you have structured your
|
||||
commits well.
|
||||
- Never use a generic term like "bug", "fix", or "refactor".
|
||||
|
||||
### Commit summary, part 2
|
||||
|
||||
This is a **complete sentence** that briefly summarizes your changes. There are
|
||||
a few rules to keep in mind:
|
||||
|
||||
- Start the sentence with an
|
||||
[imperative](https://en.wikipedia.org/wiki/Imperative_mood) verb, e.g.,
|
||||
"fix", "add", "change", "rename", etc.
|
||||
- Use proper capitalization and punctuation.
|
||||
- Avoid abbreviations and acronyms.
|
||||
- Be concise, and don't include unnecessary details. For example, "Change X and
|
||||
update tests/docs," would be better written as just, "Change X," since (as
|
||||
discussed above) _every_ commit is expected to update tests and documentation
|
||||
as needed.
|
||||
- Make it readable to someone who is familiar with Zulip's codebase, but hasn't
|
||||
been involved with the effort you're working on.
|
||||
- Use no more than 72 characters for the entire commit summary (parts 1 and 2).
|
||||
|
||||
### Examples of good commit summaries
|
||||
|
||||
- `provision: Improve performance of installing npm.`
|
||||
- `channel: Discard all HTTP responses while reloading.`
|
||||
- `integrations: Add GitLab integration.`
|
||||
- `typeahead: Rename compare_by_popularity() for clarity.`
|
||||
- `typeahead: Convert to ES6 module.`
|
||||
- `tests: Compile Handlebars templates with source maps.`
|
||||
- `blueslip: Add feature to time common operations.`
|
||||
- `gather_subscriptions: Fix exception handling bad input.`
|
||||
- `channel_settings: Fix save/discard widget on narrow screens.`
|
||||
|
||||
#### Detailed example
|
||||
|
||||
- **Good summary**: "gather_subscriptions: Fix exception handling bad input."
|
||||
- **Not so good alternatives**:
|
||||
- "gather_subscriptions was broken": This doesn't explain how it was broken, and
|
||||
doesn't follow the format guidelines for commit summaries.
|
||||
- "Fix exception when given bad input": It's impossible to tell what part of the
|
||||
codebase was changed.
|
||||
- Not using the imperative:
|
||||
- "gather_subscriptions: Fixing exception when given bad input."
|
||||
- "gather_subscriptions: Fixed exception when given bad input."
|
||||
|
||||
### Commit description
|
||||
|
||||
The body of the commit message should explain why and how the change
|
||||
was made. Like a good code comment, it should provide context and
|
||||
motivation that will help both a reviewer now, and a developer looking
|
||||
at your changes a year later, understand the motivation behind your
|
||||
decisions.
|
||||
|
||||
Many decisions may be documented in multiple places (for example, both
|
||||
in a commit message and a code comment). The general rules of thumb are:
|
||||
|
||||
- Use the commit message for information that's relevant for someone
|
||||
trying to understand the change this commit is making, or the difference
|
||||
between the old version of the code and the new version. In particular,
|
||||
this includes information about why the new version of the code is better than,
|
||||
or not worse than, the old version.
|
||||
- Use code comments, or the code itself, for information that's relevant
|
||||
for someone trying to read and understand the new version of the code
|
||||
in the future, without comparing it to the old version.
|
||||
- If the information is helpful for reviewing your work (for example,
|
||||
an alternative approach that you rejected or are considering,
|
||||
something you noticed that seemed weird, or an error you aren't sure
|
||||
you resolved correctly), include it in the PR description /
|
||||
discussion.
|
||||
|
||||
As an example, if you have a question that you expect to be resolved
|
||||
during the review process, put it in a PR comment attached to a
|
||||
relevant part of the changes. When the question is resolved, remember
|
||||
to update code comments and/or the commit description to document the
|
||||
reasoning behind the decisions.
|
||||
|
||||
There are some cases when the best approach is improving the code or commit
|
||||
structure, not writing up details in a comment or a commit message. For example:
|
||||
|
||||
- If the information is the description of a calculation or function,
|
||||
consider the abstractions you're using. Often, a better name for a
|
||||
variable or function is a better path to readable code than writing
|
||||
a prose explanation.
|
||||
- If the information describes an additional change that you made while working
|
||||
on the commit, consider whether it is separable from the rest of the changes.
|
||||
If it is, it should probably be moved to its own commit, with its own commit
|
||||
message explaining it. Reviewing and integrating a series of several
|
||||
well-written commits is far easier than reviewing those same changes in a
|
||||
single commit.
|
||||
|
||||
When you fix a GitHub issue, [mark that you have fixed the issue in
|
||||
your commit
|
||||
message](https://help.github.com/en/articles/closing-issues-via-commit-messages)
|
||||
so that the issue is automatically closed when your code is merged,
|
||||
and the commit has a permanent reference to the issue(s) that it
|
||||
resolves. Zulip's preferred style for this is to have the final
|
||||
paragraph of the commit message read, e.g., `Fixes #123.`.
|
||||
|
||||
**Note:** Avoid using a phrase like `Partially fixes #1234.`, as
|
||||
GitHub's regular expressions ignore the "partially" and close the
|
||||
issue. `Fixes part of #1234.` is a good alternative.
|
||||
|
||||
#### The purpose of the commit description
|
||||
|
||||
The commit summary and description should, taken together, explain to another
|
||||
Zulip developer (who may not be deeply familiar with the specific
|
||||
files/subsystems you're changing) why this commit improves the project. This
|
||||
means explaining both what it accomplishes, and why it won't break things one
|
||||
might worry about it breaking.
|
||||
|
||||
- Include any important investigation/reasoning that another developer
|
||||
would need to understand in order to verify the correctness of your
|
||||
change. For example, if you're removing a parameter from a function,
|
||||
the commit message might say, "It's safe to remove this parameter
|
||||
because it was always False," or, "This behavior needs to be removed
|
||||
because ...". A reviewer will likely check that indeed it was always
|
||||
`False` as part of checking your work -- what you're doing is
|
||||
providing them a chain of reasoning that they can verify.
|
||||
- Provide background context. A good pattern in a commit message
|
||||
description is, "Previously, when X happened, this caused Y to
|
||||
happen, which resulted in ...", followed by a description of the
|
||||
negative outcome.
|
||||
- Don't include details that are obvious from looking at the diff for
|
||||
the commit, such as lists of the names of the files or functions
|
||||
that were changed, or the fact that you updated the tests.
|
||||
- Avoid unnecessary personal narrative about the process through which
|
||||
you developed this commit or pull request, like "First I tried X" or
|
||||
"I changed Y".
|
||||
|
||||
#### Mentioning other contributors
|
||||
|
||||
You can
|
||||
[credit](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors)
|
||||
co-authors on a commit by adding a `Co-authored-by:` line after a blank line at
|
||||
the end of your commit message:
|
||||
|
||||
Co-authored-by: Greg Price <greg@zulip.com>
|
||||
|
||||
You should always give credit where credit is due. See our [guide on continuing
|
||||
unfinished work](../contributing/continuing-unfinished-work.md) for step-by-step
|
||||
guidance on continuing work someone else has started.
|
||||
|
||||
You can also add other notes, such as `Reported-by:`, `Debugged-by:`, or
|
||||
`Suggested-by:`, but we don't typically do so.
|
||||
|
||||
@-mentions don't belong in commit messages (and won't notify the user you
|
||||
mentioned). If you want to send someone a notification about a change, @-mention
|
||||
them in the PR thread.
|
||||
|
||||
#### Formatting guidelines
|
||||
|
||||
There are a few specific formatting guidelines to keep in mind:
|
||||
|
||||
- The commit description should be separated from the commit summary
|
||||
by a blank line. Most tools, including GitHub, will misrender commit
|
||||
messages that don't do this.
|
||||
- Use full sentences and paragraphs, with proper punctuation and
|
||||
capitalization. Paragraphs should be separated with a single blank
|
||||
line.
|
||||
- Be sure to check your description for typos, spelling, and grammar
|
||||
mistakes; commit messages are important technical writing and
|
||||
English mistakes will distract reviewers from your ideas.
|
||||
- Your commit message should be line-wrapped to about 68 characters
|
||||
per line, but no more than 70, so that your commit message will be
|
||||
easy to read in `git log` in a normal terminal. (It's OK for links
|
||||
to be longer -- ignore `gitlint` when it complains about them.)
|
||||
|
||||
**Tip:** You may find it helpful to configure Git to use your preferred editor
|
||||
using the `EDITOR` environment variable or `git config --global core.editor`,
|
||||
and configure the editor to automatically wrap text to 70 or fewer columns per
|
||||
line (all text editors support this).
|
||||
|
||||
### Examples of good commit messages
|
||||
|
||||
- [A backend testing
|
||||
commit](https://github.com/zulip/zulip/commit/4869e1b0b2bc6d56fcf44b7d0e36ca20f45d0521)
|
||||
- [A development environment provisioning
|
||||
commit](https://github.com/zulip/zulip/commit/cd5b38f5d8bdcc1771ad794f37262a61843c56c0)
|
||||
154
docs/contributing/continuing-unfinished-work.md
Normal file
154
docs/contributing/continuing-unfinished-work.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# Continuing unfinished work
|
||||
|
||||
Sometimes, work is started on an issue or PR, but not brought to completion.
|
||||
This may happen for a variety of reasons — the contributor working on the
|
||||
project gets busy, maintainers cannot prioritize reviewing the work, a
|
||||
contributor doesn't have the skills required to complete the project, there is
|
||||
an unexpected technical challenge or blocker, etc.
|
||||
|
||||
Completing work that someone else has started is a great way to contribute! Here
|
||||
are the steps required:
|
||||
|
||||
1. [Find work to be completed.](#find-work-to-be-completed)
|
||||
1. [Review existing work and feedback.](#review-existing-work-and-feedback)
|
||||
1. [Decide how to use prior work.](#decide-how-to-use-prior-work)
|
||||
1. [Credit prior work in your commit history.](#credit-prior-work-in-your-commit-history)
|
||||
1. [Present your pull request.](#present-your-pull-request)
|
||||
|
||||
## Find work to be completed
|
||||
|
||||
In Zulip's server and web app [repository](https://github.com/zulip/zulip), pull
|
||||
requests that have significant work towards something valuable are often tagged
|
||||
with a [completion candidate][completion-candidate] label. You can review
|
||||
this label for unfinished work that you find interesting and have the skills to
|
||||
complete.
|
||||
|
||||
Note that it's common to see one or more pull requests linked to an issue
|
||||
you're interested in. The guidelines below apply regardless of whether you
|
||||
intentionally set out to find work to complete or simply find yourself
|
||||
building on someone else's work.
|
||||
|
||||
## Review existing work and feedback
|
||||
|
||||
Any time there are pull requests linked to the issue you are working on, start
|
||||
by reviewing the existing work. Read the code, and pay close attention to any
|
||||
feedback the pull request received. This will help you avoid any pitfalls other
|
||||
contributors encountered.
|
||||
|
||||
## Decide how to use prior work
|
||||
|
||||
Consider how to use prior work on the issue. In your best judgment, is the
|
||||
existing PR on the right track? If there's reviewer feedback, it should help you
|
||||
figure this out.
|
||||
|
||||
If prior work looks like a good start:
|
||||
|
||||
1. Pull down the existing pull request.
|
||||
1. Rebase it on the current version of the `main` branch.
|
||||
1. Carefully address any open feedback from reviewers.
|
||||
1. Make any other changes you think are needed, including completing any parts
|
||||
of the work that had not been finished.
|
||||
1. Make sure the work of others is [properly credited](#credit-prior-work-in-your-commit-history).
|
||||
1. [Self-review](../contributing/code-reviewing.md), test, and revise the work,
|
||||
including potentially [splitting out](../contributing/commit-discipline.md)
|
||||
preparatory commits to make it easier to read. You should be proud of the
|
||||
resulting series of commits, and be prepared to argue that it is the best
|
||||
work you can produce to complete the issue.
|
||||
|
||||
Otherwise, you can:
|
||||
|
||||
1. Make your own changes from scratch.
|
||||
1. Go through reviewer feedback on prior work. Would any of it apply to the
|
||||
changes you're proposing? Be sure to address it if so.
|
||||
|
||||
## Credit prior work in your commit history
|
||||
|
||||
When you use or build upon someone else's unmerged work, it is both
|
||||
professionally and ethically necessary to [properly
|
||||
credit][coauthor-git-guide] their contributions in the commit history
|
||||
of work that you submit. Git, used properly, does a good job of
|
||||
preserving the original authorship of commits.
|
||||
|
||||
However, it's normal to find yourself making changes to commits
|
||||
originally authored by other contributors, whether resolving merge
|
||||
conflicts when doing `git rebase` or fixing bugs to create an
|
||||
atomically correct commit compliant with Zulip's [commit
|
||||
guidelines](../contributing/commit-discipline.md).
|
||||
|
||||
When you do that, it's your responsibility to ensure the resulting
|
||||
commit series correctly credits the work of everyone who materially
|
||||
contributed to it. The most direct way to credit the work of someone
|
||||
beyond the commit's author maintained in the Git metadata is
|
||||
`Co-authored-by:` line after a blank line at the end of your commit
|
||||
message:
|
||||
|
||||
Co-authored-by: Greg Price <greg@zulip.com>
|
||||
|
||||
Be careful to type it precisely, because software parses these commit
|
||||
message records in generating statistics. You should add such a line
|
||||
in two scenarios:
|
||||
|
||||
- If your own work was squashed into a commit originally authored by
|
||||
another contributor, add such a line crediting yourself.
|
||||
- If you used another contributor's work in generating your own
|
||||
commit, add such a line crediting the other contributor(s).
|
||||
|
||||
Sometimes, you make a mistake when rebasing and accidentally squash
|
||||
commits in a way that messes up Git's authorship records. Often,
|
||||
undoing the rebase change via `git reflog` is the best way to correct
|
||||
such mistakes, but there are two other Git commands that can be used
|
||||
to correct Git's primary authorship information after the fact:
|
||||
|
||||
- `git commit --amend --reset-author` will replace the Git commit
|
||||
metadata (date, author, etc.) of the currently checked out commit
|
||||
with yourself. This is useful to correct a commit that incorrectly
|
||||
shows someone else as the author of your work.
|
||||
- `git commit --amend -C <commit_id>` will replace the commit metadata
|
||||
(date, author, etc.) on a commit with that of the provided commit
|
||||
ID. This is useful if you accidentally made someone else's commit
|
||||
show yourself as the author, or lost a useful commit message via
|
||||
accidental squashing. (You can usually find the right commit ID to
|
||||
use with `git reflog` or from GitHub).
|
||||
|
||||
As an aside, maintainers who modify commits before merging them are
|
||||
credited via Git's "Committer" records (visible with `git show
|
||||
--pretty=fuller`, for example). As a result, they may not bother with
|
||||
adding a separate `Co-authored-by` record on commits that they revise
|
||||
as part of merging a pull request.
|
||||
|
||||
## Present your pull request
|
||||
|
||||
In addition to the usual [guidance](../contributing/reviewable-prs.md) for
|
||||
putting together your pull request, there are a few key points to keep in mind.
|
||||
|
||||
- **Take responsibility for the work.** Any time you propose changes to the
|
||||
Zulip project, you are accountable for those changes. Do your very best to verify that they are correct.
|
||||
|
||||
- Don't submit code you don't understand — dig in to figure out what it's
|
||||
doing, even if you didn't write it. This is a great way to catch bugs and
|
||||
make improvements.
|
||||
- Test the work carefully, even if others have tested it before. There may be
|
||||
problems that the reviewers missed, or that were introduced by rebasing across other changes.
|
||||
|
||||
- **Give credit where credit is due.** Reviewers should be able to examine your
|
||||
commit history and see that you have [properly credited](#credit-prior-work-in-your-commit-history)
|
||||
the work of others.
|
||||
|
||||
- **Explain the relationship between your PR and prior work** in the description
|
||||
for your pull request. This is required for your PR to be reviewed, as
|
||||
reviewing a new PR when there is an existing one is a good use of time only if
|
||||
the motivation for doing so is clear.
|
||||
- If you started from an existing PR, explain what changes you made, and how
|
||||
you addressed each point of reviewer feedback that hadn't been addressed previously.
|
||||
- If you started from scratch, explain _why_ you decided to do so, and how
|
||||
your approach differs from prior work. For example:
|
||||
- "I didn't use the work in PR #12345, because the surrounding code has
|
||||
changed too much since it was written."
|
||||
- "I didn't use the work in PR #23154, because [this reviewer
|
||||
comment](#present-your-pull-request) asked to solve this issue using CSS,
|
||||
rather than the JavaScript changes made in #23154."
|
||||
- "I didn't use the work in PRs #12345 and #23154, because both didn't work
|
||||
properly when a user opened their own profile."
|
||||
|
||||
[completion-candidate]: https://github.com/zulip/zulip/pulls?q=is%3Aopen+is%3Apr+label%3A%22completion+candidate%22
|
||||
[coauthor-git-guide]: https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors
|
||||
1
docs/contributing/contributing.md
Symbolic link
1
docs/contributing/contributing.md
Symbolic link
@@ -0,0 +1 @@
|
||||
../../CONTRIBUTING.md
|
||||
98
docs/contributing/counting-contributions.md
Normal file
98
docs/contributing/counting-contributions.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Counting contributions
|
||||
|
||||
The [Zulip team page](https://zulip.com/team/) displays commit counts for
|
||||
contributors to Zulip projects. We display these statistics prominently because
|
||||
they are easy to compute, and can be fun and motivating for some of our
|
||||
contributors.
|
||||
|
||||
We do not consider commit count to be a good way to measure someone's
|
||||
contributions to a software project. Many invaluable contributions may not
|
||||
result in the contributor authoring any code at all, including design, feedback,
|
||||
translations, bug reports, helping new contributors, and other types of
|
||||
participation in our [development community][dev-community]. These non-code
|
||||
contributions are essential to making the Zulip project successful.
|
||||
|
||||
Thus, Zulip's policy is to always express appreciation for non-code
|
||||
contributions to the project whenever we discuss code contribution
|
||||
statistics, especially in our highest-visibility contexts like release
|
||||
blog posts.
|
||||
|
||||
## How the contribution stats are calculated
|
||||
|
||||
The data for all contributors to the Zulip project is aggregated by
|
||||
querying [GitHub's API endpoint for listing a repository's
|
||||
contributors][github-list-contrib-endpoint]. The numbers Zulip gets
|
||||
from this endpoint differs slightly from the data GitHub displays in a
|
||||
repository's [contributors page][github-contrib-page]. This
|
||||
discrepancy is due to the following reasons:
|
||||
|
||||
- A repository's contributors page excludes commits with author email
|
||||
addresses that do not have an associated GitHub account. However,
|
||||
the GitHub API counts such emails in its contributor stats.
|
||||
- A repository's contributors page does not count commits authored by
|
||||
email addresses that have been deleted from a GitHub profile by the
|
||||
user. However, the GitHub API treats these stale emails as
|
||||
contributors as well.
|
||||
- Some commits have multiple authors when that is declared via
|
||||
[Co-Authored-By][co-authored-by] in a commit message.
|
||||
|
||||
## Old email addresses
|
||||
|
||||
If you remove an email address from your GitHub profile, the commits
|
||||
you contributed with that email as the `GIT_AUTHOR_EMAIL` will
|
||||
disappear from your GitHub profile. If you made contributions to Zulip
|
||||
with an author email address that is no longer associated with your
|
||||
GitHub profile, here are some important points to keep in mind:
|
||||
|
||||
- Zulip's team page will still display your contributions. These
|
||||
contributions will be grouped under the email that was used for the
|
||||
commits, but will not link to your GitHub profile.
|
||||
- If you still have access to the email used for the contributions, you
|
||||
can link the contributions to your GitHub profile by
|
||||
[adding the email to your GitHub account][github-add-email].
|
||||
- If you do not have access to the email in question, you can ask for
|
||||
help on chat.zulip.org, or submit a pull request editing the
|
||||
`.mailmap` file at the root of the repository where your
|
||||
contributed.
|
||||
|
||||
The comments at the top of our `.mailmap` files document how to map
|
||||
your old email address to one currently associated with your GitHub
|
||||
account.
|
||||
|
||||
## Relevant source code
|
||||
|
||||
To dig deeper into how the contributor stats are calculated, please check
|
||||
out the following files in the [Zulip server repository][server-repo]:
|
||||
|
||||
- `tools/fetch-contributor-data` - The script that fetches contributor
|
||||
data from GitHub's API.
|
||||
- `static/js/portico/team.js` - The JavaScript code that processes and
|
||||
renders the data received from GitHub.
|
||||
|
||||
## Attribution for non-code contributions
|
||||
|
||||
As noted above, Zulip's policy is to express appreciation for non-code
|
||||
contributions to the project whenever we discuss code contribution
|
||||
statistics.
|
||||
|
||||
We do not specifically attribute non-code contributions by name, because the
|
||||
logistics of giving individual attributions in a consistent and fair way across
|
||||
50+ features in a release are far more than we have the capacity to manage.
|
||||
|
||||
For context, a significant feature usually involves a half-dozen people or more
|
||||
helping with different parts of the work (suggesting ideas, providing technical
|
||||
and non-technical feedback, etc.). Contributions can range from multiple rounds
|
||||
of PR reviews to a 👍 reaction on someone else's suggestion. Even if one could
|
||||
review everything that happened (in itself a daunting task), it may not be clear
|
||||
which contributions should "count". At the same time, seeing that your name is
|
||||
missing from a list of attributions where it belongs can feel really hurtful.
|
||||
|
||||
So, while we cannot thank everyone by name, please know that your contributions
|
||||
are deeply appreciated!
|
||||
|
||||
[github-list-contrib-endpoint]: https://docs.github.com/en/rest/reference/repos#list-repository-contributors
|
||||
[github-contrib-page]: https://docs.github.com/en/repositories/viewing-activity-and-data-for-your-repository/viewing-a-projects-contributors
|
||||
[dev-community]: https://zulip.com/development-community/
|
||||
[server-repo]: https://github.com/zulip/zulip
|
||||
[github-add-email]: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-email-preferences/adding-an-email-address-to-your-github-account
|
||||
[co-authored-by]: https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors
|
||||
296
docs/contributing/design-discussions.md
Normal file
296
docs/contributing/design-discussions.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# Design discussions
|
||||
|
||||
We discuss ideas for improving Zulip's user experience, interface, and visual
|
||||
design in the [Zulip development
|
||||
community](https://zulip.com/development-community/). The purpose of these
|
||||
design discussions is to help us make smart, well-informed decisions about
|
||||
design changes to the Zulip product. We want Zulip to work great for a diverse
|
||||
array of users and organizations, and discussions in the development community
|
||||
are an incredibly valuable source of insight and ideas. We welcome all
|
||||
perspectives, respectfully shared.
|
||||
|
||||
Most design discussions take place in the [#design][design channel] channel in the
|
||||
development community. Discussions about mobile app design happen in
|
||||
[#mobile-design][mobile-design channel],
|
||||
and design of the terminal app is discussed in
|
||||
[#zulip-terminal][zulip-terminal channel].
|
||||
|
||||
## Guidelines for all participants
|
||||
|
||||
Everyone is encouraged to participate in design discussions! Your participation
|
||||
greatly helps improve the product, especially when you focus your contributions
|
||||
on supporting the productivity of the design team. The more we are able to
|
||||
incorporate a variety of ideas, experiences, and perspectives into the
|
||||
discussion, the better decisions we'll be able to make.
|
||||
|
||||
Please start by reviewing the guide to [how we
|
||||
communicate](how-we-communicate.md) in the Zulip community. Also, when sharing
|
||||
your ideas:
|
||||
|
||||
- Think about corner cases and interactions with existing features that the
|
||||
design will need to handle, and bring up problems with them, especially if they
|
||||
are not obvious. (E.g., “This component also appears with a darker background
|
||||
in the Drafts UI,” with a screenshot).
|
||||
|
||||
- Present technical considerations _where appropriate_. “X requires
|
||||
some refactoring that would take me another hour,” is probably not
|
||||
worth bringing up if X would produce a better user
|
||||
experience. “Adding X might require removing feature Y,” or “X is
|
||||
incompatible with Zulip's security model,” is important to present
|
||||
early.
|
||||
|
||||
Note that [#design][design channel] is a high-traffic channel, and thoughtful
|
||||
participation takes time. Don’t let it prevent you from doing your own work. It
|
||||
can be helpful to pick particular conversations to follow, where you feel that
|
||||
you have insight to share.
|
||||
|
||||
## Participant roles
|
||||
|
||||
At this point, it will be helpful to define a few key roles in design
|
||||
discussions:
|
||||
|
||||
- [Code contributor](#guidelines-for-code-contributors): Anyone working on a PR
|
||||
that includes some frontend changes.
|
||||
|
||||
- [Community moderator](#guidelines-for-community-moderators): Any core
|
||||
contributor or other experienced community member who is helping guide the
|
||||
discussion (with or without "moderator" permissions in the organization).
|
||||
|
||||
- **Design team**: Anyone working actively on the design of the feature at hand
|
||||
and/or overall design for the Zulip product.
|
||||
|
||||
- [Decision makers](#guidelines-for-decision-makers): Project maintainers
|
||||
responsible for design decisions, including design leaders, product leaders,
|
||||
and overall project leadership.
|
||||
|
||||
## Guidelines for code contributors
|
||||
|
||||
When you are working on a PR that includes frontend changes, you may find it helpful
|
||||
to get interactive feedback on the design. The best way to do so is by posting a
|
||||
message in the appropriate design channel in the Zulip development
|
||||
community: [#design][design channel] for the web/desktop app,
|
||||
[#mobile-design][mobile-design channel] for the mobile app, or
|
||||
[#zulip-terminal][zulip-terminal channel] for the terminal app.
|
||||
|
||||
### When to post
|
||||
|
||||
- The issue or a comment on your PR specifically asks you to get feedback in
|
||||
[#design][design channel] or another design channel.
|
||||
|
||||
- The issue you’re working on is not specific about some design point, and you
|
||||
would like advice.
|
||||
|
||||
- You’ve implemented an issue as described, but the UI doesn’t look good or
|
||||
seems awkward to use.
|
||||
|
||||
- You’re prototyping an idea that’s not fully fleshed out.
|
||||
|
||||
### Guidelines for requesting design feedback
|
||||
|
||||
You will get the most helpful feedback by sharing enough context for community
|
||||
participants to understand what you're trying to do, and clearly stating the
|
||||
questions you are looking for feedback on. Some advice:
|
||||
|
||||
- Start a new topic, or use an existing one if there is a topic linked from the
|
||||
issue you’re working on. If you’re starting a new topic, appending the issue
|
||||
or PR number (e.g., `#1234`) to the topic name will turn it into a handy link.
|
||||
|
||||
- Summarize the feature you’re working on. You should provide enough
|
||||
context for readers to understand your question, and include links
|
||||
to any relevant issues or in-progress PRs for additional background.
|
||||
|
||||
- Post screenshots, and perhaps a short video if there is an interaction that
|
||||
screenshots fail to show.
|
||||
|
||||
- Use the [guide on presenting visual
|
||||
changes](../contributing/presenting-visual-changes.md) for guidance on what to
|
||||
show, and how to capture precise Before/After screenshots when appropriate.
|
||||
|
||||
- You may want to post a few screenshots of different options you’re
|
||||
considering.
|
||||
|
||||
- Screenshots should show enough of the app to evaluate how the new feature
|
||||
looks in its context, but not so much that it’s hard to see the feature.
|
||||
|
||||
- Screen captures should demonstrate the feature with a minimal amount of
|
||||
extraneous content.
|
||||
|
||||
- Post a clear question or set of questions that you need help with. What
|
||||
specifically are you looking for feedback on?
|
||||
|
||||
- Since you’ve been working on this issue, you have likely gained some expertise
|
||||
in this area. Educate others by sharing any tradeoffs and relevant
|
||||
considerations you’re aware of.
|
||||
|
||||
Keep in mind that the Zulip community is distributed around the world, and you
|
||||
should not expect to get realtime feedback. However, feel free to bump the
|
||||
thread if you don’t see a response after a couple of business days.
|
||||
|
||||
## Guidelines for community moderators
|
||||
|
||||
Any experienced community participant can guide design discussions, and help
|
||||
make sure that we use everyone's time productively towards making the best
|
||||
decisions we can.
|
||||
|
||||
### Improving the quality of discussions
|
||||
|
||||
Here are some suggestions for how you can help the community have a productive
|
||||
design discussion:
|
||||
|
||||
- If a design discussion seems to have been derailed by a tangent or argument,
|
||||
consider moving the tangent to another topic so that the conversation can
|
||||
refocus on the questions at hand.
|
||||
|
||||
- If the direction of the discussion seems unproductive, you can explicitly
|
||||
suggest circling back to a topic where additional discussion seems valuable.
|
||||
|
||||
- If someone is repeating the same points in a way that’s unhelpful, you can let
|
||||
them know that you understand what they are saying and appreciate their
|
||||
feedback, but at this point would find it helpful to hear feedback from other
|
||||
participants. People may sometimes repeat themselves because they are not feeling
|
||||
heard.
|
||||
|
||||
- That said, sometimes the best way to deal with questions or feedback that
|
||||
don’t move the discussion forward is to let them go by without comment, rather
|
||||
than potentially getting into a protracted back-and-forth that derails the
|
||||
thread. Examples of such feedback include unmotivated personal opinions,
|
||||
proposals that ignore counterarguments that have already been discussed, etc.
|
||||
|
||||
- It’s totally fine to let the conversation slow down or die, especially if it
|
||||
seems to be going off-track. If the decision makers feel that they do not have
|
||||
enough feedback yet, they can revive the conversation as needed, and the pause
|
||||
can serve as a good reset.
|
||||
|
||||
If a conversation is going off-track and you are not sure how to fix it, please
|
||||
ping someone on the core team to intervene and help get the conversation into a
|
||||
better state.
|
||||
|
||||
### Moving threads to the most appropriate channel
|
||||
|
||||
Sometimes it helps to move (part of) a thread to a different channel, so that
|
||||
it's seen by the appropriate audience.
|
||||
|
||||
- We generally aim to discuss raw user feedback on the product’s design in
|
||||
[#feedback](https://chat.zulip.org/#narrow/channel/137-feedback) (when it
|
||||
applies to the web and desktop apps, or to all Zulip clients). The
|
||||
[#design][design channel] should be reserved for design aspects that we’re
|
||||
actively (considering) working on. This lets the design team focus on
|
||||
discussions that are expected to result in actionable decisions.
|
||||
|
||||
- If a discussion that started in another channel has shifted into the design
|
||||
phase, moving the discussion to [#design][design channel] helps the design team
|
||||
follow the conversation.
|
||||
|
||||
- Discussion of implementation-related decisions should ideally happen in
|
||||
non-design channels:
|
||||
[#frontend](https://chat.zulip.org/#narrow/channel/6-frontend) for the web
|
||||
app, and see our [guide to chat.zulip.org
|
||||
channels](https://zulip.com/development-community/#channels-for-code-contributors)
|
||||
for other Zulip codebases. The line can sometimes blur (and that’s OK), but we
|
||||
should aim to move (parts of) the thread if there is an extensive conversation
|
||||
that belongs in the other channel.
|
||||
|
||||
- Similarly, for changes to the mobile app:
|
||||
|
||||
- We aim to discuss raw user feedback in
|
||||
[#mobile](https://chat.zulip.org/#narrow/channel/48-mobile).
|
||||
The [#mobile-design][mobile-design channel] channel is reserved for design
|
||||
aspects that we're actively (considering) working on.
|
||||
- A discussion that has shifted into the design phase should be moved to
|
||||
[#mobile-design][mobile-design channel], to help the design team closely
|
||||
follow the discussion that calls for their input.
|
||||
- Discussion of implementation details should move to
|
||||
[#mobile-team](https://chat.zulip.org/#narrow/channel/243-mobile-team) or to
|
||||
[#mobile-dev-help](https://chat.zulip.org/#narrow/channel/516-mobile-dev-help).
|
||||
|
||||
- Discussions of the mobile app's design should move to
|
||||
[#mobile-design][mobile-design channel] (instead of #design), which the
|
||||
mobile team follows closely.
|
||||
|
||||
Similarly, discussions of the design of the terminal app should move to
|
||||
[#zulip-terminal][zulip-terminal channel].
|
||||
|
||||
## Guidelines for decision makers
|
||||
|
||||
The main purpose of design discussions is to help us make the best design
|
||||
decisions we can. Decision makers should guide the conversation to elicit the
|
||||
ideas, feedback and advice they need from the community.
|
||||
|
||||
Ideally, design discussions should also help us learn as a community. Community
|
||||
members who follow the conversation should get a better understanding of the
|
||||
considerations behind the decisions being discussed, and thus be better able to
|
||||
contribute to the next conversation.
|
||||
|
||||
### Managing the discussion
|
||||
|
||||
Decision makers should actively manage the discussion to make sure we're making
|
||||
good use of everyone's time and attention, and getting useful feedback.
|
||||
|
||||
- Decision makers should aim to follow design threads closely and provide input
|
||||
early and often, so that conversations don’t get blocked waiting for their
|
||||
opinion.
|
||||
|
||||
- Decision makers should actively manage discussion threads when needed in order
|
||||
to seek the types of inputs that will help them. This may include outlining a
|
||||
set of alternatives to consider, posing questions to dig into someone’s
|
||||
feedback, asking for ideas to solve a specific design challenge, etc.
|
||||
|
||||
- Decision makers should explain the reasoning behind their proposed decisions,
|
||||
so that it’s possible to identify any gaps in their thinking, and in order to
|
||||
build a shared understanding in the community.
|
||||
|
||||
- That said, decision makers are not required to respond to every comment being
|
||||
made regarding a proposal, or to answer every question.
|
||||
|
||||
### From discussion to decision
|
||||
|
||||
There are a number of factors that affect when it’s time to move a thread from
|
||||
discussion to a decision. In part, this depends on how significant a commitment
|
||||
we are making with the decision at hand:
|
||||
|
||||
- We want to be very thoughtful about decisions that will take a lot of work to
|
||||
implement, and/or will be difficult to undo.
|
||||
|
||||
- We should try to come up with good designs for the features we're building,
|
||||
but sometimes it's difficult to foresee how an interaction will feel until we
|
||||
try it. Prototyping a UI we are not sure about is a normal part of the design
|
||||
process.
|
||||
|
||||
- When the decision results in filing a non-urgent issue, it’s fine to write up
|
||||
the conclusions on GitHub relatively quickly, and update the issue if more
|
||||
ideas come in later on.
|
||||
|
||||
- We should accept that sometimes an idea we decided on is just not working out,
|
||||
and be willing to go back to the drawing board or iterate further until we get
|
||||
to a state we're happy with.
|
||||
|
||||
With those considerations in mind, here are rough guidelines for when to move on
|
||||
to a decision:
|
||||
|
||||
- For very small decisions, it may be enough to get a sanity-check from one or
|
||||
two well-informed community participants.
|
||||
|
||||
- For more significant decisions, one should generally allow at least 1-2 business
|
||||
days for discussion, to give core team members time to share their perspective
|
||||
if they have something to contribute.
|
||||
|
||||
- Beyond that minimum, the decision makers can move to the decision phase
|
||||
whenever they have enough input to make a well-informed decision. Here are
|
||||
some situations that would indicate that it’s time to move on:
|
||||
|
||||
- There is general consensus on how to proceed. Or, there is consensus
|
||||
between the well-informed participants in the discussion.
|
||||
|
||||
- For a relatively small decision, there is enough useful feedback to
|
||||
generate a solid proposal.
|
||||
|
||||
- If the discussion is primarily rehashing old points, and doesn’t seem to
|
||||
be generating additional insights, it’s time to redirect the conversation
|
||||
or move on to a decision.
|
||||
|
||||
- If the thread has died down, and the decision makers feel that they have
|
||||
enough information to go on. (If they don’t, the thread can be bumped.)
|
||||
|
||||
[design channel]: https://chat.zulip.org/#narrow/channel/101-design
|
||||
[mobile-design channel]: https://chat.zulip.org/#narrow/channel/530-mobile-design
|
||||
[zulip-terminal channel]: https://chat.zulip.org/#narrow/channel/206-zulip-terminal
|
||||
116
docs/contributing/how-we-communicate.md
Normal file
116
docs/contributing/how-we-communicate.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# How we communicate
|
||||
|
||||
The primary communication forum for the Zulip community is the Zulip server
|
||||
hosted at [chat.zulip.org](https://chat.zulip.org/). If you are not familiar
|
||||
with it, start by reading the [Zulip development community
|
||||
guide](https://zulip.com/development-community/). The guidelines here also apply
|
||||
to how we communicate on GitHub issues and pull requests, but other pages in
|
||||
this section go into greater detail about expectations that are specific to pull
|
||||
requests.
|
||||
|
||||
We are deeply committed to maintaining a respectful, collaborative atmosphere
|
||||
across all interactions in the Zulip community. To get a feel for what that
|
||||
means to us, please review the [code of conduct](../code-of-conduct.md) for our
|
||||
community.
|
||||
|
||||
Beyond that, the following guidelines should help you communicate effectively to
|
||||
express your perspective, and support and encourage other participants in the
|
||||
community. By incorporating these patterns of behavior, we'll be able to reach
|
||||
better decisions as a group, and learn and have fun along the way.
|
||||
|
||||
## Providing suggestions and feedback
|
||||
|
||||
- Aim to present your feedback precisely, with reasoning, and in as objective a
|
||||
fashion as you can manage. E.g., “This button really jumps out at me in a way
|
||||
that’s distracting; maybe it’s because of the color has a higher contrast than
|
||||
the surrounding components?” is better than, “Can we make that color less
|
||||
dark?”.
|
||||
|
||||
- Clarify your feedback if there are follow-up questions or points of confusion.
|
||||
However, avoid simply repeating the same points, as it does not move us closer
|
||||
to making the best decisions we can.
|
||||
|
||||
- When relevant, highlight information you have beyond your personal opinion.
|
||||
E.g., “I moderate a community, and often have to answer questions about how
|
||||
this works,” is more helpful than, “This is confusing.”
|
||||
|
||||
- In addition to offering constructive feedback, call out specific things that
|
||||
someone is doing well. This helps folks feel good about their work, and also
|
||||
helps them learn. E.g., “I particularly like the test you added, because...”
|
||||
|
||||
- When asking someone to do something, explain the reasoning behind your
|
||||
request. This is more motivating, and educates folks on what to do next time.
|
||||
|
||||
- If you are not certain about a suggestion you're making, it often works well
|
||||
to frame it as a question. E.g., “Would this be clearer if we...?” or “Could
|
||||
we...?”.
|
||||
|
||||
- Invite others to disagree or contribute additional thoughts, especially if you
|
||||
might be considered an authority in the area being discussed. When more folks
|
||||
feel comfortable speaking up, we are better able to identify problems and
|
||||
fine-tune solutions.
|
||||
|
||||
## Handling disagreements
|
||||
|
||||
- Always treat other participants in the discussion with respect, regardless of
|
||||
whether you agree with their ideas. Ad hominem attacks are never appropriate.
|
||||
|
||||
- Approach discussions with a perspective of curiosity. If someone has expressed
|
||||
an opinion you find odd or surprising, ask them to explain in more detail
|
||||
where they are coming from.
|
||||
|
||||
- If you think someone is factually mistaken, consider how they might have reached
|
||||
their conclusion, and aim to get to a shared understanding. For example:
|
||||
|
||||
- “I wasn't able to replicate this -- is it possible you are on an old Zulip
|
||||
server?”, rather than “This bug report is wrong.”
|
||||
- “Using this function won't work here, because...” instead of “That's the
|
||||
wrong function.”
|
||||
|
||||
- If you disagree with someone on the core team, the best way to make progress
|
||||
is usually to state your opinions and reasoning clearly and respectfully, and
|
||||
then let the other core team members catch up on the conversation. Other
|
||||
project members may find your argument persuasive, and may have ideas that
|
||||
address your concerns.
|
||||
|
||||
## Expressing your appreciation
|
||||
|
||||
There are many ways to contribute to the Zulip community, and it's important to
|
||||
express our appreciation for all the different ways in which folks jump in to
|
||||
help. It helps motivate others, builds consensus towards decisions, and creates
|
||||
a more positive atmosphere in the community.
|
||||
|
||||
For many community participants, it takes stepping out their comfort zone to try
|
||||
something for the first time, such as submitting a pull request, answering a
|
||||
question in the development community, or suggesting a new feature. It's
|
||||
especially important to thank and encourage folks who are stretching themselves
|
||||
to try something new.
|
||||
|
||||
- Remember to say “thanks” when responding to a question or suggestion. For
|
||||
example:
|
||||
|
||||
- “Thanks for the report! ... ” when someone reports a bug.
|
||||
- “Thanks for reviewing my PR! ... ”
|
||||
|
||||
- Express your appreciation for the work that went into a pull request, even
|
||||
when it turns out that the approach taken in the PR is not successful. E.g.,
|
||||
“Thanks for working on this! ... ”
|
||||
|
||||
- Try especially hard to express your appreciation for others' contributions,
|
||||
effort and ideas when you are also providing negative (constructive) feedback
|
||||
on their work.
|
||||
|
||||
- You can use a variety of channels to express your appreciation. A comment
|
||||
directly in a Zulip thread or on a pull request is often best, but in some
|
||||
cases you may also want to send a friendly direct message. For example:
|
||||
|
||||
- “I've noticed that you've been answering lots of questions in #**development
|
||||
help** lately. Thanks so much for doing that!”
|
||||
- “Thanks for moving those messages into a new topic -- the discussion was
|
||||
getting really tangled!”
|
||||
|
||||
- Sometimes a quick emoji reaction can help someone feel that their work is
|
||||
appreciated. 🎉
|
||||
|
||||
- Look over the message you just sent. Did you forget to say “thanks”? It's easy
|
||||
to edit your message, or send a quick follow-up.
|
||||
26
docs/contributing/index.md
Normal file
26
docs/contributing/index.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Contributing to Zulip
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
maxdepth: 3
|
||||
---
|
||||
|
||||
contributing
|
||||
../code-of-conduct
|
||||
how-we-communicate
|
||||
asking-great-questions
|
||||
design-discussions
|
||||
commit-discipline
|
||||
code-style
|
||||
presenting-visual-changes
|
||||
code-reviewing
|
||||
reviewable-prs
|
||||
review-process
|
||||
continuing-unfinished-work
|
||||
zulipbot-usage
|
||||
reporting-bugs
|
||||
reporting-security-vulnerabilities
|
||||
suggesting-features
|
||||
counting-contributions
|
||||
licensing
|
||||
```
|
||||
40
docs/contributing/licensing.md
Normal file
40
docs/contributing/licensing.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Licensing
|
||||
|
||||
Zulip is distributed under the [Apache 2.0
|
||||
license](https://github.com/zulip/zulip/blob/main/LICENSE). This means that all
|
||||
contributions to Zulip — code, images, sounds, etc. — must be compatible with
|
||||
this license.
|
||||
|
||||
## Contributing your own work
|
||||
|
||||
If the work you are contributing is 100% your own, Zulip doesn't require you to
|
||||
sign a copyright assignment or a contributor license agreement for your
|
||||
contribution. As noted [in the GitHub Terms of
|
||||
Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service#6-contributions-under-repository-license):
|
||||
|
||||
> “Whenever you add Content to a repository containing notice of a license, you
|
||||
> license that Content under the same terms, and you agree that you have the
|
||||
> right to license that Content under those terms... This is widely accepted as
|
||||
> the norm in the open-source community; ...”
|
||||
|
||||
## Contributing someone else's work
|
||||
|
||||
If any part of your contribution is from someone else (code snippets, images,
|
||||
sounds, or any other copyrightable work, modified or unmodified), you need to
|
||||
check whether it was distributed under an open-source license that is
|
||||
[compatible][wiki-compatibility] with the [Apache 2.0
|
||||
license](https://github.com/zulip/zulip/blob/main/LICENSE). If it was not, this
|
||||
work cannot be contributed to Zulip, with or without modification.
|
||||
|
||||
[wiki-compatibility]: https://en.wikipedia.org/wiki/License_compatibility#Compatibility_of_FOSS_licenses
|
||||
|
||||
If you have verified that the work is OK to use, you will need to provide
|
||||
appropriate attribution in the [`docs/THIRDPARTY`
|
||||
file](https://github.com/zulip/zulip/blob/main/docs/THIRDPARTY) as part of your
|
||||
PR. Please refer to the [`debian/copyright` file
|
||||
documentation](https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/)
|
||||
for a detailed description (including examples) of how to correctly describe the
|
||||
copyright and licensing information in your PR.
|
||||
|
||||
If you are not sure about the licensing or attribution for your work, please
|
||||
include the full details of your open questions in the description for your PR.
|
||||
390
docs/contributing/presenting-visual-changes.md
Normal file
390
docs/contributing/presenting-visual-changes.md
Normal file
@@ -0,0 +1,390 @@
|
||||
# Presenting visual changes
|
||||
|
||||
If your pull request makes visual changes, or includes refactoring that might
|
||||
cause visual changes, you must include screenshots demonstrating the impact of
|
||||
your changes in the description for your pull request.
|
||||
|
||||
**Always make sure the screenshots in the PR description capture the _current_
|
||||
state of the PR.** To avoid confusion, delete outdated screenshots from the
|
||||
description. If reviewers need to see multiple variants of the UI to make some
|
||||
decision, include those variants in the comments.
|
||||
|
||||
## What to capture
|
||||
|
||||
Always include screenshots of _all_ the UI components and states affected by
|
||||
your PR. For example, a PR that adds a new dropdown setting would need
|
||||
screenshots to demonstrate:
|
||||
|
||||
- What the setting looks like in the settings UI (with some surrounding context).
|
||||
- The open dropdown.
|
||||
- The disabled version of the setting with its accompanying tooltip that would
|
||||
be shown to users who aren't allowed to modify the setting.
|
||||
- Visual impact of using each value of the setting (if any).
|
||||
- Updated help center documentation (if any); see
|
||||
[note](#presenting-documentation-changes) below.
|
||||
|
||||
If you're using standard components, there's no need to go overboard with
|
||||
screenshots:
|
||||
|
||||
- Show the Before state if it provides helpful context (e.g., if you're changing
|
||||
text on a banner), but otherwise you can skip them (e.g., if you're adding a
|
||||
setting).
|
||||
- There's usually no need to show light and dark theme screenshots, or
|
||||
screenshots at different font sizes.
|
||||
- There's usually no need to show the keyboard selection UI.
|
||||
|
||||
However, if your pull request makes any CSS changes, you'll need to thoroughly
|
||||
demonstrate its effects. You will need to **capture precise screenshots**
|
||||
demonstrating the differences between the Before and After states, as described
|
||||
[below](#capturing-precise-screenshots).
|
||||
|
||||
Precise screenshots are necessary not only to document your intended
|
||||
changes, but also to demonstrate that there are **no unintended side-effects**
|
||||
or visual regressions. In fact, PRs that refactor templates or CSS often need to
|
||||
include screenshots to explicitly demonstrate that there are no visual changes.
|
||||
|
||||
:::{important}
|
||||
Wherever possible, use still screenshots rather than videos.
|
||||
:::
|
||||
|
||||
Static screenshots are much easier to review than screencast videos. Use a video
|
||||
only when necessary to demonstrate an interaction, and only to supplement still
|
||||
screenshots. Always include screenshots for any aspects of your changes which
|
||||
can be seen on a still screenshot. See
|
||||
[below](#capturing-and-presenting-short-videos) for how to capture reviewable videos.
|
||||
|
||||
For updates or changes to CSS class rules, it's a good practice
|
||||
to include the results of a [`git grep`][git-grep] search for
|
||||
the class name(s) to confirm that you've tested and captured screenshots
|
||||
of all the impacted areas of the UI or Zulip documentation.
|
||||
|
||||
```console
|
||||
$ git grep '.example-class-name' web/templates/ templates/
|
||||
templates/corporate/...
|
||||
templates/zerver/...
|
||||
web/templates/...
|
||||
```
|
||||
|
||||
Never include screenshots of your code or the GitHub UI, which reviewers can
|
||||
easily see directly.
|
||||
|
||||
## What are precise Before/After screenshots?
|
||||
|
||||
Precise Before/After screenshots have two essential qualities:
|
||||
|
||||
1. **The state of the UI should be identical between screenshots.**
|
||||
For example, a screenshot of the message feed should have messages scrolled to the
|
||||
same spot, the focus ring should be around the same message, etc. The goal is to
|
||||
highlight the differences your PR introduces, and not include any unintended noise in
|
||||
the screenshots from things that just happen to be different.
|
||||
1. **The screenshots must have the exact same pixel dimensions.** If the Before
|
||||
screenshot is 800px by 600px, the After screenshot should be too. This is
|
||||
to make sure that there's a pixel-to-pixel correspondence of everything
|
||||
you've captured onscreen.
|
||||
|
||||
## Why bother with precise Before/After screenshots?
|
||||
|
||||
Capturing precise screenshots serves two primary purposes:
|
||||
|
||||
1. For you as a contributor, **checking your own screenshots** will help you to
|
||||
catch any regressions on your own, prior to submitting your PR. It'll also
|
||||
help you point out changes or shifts for reviewers to consider, which may
|
||||
require some design discussion.
|
||||
2. For reviewers, checking screenshots is a quick way to **verify** that a PR
|
||||
does what's expected, and provide **feedback** on visual changes without
|
||||
pulling down the PR.
|
||||
|
||||
## Capturing precise screenshots
|
||||
|
||||
This section describes different techniques for producing pixel-precise
|
||||
screen captures. To master these techniques, you'll likely need to spend some time
|
||||
working with your capture tools of choice, whether they're part of your browser or
|
||||
operating system, or a third-party screen capture tool or browser plugin.
|
||||
|
||||
### Using Git to get required states
|
||||
|
||||
Git is, of course, your friend for setting up the UI state for Before and After
|
||||
screenshots: the Before shot will typically be of the `main` branch updated from
|
||||
upstream, while the After shot will be of your PR's working branch. Take the time
|
||||
to rebase your working branch over the latest `main`, too, before capturing your
|
||||
screenshots.
|
||||
|
||||
Sometimes you may be asked to present alternative looks to your PR in tandem
|
||||
with a discussion [#design](https://chat.zulip.org/#topics/channel/101-design)
|
||||
channel in the Zulip development community, in which case you'll need to walk
|
||||
through different commits on your branch—or make judicious use of `git stash`
|
||||
and `git stash pop`.
|
||||
|
||||
### Capturing precise screenshots with your browser
|
||||
|
||||
The easiest cross-platform way of capturing screenshots of your PR's changes
|
||||
is to use your browser. Both Chrome and Firefox have built-in screenshot capabilities,
|
||||
so it's worth your time to explore how those work. Firefox's capabilities are neatly
|
||||
tied to its responsive design view, which means you can very precisely size the viewport
|
||||
to highlight the changes in your PR. (And if you're not used to developing in Firefox,
|
||||
this can be a convenient way to check your work in a different browser, too.)
|
||||
|
||||
For example, it's easy to capture a mobile-scale viewport in Firefox like this:
|
||||
|
||||
| In responsive mode for capture | Resulting screenshot |
|
||||
| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
|  |  |
|
||||
|
||||
For another example, if you're making changes to the left sidebar, you'll want to open
|
||||
the viewport wider, until the left sidebar is showing:
|
||||
|
||||

|
||||
|
||||
The great thing about capturing screenshots in your browser is that it is very easy to ensure that you meet both criteria for precise screenshots: a UI in the same state for
|
||||
the Before and After shots, and screenshots that are the same exact dimensions—easily verified by the values you set on the width and height of the viewport.
|
||||
|
||||
Additionally, if you need to demonstrate states like `:hover` or `:active` on an element,
|
||||
you can use your browser's developer tools to emulate that state for you, without your
|
||||
needing to fiddle with the keyboard or mouse.
|
||||
|
||||
### Capturing precise screenshots with native OS tools
|
||||
|
||||
Most of the time, browser-captured screenshots are ideal. Screens are generally
|
||||
high-enough resolution that your reviewers (and you) can quickly recognize any
|
||||
changes just by comparing the full-size screenshots.
|
||||
|
||||
However, if you really do need to illustrate a change in closer detail, it can be helpful
|
||||
to use your operating system's native screen-capture tools. See if your OS allows
|
||||
you to specify a box of fixed dimensions that you can use to repeatedly capture the same
|
||||
area of the screen.
|
||||
|
||||
For example, perhaps there's something very subtle about the channel list that a PR needs
|
||||
to highlight:
|
||||
|
||||

|
||||
|
||||
Note that [a fixed, reusable capture box is different from a freehand capture](#freehand-versus-fixed-screenshots),
|
||||
because the OS enables you to call up the same fixed-size box for repeated screenshots
|
||||
of the same region of the screen, helping you to maintain pixel precision in the
|
||||
Before and After shots. Just be careful not to move your browser window around between
|
||||
shots.
|
||||
|
||||
### Capturing precise screenshots with other software
|
||||
|
||||
If you find that your operating system or browser's tools are insufficient for capturing
|
||||
the screenshots that you need, you might want to explore [third-party software](#screenshot-and-gif-software). Just keep
|
||||
in mind the two qualities your screenshots need to maintain: identical UI state, and
|
||||
pixel-precise dimensions between Before and After shots.
|
||||
|
||||
### Freehand versus fixed screenshots
|
||||
|
||||
It may be tempting to freehand your screenshots, perhaps by using your operating
|
||||
system's screen-capture utility that allows freehand dragging of a capture area.
|
||||
The two freehand-captured images below represent Before and After states. Can you
|
||||
spot any changes to the UI? How about if you open each image in a separate tab in
|
||||
your browser? (Typically a reviewer will open up the full-size images in separate
|
||||
tabs in order to more easily compare them.)
|
||||
|
||||
| Before | After |
|
||||
| --------------------------------------------------------------- | ------------------------------------------------------------- |
|
||||
|  |  |
|
||||
|
||||
Here's an animated GIF approximating a comparison of the full-size images:
|
||||
|
||||

|
||||
|
||||
Compare those to this set of screenshots. These are the same Before and After
|
||||
states as captured in the freehand shots above, but these have been captured using
|
||||
a fixed box offered by an operating system's native screen-capture utility:
|
||||
|
||||
| Before | After |
|
||||
| --------------------------------------------------------- | ------------------------------------------------------- |
|
||||
|  |  |
|
||||
|
||||
Now see if you can catch the change between the Before and After images in this GIF:
|
||||
|
||||

|
||||
|
||||
Those screenshots make it obvious that the space between the Zulip logo and the top
|
||||
of the message area has been reduced. Without precise screenshots, that change
|
||||
would've been nearly impossible to detect.
|
||||
|
||||
### Providing sufficient UI context
|
||||
|
||||
The images above might have been intended to show close details of the Zulip logo
|
||||
and message area. But the contributor could have also just used their browser
|
||||
(Firefox, in this case) to capture more of the viewport:
|
||||
|
||||
| Before | After |
|
||||
| ----------------------------------------------------------------- | --------------------------------------------------------------- |
|
||||
|  |  |
|
||||
|
||||
Even if your work is targeted at a specific element, detailed screenshots are not
|
||||
always the best choice. CSS adjustments are notorious for having unintended consequences,
|
||||
so it's often a smart choice to show as much of the UI as you can.
|
||||
|
||||
As with the fixed-box screenshots above, having pixel-precise screenshots
|
||||
where the UI is in an identical state and there isn't a bunch of unintended movement
|
||||
or other noise, the browser captures above make catching the space shift much easier.
|
||||
|
||||
## Capturing and presenting short videos
|
||||
|
||||
Still screenshots are almost always superior to videos. They are easier to compare, and
|
||||
enable reviewers to focus more precisely on the changes your PR introduces.
|
||||
|
||||
If you absolutely must show off a brief interaction on your PR, see whether your operating
|
||||
system will allow you to again set a fixed box for capturing video of a region of your
|
||||
screen.
|
||||
|
||||
Be sure to edit your video down to the shortest length possible. And rather
|
||||
than post the video—whose format may not be suitable for the web or accessible to all
|
||||
reviewers—use a video-to-GIF service like [ezgif.com](https://ezgif.com/video-to-gif)
|
||||
to create a looping animation showing off the interaction.
|
||||
|
||||
Here, for an example, is a short looping animation from [an actual PR](https://github.com/zulip/zulip/pull/35969)
|
||||
that modified some interactions on the compose box:
|
||||
|
||||

|
||||
|
||||
It's worth noting here that [the full PR](https://github.com/zulip/zulip/pull/35969)
|
||||
included plenty of static screenshots in addition to the GIFs showing off interactivity.
|
||||
|
||||
Finally, make sure a person watching your video can see what you're typing, or where on
|
||||
the screen you're tapping or clicking. Use the "show touches" or "include the mouse
|
||||
pointer" feature if your screen-recording software supports it. To show keyboard
|
||||
interactions, e.g., using a [keyboard shortcut](https://zulip.com/help/keyboard-shortcuts),
|
||||
you can use a [keypress visualizer](#keypress-visualizers-by-platform) while recording.
|
||||
|
||||
## Presenting screenshots on your pull request
|
||||
|
||||
Now that you've got all these screenshots, how do you present them in the
|
||||
description for your PR?
|
||||
|
||||
### Using tables for Before/After comparisons
|
||||
|
||||
For presenting Before and After states, use GitHub's table syntax to render
|
||||
them side-by-side. Reviewers can open the full-size image from GitHub for quick
|
||||
and easy comparison:
|
||||
|
||||
```
|
||||
### Descriptive header for images:
|
||||
|
||||
| Before | After |
|
||||
| --- | --- |
|
||||
|  | 
|
||||
```
|
||||
|
||||
To quickly insert these tables, consider
|
||||
[creating a GitHub Saved Reply](https://docs.github.com/en/get-started/writing-on-github/working-with-saved-replies/creating-a-saved-reply).
|
||||
|
||||
### Making screenshots collapsible
|
||||
|
||||
When including numerous screenshots or screencasts, consider grouping them
|
||||
in details/summary tags to reduce visual clutter and the scroll length of
|
||||
pull-request descriptions and comments. This is especially useful when you
|
||||
have several screenshots or screencasts to include in your PR description
|
||||
or follow-up comments, as you can put groups of related images in separate
|
||||
details/summary tags.
|
||||
|
||||
Do think about your reviewers' comfort when using more than one set of
|
||||
details/summary tags, as it is generally much easier to scroll past a
|
||||
bunch of screenshots than it is to open numerous collapsed details/summary
|
||||
tags.
|
||||
|
||||
```
|
||||
<details>
|
||||
<summary>Descriptive summary of image group</summary>
|
||||
|
||||
| Before | After |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
</details>
|
||||
```
|
||||
|
||||
### Presenting documentation changes
|
||||
|
||||
If you've updated existing documentation in your pull request,
|
||||
include a link to the current documentation above the screenshot
|
||||
of the updates. That way a reviewer can quickly compare the current
|
||||
documentation while reviewing your changes.
|
||||
|
||||
```
|
||||
[Current documentation](link-to-current-documentation-page)
|
||||

|
||||
```
|
||||
|
||||
[git-grep]: https://git-scm.com/docs/git-grep
|
||||
[screenshots-gifs]: ../contributing/presenting-visual-changes.md#screenshot-and-gif-software
|
||||
[zulip-dev-community]: https://chat.zulip.org
|
||||
[link-to-message]: https://zulip.com/help/link-to-a-message-or-conversation#get-a-link-to-a-specific-message
|
||||
[dev-community-linkifiers]: https://zulip.com/development-community/#linking-to-github-issues-and-pull-requests
|
||||
|
||||
## Screenshot and GIF software
|
||||
|
||||
You can check out the following tools for capturing screenshots and videos/GIFs.
|
||||
|
||||
### Screenshot tools by platform
|
||||
|
||||
#### Browser
|
||||
|
||||
- [Firefox screenshots](https://support.mozilla.org/en-US/kb/take-screenshots-firefox) without any plugins
|
||||
- [Chrome screenshots](https://developer.chrome.com/docs/devtools/device-mode#screenshot) without any plugins
|
||||
- [LightShot Screenshot](https://app.prntscr.com/en/index.html) (Chrome, Firefox, IE & Opera)
|
||||
- [Chrome Capture](https://chrome.google.com/webstore/detail/chrome-capture-screenshot/ggaabchcecdbomdcnbahdfddfikjmphe?hl=en)
|
||||
|
||||
#### macOS
|
||||
|
||||
- [Take a screenshot on Mac](https://support.apple.com/en-us/102646)
|
||||
- [LightShot Screenshot](https://app.prntscr.com/en/index.html)
|
||||
- [Gyazo](https://gyazo.com/en)
|
||||
|
||||
#### Windows
|
||||
|
||||
- [Use Snipping Tool to capture screenshots](https://support.microsoft.com/en-us/windows/use-snipping-tool-to-capture-screenshots-00246869-1843-655f-f220-97299b865f6b)
|
||||
- [LightShot Screenshot](https://app.prntscr.com/en/index.html)
|
||||
- [Gyazo](https://gyazo.com/en)
|
||||
- [ScreenToGif](https://www.screentogif.com/)
|
||||
|
||||
#### Linux
|
||||
|
||||
- [GNOME Screenshots and screencasts](https://help.gnome.org/gnome-help/screen-shot-record.html)
|
||||
- [Spectacle by KDE](https://apps.kde.org/spectacle/)
|
||||
|
||||
### GIF tools by platform
|
||||
|
||||
#### Browser
|
||||
|
||||
- [GIPHY](https://giphy.com)
|
||||
- [Chrome Capture](https://chrome.google.com/webstore/detail/chrome-capture/ggaabchcecdbomdcnbahdfddfikjmphe?hl=en)
|
||||
(Tip: Use `Alt`+`I` to interact with the page while recording)
|
||||
|
||||
#### macOS
|
||||
|
||||
- [QuickTime](https://support.apple.com/en-in/HT201066)
|
||||
- [GIPHY](https://giphy.com/apps/giphycapture)
|
||||
- [Zight](https://zight.com)
|
||||
- [Kap](https://getkap.co)
|
||||
- [Gifski](https://sindresorhus.com/gifski)
|
||||
- [Gyazo GIF](https://gyazo.com/en)
|
||||
|
||||
#### Windows
|
||||
|
||||
- [ScreenToGif](https://www.screentogif.com)
|
||||
- [Gyazo GIF](https://gyazo.com/en)
|
||||
|
||||
#### Linux
|
||||
|
||||
- [Peek](https://github.com/phw/peek)
|
||||
- [SilentCast](https://github.com/colinkeenan/silentcast)
|
||||
|
||||
### Keypress visualizers by platform
|
||||
|
||||
#### macOS
|
||||
|
||||
- [KeyCastr](https://github.com/keycastr/keycastr)
|
||||
|
||||
#### Windows
|
||||
|
||||
- [YetAnotherKeyDisplayer(YAKD)](https://github.com/Jagailo/YetAnotherKeyDisplayer)
|
||||
|
||||
#### Linux
|
||||
|
||||
- [hibiki](https://github.com/linuxmobile/hibiki), for Wayland.
|
||||
- [screenkey](https://gitlab.com/screenkey/screenkey), for X11.
|
||||
157
docs/contributing/reporting-bugs.md
Normal file
157
docs/contributing/reporting-bugs.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# Reporting bugs
|
||||
|
||||
There are several ways to report bugs (or possible bugs) you encounter in Zulip:
|
||||
|
||||
- If you have a concrete bug report with steps to reproduce the behavior, [file an
|
||||
issue](#filing-a-github-issue) in the appropriate GitHub repository.
|
||||
- If you are not sure whether the issue you encountered is a bug, or how to
|
||||
reproduce it, [start a
|
||||
conversation](#starting-a-conversation-about-a-possible-bug) in the Zulip
|
||||
development community.
|
||||
- To report a possible security issue, contact Zulip's security team at
|
||||
[security@zulip.com](mailto:security@zulip.com). _Do not_ report security issues
|
||||
publicly (in GitHub or in the Zulip development community). We create a CVE for
|
||||
every security issue in our released software.
|
||||
- If reporting a bug requires sharing private details about your
|
||||
organization, email [support@zulip.com](mailto:support@zulip.com).
|
||||
|
||||
No matter where you report the bug, please follow the instructions below for
|
||||
what to include in a bug report.
|
||||
|
||||
## What to include in a bug report
|
||||
|
||||
1. **Describe** what you were expecting to see, what you saw instead, and steps
|
||||
that may help others reproduce the surprising behavior you experienced.
|
||||
Include screenshots and/or screen captures (see
|
||||
[recommended tools](../contributing/presenting-visual-changes.md#screenshot-and-gif-software))
|
||||
if they help communicate what you are describing, but avoid posting long videos.
|
||||
1. **Indicate the [version](https://zulip.com/help/view-zulip-version)** of the
|
||||
Zulip app where you encountered the bug. It may also be helpful to note your
|
||||
operating system, whether you are using the web app or the desktop app, and
|
||||
your browser if using the web app.
|
||||
|
||||
## Filing a GitHub issue
|
||||
|
||||
Filing a GitHub issue works best when:
|
||||
|
||||
- You are confident that the behavior you encountered is a bug, not some quirk
|
||||
of how a feature works that may turn out to be intentional.
|
||||
- You can describe clearly what you were expecting to see, and what you saw instead.
|
||||
- You can provide steps for someone else to reproduce the issue you encountered.
|
||||
This is important for developers to be able to fix the bug, and test that
|
||||
their fix worked.
|
||||
|
||||
If all of the above accurately describe your situation, please file an issue!
|
||||
Otherwise, we recommend [starting a
|
||||
conversation](#starting-a-conversation-about-a-possible-bug) in the Zulip
|
||||
development community so that the problem you encountered can be discussed
|
||||
interactively.
|
||||
|
||||
Steps and best practices for filing a GitHub issue:
|
||||
|
||||
1. Report the issue in the **appropriate [Zulip
|
||||
repository](https://github.com/zulip)**. The most commonly used repositories
|
||||
are:
|
||||
- [zulip/zulip](https://github.com/zulip/zulip/issues) for issues with the
|
||||
Zulip web app or server. A good default if you aren't sure which repository
|
||||
to use.
|
||||
- [zulip/zulip-flutter](https://github.com/zulip/zulip-flutter/issues) for
|
||||
issues with the mobile apps.
|
||||
- [zulip/zulip-desktop](https://github.com/zulip/zulip-desktop/issues) for
|
||||
issues that are specific to the Zulip desktop app, and therefore _do not_
|
||||
occur in the web app.
|
||||
- [zulip/zulip-terminal](https://github.com/zulip/zulip-terminal/issues) for
|
||||
issues with the terminal app.
|
||||
2. Do a **quick search** of the repository to see if your issue has already
|
||||
been filed. If it has, you can add a comment if that seems helpful.
|
||||
3. If you are aware of a related discussion in the Zulip development community,
|
||||
please **cross-link** between the issue and the discussion thread. [Link to a
|
||||
specific
|
||||
message](https://zulip.com/help/link-to-a-message-or-conversation#get-a-link-to-a-specific-message)
|
||||
in the discussion thread, as message links will still work even if the topic is
|
||||
renamed or resolved.
|
||||
|
||||
To encourage prompt attention and discussion for a bug report you have filed,
|
||||
you can send a message in the Zulip development community with the key points
|
||||
from your report. Be sure to [link to the GitHub
|
||||
issue](https://zulip.com/development-community/#linking-to-github-issues-and-pull-requests).
|
||||
See the following section for advice on where and how to start the conversation.
|
||||
|
||||
## Starting a conversation about a possible bug
|
||||
|
||||
If you are not sure whether the issue you encountered is a bug, or how to
|
||||
reproduce it, we highly recommend reporting it in the [Zulip development
|
||||
community](https://zulip.com/development-community/). It's the best place to
|
||||
interactively discuss your problem.
|
||||
|
||||
Steps and best practices for starting a conversation:
|
||||
|
||||
1. [**Join** the Zulip development
|
||||
community](https://zulip.com/development-community/) if you don't already
|
||||
have an account.
|
||||
2. Pick an **appropriate channel** to report your issue:
|
||||
- [#issues](https://chat.zulip.org/#narrow/channel/9-issues) for issues with
|
||||
the Zulip web app or server. Use this channel if you aren't sure which
|
||||
channel is most appropriate.
|
||||
- [#mobile](https://chat.zulip.org/#narrow/channel/48-mobile) for issues with
|
||||
the mobile apps.
|
||||
- [#desktop](https://chat.zulip.org/#narrow/channel/16-desktop) for issues
|
||||
that are specific to the Zulip desktop app, and therefore _do not_
|
||||
occur in the web app.
|
||||
- [#zulip-terminal](https://chat.zulip.org/#narrow/channel/206-zulip-terminal)
|
||||
for issues with the terminal app.
|
||||
- [#production
|
||||
help](https://chat.zulip.org/#narrow/channel/31-production-help) for issues
|
||||
related to self-hosting Zulip. See the [troubleshooting
|
||||
guide](../production/troubleshooting.md) for additional details.
|
||||
3. **[Start a new topic](https://zulip.com/help/introduction-to-topics#how-to-start-a-new-topic)**
|
||||
for discussing your issue, using a brief summary of the issue as the name of
|
||||
the topic.
|
||||
|
||||
If you aren't sure where to post or how to name your topic, don't worry!
|
||||
Moderators can always rename the topic, or move the thread to another channel.
|
||||
|
||||
Once a possible bug is reported, members of the development community will jump
|
||||
in to discuss whether the report constitutes a bug, how to reproduce it, and how
|
||||
it can be resolved. The initial reporter can help by monitoring the discussion
|
||||
and replying to any follow-up questions. If the report is determined to be a
|
||||
reproducible bug, a GitHub issue will be filed to keep track of it (see below).
|
||||
|
||||
## Managing bug reports
|
||||
|
||||
This section describes our process for managing bugs. All community members are
|
||||
encouraged to help make sure this process runs smoothly, whether or not they
|
||||
originally reported the bug.
|
||||
|
||||
Whenever a bug is tracked in GitHub and also discussed in the development
|
||||
community, be sure to cross-link between the issue and the conversation. [Link
|
||||
to a specific
|
||||
message](https://zulip.com/help/link-to-a-message-or-conversation#get-a-link-to-a-specific-message)
|
||||
in the discussion thread, as message links will still work even if the topic is
|
||||
renamed or resolved.
|
||||
|
||||
- If you encounter a definite bug with a clear reproducer and significant user
|
||||
impact, it is best to both file a GitHub issue and immediately start a
|
||||
discussion in the development community. This helps us address important
|
||||
issues as quickly as possible.
|
||||
- For minor bugs (e.g., a visual glitch in a settings menu for very long channel
|
||||
names), filing a GitHub issue is sufficient.
|
||||
- If a potential bug discussed in the development community is confirmed to be
|
||||
an actual, reproducible bug, anyone can help out by filing a GitHub issue to
|
||||
track it:
|
||||
- In some cases, especially if we're planning to fix the issue right away, the
|
||||
GitHub issue description can simply quote and link to a message from the
|
||||
discussion in the development community -- no need to stress over making it
|
||||
perfect.
|
||||
- [Use Zulipbot](../contributing/zulipbot-usage.md) to add the appropriate
|
||||
labels, including “bug” and at least one area label; leave a comment on
|
||||
the issue if you don't know what area labels to use.
|
||||
- You can add the “help wanted” label (and claim the issue if you like) if
|
||||
that is appropriate based on the discussion. Note that sometimes we won't
|
||||
mark a reproducible bug as “help wanted” for various reasons. For example,
|
||||
we might want a core contributor to take it on, or the fix might be planned
|
||||
as part of a larger project.
|
||||
- Don't forget to cross-link between the issue and the discussion.
|
||||
- If a bug report in GitHub is not sufficiently clear, Zulip maintainers will
|
||||
often encourage the reporter to discuss it interactively in the development
|
||||
community.
|
||||
1
docs/contributing/reporting-security-vulnerabilities.md
Symbolic link
1
docs/contributing/reporting-security-vulnerabilities.md
Symbolic link
@@ -0,0 +1 @@
|
||||
../../SECURITY.md
|
||||
135
docs/contributing/review-process.md
Normal file
135
docs/contributing/review-process.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# Pull request review process
|
||||
|
||||
Pull requests submitted to Zulip go through a rigorous review process, which is
|
||||
designed to ensure that we are building a high-quality product with a
|
||||
maintainable codebase. This page describes the stages of review your pull
|
||||
request may go through, and offers guidance on how you can help keep your pull
|
||||
request moving along.
|
||||
|
||||
## Labels for managing the stages of pull request review
|
||||
|
||||
In the Zulip server/web app repository
|
||||
([`zulip/zulip`](https://github.com/zulip/zulip/)), we use GitHub labels to help
|
||||
everyone understand where a pull request is in the review process. These labels
|
||||
are noted below, alongside their corresponding pull-request stage. Each label is
|
||||
removed by the reviewer for that stage when they have no more feedback on the PR
|
||||
and consider it ready for the next stage of review.
|
||||
|
||||
Sometimes, a label may also be removed because significant changes by
|
||||
the contributor are required before the PR ready to be reviewed again. In that
|
||||
case, the contributor should post a comment mentioning the reviewer when the
|
||||
changes have been completed, unless the reviewer requested some other action.
|
||||
|
||||
## Stages of a pull request review
|
||||
|
||||
This section describes the stages of the pull request review process. Each stage
|
||||
may require several rounds of iteration. Don't feel daunted! Not every PR will
|
||||
require all the stages described, and the process often goes quite quickly for
|
||||
smaller changes that are clearly explained.
|
||||
|
||||
1. **Product review.** Oftentimes, seeing an initial implementation will make it
|
||||
clear that the product design for a feature needs to be revised, or that
|
||||
additional changes are needed. The reviewer may therefore ask you to amend or
|
||||
change the implementation. Some changes may be blockers for getting the PR
|
||||
merged, while others may be improvements that can happen afterwards. Feel
|
||||
free to ask if it's unclear which type of feedback you're getting.
|
||||
(Follow-ups can be a great next issue to work on!)
|
||||
|
||||
Your PR might be assigned the [product
|
||||
review](https://github.com/zulip/zulip/pulls?q=is%3Aopen+is%3Apr+label%3A%22product+review%22)
|
||||
label at this stage, or later in the review process as questions come up. You
|
||||
can also add this label yourself if appropriate. If doing so, be sure to
|
||||
clearly outline the product questions that need to be addressed.
|
||||
|
||||
2. **QA.** If your PR makes user-facing changes, it may get a round of testing
|
||||
without reference to the code. You will get feedback on any user-facing bugs
|
||||
in the implementation. To minimize the number of review round-trips, make
|
||||
sure to [thoroughly test](../contributing/code-reviewing.md#manual-testing)
|
||||
your own PR prior to asking for review.
|
||||
|
||||
Your PR might be assigned the [QA
|
||||
needed](https://github.com/zulip/zulip/pulls?q=is%3Aopen+is%3Apr+label%3A%22QA+needed%22)
|
||||
label at this stage, or later on if re-testing is required.
|
||||
|
||||
3. **Initial code review.** All PRs will go through one or more rounds of code
|
||||
review. Your code may initially be [reviewed by other
|
||||
contributors](../contributing/code-reviewing.md). This helps us make good use
|
||||
of project maintainers' time, and helps you make progress on the PR by
|
||||
getting quick feedback. A project maintainer may leave a comment asking
|
||||
someone with expertise in the area you're working on to review your work.
|
||||
|
||||
4. **Maintainer code review.** In this phase, a Zulip maintainer will do a
|
||||
thorough review of your proposed code changes. Your PR may be assigned the
|
||||
[maintainer
|
||||
review](https://github.com/zulip/zulip/pulls?q=is%3Aopen+is%3Apr+label%3A%22maintainer+review%22)
|
||||
label at this stage.
|
||||
|
||||
5. **Documentation review.** If your PR includes documentation changes, those
|
||||
changes will require review. This generally happens fairly late in the review
|
||||
process, once the UI and the code are unlikely to undergo major changes.
|
||||
Maintainers may indicate that a PR is ready for documentation review by
|
||||
adding a [help center
|
||||
review](https://github.com/zulip/zulip/pulls?q=is%3Aopen+is%3Apr+label%3A%22help+center+review%22)
|
||||
and/or [api docs
|
||||
review](https://github.com/zulip/zulip/pulls?q=is%3Aopen+is%3Apr+label%3A%22api+docs+review%22)
|
||||
label, and mentioning a documentation maintainer in the comments.
|
||||
|
||||
6. **Integration review**. This is the final round of the review process,
|
||||
generally done by `@timabbott` for server and web app PRs. A maintainer will
|
||||
usually assign the [integration
|
||||
review](https://github.com/zulip/zulip/pulls?q=is%3Aopen+is%3Apr+label%3A%22integration+review%22)
|
||||
label when the PR is ready for this phase.
|
||||
|
||||
## How to help move the review process forward
|
||||
|
||||
If there are no comments on your PR for a week after you submit it, you can
|
||||
check again to make sure that it's ready for review, and then post a quick
|
||||
comment to remind Zulip's maintainers to take a look at your work. Consider also
|
||||
[asking for a
|
||||
review](../contributing/code-reviewing.md#asking-for-a-code-review) in the Zulip
|
||||
development community.
|
||||
|
||||
After that, the key to keeping your review moving through the review process is to:
|
||||
|
||||
- Address _all_ the feedback to the best of your ability.
|
||||
- Make it clear when the requested changes have been made
|
||||
and you believe it's time for another look.
|
||||
- Make it as easy as possible to review the changes you made.
|
||||
|
||||
In order to do this, when you believe you have addressed the previous round of
|
||||
feedback on your PR as best you can, post a comment asking reviewers to take
|
||||
another look. Your comment should make it easy to understand what has been done
|
||||
and what remains by:
|
||||
|
||||
- Summarizing the changes made since the last review you received. Be clear
|
||||
about which issues you've resolved (and how!).
|
||||
- Highlighting remaining questions or decisions, with links to any relevant
|
||||
threads in the [Zulip development
|
||||
community](https://zulip.com/development-community/). It should be clear which
|
||||
feedback you _haven't_ addressed yet.
|
||||
- Providing updated screenshots and information on manual testing if
|
||||
appropriate.
|
||||
|
||||
The easier it is to review your work, the more likely you are to receive quick
|
||||
feedback.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
Sometimes reviewers will comment on "follow-ups" to your pull request. A
|
||||
follow-up is something that can be done separately from the changes in the
|
||||
current pull request, because it's tangential to the current changes, or would
|
||||
be the next task to do once the current changes are completed.
|
||||
|
||||
You should prioritize completing the current pull request over working on
|
||||
follow-ups. However, you are expected to manage follow-ups to your work:
|
||||
|
||||
1. If possible, it's best to complete follow-ups as soon as you are done with
|
||||
the current pull request. That way, both you and reviewers have the context
|
||||
for the changes fresh in mind.
|
||||
|
||||
1. If you don't expect to have time to complete a follow-up soon (or aren't sure
|
||||
if you will), please file an issue to track it. Include a description of the
|
||||
required changes, and a link to the comment where the follow-up was
|
||||
discussed. You can copy-paste the issue description from the prior
|
||||
discussion, but be sure that what you write makes sense without needing to
|
||||
refer to the original thread.
|
||||
168
docs/contributing/reviewable-prs.md
Normal file
168
docs/contributing/reviewable-prs.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# Submitting a pull request
|
||||
|
||||
A pull request (PR) is a presentation of your proposed changes to Zulip. Your aim
|
||||
should be to explain your changes as clearly as possible. This will help
|
||||
reviewers evaluate whether the proposed changes are correct, and address any
|
||||
open questions. Clear communication helps the whole Zulip project move more
|
||||
quickly by saving maintainers time when they review your code. It will also make
|
||||
a big difference for getting your work integrated without delay.
|
||||
|
||||
You will go through the following steps to prepare your work for review. Each
|
||||
step is described in detail below, with links to additional resources:
|
||||
|
||||
1. Write your code [with clarity in mind](#write-clear-code).
|
||||
1. [Organize your proposed changes](#organize-your-proposed-changes) into a
|
||||
series of commits that tell the story of how the codebase will change.
|
||||
1. [Explain your changes](#explain-your-changes) in the description for your
|
||||
pull request, including
|
||||
[screenshots](../contributing/presenting-visual-changes.md) for visual changes.
|
||||
1. Carefully [review your own work](#review-your-own-work).
|
||||
1. [Submit your pull request](#submit-your-pull-request-for-review) for review.
|
||||
|
||||
To learn more about putting together pull requests maintainers will love to
|
||||
review, check out [this FOSDEM
|
||||
talk](https://fosdem.org/2026/schedule/event/L7ERNP-prs-maintainers-will-love/)
|
||||
by a Zulip maintainer.
|
||||
|
||||
See the [pull request review process](../contributing/review-process.md) guide
|
||||
for a detailed overview of what happens once your pull request is submitted.
|
||||
|
||||
## Write clear code
|
||||
|
||||
When you write code, you should make sure that you understand _why it works_ as
|
||||
intended. This is the foundation for being able to explain your proposed changes
|
||||
to others.
|
||||
|
||||
Zulip’s coding philosophy is to focus relentlessly on making the codebase easy
|
||||
to understand and difficult to make dangerous mistakes. Our linters, tests, code
|
||||
style guidelines, [testing philosophy](../testing/philosophy.md), [commit
|
||||
discipline](../contributing/commit-discipline.md), this documentation, and our
|
||||
attention to detail in [code review](../contributing/review-process.md) are all
|
||||
important elements of this strategy. Following these guidelines is essential if
|
||||
you'd like your work to be merged into the project.
|
||||
|
||||
If any part of your contribution is from someone else (code snippets, images,
|
||||
sounds, or any other copyrightable work, modified or unmodified), be sure to
|
||||
review the instructions on how to [properly attribute](./licensing.md) the work.
|
||||
|
||||
## Organize your proposed changes
|
||||
|
||||
The changes you submit will be organized into a series of commits. A PR might
|
||||
contain a single commit, or a dozen or more, depending on the changes being
|
||||
made.
|
||||
|
||||
Commits help you tell the story of how each change you are proposing is
|
||||
necessary or helpful. If you were presenting your changes, a commit might be a
|
||||
slide in your presentation. As a rough guideline, a good commit usually has less
|
||||
than 100 lines of code changes. If you can see a way to split a commit into
|
||||
different pieces of meaning, you should split it.
|
||||
|
||||
Keep in mind that you are presenting your final work product, _not_ the path you
|
||||
took to get there. You should never have a commit that can be described as
|
||||
fixing a mistake in an earlier commit in the same PR; use `git rebase -i` to fix
|
||||
the mistake in the original commit.
|
||||
|
||||
See the [commit discipline guide](../contributing/commit-discipline.md) for more
|
||||
details on how to structure your commits, and guidelines on how to write good
|
||||
commit messages. Your pull request can only be reviewed once you've followed
|
||||
these guidelines to the best of your ability. This makes it much easier for
|
||||
reviewers to understand your work and identify any problems.
|
||||
|
||||
Ideally, when reviewing a pull request for a complex project, Zulip's
|
||||
maintainers should be able to verify and merge the first few commits, and leave
|
||||
comments on the rest. It is by far the most efficient way to do collaborative
|
||||
development, since one is constantly making progress, we keep branches small,
|
||||
and reviewers don't end up repeatedly going over the earlier parts of a pull
|
||||
request.
|
||||
|
||||
## Explain your changes
|
||||
|
||||
By the time you are submitting your pull request, you should already have put a
|
||||
lot of thought into how to organize and present your proposed changes. In the
|
||||
description for your pull request, you will:
|
||||
|
||||
- Provide an overview of your changes.
|
||||
- Note any differences from prior plans (e.g., from the description of the issue you
|
||||
are solving).
|
||||
- Call out any open questions, concerns, or decisions you are uncertain about.
|
||||
The review process will go a lot more smoothly if points of uncertainty are
|
||||
explicitly laid out.
|
||||
- Include screenshots for all visual changes, so that they can be reviewed
|
||||
without running your code. Be sure to follow our
|
||||
[guide on presenting visual changes](../contributing/presenting-visual-changes.md).
|
||||
|
||||
If you have a question about a specific part of your code that you expect to be
|
||||
resolved during the review process, put it in a PR comment attached to a
|
||||
relevant part of the changes.
|
||||
|
||||
Take advantage of [GitHub's formatting][github-syntax] to make your pull request
|
||||
description and comments easy to read.
|
||||
|
||||
[github-syntax]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax
|
||||
|
||||
### Discussions in the development community
|
||||
|
||||
Any questions for which broader feedback or visibility is helpful are discussed
|
||||
in the [Zulip development community](https://zulip.com/development-community/).
|
||||
|
||||
If there has been a conversation in the [Zulip development
|
||||
community][zulip-dev-community] about the changes you've made or the issue your
|
||||
pull request addresses, please cross-link between your pull request and those
|
||||
conversations in both directions. This provides helpful context for maintainers
|
||||
and reviewers. Specifically, it's best to link from your pull request [to a
|
||||
specific message][link-to-message], as these links will still work even if the
|
||||
topic of the conversation is renamed, moved or resolved.
|
||||
|
||||
Once you've created a pull request on GitHub, you can use one of the [custom
|
||||
linkifiers][dev-community-linkifiers] in the development community to easily
|
||||
link to your pull request from the relevant conversation.
|
||||
|
||||
[zulip-dev-community]: https://chat.zulip.org
|
||||
[link-to-message]: https://zulip.com/help/link-to-a-message-or-conversation#get-a-link-to-a-specific-message
|
||||
[dev-community-linkifiers]: https://zulip.com/development-community/#linking-to-github-issues-and-pull-requests
|
||||
|
||||
## Review your own work
|
||||
|
||||
Before requesting a review for your pull request, follow our [review
|
||||
guide](./code-reviewing.md#reviewing-your-own-code) to carefully review and test
|
||||
your own work. You can often find things you missed by taking a step back to
|
||||
look over your work before asking others to do so. Catching mistakes yourself
|
||||
will help your PRs be merged faster, and reviewers will appreciate the quality
|
||||
and professionalism of your work.
|
||||
|
||||
The pull request template in the `zulip/zulip` repository has a checklist of
|
||||
reminders for points you need to cover in your review. Make sure that all the
|
||||
relevant items on the self-review checklist have been addressed, and check them
|
||||
off on the list.
|
||||
|
||||
## Submit your pull request for review
|
||||
|
||||
If you are new to Git, see our guide on [making a pull
|
||||
request](../git/pull-requests.md) for detailed technical instructions on how to
|
||||
submit a pull request.
|
||||
|
||||
When submitting your PR, you will need to make sure that the pull request passes
|
||||
all CI tests. You can sometimes request initial feedback if there are open
|
||||
questions that will impact how you update the tests. But in general,
|
||||
maintainers will wait for your PR to pass tests before reviewing your work.
|
||||
|
||||
If your PR was not ready for review when you first posted it (e.g., because it
|
||||
was failing tests, or you weren't done working through the self-review
|
||||
checklist), notify maintainers when you'd like them to take a look by posting a
|
||||
clear comment on the main GitHub thread for your PR with details on any changes
|
||||
from the original version; this is very helpful for any maintainers who already
|
||||
read the draft PR.
|
||||
|
||||
## Draft pull requests
|
||||
|
||||
If it helps your workflow, you can submit your pull request marked as
|
||||
a [draft][github-help-draft-pr] while you're still working on it. When ready for
|
||||
review:
|
||||
|
||||
1. Make sure your PR is no longer marked as a [draft][github-help-draft-pr], and
|
||||
doesn't have "WIP" in the title.
|
||||
|
||||
1. Post a quick "Ready for review!" comment on the main GitHub thread for your
|
||||
PR.
|
||||
|
||||
[github-help-draft-pr]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests
|
||||
111
docs/contributing/suggesting-features.md
Normal file
111
docs/contributing/suggesting-features.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Suggesting features and improvements
|
||||
|
||||
If you have ideas for how to make Zulip better, we'd love to hear from you! Many
|
||||
improvements start with a user's suggestion. The best way to suggest a feature
|
||||
or an improvement is by starting a conversation in the [Zulip development
|
||||
community](https://zulip.com/development-community/). It's a great way to engage
|
||||
interactively with members of the community, and explore how best to improve
|
||||
Zulip for you and other users.
|
||||
|
||||
Usually, if the discussion leads to a concrete proposal, Zulip's product team
|
||||
will follow up by filing a GitHub issue to track the idea. Many conversations do
|
||||
not immediately lead to a GitHub issue, and that's OK! Sometimes the time is not
|
||||
right to pin down a plan, or more ideas need to come in before a great proposal
|
||||
emerges. Regardless of whether a discussion results in immediate action, we
|
||||
appreciate the time everyone takes to make suggestions and brainstorm ideas.
|
||||
|
||||
## What to include in your proposal
|
||||
|
||||
- Describe your idea. It's absolutely fine to bring up a problem without
|
||||
suggesting a concrete solution.
|
||||
- Provide context on how the change you are proposing would help you or your
|
||||
organization. It is often helpful to describe how you are using Zulip (e.g.,
|
||||
"I work at a small startup", or "I'm teaching a class"). This lets us combine
|
||||
our Zulip expertise with your requirements to come up with a great design for
|
||||
a feature.
|
||||
- If you are aware of a related issue in GitHub or a prior conversation in the
|
||||
development community, please include a link.
|
||||
|
||||
## Starting a conversation about a suggested feature or improvement
|
||||
|
||||
Steps and best practices for starting a conversation:
|
||||
|
||||
1. [**Join** the Zulip development
|
||||
community](https://zulip.com/development-community/) if you don't already
|
||||
have an account.
|
||||
2. Pick an **appropriate channel** to discuss your idea:
|
||||
- [#feedback](https://chat.zulip.org/#narrow/channel/137-feedback) for suggestions for
|
||||
the Zulip web app or server. Use this channel if you aren't sure which channel is
|
||||
most appropriate.
|
||||
- [#mobile](https://chat.zulip.org/#narrow/channel/48-mobile) for suggestions
|
||||
for the mobile apps.
|
||||
- [#desktop](https://chat.zulip.org/#narrow/channel/16-desktop) for suggestions
|
||||
that are specific to the Zulip desktop app.
|
||||
- [#zulip-terminal](https://chat.zulip.org/#narrow/channel/206-zulip-terminal)
|
||||
for suggestions for the terminal app.
|
||||
- [#production
|
||||
help](https://chat.zulip.org/#narrow/channel/31-production-help) for suggestions
|
||||
related to self-hosting Zulip.
|
||||
3. **[Start a new topic](https://zulip.com/help/introduction-to-topics#how-to-start-a-new-topic)**
|
||||
for discussing your suggestions, using a brief summary of your idea as the
|
||||
name of the topic.
|
||||
|
||||
If you aren't sure where to post or how to name your topic, don't worry!
|
||||
Moderators can always rename the topic, or move the thread to another channel.
|
||||
|
||||
Members of the development community will jump in to discuss your idea. You can
|
||||
help by participating in the discussion, including replying to any follow-up
|
||||
questions, and helping develop the proposal. The discussion may conclude with an
|
||||
issue being filed in GitHub to track the plan that was developed.
|
||||
|
||||
## Filing a GitHub issue
|
||||
|
||||
Filing a GitHub issue can be effective when you have a very specific proposal
|
||||
for a feature or improvement. Steps and best practices for filing an issue:
|
||||
|
||||
1. File the issue in the **appropriate [Zulip
|
||||
repository](https://github.com/zulip)**. The most commonly used repositories
|
||||
are:
|
||||
- [zulip/zulip](https://github.com/zulip/zulip/issues) for suggestions for the
|
||||
Zulip web app or server. A good default if you aren't sure which repository
|
||||
to use.
|
||||
- [zulip/zulip-flutter](https://github.com/zulip/zulip-flutter/issues) for
|
||||
suggestions for the mobile apps.
|
||||
- [zulip/zulip-desktop](https://github.com/zulip/zulip-desktop/issues) for
|
||||
suggestions that are specific to the Zulip desktop app.
|
||||
- [zulip/zulip-terminal](https://github.com/zulip/zulip-terminal/issues) for
|
||||
suggestions for the terminal app.
|
||||
2. Do a **quick search** of the repository to see if there is already a similar
|
||||
request. If there is, add a comment explaining why you would also appreciate
|
||||
the proposed change, and make any additional suggestions you might have. Do
|
||||
not file a new issue.
|
||||
3. If you are aware of a related discussion in the Zulip development community,
|
||||
please **cross-link** between the issue and the discussion thread. [Link to a
|
||||
specific
|
||||
message](https://zulip.com/help/link-to-a-message-or-conversation#get-a-link-to-a-specific-message)
|
||||
in the discussion thread, as message links will still work even if the topic is
|
||||
renamed or resolved.
|
||||
|
||||
## Evaluation and onboarding feedback
|
||||
|
||||
If you have been involved in the decision to use (or not use!) Zulip, or are
|
||||
currently considering it, we'd love to hear about it. You can contact us
|
||||
publicly in the [#feedback](https://chat.zulip.org/#narrow/channel/137-feedback)
|
||||
channel in the [Zulip development
|
||||
community](https://zulip.com/development-community/), or privately at
|
||||
[feedback@zulip.com](mailto:feedback@zulip.com).
|
||||
|
||||
Here are some questions we're especially interested in:
|
||||
|
||||
- **Who you are**: Tell us a bit about your organization. What does it do? How many
|
||||
people are involved?
|
||||
- **Evaluation**: What is the process by which your organization chose or will
|
||||
choose a team chat product?
|
||||
- **Pros and cons**: What are the pros and cons of Zulip for your organization,
|
||||
and the pros and cons of other products you are evaluating?
|
||||
- **Features**: What are the features that are most important for your
|
||||
organization? In the best-case scenario, what would your chat solution do
|
||||
for you?
|
||||
- **Onboarding**: If you remember, what were your impressions during your first
|
||||
few minutes of using Zulip? What did you notice, and how did you feel? Was
|
||||
there anything that stood out to you as confusing, or unexpected, or great?
|
||||
94
docs/contributing/zulipbot-usage.md
Normal file
94
docs/contributing/zulipbot-usage.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Using zulipbot
|
||||
|
||||
Zulip uses [@zulipbot](https://github.com/zulipbot), a GitHub workflow bot
|
||||
deployed on all Zulip repositories, to handle issues and pull requests in our
|
||||
repositories in order to create a better workflow for Zulip contributors.
|
||||
|
||||
Its purpose is to work around various limitations in GitHub's
|
||||
permissions and notifications systems to make it possible to have a
|
||||
much more democratic workflow for our contributors. It allows anyone
|
||||
to self-assign or label an issue, not just the core contributors
|
||||
trusted with full write access to the repository (which is the only
|
||||
model GitHub supports).
|
||||
|
||||
## Usage
|
||||
|
||||
- **Claim an issue** — Comment `@zulipbot claim` on the issue you want
|
||||
to claim; **@zulipbot** will assign you to the issue and label the issue as
|
||||
**in progress**.
|
||||
|
||||
- If you're a new contributor, **@zulipbot** will give you read-only
|
||||
collaborator access to the repository and leave a welcome message on the
|
||||
issue you claimed.
|
||||
|
||||
- You can also claim an issue that you've opened by including
|
||||
`@zulipbot claim` in the body of your issue.
|
||||
|
||||
- If you accidentally claim an issue you didn't want to claim, comment
|
||||
`@zulipbot abandon` to abandon an issue.
|
||||
|
||||
- **Label your issues** — Add appropriate labels to issues that you opened by
|
||||
including `@zulipbot add` in an issue comment or the body of your issue
|
||||
followed by the desired labels enclosed within double quotes (`""`).
|
||||
|
||||
- For example, to add the **bug** and **help wanted** labels to your
|
||||
issue, comment or include `@zulipbot add "bug" "help wanted"` in the
|
||||
issue body.
|
||||
|
||||
- You'll receive an error message if you try to add any labels to your issue
|
||||
that don't exist in your repository.
|
||||
|
||||
- If you accidentally added the wrong labels, you can remove them by commenting
|
||||
`@zulipbot remove` followed by the desired labels enclosed with double quotes
|
||||
(`""`).
|
||||
|
||||
- **Find unclaimed issues** — Use the [GitHub search
|
||||
feature](https://help.github.com/en/articles/using-search-to-filter-issues-and-pull-requests)
|
||||
to find unclaimed issues by adding one of the following filters to your search:
|
||||
|
||||
- `-label: "in progress"` (excludes issues labeled with the **in progress** label)
|
||||
|
||||
- `no:assignee` (shows issues without assignees)
|
||||
|
||||
Issues labeled with the **in progress** label and/or assigned to other users have
|
||||
already been claimed.
|
||||
|
||||
- **Collaborate in area label teams** — Receive notifications on
|
||||
issues and pull requests within your fields of expertise on the
|
||||
[Zulip server repository](https://github.com/zulip/zulip) by joining
|
||||
the Zulip server
|
||||
[area label teams](https://github.com/orgs/zulip/teams?utf8=✓&query=Server)
|
||||
(Note: this link only works for members of the Zulip organization;
|
||||
we'll happily add you if you're interested). These teams correspond
|
||||
to the repository's
|
||||
[area labels](https://github.com/zulip/zulip/labels), although some
|
||||
teams are associated with multiple labels; for example, the **area:
|
||||
message-editing** and **area: message view** labels are both related
|
||||
to the
|
||||
[Server message view](https://github.com/orgs/zulip/teams/server-message-view)
|
||||
team. Feel free to join as many area label teams as you'd like!
|
||||
|
||||
After your request to join an area label team is approved, you'll receive
|
||||
notifications for any issues labeled with the team's corresponding area
|
||||
label as well as any pull requests that reference issues labeled with your
|
||||
team's area label.
|
||||
|
||||
- **Track inactive claimed issues** — If a claimed issue has not been updated
|
||||
for a week, **@zulipbot** will post a comment on the inactive issue to ask the
|
||||
assignee(s) if they are still working on the issue.
|
||||
|
||||
If you see this comment on an issue you claimed, you should post a comment
|
||||
on the issue to notify **@zulipbot** that you're still working on it.
|
||||
|
||||
If **@zulipbot** does not receive a response from the assignee within 3 days
|
||||
of an inactive issue prompt, **@zulipbot** will automatically remove the
|
||||
issue's current assignee(s) and the "in progress" label to allow others to
|
||||
work on an inactive issue.
|
||||
|
||||
### Contributing
|
||||
|
||||
If you wish to help develop and contribute to **@zulipbot**, check out the
|
||||
[zulip/zulipbot](https://github.com/zulip/zulipbot) repository on GitHub and read
|
||||
the project's [contributing
|
||||
guidelines](https://github.com/zulip/zulipbot/blob/main/.github/CONTRIBUTING.md#contributing) for
|
||||
more information.
|
||||
Reference in New Issue
Block a user