Skip to content

Commit d25cdfb

Browse files
committed
docs: restructure CONTRIBUTING.md to enhance clarity and organization
1 parent 45fce51 commit d25cdfb

1 file changed

Lines changed: 144 additions & 118 deletions

File tree

CONTRIBUTING.md

Lines changed: 144 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,18 @@
11
# Guidelines for contributing
22

3-
## Table of Contents <!-- omit in toc -->
4-
5-
- [Guidelines for contributing](#guidelines-for-contributing)
6-
- [Summary](#summary)
7-
- [Git](#git)
8-
- [Python](#python)
9-
- [Pdm](#pdm)
10-
- [Highlights](#highlights)
11-
- [Key commands](#key-commands)
12-
- [Design philosophy](#design-philosophy)
13-
- [Testing with pytest](#testing-with-pytest)
14-
- [GitHub Actions workflows](#github-actions-workflows)
15-
- [Maintainers](#maintainers)
3+
## Design philosophy
164

17-
## Summary
18-
19-
**PRs welcome!**
20-
21-
- **Consider starting a discussion to see if there's interest in what you want to do.**
22-
- **Submit PRs from feature branches on forks to the `develop` branch.**
23-
- **Ensure PRs pass all CI checks.**
24-
- **Maintain test coverage at 100%.**
25-
26-
## Git
5+
`SiaPy` is built with several key design principles:
276

28-
- _[Why use Git?](https://www.git-scm.com/about)_ Git enables creation of multiple versions of a code repository called branches, with the ability to track and undo changes in detail.
29-
- Install Git by [downloading](https://www.git-scm.com/downloads) from the website, or with a package manager like [Homebrew](https://brew.sh/).
30-
- [Configure Git to connect to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh).
31-
- [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) this repo.
32-
- Create a [branch](https://www.git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) in your fork.
33-
- Commit your changes with a [properly-formatted Git commit message](https://chris.beams.io/posts/git-commit/).
34-
- Create a [pull request (PR)](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) to incorporate your changes into the upstream project you forked.
7+
1. **Type Safety**: Comprehensive type hints throughout the codebase
8+
2. **Modular Design**: Composable components that can be used independently
9+
3. **Consistent APIs**: Uniform interface patterns across the library
10+
4. **Pythonic Interfaces**: Following Python best practices and conventions
11+
5. **Error Handling**: Structured exception hierarchy for clear error reporting
3512

36-
## Python
13+
## Code standard
3714

38-
### Pdm
15+
### Dependency management
3916

4017
This project uses [PDM](https://github.com/pdm-project/pdm) for dependency management and packaging.
4118

@@ -48,109 +25,158 @@ This project uses [PDM](https://github.com/pdm-project/pdm) for dependency manag
4825

4926
#### Key commands
5027

28+
| Command | Description |
29+
|---------|-------------|
30+
| `pdm init` | Initialize a new project |
31+
| `pdm add PACKAGE_NAME` | Add a package to the project dependencies |
32+
| `pdm install` | Install dependencies from pyproject.toml |
33+
| `pdm list` | Show a list of installed packages |
34+
| `pdm run COMMAND` | Run a command within the PDM environment |
35+
| `pdm shell` | Activate the PDM environment, similar to activating a virtualenv |
36+
| `pdm sync` | Synchronize the project's dependencies |
37+
38+
### Testing with pytest
39+
40+
Tests are located in the _tests_ directory. The project uses [pytest](https://docs.pytest.org/en/latest/) as its testing framework, with configuration stored in _pyproject.toml_.
41+
42+
#### Key features
43+
44+
| Feature | Description | Documentation |
45+
|---------|-------------|---------------|
46+
| `capfd` | Capture stdout/stderr output | [Capturing output](https://docs.pytest.org/en/latest/how-to/capture-stdout-stderr.html) |
47+
| `fixtures` | Reusable test components | [Fixtures](https://docs.pytest.org/en/latest/how-to/fixtures.html) |
48+
| `monkeypatch` | Modify behavior during tests | [Monkeypatching](https://docs.pytest.org/en/latest/how-to/monkeypatch.html) |
49+
| `parametrize` | Run tests with different inputs | [Parametrization](https://docs.pytest.org/en/latest/how-to/parametrize.html) |
50+
| `tmp_path`/`tmp_dir` | Create temporary test files | [Temporary directories](https://docs.pytest.org/en/latest/how-to/tmpdir.html) |
51+
52+
### Code quality
53+
54+
#### Style and format
55+
56+
Python code is formatted with [Ruff](https://docs.astral.sh/ruff/). Ruff configuration is stored in _pyproject.toml_.
57+
58+
#### Static type checking
59+
60+
To learn type annotation basics, see the [Python typing module docs](https://docs.python.org/3/library/typing.html) and [Python type annotations how-to](https://docs.python.org/3/howto/annotations.html).
61+
Type annotations are not used at runtime. The standard library `typing` module includes a `TYPE_CHECKING` constant that is `False` at runtime, but `True` when conducting static type checking prior to runtime. Type imports are included under `if TYPE_CHECKING:` conditions so that they are not imported at runtime.
62+
[Mypy](https://mypy.readthedocs.io/en/stable/) is used for type-checking and it's [configuration](https://mypy.readthedocs.io/en/stable/config_file.html) is included in _pyproject.toml_.
63+
64+
#### Spell check
65+
66+
Spell check is performed with [CSpell](https://cspell.org/). Configuration is stored in _pyproject.toml_.
67+
68+
## Scripts
69+
70+
The project provides several helpful commands through the `make` utility, which mostly calls scripts from the _scripts_ folder. You can run these from the project root directory.
71+
72+
To view all available commands with descriptions, run:
73+
5174
```sh
52-
pdm init # Initialize a new project
53-
pdm add PACKAGE_NAME # Add a package to the project dependencies
54-
pdm install # Install dependencies from pyproject.toml
55-
pdm list # Show a list of installed packages
56-
pdm run COMMAND # Run a command within the PDM environment
57-
pdm shell # Activate the PDM environment, similar to activating a virtualenv
58-
pdm sync # Synchronize the project's dependencies
75+
make help
5976
```
6077

61-
### Design philosophy
78+
Available commands include:
6279

63-
SiaPy is built with several key design principles:
80+
| Command | Description |
81+
|---------|-------------|
82+
| `make install` | Install the package, dependencies, and pre-commit for local development |
83+
| `make format` | Auto-format python source files |
84+
| `make lint` | Lint python source files |
85+
| `make test` | Run all tests |
86+
| `make flt` | Run format, lint, and test in sequence |
87+
| `make testcov` | Run tests and generate a coverage report |
88+
| `make codespell` | Use Codespell to do spellchecking |
89+
| `make refresh-lockfiles` | Sync lockfiles with requirements files |
90+
| `make rebuild-lockfiles` | Rebuild lockfiles from scratch, updating all dependencies |
91+
| `make clean` | Clear local caches and build artifacts |
92+
| `make generate-docs` | Generate the documentation |
93+
| `make serve-docs` | Serve the documentation locally |
94+
| `make serve-docs-mike` | Serve the documentation using mike |
95+
| `make update-branches` | Update local git branches after successful PR |
96+
| `make version` | Check the current project version |
97+
| `make compress-data` | Compress the data files |
6498

65-
1. **Type Safety**: Comprehensive type hints throughout the codebase
66-
2. **Modular Design**: Composable components that can be used independently
67-
3. **Consistent APIs**: Uniform interface patterns across the library
68-
4. **Pythonic Interfaces**: Following Python best practices and conventions
69-
5. **Error Handling**: Structured exception hierarchy for clear error reporting
99+
Most commands use PDM (Python package and dependency manager) internally, which will be checked for installation with `.pdm` and `.pre-commit` helper tasks.
70100

71-
### Testing with pytest
101+
## Development
102+
103+
### Git
72104

73-
- Tests are in the _tests/_ directory.
74-
- [pytest](https://docs.pytest.org/en/latest/) features used include:
75-
- [capturing `stdout` with `capfd`](https://docs.pytest.org/en/latest/how-to/capture-stdout-stderr.html)
76-
- [fixtures](https://docs.pytest.org/en/latest/how-to/fixtures.html)
77-
- [monkeypatch](https://docs.pytest.org/en/latest/how-to/monkeypatch.html)
78-
- [parametrize](https://docs.pytest.org/en/latest/how-to/parametrize.html)
79-
- [temporary directories and files (`tmp_path` and `tmp_dir`)](https://docs.pytest.org/en/latest/how-to/tmpdir.html)
80-
- [pytest plugins](https://docs.pytest.org/en/latest/how-to/plugins.html) include:
81-
- [pytest-mock](https://github.com/pytest-dev/pytest-mock)
82-
- [pytest configuration](https://docs.pytest.org/en/latest/reference/customize.html) is in _pyproject.toml_.
83-
- Run tests with pytest
84-
- Test coverage reports are generated by pytest-cov
105+
_[Why use Git?](https://www.git-scm.com/about)_ Git enables creation of multiple versions of a code repository called branches, with the ability to track and undo changes in detail.
85106

86-
<!-- ## Code quality
107+
Contribute by following:
87108

88-
### Running code quality checks
109+
- Install Git by [downloading](https://www.git-scm.com/downloads) from the website, or with a package manager like [Homebrew](https://brew.sh/).
110+
- [Configure Git to connect to GitHub with SSH](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh).
111+
- [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) this repo.
112+
- Create a [branch](https://www.git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) in your fork.
113+
- Commit your changes with a [properly-formatted Git commit message](https://chris.beams.io/posts/git-commit/).
114+
- Create a [pull request (PR)](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) to incorporate your changes into the upstream project you forked.
89115

90-
Code quality checks can be run using the Hatch scripts in _pyproject.toml_.
116+
### Project organization around git
91117

92-
- Check: `hatch run check`
93-
- Format: `hatch run format`
118+
### Branch Structure
94119

95-
### Code style
120+
| Branch | Purpose | Protection Rules |
121+
|-----------|-----------------------------|---------------------------------|
122+
| `main` | Stable production code | • Signed commits required<br>• No force pushing<br>• Status checks required<br>• Admin included |
123+
| `develop` | Integration branch | • Signed commits required<br>• Force pushing allowed<br>• Admin included |
96124

97-
- Python code is formatted with [Ruff](https://docs.astral.sh/ruff/). Ruff configuration is stored in _pyproject.toml_.
98-
- Other web code (JSON, Markdown, YAML) is formatted with [Prettier](https://prettier.io/).
125+
### Workflow Rules
99126

100-
### Static type checking
127+
- The default branch is `main`
128+
- Feature branches must target `develop` for pull requests
129+
- Only PRs from `develop` may be merged into `main`
130+
- Status checks must pass on `develop` before merging to `main`
101131

102-
- To learn type annotation basics, see the [Python typing module docs](https://docs.python.org/3/library/typing.html), [Python type annotations how-to](https://docs.python.org/3/howto/annotations.html), the [Real Python type checking tutorial](https://realpython.com/python-type-checking/), and [this gist](https://gist.github.com/987bdc6263217895d4bf03d0a5ff114c).
103-
- Type annotations are not used at runtime. The standard library `typing` module includes a `TYPE_CHECKING` constant that is `False` at runtime, but `True` when conducting static type checking prior to runtime. Type imports are included under `if TYPE_CHECKING:` conditions so that they are not imported at runtime. These conditions are ignored when calculating test coverage.
104-
- Type annotations can be provided inline or in separate stub files. Much of the Python standard library is annotated with stubs. For example, the Python standard library [`logging.config` module uses type stubs](https://github.com/python/typeshed/blob/main/stdlib/logging/config.pyi). The typeshed types for the `logging.config` module are used solely for type-checking usage of the `logging.config` module itself. They cannot be imported and used to type annotate other modules.
105-
- The standard library `typing` module includes a `NoReturn` type. This would seem useful for [unreachable code](https://typing.readthedocs.io/en/stable/source/unreachable.html), including functions that do not return a value, such as test functions. Unfortunately mypy reports an error when using `NoReturn`, "Implicit return in function which does not return (misc)." To avoid headaches from the opaque "misc" category of [mypy errors](https://mypy.readthedocs.io/en/stable/error_code_list.html), these functions are annotated as returning `None`.
106-
- [Mypy](https://mypy.readthedocs.io/en/stable/) is used for type-checking. [Mypy configuration](https://mypy.readthedocs.io/en/stable/config_file.html) is included in _pyproject.toml_.
107-
- Mypy strict mode is enabled. Strict includes `--no-explicit-reexport` (`implicit_reexport = false`), which means that objects imported into a module will not be re-exported for import into other modules. Imports can be made into explicit exports with the syntax `from module import x as x` (i.e., changing from `import logging` to `import logging as logging`), or by including imports in `__all__`. This explicit import syntax can be confusing. Another option is to apply mypy overrides to any modules that need to leverage implicit exports.
132+
#### Commit structure
108133

109-
### Spell check
134+
Follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#specification) specification for commit messages. This standardizes the commit history and facilitates automatic generation of the changelog.
135+
Ensure your commit messages clearly describe the changes made and follow the format `type(scope?): subject`, where `scope` is optional.
110136

111-
Spell check is performed with [CSpell](https://cspell.org/). The CSpell command is included in the Hatch script for code quality checks (`hatch run check`). -->
137+
_Type_ must be one of the following:
138+
139+
- `feat`: A new feature
140+
- `fix`: A bug fix
141+
- `perf`: A code change that improves performance
142+
- `deps`: Dependency updates
143+
- `revert`: Reverts a previous commit
144+
- `docs`: Documentation only changes
145+
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc), hidden
146+
- `chore`: Miscellaneous chores, hidden
147+
- `refactor`: A code change that neither fixes a bug nor adds a feature, hidden
148+
- `test`: Adding missing tests or correcting existing tests, hidden
149+
- `build`: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm), hidden
150+
- `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs), hidden
112151

113152
## GitHub Actions workflows
114153

115-
[GitHub Actions](https://github.com/features/actions) is a continuous integration/continuous deployment (CI/CD) service that runs on GitHub repos. It replaces other services like Travis CI. Actions are grouped into workflows and stored in _.github/workflows_.
116-
117-
## Maintainers
118-
119-
- **The default branch is `main`.**
120-
- **PRs from feature branches should be merged into `develop`.**
121-
- **The only merges to `main` should be PRs from `develop`.**
122-
- **Branch protection is enabled on `develop` and `main`.**
123-
- `develop`:
124-
- Require signed commits
125-
- Include administrators
126-
- Allow force pushes
127-
- `main`:
128-
- Require signed commits
129-
- Include administrators
130-
- Do not allow force pushes
131-
- Require status checks to pass before merging (commits must have previously been pushed to `develop` and passed all checks)
132-
- **To commit:**
133-
- Follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#specification) specification for commit messages. This standardizes the commit history and facilitates automatic generation of the changelog.
134-
- _Type_ must be one of the following:
135-
- `feat`: A new feature
136-
- `fix`: A bug fix
137-
- `perf`: A code change that improves performance
138-
- `deps`: Dependency updates
139-
- `revert`: Reverts a previous commit
140-
- `docs`: Documentation only changes
141-
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc), hidden
142-
- `chore`: Miscellaneous chores, hidden
143-
- `refactor`: A code change that neither fixes a bug nor adds a feature, hidden
144-
- `test`: Adding missing tests or correcting existing tests, hidden
145-
- `build`: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm), hidden
146-
- `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs), hidden
147-
148-
- Ensure your commit messages clearly describe the changes made and follow the format `type(scope?): subject`, where `scope` is optional.
149-
150-
- **To create a release:**
151-
- Follow [SemVer](https://semver.org/) guidelines when choosing a version number. Note that [PEP 440](https://peps.python.org/pep-0440/) Python version specifiers and SemVer version specifiers differ, particularly with regard to specifying prereleases. Use syntax compatible with both.
152-
- The PEP 440 default (like `1.0.0a0`) is different from SemVer.
153-
- An alternative form of the Python prerelease syntax permitted in PEP 440 (like `1.0.0-alpha.0`) is compatible with SemVer, and this form should be used when tagging releases.
154-
- Examples of acceptable tag names: `1.0.0`, `1.0.0-alpha.0`, `1.0.0-beta.1`
155-
- Push to `develop` and verify all CI checks pass.
156-
- Fast-forward merge to `main`, push, and verify all CI checks pass.
154+
[GitHub Actions](https://github.com/features/actions) is a continuous integration/continuous deployment (CI/CD) service that runs on GitHub repos. Actions are grouped into workflows and stored in _.github/workflows_.
155+
156+
### Releases
157+
158+
The CI pipeline automatically creates release based on conventional commit messages.
159+
160+
Release version numbers are determined by analyzing commit types:
161+
162+
- `feat`: Increments minor version (1.0.0 → 1.1.0)
163+
- `fix`: Increments patch version (1.0.0 → 1.0.1)
164+
- `feat` with `BREAKING CHANGE`: Increments major version (1.0.0 → 2.0.0)
165+
166+
The following guidelines are considered:
167+
168+
- [SemVer](https://semver.org/) guidelines when choosing a version number. Note that [PEP 440](https://peps.python.org/pep-0440/) Python version specifiers and SemVer version specifiers differ, particularly with regard to specifying prereleases. Use syntax compatible with both.
169+
- The PEP 440 default (like `1.0.0a0`) is different from SemVer.
170+
- An alternative form of the Python prerelease syntax permitted in PEP 440 (like `1.0.0-alpha.0`) is compatible with SemVer, and this form should be used when tagging releases.
171+
- Examples of acceptable tag names: `1.0.0`, `1.0.0-alpha.0`, `1.0.0-beta.1`
172+
- Push to `develop` and verify all CI checks pass.
173+
- Fast-forward merge to `main`, push, and verify all CI checks pass.
174+
175+
## Summary
176+
177+
**PRs welcome!**
178+
179+
- **Consider starting a discussion to see if there's interest in what you want to do.**
180+
- **Submit PRs from feature branches on forks to the `develop` branch.**
181+
- **Ensure PRs pass all CI checks.**
182+
- **Maintain high test coverage (>80%).**

0 commit comments

Comments
 (0)