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

Add project releases RSS feed #7013

Merged
merged 17 commits into from
May 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions docs/api-reference/feeds.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
Feeds
=====

PyPI offers two RSS feeds, the `Newest Packages Feed`_ and the `Latest Updates
Feed`_. You can also call its APIs to get more details on project activity.
PyPI offers three RSS feeds, the `Newest Packages Feed`_, the `Latest Updates
Feed`_, and the `Project Releases Feed`_. You can also call its APIs to get
more details on project activity.


Newest Packages Feed
Expand All @@ -21,6 +22,15 @@ newly created releases for individual projects on PyPI, including the project
name and description, release version, and a link to the release page.


Project Releases Feed
---------------------

Available at ``https://pypi.org/rss/project/<project_name>/releases.xml`` for each
project, this feed provides the latest releases for the given project on
PyPI, including the package name and description, release version, and a link
to the release page.


Project and release activity details
------------------------------------

Expand Down
29 changes: 29 additions & 0 deletions tests/unit/rss/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,35 @@ def test_rss_packages(db_request):
assert db_request.response.content_type == "text/xml"


def test_rss_project_releases(db_request):
db_request.find_service = pretend.call_recorder(
lambda *args, **kwargs: pretend.stub(
enabled=False, csp_policy=pretend.stub(), merge=lambda _: None
)
)

db_request.session = pretend.stub()

project = ProjectFactory.create()

release_v1 = ReleaseFactory.create(project=project, version="1.0.0")
release_v1.created = datetime.date(2018, 1, 1)
release_v3 = ReleaseFactory.create(project=project, version="3.0.0")
release_v3.created = datetime.date(2019, 1, 1)
release_v2 = ReleaseFactory.create(project=project, version="2.0.0")
release_v2.created = datetime.date(2020, 1, 1)

release_v3.author_email = "noreply@pypi.org"

assert rss.rss_project_releases(project, db_request) == {
"project": project,
"latest_releases": tuple(
zip((release_v2, release_v3, release_v1), (None, "noreply@pypi.org", None))
),
}
assert db_request.response.content_type == "text/xml"


def test_format_author(db_request):
db_request.find_service = pretend.call_recorder(
lambda *args, **kwargs: pretend.stub(
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,14 @@ def add_policy(name, filename):
pretend.call("ses.hook", "/_/ses-hook/", domain=warehouse),
pretend.call("rss.updates", "/rss/updates.xml", domain=warehouse),
pretend.call("rss.packages", "/rss/packages.xml", domain=warehouse),
pretend.call(
"rss.project.releases",
"/rss/project/{name}/releases.xml",
factory="warehouse.packaging.models:ProjectFactory",
traverse="/{name}/",
read_only=True,
domain=warehouse,
),
pretend.call("legacy.api.simple.index", "/simple/", domain=warehouse),
pretend.call(
"legacy.api.simple.detail",
Expand Down
Loading