Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: migrate to pyproject.toml #1068

Merged
merged 49 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
47f8537
Remove obsoleted files.
tonyandrewmeyer Nov 16, 2023
c942cc7
Organise the build files together and ensure that version.py doesn't …
tonyandrewmeyer Nov 16, 2023
a160ce8
Migrate data from setup.py.
tonyandrewmeyer Nov 16, 2023
a0feaeb
Exclude some files from the sdist.
tonyandrewmeyer Nov 16, 2023
0d18f51
Update the dependency location.
tonyandrewmeyer Nov 16, 2023
0b8f710
Remove auto-generated file.
tonyandrewmeyer Nov 16, 2023
b58abed
Update with email address.
tonyandrewmeyer Nov 16, 2023
edca060
Move the requirements into pyproject.toml.
tonyandrewmeyer Nov 16, 2023
9fedd2e
Remove outdated tests.
tonyandrewmeyer Nov 16, 2023
66b8057
Use build to create the distribution package.
tonyandrewmeyer Nov 16, 2023
96d0c39
Update build command.
tonyandrewmeyer Nov 16, 2023
183ff1a
Add pinned versions of requirements files.
tonyandrewmeyer Nov 16, 2023
3790aa4
Add dev dependencies.
tonyandrewmeyer Nov 16, 2023
54a471e
Add type hint now that the default value is gone.
tonyandrewmeyer Nov 16, 2023
412b68a
Provide instructions for generating the doc requirements.
tonyandrewmeyer Nov 19, 2023
2ce49c1
Fix spacing around import.
tonyandrewmeyer Nov 19, 2023
063abdc
Ensure that the requirements are kept in sync. Ensure version.py exists.
tonyandrewmeyer Nov 19, 2023
c856db6
Ensure setuptools-svm is available to generate the version.py file.
tonyandrewmeyer Nov 19, 2023
e4d41a7
Add setuptools to the dev dependencies so that the version.py file ca…
tonyandrewmeyer Nov 19, 2023
5a921a6
Extend the information on tooling.
tonyandrewmeyer Nov 19, 2023
3ad12d0
Don't bundle the .gitignore, that's just for when you have a clone.
tonyandrewmeyer Nov 19, 2023
e9f0cb6
Merge branch 'main' into pyproject-build-893
tonyandrewmeyer Nov 19, 2023
2947d92
Remove the setuptools-scm dependency.
tonyandrewmeyer Nov 22, 2023
fc47085
Merge branch 'main' into pyproject-build-893
tonyandrewmeyer Nov 22, 2023
993892d
Tell setuptools where to find the version.
tonyandrewmeyer Nov 22, 2023
3190143
We need the dependencies installed to import ops to get the version.
tonyandrewmeyer Nov 22, 2023
3fe6176
Explicitly list the files to include (no longer using setuptools-scm).
tonyandrewmeyer Nov 22, 2023
20ca414
Pin using Python 3.8.
tonyandrewmeyer Nov 22, 2023
adde28f
Merge branch 'main' into pyproject-build-893
tonyandrewmeyer Dec 12, 2023
2a50930
Merge branch 'main' into pyproject-build-893
tonyandrewmeyer Jan 11, 2024
71cedc2
Update HACKING.md
tonyandrewmeyer Jan 12, 2024
3b7c10a
Update HACKING.md
tonyandrewmeyer Jan 12, 2024
e6a23c3
Bump pyright version to match main's requirements-dev.txt value.
tonyandrewmeyer Jan 11, 2024
7f32a09
Address review comments.
tonyandrewmeyer Jan 12, 2024
9edc6fc
Fix smoke name.
tonyandrewmeyer Jan 12, 2024
339740d
Style fix.
tonyandrewmeyer Jan 12, 2024
556d139
requirements-dev is now not used.
tonyandrewmeyer Jan 12, 2024
b6837c9
Per code review.
tonyandrewmeyer Jan 12, 2024
0d726d9
Bump to next expected version.
tonyandrewmeyer Jan 12, 2024
50b6386
Fix the manifest to pick up the correct files.
tonyandrewmeyer Jan 12, 2024
1560224
Update HACKING.md for latest changes.
tonyandrewmeyer Jan 12, 2024
fadd413
Move to putting the dev dependencies direclty in tox.ini.
tonyandrewmeyer Jan 14, 2024
e1be35e
Minor cleanup after change to deps in tox.ini.
tonyandrewmeyer Jan 14, 2024
06de826
Merge branch 'main' into pyproject-build-893
tonyandrewmeyer Jan 14, 2024
8867b1d
Ensure there is a requirements file for readthedocs to use - and it's…
tonyandrewmeyer Jan 14, 2024
84fcb74
Update pyproject.toml
tonyandrewmeyer Jan 15, 2024
99ae4ee
Update tox.ini
tonyandrewmeyer Jan 15, 2024
18db4e5
Regenerate using Python 3.8
tonyandrewmeyer Jan 15, 2024
c9c325d
Do a local install for rtd.
tonyandrewmeyer Jan 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 11 additions & 4 deletions .github/workflows/framework-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,27 @@ jobs:
PEBBLE: /tmp/pebble

