diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..f08ce6e
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,36 @@
+.. _changelog:
+
+---------
+Changelog
+---------
+
+.. note::
+
+ Until the Python API has stabilised, ``venvstacks`` is using
+ `ZeroVer `__ (starting from 0.1.0).
+
+ Refer to the :ref:`version-numbering` for additional details
+ on the way releases are versioned.
+
+
+Unreleased
+==========
+
+See the fragment files in the `changelog.d directory`_.
+
+.. _changelog.d directory: https://github.com/lmstudio-ai/venvstacks/tree/master/changelog.d
+
+
+.. scriv-insert-here
+
+.. _changelog-0.1.0rc1:
+
+0.1.0rc1 — 2024-10-29
+=====================
+
+Added
+-----
+
+- Initial export of `venvstacks` from Project Amphibian.
+
+- Adopted ``scriv`` for ``CHANGELOG`` management.
diff --git a/changelog.d/README.txt b/changelog.d/README.txt
new file mode 100644
index 0000000..528bf4b
--- /dev/null
+++ b/changelog.d/README.txt
@@ -0,0 +1 @@
+Unpublished CHANGELOG entries (managed via scriv)
diff --git a/changelog.d/ghrel_template.md.j2 b/changelog.d/ghrel_template.md.j2
new file mode 100644
index 0000000..65cb742
--- /dev/null
+++ b/changelog.d/ghrel_template.md.j2
@@ -0,0 +1,3 @@
+:arrow_right: PyPI page: [ venvstacks {{version}}](https://pypi.org/project/venvstacks/{{version}}).
+
+{{body}}
diff --git a/ci-bootstrap-requirements.txt b/ci-bootstrap-requirements.txt
index 3efc673..080a4a2 100644
--- a/ci-bootstrap-requirements.txt
+++ b/ci-bootstrap-requirements.txt
@@ -111,6 +111,6 @@ typing-extensions==4.12.2 \
unearth==0.17.2 \
--hash=sha256:0b8a2afd3476f1ab6155fc579501ac47fffe43547d88a70e5a5b76a7fe6caa2c \
--hash=sha256:4d21af1238a583835fca156322f7225382e718cdcc42d6278050a88e605c4ad5
-virtualenv==20.27.0 \
- --hash=sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2 \
- --hash=sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655
+virtualenv==20.27.1 \
+ --hash=sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba \
+ --hash=sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4
diff --git a/ci-constraints.txt b/ci-constraints.txt
index ce7f547..abe3b5a 100644
--- a/ci-constraints.txt
+++ b/ci-constraints.txt
@@ -49,6 +49,9 @@ charset-normalizer==3.4.0 \
click==8.1.7 \
--hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \
--hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de
+click-log==0.4.0 \
+ --hash=sha256:3970f8570ac54491237bcdb3d8ab5e3eef6c057df29f8c3d1151a51a9c23b975 \
+ --hash=sha256:a43e394b528d52112af599f2fc9e4b7cf3c15f94e53581f74fa6867e68c91756
colorama==0.4.6 \
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
@@ -229,6 +232,9 @@ ruff==0.7.1 \
--hash=sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad \
--hash=sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4 \
--hash=sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307
+scriv==1.5.1 \
+ --hash=sha256:30ae9ff8d144f8e0cf394c4e1d379542f1b3823767642955b54ec40dc00b32b6 \
+ --hash=sha256:a3adc657733b4124fcb54527a5f3daab0d3c300de82d0fd2b9b297b243151b78
shellingham==1.5.4 \
--hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \
--hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de
@@ -302,6 +308,6 @@ uv==0.4.21 \
--hash=sha256:9dcddbb3b6e1662c6db41d63db539742450e2ce17d6c746329c016e3651bfb4a \
--hash=sha256:a1a9a126ce48f0f0893891adb5a9749220425169092f3e4da1216168736ac16d \
--hash=sha256:ba3e3b40cc1d5a980d36589775d6a7e4defa1b33e7e06423af0e395b8e4d9505
-virtualenv==20.27.0 \
- --hash=sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2 \
- --hash=sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655
+virtualenv==20.27.1 \
+ --hash=sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba \
+ --hash=sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4
diff --git a/docs/api/index.rst b/docs/api/index.rst
index 924876c..490eb36 100644
--- a/docs/api/index.rst
+++ b/docs/api/index.rst
@@ -1,5 +1,6 @@
+----------
Python API
-==========
+----------
.. warning::
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644
index 0000000..565b052
--- /dev/null
+++ b/docs/changelog.rst
@@ -0,0 +1 @@
+.. include:: ../CHANGELOG.rst
diff --git a/docs/conf.py b/docs/conf.py
index 9bae84c..4b81529 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -48,6 +48,7 @@
intersphinx_mapping = {
"py": ("https://docs.python.org/3", None),
+ "packaging": ("https://packaging.python.org/en/latest/", None),
}
diff --git a/docs/design.rst b/docs/design.rst
index b170b4c..02666c8 100644
--- a/docs/design.rst
+++ b/docs/design.rst
@@ -1,5 +1,9 @@
+-----------------
Design Discussion
-=================
+-----------------
+
+Project
+=======
Why does ``venvstacks`` exist?
------------------------------
@@ -37,7 +41,7 @@ environments, it doesn't refer to being able combine ``sys.path``
across multiple environments.
Splitting environments into layers the way ``venvstacks`` does
-really doesn't align well with the way the ``conda`` dependency
+also doesn't align well with the way the ``conda`` dependency
resolver works, so it ended up making more sense to design
``venvstacks`` to work with ``venv`` and ``pip``.
@@ -47,6 +51,10 @@ archives were eliminated from consideration as they lacked the ability
to readily share the large common framework components that feature
heavily in the Python AI ecosystem across different applications.
+
+Technical
+=========
+
Why use ``python-build-standalone`` for the base runtimes?
----------------------------------------------------------
diff --git a/docs/development/index.rst b/docs/development/index.rst
index ff8a954..73422d5 100644
--- a/docs/development/index.rst
+++ b/docs/development/index.rst
@@ -1,7 +1,12 @@
.. _dev-guide:
+-----------
Development
-===========
+-----------
+
+
+Getting Started
+===============
(With thanks to pip's `Getting Started`_ guide for the general structure here!)
@@ -32,6 +37,29 @@ Given these tools, the default development environment can be set up
and other commands executed as described below.
+Changelog Entries
+-----------------
+
+The ``venvstacks`` changelog is managed with :pypi:`scriv`.
+
+Entries are written in ``.rst`` format by default, so they
+can use semantic references to the rest of the documentation.
+However, ``.md`` fragments are entirely fine if internal
+semantic links aren't needed.
+
+All changes which may affect ``venvstacks`` users should be
+given a user facing changelog entry with ``scriv create``.
+
+Refer to the
+`"per-user" settings `__
+in the ``scriv`` documentation for details on how to customise the
+local behaviour of ``scriv create``.
+
+The project level ``scriv`` settings are stored in
+``pyproject.toml`` (but the project largely relies on the default
+settings)
+
+
Running from the source tree
----------------------------
@@ -62,6 +90,22 @@ venvstacks can then be executed via the ``-m`` switch:
│ publish Publish layer archives for Python virtual environment stacks. │
╰─────────────────────────────────────────────────────────────────────────────────╯
+Building Documentation
+----------------------
+
+pip's documentation is built using :pypi:`Sphinx`. The documentation is written
+in reStructuredText.
+
+To build it locally, run:
+
+.. code-block:: console
+
+ $ tox -e docs
+
+The built documentation can be found in the ``docs/_build`` folder.
+
+Automated Testing
+=================
Code consistency checks
-----------------------
@@ -95,7 +139,7 @@ All of these commands can be invoked via tox:
``# fmt: off/on`` and ``# fmt: skip`` comments may be used as needed
when the autoformatter makes readability worse instead of better
(for example, collapsing lists to a single line when they intentionally
- cover multiple lines, or )
+ cover multiple lines, or breaking alignment of end-of-line comments).
Running tests locally
@@ -183,19 +227,51 @@ closing and reopening the PR once the relevants fixes have been
implemented.
-Building Documentation
+Release Management
+==================
+
+.. _version-numbering:
+
+Version Numbering
+-----------------
+
+Until the Python API has stabilised, ``venvstacks`` is using
+`ZeroVer `__ (starting from 0.1.0).
+
+The versioning scheme to be used after the leading zero is
+dropped has not yet been decided (see
+:external+packaging:ref:`versioning`
+for some of the options being considered).
+
+Except for when a release is being prepared, the nominal version on
+``main`` will have ``.dev0`` appended to indicate it is not a
+release build.
+
+Most releases are expected to be published directly without a prior
+release candidate build, but one may be used if it is deemed
+necessary (for example, ``0.1.0rc1`` was published in order to
+test the release pipeline prior to publishing ``0.1.0``).
+
+
+Preparing New Releases
----------------------
-pip's documentation is built using :pypi:`Sphinx`. The documentation is written
-in reStructuredText.
+Prior to release:
-To build it locally, run:
+* Update the version in ``pyproject.toml`` to remove the pre-release suffix
+* Run ``scriv collect`` to update ``CHANGELOG.rst``
+* Create a PR for the collected change log updates
+* Check the updated docs after the PR has been merged
-.. code-block:: console
+Release (requires ``pandoc``):
- $ tox -e docs
+* Run ``scriv github-release --dry-run`` to check what would be published
+* Run ``scriv github-release`` to make the release tag
-The built documentation can be found in the ``docs/_build`` folder.
+After release:
+
+* Check the release GitHub Action has published to PyPI correctly
+* Bump the version in ``pyproject.toml`` and add a ``.dev0`` suffix
.. _`Getting Started`: https://pip.pypa.io/en/stable/development/getting-started/
.. _`open an issue`: https://github.com/lmstudio/venvstacks/issues/new?title=Trouble+with+development+environment
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 522634d..618e433 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -1,5 +1,6 @@
+----------------------------
Essential Terms and Concepts
-============================
+----------------------------
.. glossary::
diff --git a/docs/index.rst b/docs/index.rst
index 06bc82c..1afcf6f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -14,3 +14,4 @@ Welcome to ``venvstacks``'s documentation!
design
api/index
development/index
+ changelog
diff --git a/docs/overview.rst b/docs/overview.rst
index 6b8211d..3a61833 100644
--- a/docs/overview.rst
+++ b/docs/overview.rst
@@ -1,5 +1,6 @@
+----------------------------------
Layered Virtual Environment Stacks
-==================================
+----------------------------------
``venvstacks`` uses Python's ``sitecustomize.py`` environment setup feature
to chain together three layers of Python virtual environments:
@@ -14,7 +15,7 @@ and the framework layers to share dependencies installed in the runtime layers.
Installing
-----------
+==========
``venvstacks`` is available from the :pypi:`Python Package Index `,
and can be installed with :pypi:`pipx` (or similar tools):
@@ -59,6 +60,9 @@ The command line help also provides additional usage information:
:issue:`supported in a future release <26>`.
+Working with environment stacks
+===============================
+
Defining environment stacks
---------------------------
@@ -178,7 +182,7 @@ but the details related specifically to the published archive (such as its size
contents hash) are necessarily omitted.
Contributing to ``venvstacks`` development
-------------------------------------------
+==========================================
``venvstacks`` is MIT Licensed and `developed on GitHub `__.
diff --git a/docs/requirements.txt b/docs/requirements.txt
index fba43bd..6853425 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -12,6 +12,7 @@ certifi==2024.8.30
chardet==5.2.0
charset-normalizer==3.4.0
click==8.1.7
+click-log==0.4.0
colorama==0.4.6
coverage[toml]==7.6.4
dep-logic==0.4.9
@@ -51,6 +52,7 @@ requests==2.32.3
resolvelib==1.0.1
rich==13.9.3
ruff==0.7.1
+scriv[toml]==1.5.1
shellingham==1.5.4
sniffio==1.3.1
snowballstemmer==2.2.0
@@ -74,5 +76,5 @@ typing-extensions==4.12.2
unearth==0.17.2
urllib3==2.2.3
uv==0.4.21
-virtualenv==20.27.0
+virtualenv==20.27.1
. # this package
diff --git a/pdm.lock b/pdm.lock
index 41bd8d7..5f7543e 100644
--- a/pdm.lock
+++ b/pdm.lock
@@ -5,7 +5,7 @@
groups = ["default", "bootstrap", "dev", "docs"]
strategy = ["inherit_metadata"]
lock_version = "4.5.0"
-content_hash = "sha256:b87d49f37d3f661dbd8fc83049b4430eaa012c35b3de694fd1f309d371a7fd1e"
+content_hash = "sha256:6aeecbbca3ae78365eaedbfdb879aac15904991e06a0edac3a51a347814071bd"
[[metadata.targets]]
requires_python = ">=3.11"
@@ -128,7 +128,7 @@ name = "certifi"
version = "2024.8.30"
requires_python = ">=3.6"
summary = "Python package for providing Mozilla's CA Bundle."
-groups = ["default", "bootstrap", "docs"]
+groups = ["default", "bootstrap", "dev", "docs"]
files = [
{file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
{file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
@@ -150,7 +150,7 @@ name = "charset-normalizer"
version = "3.4.0"
requires_python = ">=3.7.0"
summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-groups = ["docs"]
+groups = ["dev", "docs"]
files = [
{file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"},
{file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"},
@@ -176,7 +176,7 @@ name = "click"
version = "8.1.7"
requires_python = ">=3.7"
summary = "Composable command line interface toolkit"
-groups = ["default"]
+groups = ["default", "dev"]
dependencies = [
"colorama; platform_system == \"Windows\"",
"importlib-metadata; python_version < \"3.8\"",
@@ -186,6 +186,19 @@ files = [
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
+[[package]]
+name = "click-log"
+version = "0.4.0"
+summary = "Logging integration for Click"
+groups = ["dev"]
+dependencies = [
+ "click",
+]
+files = [
+ {file = "click-log-0.4.0.tar.gz", hash = "sha256:3970f8570ac54491237bcdb3d8ab5e3eef6c057df29f8c3d1151a51a9c23b975"},
+ {file = "click_log-0.4.0-py2.py3-none-any.whl", hash = "sha256:a43e394b528d52112af599f2fc9e4b7cf3c15f94e53581f74fa6867e68c91756"},
+]
+
[[package]]
name = "colorama"
version = "0.4.6"
@@ -414,7 +427,7 @@ name = "idna"
version = "3.10"
requires_python = ">=3.6"
summary = "Internationalized Domain Names in Applications (IDNA)"
-groups = ["default", "bootstrap", "docs"]
+groups = ["default", "bootstrap", "dev", "docs"]
files = [
{file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
{file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
@@ -458,7 +471,7 @@ name = "jinja2"
version = "3.1.4"
requires_python = ">=3.7"
summary = "A very fast and expressive template engine."
-groups = ["docs"]
+groups = ["dev", "docs"]
dependencies = [
"MarkupSafe>=2.0",
]
@@ -472,7 +485,7 @@ name = "markdown-it-py"
version = "3.0.0"
requires_python = ">=3.8"
summary = "Python port of markdown-it. Markdown parsing, done right!"
-groups = ["default", "bootstrap"]
+groups = ["default", "bootstrap", "dev"]
dependencies = [
"mdurl~=0.1",
]
@@ -486,7 +499,7 @@ name = "markupsafe"
version = "3.0.2"
requires_python = ">=3.9"
summary = "Safely add untrusted strings to HTML/XML markup."
-groups = ["docs"]
+groups = ["dev", "docs"]
files = [
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"},
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"},
@@ -512,7 +525,7 @@ name = "mdurl"
version = "0.1.2"
requires_python = ">=3.7"
summary = "Markdown URL utilities"
-groups = ["default", "bootstrap"]
+groups = ["default", "bootstrap", "dev"]
files = [
{file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
@@ -764,7 +777,7 @@ name = "requests"
version = "2.32.3"
requires_python = ">=3.8"
summary = "Python HTTP for Humans."
-groups = ["docs"]
+groups = ["dev", "docs"]
dependencies = [
"certifi>=2017.4.17",
"charset-normalizer<4,>=2",
@@ -817,6 +830,39 @@ files = [
{file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"},
]
+[[package]]
+name = "scriv"
+version = "1.5.1"
+summary = "Scriv changelog management tool"
+groups = ["dev"]
+dependencies = [
+ "attrs",
+ "click",
+ "click-log",
+ "jinja2",
+ "markdown-it-py",
+ "requests",
+]
+files = [
+ {file = "scriv-1.5.1-py2.py3-none-any.whl", hash = "sha256:a3adc657733b4124fcb54527a5f3daab0d3c300de82d0fd2b9b297b243151b78"},
+ {file = "scriv-1.5.1.tar.gz", hash = "sha256:30ae9ff8d144f8e0cf394c4e1d379542f1b3823767642955b54ec40dc00b32b6"},
+]
+
+[[package]]
+name = "scriv"
+version = "1.5.1"
+extras = ["toml"]
+summary = "Scriv changelog management tool"
+groups = ["dev"]
+dependencies = [
+ "scriv==1.5.1",
+ "tomli; python_version < \"3.11\"",
+]
+files = [
+ {file = "scriv-1.5.1-py2.py3-none-any.whl", hash = "sha256:a3adc657733b4124fcb54527a5f3daab0d3c300de82d0fd2b9b297b243151b78"},
+ {file = "scriv-1.5.1.tar.gz", hash = "sha256:30ae9ff8d144f8e0cf394c4e1d379542f1b3823767642955b54ec40dc00b32b6"},
+]
+
[[package]]
name = "shellingham"
version = "1.5.4"
@@ -1102,7 +1148,7 @@ name = "urllib3"
version = "2.2.3"
requires_python = ">=3.8"
summary = "HTTP library with thread-safe connection pooling, file post, and more."
-groups = ["docs"]
+groups = ["dev", "docs"]
files = [
{file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
{file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
@@ -1125,7 +1171,7 @@ files = [
[[package]]
name = "virtualenv"
-version = "20.27.0"
+version = "20.27.1"
requires_python = ">=3.8"
summary = "Virtual Python Environment builder"
groups = ["default", "bootstrap", "dev"]
@@ -1136,6 +1182,6 @@ dependencies = [
"platformdirs<5,>=3.9.1",
]
files = [
- {file = "virtualenv-20.27.0-py3-none-any.whl", hash = "sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655"},
- {file = "virtualenv-20.27.0.tar.gz", hash = "sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2"},
+ {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"},
+ {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"},
]
diff --git a/pyproject.toml b/pyproject.toml
index 27d26d4..aa9f61a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -70,6 +70,7 @@ dev = [
"pbs-installer==2024.10.10",
# Uses exact pin for dev as lock file regeneration is sensitive to the exact uv version
"uv==0.4.21",
+ "scriv[toml]>=1.5.1",
]
bootstrap = [
"pdm>=2.16.1",
@@ -115,3 +116,7 @@ source = [
[tool.ruff]
# Assume Python 3.11
target-version = "py311"
+
+[tool.scriv]
+version = "literal: pyproject.toml: project.version"
+ghrel_template = "file: ghrel_template.md.j2"