From d8d0f05a88651d05a7ec1592cf130d839d9f0a3c Mon Sep 17 00:00:00 2001 From: pacrob <5199899+pacrob@users.noreply.github.com> Date: Mon, 20 May 2024 15:20:59 -0600 Subject: [PATCH] update default docs and release process, drop bumpversion for bump-my-version --- .bumpversion.cfg | 22 ---- .pre-commit-config.yaml | 2 +- Makefile | 106 ++++++++++-------- README.md | 57 +--------- docs/MODULE_NAME.rst | 12 +++ docs/code_of_conduct.rst | 78 ++++++++++++++ docs/contributing.rst | 149 ++++++++++++++++++++++++++ docs/index.rst | 24 +++-- pyproject.toml | 43 ++++++++ scripts/release/test_package.py | 50 +++++++++ setup.py | 2 +- tests/core/test_import_and_version.py | 2 +- tox.ini | 2 +- 13 files changed, 419 insertions(+), 130 deletions(-) delete mode 100644 .bumpversion.cfg create mode 100644 docs/MODULE_NAME.rst create mode 100644 docs/code_of_conduct.rst create mode 100644 docs/contributing.rst create mode 100644 scripts/release/test_package.py diff --git a/.bumpversion.cfg b/.bumpversion.cfg deleted file mode 100644 index 39ae22d4..00000000 --- a/.bumpversion.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[bumpversion] -current_version = 0.1.0-alpha.0 -commit = True -tag = True -parse = (?P\d+)\.(?P\d+)\.(?P\d+)(-(?P[^.]*)\.(?P\d+))? -serialize = - {major}.{minor}.{patch}-{stage}.{devnum} - {major}.{minor}.{patch} - -[bumpversion:part:stage] -optional_value = stable -first_value = stable -values = - alpha - beta - stable - -[bumpversion:part:devnum] - -[bumpversion:file:setup.py] -search = version="{current_version}", -replace = version="{new_version}", diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 051fdb8f..52554889 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: '.project-template|docs/conf.py|.bumpversion.cfg' +exclude: '.project-template|docs/conf.py' repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 diff --git a/Makefile b/Makefile index 2be3c1ab..46778052 100644 --- a/Makefile +++ b/Makefile @@ -5,15 +5,15 @@ CURRENT_SIGN_SETTING := $(shell git config commit.gpgSign) help: @echo "clean-build - remove build artifacts" @echo "clean-pyc - remove Python file artifacts" + @echo "clean - run clean-build and clean-pyc" + @echo "dist - build package and cat contents of the dist directory" @echo "lint - fix linting issues with pre-commit" @echo "test - run tests quickly with the default Python" @echo "docs - generate docs and open in browser (linux-docs for version on linux)" @echo "autobuild-docs - live update docs when changes are saved" - @echo "notes - consume towncrier newsfragments/ and update release notes in docs/" - @echo "release - package and upload a release (does not run notes target)" - @echo "dist - package" - -clean: clean-build clean-pyc + @echo "package-test - build package and install it in a venv for manual testing" + @echo "notes - consume towncrier newsfragments and update release notes in docs - requires bump to be set" + @echo "release - package and upload a release (does not run notes target) - requires bump to be set" clean-build: rm -fr build/ @@ -26,6 +26,12 @@ clean-pyc: find . -name '*~' -exec rm -f {} + find . -name '__pycache__' -exec rm -rf {} + +clean: clean-build clean-pyc + +dist: clean + python -m build + ls -l dist + lint: @pre-commit run --all-files --show-diff-on-failure || ( \ echo "\n\n\n * pre-commit should have fixed the errors above. Running again to make sure everything is good..." \ @@ -35,26 +41,7 @@ lint: test: python -m pytest tests -autobuild-docs: - sphinx-autobuild --open-browser docs docs/_build/html - -build-docs: - sphinx-apidoc -o docs/ . setup.py "*conftest*" - $(MAKE) -C docs clean - $(MAKE) -C docs html - $(MAKE) -C docs doctest - -build-docs-ci: - $(MAKE) -C docs latexpdf - $(MAKE) -C docs epub - -validate-newsfragments: - python ./newsfragments/validate_files.py - towncrier build --draft --version preview - -check-docs: build-docs validate-newsfragments - -check-docs-ci: build-docs build-docs-ci validate-newsfragments +# docs commands docs: check-docs open docs/_build/html/index.html @@ -62,35 +49,70 @@ docs: check-docs linux-docs: check-docs xdg-open docs/_build/html/index.html -check-bump: -ifndef bump - $(error bump must be set, typically: major, minor, patch, or devnum) -endif +autobuild-docs: + sphinx-autobuild --open-browser docs docs/_build/html -notes: check-bump validate-newsfragments +# docs helpers + +validate-newsfragments: + python ./newsfragments/validate_files.py + towncrier build --draft --version preview + +check-docs: build-docs validate-newsfragments + +build-docs: + sphinx-apidoc -o docs/ . setup.py "*conftest*" + $(MAKE) -C docs clean + $(MAKE) -C docs html + $(MAKE) -C docs doctest + +check-docs-ci: build-docs build-docs-ci validate-newsfragments + +build-docs-ci: + $(MAKE) -C docs latexpdf + $(MAKE) -C docs epub + +# release commands + +package-test: clean + python -m build + python scripts/release/test_package.py + +notes: check-bump # Let UPCOMING_VERSION be the version that is used for the current bump - $(eval UPCOMING_VERSION=$(shell bumpversion $(bump) --dry-run --list | grep new_version= | sed 's/new_version=//g')) + $(eval UPCOMING_VERSION=$(shell bump-my-version show --increment $(bump) new_version)) # Now generate the release notes to have them included in the release commit towncrier build --yes --version $(UPCOMING_VERSION) # Before we bump the version, make sure that the towncrier-generated docs will build make build-docs git commit -m "Compile release notes for v$(UPCOMING_VERSION)" -release: check-bump clean - # require that upstream is configured for ethereum/ - @git remote -v | grep "upstream[[:space:]]git@github.com:ethereum/.git (push)\|upstream[[:space:]]https://github.com/ethereum/ (push)" - # verify that docs build correctly +release: check-bump check-git clean + # verify that notes command ran correctly ./newsfragments/validate_files.py is-empty - make build-docs CURRENT_SIGN_SETTING=$(git config commit.gpgSign) git config commit.gpgSign true - bumpversion $(bump) - git push upstream && git push upstream --tags + bump-my-version bump $(bump) python -m build - twine upload dist/* git config commit.gpgSign "$(CURRENT_SIGN_SETTING)" + git push upstream && git push upstream --tags + twine upload dist/* +# release helpers -dist: clean - python -m build - ls -l dist +check-bump: +ifndef bump + $(error bump must be set, typically: major, minor, patch, or devnum) +endif + +check-git: + # require that you be on a branch that's linked to upstream/main + @if ! git status -s -b | head -1 | grep -q "\.\.upstream/main"; then \ + echo "Error: You must be on a branch that's linked to upstream/main"; \ + exit 1; \ + fi + # require that upstream is configured for ethereum/ + @if ! git remote -v | grep "upstream[[:space:]]git@github.com:ethereum/.git (push)\|upstream[[:space:]]https://github.com/ethereum/ (push)"; then \ + echo "Error: You must have a remote named 'upstream' that points to ''"; \ + exit 1; \ + fi diff --git a/README.md b/README.md index fa56f2e3..c81b3614 100644 --- a/README.md +++ b/README.md @@ -8,61 +8,12 @@ -Read more in the [documentation on ReadTheDocs](https://.readthedocs.io/). [View the change log](https://.readthedocs.io/en/latest/release_notes.html). +Read the [documentation](https://.readthedocs.io/). -## Quickstart +View the [change log](https://.readthedocs.io/en/latest/release_notes.html). + +## Installation ```sh python -m pip install ``` - -## Developer Setup - -If you would like to hack on , please check out the [Snake Charmers -Tactical Manual](https://github.com/ethereum/snake-charmers-tactical-manual) -for information on how we do: - -- Testing -- Pull Requests -- Documentation - -We use [pre-commit](https://pre-commit.com/) to maintain consistent code style. Once -installed, it will run automatically with every commit. You can also run it manually -with `make lint`. If you need to make a commit that skips the `pre-commit` checks, you -can do so with `git commit --no-verify`. - -### Development Environment Setup - -You can set up your dev environment with: - -```sh -git clone git@github.com:ethereum/.git -cd -virtualenv -p python3 venv -. venv/bin/activate -python -m pip install -e ".[dev]" -pre-commit install -``` - -### Release setup - -To release a new version: - -```sh -make release bump=$$VERSION_PART_TO_BUMP$$ -``` - -#### How to bumpversion - -The version format for this repo is `{major}.{minor}.{patch}` for stable, and -`{major}.{minor}.{patch}-{stage}.{devnum}` for unstable (`stage` can be alpha or beta). - -To issue the next version in line, specify which part to bump, -like `make release bump=minor` or `make release bump=devnum`. This is typically done from the -main branch, except when releasing a beta (in which case the beta is released from main, -and the previous stable branch is released from said branch). - -If you are in a beta version, `make release bump=stage` will switch to a stable. - -To issue an unstable version when the current version is stable, specify the -new version explicitly, like `make release bump="--new-version 4.0.0-alpha.1 devnum"` diff --git a/docs/MODULE_NAME.rst b/docs/MODULE_NAME.rst new file mode 100644 index 00000000..9c469afd --- /dev/null +++ b/docs/MODULE_NAME.rst @@ -0,0 +1,12 @@ +Usage +----- + +Example usage: + + +------------- + +.. automodule:: + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/code_of_conduct.rst b/docs/code_of_conduct.rst new file mode 100644 index 00000000..64954bd3 --- /dev/null +++ b/docs/code_of_conduct.rst @@ -0,0 +1,78 @@ +Code of Conduct +--------------- + +Our Pledge +~~~~~~~~~~ + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +Our Standards +~~~~~~~~~~~~~ + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +Our Responsibilities +~~~~~~~~~~~~~~~~~~~~ + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +Scope +~~~~~ + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +Enforcement +~~~~~~~~~~~ + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at snakecharmers@ethereum.org. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +Attribution +~~~~~~~~~~~ + +This Code of Conduct is adapted from the `Contributor Covenant `_, version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 00000000..68d258af --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1,149 @@ +Contributing +------------ + +Thank you for your interest in contributing! We welcome all contributions no matter +their size. Please read along to learn how to get started. If you get stuck, feel free +to ask for help in `Ethereum Python Discord server `_. + +Setting the stage +~~~~~~~~~~~~~~~~~ + +To get started, fork the repository to your own github account, then clone it to your +development machine: + +.. code:: sh + git clone git@github.com:your-github-username/.git + +Next, install the development dependencies. We recommend using a virtual environment, +such as `virtualenv `_. + +.. code:: sh + cd + virtualenv -p python venv + . venv/bin/activate + python -m pip install -e ".[dev]" + pre-commit install + +Running the tests +~~~~~~~~~~~~~~~~~ + +A great way to explore the code base is to run the tests. + +We can run all tests with: + +.. code:: sh + pytest tests + +Code Style +~~~~~~~~~~ + +We use `pre-commit `_ to enforce a consistent code style across +the library. This tool runs automatically with every commit, but you can also run it +manually with: + +.. code:: sh + make lint + +If you need to make a commit that skips the ``pre-commit`` checks, you can do so with +``git commit --no-verify``. + +This library uses type hints, which are enforced by the ``mypy`` tool (part of the +``pre-commit`` checks). All new code is required to land with type hints, with the +exception of code within the ``tests`` directory. + +Documentation +~~~~~~~~~~~~~ + +Good documentation will lead to quicker adoption and happier users. Please check out our +guide on +`how to create documentation for the Python Ethereum ecosystem `_. + +Pull Requests +~~~~~~~~~~~~~ + +It's a good idea to make pull requests early on. A pull request represents the start of +a discussion, and doesn't necessarily need to be the final, finished submission. + +GitHub's documentation for working on pull requests is +`available here `_. + +Once you've made a pull request, take a look at the Circle CI build status in the +GitHub interface and make sure all tests are passing. In general pull requests that +do not pass the CI build yet won't get reviewed unless explicitly requested. + +If the pull request introduces changes that should be reflected in the release notes, +please add a `newsfragment` file as explained +`here /blob/main/newsfragments/README.md>`_. + +If possible, the change to the release notes file should be included in the commit that +introduces the feature or bugfix. + +Releasing +~~~~~~~~~ + +Releases are typically done from the ``main`` branch, except when releasing a beta (in +which case the beta is released from ``main``, and the previous stable branch is +released from said branch). + +Final test before each release +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before releasing a new version, build and test the package that will be released: + +.. code:: sh + git checkout main && git pull + make package-test + +This will build the package and install it in a temporary virtual environment. Follow +the instructions to activate the venv and test whatever you think is important. + +You can also preview the release notes: + +.. code:: sh + towncrier --draft + +Build the release notes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before bumping the version number, build the release notes. You must include the part of +the version to bump (see below), which changes how the version number will show in the +release notes. + +.. code:: sh + make notes bump=$$VERSION_PART_TO_BUMP$$ + +If there are any errors, be sure to re-run make notes until it works. + +Push the release to github & pypi +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After confirming that the release package looks okay, release a new version: + +.. code:: sh + make release bump=$$VERSION_PART_TO_BUMP$$ + +This command will: + +- Bump the version number as specified in ``.pyproject.toml`` and ``setup.py``. +- Create a git commit and tag for the new version. +- Build the package. +- Push the commit and tag to github. +- Push the new package files to pypi. + +Which version part to bump +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``$$VERSION_PART_TO_BUMP$$`` must be one of: ``major``, ``minor``, ``patch``, ``stage``, +or ``devnum``. + +The version format for this repo is ``{major}.{minor}.{patch}`` for stable, and +``{major}.{minor}.{patch}-{stage}.{devnum}`` for unstable (``stage`` can be alpha or +beta). + +If you are in a beta version, ``make release bump=stage`` will switch to a stable. + +To issue an unstable version when the current version is stable, specify the new version +explicitly, like ``make release bump="--new-version 4.0.0-alpha.1"`` + +You can see what the result of bumping any particular version part would be with +``bump-my-version show-bump`` diff --git a/docs/index.rst b/docs/index.rst index 89815efa..6110067f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,18 +3,24 @@ -Contents --------- +Installation +------------ + +.. code-block:: bash + + python -m pip install + .. toctree:: - :maxdepth: 3 + :maxdepth: 1 + :caption: General - + Usage<> release_notes +.. toctree:: + :maxdepth: 1 + :caption: Community -Indices and tables ------------------- - -* :ref:`genindex` -* :ref:`modindex` + contributing + code_of_conduct diff --git a/pyproject.toml b/pyproject.toml index 23b8399e..910b3861 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -123,3 +123,46 @@ showcontent = true directory = "removal" name = "Removals" showcontent = true + +[tool.bumpversion] +current_version = "0.1.0-alpha.0" +parse = """ + (?P\\d+) + \\.(?P\\d+) + \\.(?P\\d+) + (- + (?P[^.]*) + \\.(?P\\d+) + )? +""" +serialize = [ + "{major}.{minor}.{patch}-{stage}.{devnum}", + "{major}.{minor}.{patch}", +] +search = "{current_version}" +replace = "{new_version}" +regex = false +ignore_missing_version = false +tag = true +sign_tags = true +tag_name = "v{new_version}" +tag_message = "Bump version: {current_version} → {new_version}" +allow_dirty = false +commit = true +message = "Bump version: {current_version} → {new_version}" + +[tool.bumpversion.parts.stage] +optional_value = "stable" +first_value = "stable" +values = [ + "alpha", + "beta", + "stable", +] + +[tool.bumpversion.part.devnum] + +[[tool.bumpversion.files]] +filename = "setup.py" +search = "version=\"{current_version}\"" +replace = "version=\"{new_version}\"" diff --git a/scripts/release/test_package.py b/scripts/release/test_package.py new file mode 100644 index 00000000..2f23898e --- /dev/null +++ b/scripts/release/test_package.py @@ -0,0 +1,50 @@ +from pathlib import ( + Path, +) +import subprocess +from tempfile import ( + TemporaryDirectory, +) +import venv + + +def create_venv(parent_path: Path) -> Path: + venv_path = parent_path / "package-smoke-test" + venv.create(venv_path, with_pip=True) + subprocess.run( + [venv_path / "bin" / "pip", "install", "-U", "pip", "setuptools"], check=True + ) + return venv_path + + +def find_wheel(project_path: Path) -> Path: + wheels = list(project_path.glob("dist/*.whl")) + + if len(wheels) != 1: + raise Exception( + f"Expected one wheel. Instead found: {wheels} " + f"in project {project_path.absolute()}" + ) + + return wheels[0] + + +def install_wheel(venv_path: Path, wheel_path: Path) -> None: + subprocess.run( + [venv_path / "bin" / "pip", "install", f"{wheel_path}"], + check=True, + ) + + +def test_install_local_wheel() -> None: + with TemporaryDirectory() as tmpdir: + venv_path = create_venv(Path(tmpdir)) + wheel_path = find_wheel(Path(".")) + install_wheel(venv_path, wheel_path) + print("Installed", wheel_path.absolute(), "to", venv_path) + print(f"Activate with `source {venv_path}/bin/activate`") + input("Press enter when the test has completed. The directory will be deleted.") + + +if __name__ == "__main__": + test_install_local_wheel() diff --git a/setup.py b/setup.py index c9e821d9..cbc9fb9d 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ from setuptools import ( extras_require = { "dev": [ "build>=0.9.0", - "bumpversion>=0.5.3", + "bump_my_version>=0.19.0", "ipython", "pre-commit>=3.4.0", "tox>=4.0.0", diff --git a/tests/core/test_import_and_version.py b/tests/core/test_import_and_version.py index 6a2f8ea5..9d5ea0a8 100644 --- a/tests/core/test_import_and_version.py +++ b/tests/core/test_import_and_version.py @@ -1,4 +1,4 @@ def test_import_and_version(): import - + assert isinstance(.__version__, str) diff --git a/tox.ini b/tox.ini index 90d502d2..f7c0dfee 100644 --- a/tox.ini +++ b/tox.ini @@ -36,7 +36,7 @@ allowlist_externals=make,pre-commit [testenv:py{38,39,310,311,312}-lint] deps=pre-commit commands= - pre-commit install + pre-commit install pre-commit run --all-files --show-diff-on-failure [testenv:py{38,39,310,311,312}-wheel]