pip-install:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v3
- name: Set up Python 3
uses: actions/setup-python@v2
with:
python-version: '3.11'
python-version: ${{ matrix.python-version }}

- name: Install build dependencies
run: pip install wheel build

- name: Build
run: python setup.py sdist
run: python -m build

# Test that a pip install of the source dist .tar.gz will work
- name: Test 'pip install'
# Shouldn't happen, but pip install will fail if ls returns multiple lines
run: pip install $(ls dist/ops*.gz)

8 changes: 3 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ jobs:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v1
with:
python-version: "3.10"
- name: Install wheel
run: pip install wheel
- name: Install build dependencies
run: pip install wheel build
- name: Build
run: python setup.py sdist bdist_wheel
run: python -m build
- name: Publish
uses: pypa/gh-action-pypi-publish@release/v1
with:
Expand Down
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
__pycache__
/sandbox
/build
/dist
/ops.egg-info
.idea
/docs/_build
*~
.venv
venv
Expand All @@ -13,6 +10,11 @@ venv
.coverage
/.tox

# Build artifacts
/dist
/build
/docs/_build

# Smoke test artifacts
*.tar.gz
*.charm
Expand Down
57 changes: 47 additions & 10 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,26 +180,63 @@ next to the relevant content (e.g. headings, etc.).

Noteworthy changes should also get a new entry in [CHANGES.md](CHANGES.md).

As noted above, you can generate a local copy of the API reference docs with tox:

## Dependencies
```sh
tox -e docs
open docs/_build/html/index.html
```

# Dependencies

The Python dependencies of `ops` are kept as minimal as possible, to avoid
bloat and to minimise conflict with the charm's dependencies. The dependencies
are listed in [requirements.txt](requirements.txt).
are listed in [pyproject.toml](pyproject.toml) in the `project.dependencies` section.

# Dev Tools

## Formatting and Checking

