mirror of
https://github.com/penpot/penpot.git
synced 2026-04-30 05:38:42 +00:00
Expand the Pull Requests section with detailed guidance on PR title format, description expectations, branch naming conventions, the review process, and a list of PRs that will not be accepted. Also clarify the 'Discuss Before Building' rule to link to GitHub Issues and Discussions and reference Taiga stories. Update the Table of Contents with nested links for all new subsections. Signed-off-by: Andrey Antukh <niwi@niwi.nz>
290 lines
9.5 KiB
Markdown
290 lines
9.5 KiB
Markdown
# Contributing Guide
|
|
|
|
Thank you for your interest in contributing to Penpot. This guide covers
|
|
how to propose changes, submit fixes, and follow project conventions.
|
|
|
|
For architecture details, module-specific guidelines, and AI-agent
|
|
instructions, see [AGENTS.md](AGENTS.md). For final user technical
|
|
documentation, see the `docs/` directory or the rendered [Help
|
|
Center](https://help.penpot.app/).
|
|
|
|
## Table of Contents
|
|
|
|
- [Prerequisites](#prerequisites)
|
|
- [Reporting Bugs](#reporting-bugs)
|
|
- [Pull Requests](#pull-requests)
|
|
- [Workflow](#workflow)
|
|
- [Title format](#title-format)
|
|
- [Description](#description)
|
|
- [Branch naming](#branch-naming)
|
|
- [Review process](#review-process)
|
|
- [What we won't accept](#what-we-wont-accept)
|
|
- [Good first issues](#good-first-issues)
|
|
- [Commit Guidelines](#commit-guidelines)
|
|
- [Commit types](#commit-types)
|
|
- [Rules](#rules)
|
|
- [Examples](#examples)
|
|
- [Formatting and Linting](#formatting-and-linting)
|
|
- [Changelog](#changelog)
|
|
- [Code of Conduct](#code-of-conduct)
|
|
- [Developer's Certificate of Origin (DCO)](#developers-certificate-of-origin-dco)
|
|
|
|
## Prerequisites
|
|
|
|
- **Language**: Penpot is written primarily in Clojure (backend), ClojureScript
|
|
(frontend/exporter), and Rust (render-wasm). Familiarity with the Clojure
|
|
ecosystem is expected for most contributions.
|
|
- **Issue tracker**: We use [GitHub Issues](https://github.com/penpot/penpot/issues)
|
|
for public bugs and [Taiga](https://tree.taiga.io/project/penpot/) for
|
|
internal project management. Changelog entries reference both.
|
|
|
|
## Reporting Bugs
|
|
|
|
Report bugs via [GitHub Issues](https://github.com/penpot/penpot/issues).
|
|
Before filing, search existing issues to avoid duplicates.
|
|
|
|
Include the following when possible:
|
|
|
|
1. Steps to reproduce the error.
|
|
2. Browser and browser version used.
|
|
3. DevTools console exception stack trace (if available).
|
|
|
|
For security bugs or issues better discussed in private, email
|
|
`support@penpot.app` or report them on [Github Security
|
|
Advisories](https://github.com/penpot/penpot/security/advisories)
|
|
|
|
> **Note:** We do not have a formal bug bounty program. Security
|
|
> contributions are recognized in the changelog.
|
|
|
|
## Pull Requests
|
|
|
|
### Workflow
|
|
|
|
1. **Read the DCO** — see [Developer's Certificate of Origin](#developers-certificate-of-origin-dco)
|
|
below. All code patches must include a `Signed-off-by` line.
|
|
2. **Discuss before building** — open a [GitHub
|
|
Issue](https://github.com/penpot/penpot/issues) or start a [GitHub
|
|
Discussion](https://github.com/penpot/penpot/discussions) before starting
|
|
work on a new feature or significant change. For planned features on the
|
|
roadmap, reference the corresponding Taiga story. No PR will be accepted
|
|
without prior discussion, whether it is a new feature, a planned one, or a
|
|
quick win.
|
|
3. **Bug fixes** — you may submit a PR directly, but we still recommend
|
|
filing an issue first so we can track it independently of your fix.
|
|
4. **Format and lint** — run the checks described in
|
|
[Formatting and Linting](#formatting-and-linting) before submitting.
|
|
|
|
### Title format
|
|
|
|
Pull request titles **must** follow the same convention as commit subjects:
|
|
|
|
```
|
|
:emoji: <subject>
|
|
```
|
|
|
|
- Use the **imperative mood** (e.g. "Fix", not "Fixed").
|
|
- Capitalize the first letter of the subject.
|
|
- Do not end the subject with a period.
|
|
- Keep the subject to **70 characters** or fewer.
|
|
- Use one of the [commit type emojis](#commit-types) listed below.
|
|
|
|
When a PR contains multiple unrelated commits, choose the emoji that
|
|
best represents the dominant change.
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
:bug: Fix unexpected error on launching modal
|
|
:sparkles: Enable new modal for profile
|
|
:zap: Improve performance of dashboard navigation
|
|
```
|
|
|
|
> **Note:** When a PR is squash-merged, the PR title becomes the
|
|
> commit message on the main branch. Getting the title right matters.
|
|
|
|
### Description
|
|
|
|
Every pull request should include a description that helps reviewers
|
|
understand the change quickly:
|
|
|
|
1. **What and why** — describe the change and its motivation.
|
|
2. **Link related issues** — use `Closes #1234` or reference a Taiga
|
|
story (e.g. `Taiga #5678`).
|
|
3. **Screenshots or recordings** — required for any UI-visible change.
|
|
4. **Testing notes** — how did you verify the change? Any edge cases?
|
|
5. **Breaking changes** — call out anything that affects existing users
|
|
or requires migration steps.
|
|
|
|
### Branch naming
|
|
|
|
Use a descriptive branch name that reflects the type and scope of the
|
|
change:
|
|
|
|
```
|
|
<type>/<short-description>
|
|
```
|
|
|
|
Types: `fix`, `feat`, `refactor`, `docs`, `chore`, `perf`.
|
|
|
|
Optionally include the issue number:
|
|
|
|
```
|
|
fix/9122-email-blacklisting
|
|
feat/export-webp
|
|
refactor/layout-sizing
|
|
```
|
|
|
|
### Review process
|
|
|
|
- Maintainers review PRs when time permits. Please be patient.
|
|
- Address review feedback by **pushing new commits** — do not
|
|
force-push during review, as it breaks comment threads.
|
|
- PRs require at least **one approval** before merge.
|
|
- We use **squash-merge** by default. The PR title becomes the final
|
|
commit message, so follow the [title format](#title-format) above.
|
|
|
|
### What we won't accept
|
|
|
|
To save time on both sides, please avoid submitting PRs that:
|
|
|
|
- Introduce new dependencies without prior discussion.
|
|
- Change the build system or CI configuration without maintainer
|
|
approval.
|
|
- Mix unrelated changes in a single PR — keep PRs focused on one
|
|
concern.
|
|
- Skip the [discussion step](#workflow) for non-bug-fix changes.
|
|
|
|
### Good first issues
|
|
|
|
We use the `easy fix` label to mark issues appropriate for newcomers.
|
|
|
|
## Commit Guidelines
|
|
|
|
Commit messages must follow this format:
|
|
|
|
```
|
|
:emoji: <subject>
|
|
|
|
[body]
|
|
|
|
[footer]
|
|
```
|
|
|
|
### Commit types
|
|
|
|
| Emoji | Description |
|
|
|-------|-------------|
|
|
| :bug: | Bug fix |
|
|
| :sparkles: | Improvement or enhancement |
|
|
| :tada: | New feature |
|
|
| :recycle: | Refactor |
|
|
| :lipstick: | Cosmetic changes |
|
|
| :ambulance: | Critical bug fix |
|
|
| :books: | Documentation |
|
|
| :construction: | Work in progress |
|
|
| :boom: | Breaking change |
|
|
| :wrench: | Configuration update |
|
|
| :zap: | Performance improvement |
|
|
| :whale: | Docker-related change |
|
|
| :paperclip: | Other non-relevant changes |
|
|
| :arrow_up: | Dependency update |
|
|
| :arrow_down: | Dependency downgrade |
|
|
| :fire: | Removal of code or files |
|
|
| :globe_with_meridians: | Add or update translations |
|
|
| :rocket: | Epic or highlight |
|
|
|
|
### Rules
|
|
|
|
- Use the **imperative mood** in the subject (e.g. "Fix", not "Fixed")
|
|
- Capitalize the first letter of the subject
|
|
- Add clear and concise description on the body
|
|
- Do not end the subject with a period
|
|
- Keep the subject to **70 characters** or fewer
|
|
- Separate the subject from the body with a **blank line**
|
|
|
|
### Examples
|
|
|
|
```
|
|
:bug: Fix unexpected error on launching modal
|
|
:sparkles: Enable new modal for profile
|
|
:zap: Improve performance of dashboard navigation
|
|
:ambulance: Fix critical bug on user registration process
|
|
:tada: Add new approach for user registration
|
|
```
|
|
|
|
## Formatting and Linting
|
|
|
|
We use [cljfmt](https://github.com/weavejester/cljfmt) for formatting and
|
|
[clj-kondo](https://github.com/clj-kondo/clj-kondo) for linting.
|
|
|
|
```bash
|
|
# Check formatting (does not modify files)
|
|
./scripts/check-fmt
|
|
|
|
# Fix formatting (modifies files in place)
|
|
./scripts/fmt
|
|
|
|
# Lint
|
|
./scripts/lint
|
|
```
|
|
|
|
Ideally, run these as git pre-commit hooks.
|
|
[Husky](https://typicode.github.io/husky/#/) is a convenient option for
|
|
setting this up.
|
|
|
|
## Changelog
|
|
|
|
When your change is user-facing or otherwise notable, add an entry to
|
|
[CHANGES.md](CHANGES.md) following the same commit-type conventions. Reference
|
|
the relevant GitHub issue or Taiga user story.
|
|
|
|
## Code of Conduct
|
|
|
|
This project follows the [Contributor Covenant](https://www.contributor-covenant.org/).
|
|
The full Code of Conduct is available at
|
|
[help.penpot.app/contributing-guide/coc](https://help.penpot.app/contributing-guide/coc/)
|
|
and in the repository's [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
|
|
|
|
To report unacceptable behavior, open an issue or contact a project maintainer
|
|
directly.
|
|
|
|
## Developer's Certificate of Origin (DCO)
|
|
|
|
By submitting code you agree to and can certify the following:
|
|
|
|
> **Developer's Certificate of Origin 1.1**
|
|
>
|
|
> By making a contribution to this project, I certify that:
|
|
>
|
|
> (a) The contribution was created in whole or in part by me and I have the
|
|
> right to submit it under the open source license indicated in the file; or
|
|
>
|
|
> (b) The contribution is based upon previous work that, to the best of my
|
|
> knowledge, is covered under an appropriate open source license and I have
|
|
> the right under that license to submit that work with modifications,
|
|
> whether created in whole or in part by me, under the same open source
|
|
> license (unless I am permitted to submit under a different license), as
|
|
> indicated in the file; or
|
|
>
|
|
> (c) The contribution was provided directly to me by some other person who
|
|
> certified (a), (b) or (c) and I have not modified it.
|
|
>
|
|
> (d) I understand and agree that this project and the contribution are public
|
|
> and that a record of the contribution (including all personal information
|
|
> I submit with it, including my sign-off) is maintained indefinitely and
|
|
> may be redistributed consistent with this project or the open source
|
|
> license(s) involved.
|
|
|
|
### Signed-off-by
|
|
|
|
All code patches (**documentation is excluded**) must contain a sign-off line
|
|
at the end of the commit body. Add it automatically with `git commit -s`.
|
|
|
|
```
|
|
Signed-off-by: Your Real Name <your.email@example.com>
|
|
```
|
|
|
|
- Use your **real name** — pseudonyms and anonymous contributions are not
|
|
allowed.
|
|
- The `Signed-off-by` line is **mandatory** and must match the commit author.
|