What follows is a proposal to implement “Draft Reviews” in PyPI.
Context
Since at least 2015, there has been a need for “Unpublished Releases”. The following Issue has a history of comments along with a link to the original discussion:
After a reasonable discussion with @dustin, we came up with a viable implementation.
This proposal has been posted here per the recommendation of @sumanah, and any suggestions regarding forum etiquette can be directed at them.
Summary of the Feature Request
Maintainers of packages would like to be able to separate the Upload and the Publish stages of their releases, in order to double check and test their package as if it was already release, before publishing the release for all others to use.
Since users want to be able to fix last-minute details in either the package or its metadata, these draft releases need to be mutable, contrary to normal releases on PyPI and Test PyPI.
Because these draft releases are only intended for maintainers and their workflows, they should not be accidentally installed by the average user. This means it’s not going to be visible nor discoverable on PyPI or any of its clients.
All other aspects about the release should stay the same, in order to provide the most accurate representation of how the published release will look and behave like.
Solution
In order to fulfill the maintainer’s needs, while leveraging our existing arquitecture and making as few changes as possible, the following solution is proposed:
- Add one field to the
Release
model:-
published
- a timestamp, which will be taken from thecreated
value for all pre-existing releases. This will tell apart draft releases from published releases.
-
- Add one field to the
Project
model:-
auto_publish_releases
- boolean, default to true - UI for setting this value in the project management UI
-
- Filter on whether
published
is set for a release in public UIs, likewise for thesimple
API. - In management UI, separate the draft release from published releases at the top
- with a button to publish the release
- URL routes for testing and viewing draft releases in the form of something like:
https://pypi.org/project/pip/20.0.2-draft-a1b2c3/
- Where
a1b2c3
is a hash of the release id - Installation command example in release description is updated to use this URL. e.g.
pip install pip=20.0.2-draft-a1b2c3
- Update the traversal logic here to consider these draft versions
- Special banner / indicator / badge in release subscription that this release is a draft
- Draft URL can redirect to actual URL after publication
- Where
- Only one draft release per project
- On publishing, the
published
timestamp is set - Unpublished releases do not show up in XML-RPC for mirrors until it is published.
Long term, we’ll also want the following:
- An API to indicate whether a project/release should be auto-published from the upload client
- An API to publish a draft release from an upload client
It’s also important to note that this change would not require any work on the upload/installer clients. As it would be managed entirely by Warehouse, the PyPI backend.
Any feedback on this is welcome, especially thoughts about:
- how to generate the hashed draft link
- how installing an draft release should work with
pip
(maybe using an obfuscated simple index and--index-url
?)
I’d like to hear your opinions on this, specially if you’re a package maintainer.
I’ll need your feedback by April 30th 2020 at which point I’ll proceed with the basis of what I know.