Test environments are managed with [tox](https://tox.wiki/) and executed with
[pytest](https://pytest.org), with coverage measured by
[coverage](https://coverage.readthedocs.io/).
Static type checking is done using [pyright](https://github.com/microsoft/pyright),
and extends the Python 3.8 type hinting support through the
[typing_extensions](https://pypi.org/project/typing-extensions/) package.

Formatting uses [isort](https://pypi.org/project/isort/) and
[autopep8](https://pypi.org/project/autopep8/), with linting also using
[flake8](https://github.com/PyCQA/flake8), including the
[docstrings](https://pypi.org/project/flake8-docstrings/),
[builtins](https://pypi.org/project/flake8-builtins/) and
[pep8-naming](https://pypi.org/project/pep8-naming/) extensions.

All tool configuration is kept in [project.toml](pyproject.toml). The list of
dependencies can be found in the relevant `tox.ini` environment `deps` field.

## Building

The build backend is [setuptools](https://pypi.org/project/setuptools/), and
the build frontend is [build](https://pypi.org/project/build/).

# Publishing a Release

To make a release of the ops library, do the following:

1. Visit the [releases page on GitHub](https://github.com/canonical/operator/releases).
2. Click "Draft a new release"
3. The "Release Title" is simply the full version number, in the form <major>.<minor>.<patch>
E.g. 2.3.12
4. Drop notes and a changelog in the description.
5. When you are ready, click "Publish". (If you are not ready, click "Save as Draft".)

This will trigger an automatic build for the Python package and publish it to PyPI (the API token/secret is already set up in the repository settings).
1. Open a PR to change [version.py][ops/version.py]'s `version` to the
[appropriate string](https://semver.org/), and get that merged to main.
2. Visit the [releases page on GitHub](https://github.com/canonical/operator/releases).
3. Click "Draft a new release"
4. The "Release Title" is simply the full version number, in the form <major>.<minor>.<patch>
and a brief summary of the main changes in the release
E.g. 2.3.12 Bug fixes for the Juju foobar feature when using Python 3.12
5. Drop notes and a changelog in the description.
6. When you are ready, click "Publish". (If you are not ready, click "Save as Draft".) Wait for the new version to be published successfully to [the PyPI project](https://pypi.org/project/ops/).
7. Open a PR to change [version.py][ops/version.py]'s `version` to the expected
next version, with "+dev" appended (for example, if 3.14.1 is the next expected version, use
`'3.14.1.dev0'`).
benhoyt marked this conversation as resolved.
Show resolved Hide resolved

This will trigger an automatic build for the Python package and publish it to PyPI (authorization is handled via a [Trusted Publisher](https://docs.pypi.org/trusted-publishers/) relationship).

See [.github/workflows/publish.yml](.github/workflows/publish.yml) for details. (Note that the versions in publish.yml refer to versions of the GitHub actions, not the versions of the ops library.)

Expand Down
10 changes: 10 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
graft ops
graft test

include *.txt
include *.md
include MANIFEST.in
include pyproject.toml
include tox.ini

global-exclude *~ *.py[cod] __pycache__ *.charm
benhoyt marked this conversation as resolved.
Show resolved Hide resolved
7 changes: 0 additions & 7 deletions docs/requirements.in

This file was deleted.

102 changes: 79 additions & 23 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,31 +1,87 @@
alabaster==0.7.13
babel==2.12.1
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --extra=docs --output-file=docs/requirements.txt pyproject.toml
#
alabaster==0.7.16
# via sphinx
babel==2.14.0
# via sphinx
beautifulsoup4==4.12.2
certifi==2023.7.22
charset-normalizer==3.1.0
# via
# canonical-sphinx-extensions
# furo
canonical-sphinx-extensions==0.0.18
# via lxd-sphinx-extensions
certifi==2023.11.17
# via requests
charset-normalizer==3.3.2
# via requests
docutils==0.18.1
furo==2023.5.20
idna==3.4
# via
# canonical-sphinx-extensions
# sphinx
# sphinx-tabs
furo==2023.9.10
# via ops (pyproject.toml)
idna==3.6
# via requests
imagesize==1.4.1
jinja2==3.1.2
lxd-sphinx-extensions==0.0.7
markupsafe==2.1.2
packaging==23.1
pygments==2.15.1
pyyaml==6.0
# via sphinx
jinja2==3.1.3
# via sphinx
lxd-sphinx-extensions==0.0.16
# via ops (pyproject.toml)
markupsafe==2.1.3
# via jinja2
packaging==23.2
# via sphinx
pygments==2.17.2
# via
# furo
# sphinx
# sphinx-tabs
pyyaml==6.0.1
# via ops (pyproject.toml)
requests==2.31.0
# via
# canonical-sphinx-extensions
# sphinx
snowballstemmer==2.2.0
soupsieve==2.4.1
# via sphinx
soupsieve==2.5
# via beautifulsoup4
sphinx==6.2.1
sphinx-basic-ng==1.0.0b1
# via
# canonical-sphinx-extensions
# furo
# ops (pyproject.toml)
# sphinx-basic-ng
# sphinx-copybutton
# sphinx-design
# sphinx-tabs
sphinx-basic-ng==1.0.0b2
# via furo
sphinx-copybutton==0.5.2
sphinx-design==0.4.1
sphinx-tabs==3.4.1
sphinxcontrib-applehelp==1.0.4
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.1
# via ops (pyproject.toml)
sphinx-design==0.5.0
# via ops (pyproject.toml)
sphinx-tabs==3.4.4
# via ops (pyproject.toml)
sphinxcontrib-applehelp==1.0.8
# via sphinx
sphinxcontrib-devhelp==1.0.6
# via sphinx
sphinxcontrib-htmlhelp==2.0.5
# via sphinx
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
urllib3==2.0.7
websocket-client==1.5.2
# via sphinx
sphinxcontrib-qthelp==1.0.7
# via sphinx
sphinxcontrib-serializinghtml==1.1.10
# via sphinx
urllib3==2.1.0
# via requests
websocket-client==1.7.0
# via ops (pyproject.toml)
12 changes: 0 additions & 12 deletions docs/update_requirements.sh

This file was deleted.

42 changes: 3 additions & 39 deletions ops/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 Canonical Ltd.
# Copyright 2023 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,45 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Helper to define the version of the ops library.
"""Package version.

This module is NOT to be used when developing charms using ops.
"""

import subprocess
from pathlib import Path

__all__ = ('version',)

_FALLBACK = '1.0' # this gets bumped after release


def _get_version():
version = f"{_FALLBACK}.dev0+unknown"

p = Path(__file__).parent
if (p.parent / '.git').exists():
try:
proc = subprocess.run(
['git', 'describe', '--tags', '--dirty'],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
cwd=p,
check=True,
encoding='utf-8')
except Exception:
pass
else:
version = proc.stdout.strip()
if '-' in version:
# version will look like <tag>-<#commits>-g<hex>[-dirty]
# in terms of PEP 440, the tag we'll make sure is a 'public version identifier';
# everything after the first - needs to be a 'local version'
public, local = version.split('-', 1)
version = f"{public}+{local.replace('-', '.')}"
# version now <tag>+<#commits>.g<hex>[.dirty]
# which is PEP440-compliant (as long as <tag> is :-)
return version


version = _get_version()
version: str = '2.10.0.dev0'
51 changes: 51 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
[project]
name = "ops"
description = "The Python library behind great charms"
readme = "README.md"
requires-python = ">=3.8"
authors = [
{name="The Charm Tech team at Canonical Ltd.", email="charm-tech@lists.launchpad.com"},
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: System Administrators",
"Operating System :: MacOS :: MacOS X",
"Operating System :: POSIX :: Linux",
]
dependencies = [
"PyYAML==6.*",
"websocket-client==1.*",
]
dynamic = ["version"]

[project.optional-dependencies]
docs = [
"sphinx==6.2.1",
"sphinx-design",
"furo",
"sphinx-tabs",
"lxd-sphinx-extensions",
"sphinx-copybutton",
]

[project.urls]
"Homepage" = "https://juju.is/docs/sdk"
"Repository" = "https://github.com/canonical/operator"
"Issues" = "https://github.com/canonical/operator/issues"
"Documentation" = "https://ops.readthedocs.io"
"Changelog" = "https://github.com/canonical/operator/blob/main/CHANGES.md"

[build-system]
requires = [
"setuptools>=60",
"PyYAML==6.*",
"websocket-client==1.*",
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
]
build-backend = "setuptools.build_meta"

[tool.setuptools.dynamic]
version = {attr = "ops.version.version"}

# Testing tools configuration
[tool.coverage.run]
branch = true
Expand Down