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

Support X-PyPI-Is-Staged #17331

Draft
wants to merge 39 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a45892a
Fix cherry-pick
warsaw Sep 21, 2024
831095a
Add `published` to the `ReleaseFactory`
alanbato May 2, 2022
5846e30
Add migrations
DarkaMaul Dec 6, 2024
60f4a01
Add a default value for Release.published field.
DarkaMaul Dec 9, 2024
60de6e8
Change to a boolean field
DarkaMaul Dec 10, 2024
d2438e8
Merge branch 'main' into dm/published-date
DarkaMaul Dec 10, 2024
a792738
Filter out unpublished releases
DarkaMaul Dec 10, 2024
76fd2e4
Merge branch 'main' into dm/published-date
DarkaMaul Dec 11, 2024
018d047
Merge branch 'main' into dm/draft-header
DarkaMaul Dec 16, 2024
35395da
Merge branch 'main' into dm/published-date
woodruffw Dec 16, 2024
38221fb
Merge branch 'main' into dm/published-date
DarkaMaul Dec 18, 2024
0957242
Merge branch 'dm/published-date' into dm/draft-header
DarkaMaul Dec 18, 2024
4b8b395
Add `staged` releases publication
DarkaMaul Dec 20, 2024
1d81d5d
Remove empty upload.
DarkaMaul Dec 27, 2024
c781e5b
Add test with OIDC publishing
DarkaMaul Dec 27, 2024
e6efef9
Merge branch 'main' into dm/draft-header
DarkaMaul Dec 27, 2024
90bc0b3
Update translations
DarkaMaul Dec 27, 2024
943f630
Merge branch 'main' into dm/draft-header
DarkaMaul Dec 31, 2024
2b51092
Upgrade tests
DarkaMaul Dec 31, 2024
852db29
Merge remote-tracking branch 'origin/dm/draft-header' into dm/draft-h…
DarkaMaul Dec 31, 2024
840951d
Add `published` column
DarkaMaul Jan 22, 2025
deddcc1
Add `published` to the `ReleaseFactory`
alanbato May 2, 2022
c8affce
Add migrations
DarkaMaul Dec 6, 2024
f830b63
Add a default value for Release.published field.
DarkaMaul Dec 9, 2024
cdf1acb
Change to a boolean field
DarkaMaul Dec 10, 2024
d3f59b4
Filter out unpublished releases
DarkaMaul Dec 10, 2024
8fcb92e
Use a SQLAlchemy event
DarkaMaul Jan 3, 2025
cf2abc8
Remove field from PR
DarkaMaul Jan 22, 2025
eb025b6
Resolve merge conflict
DarkaMaul Jan 22, 2025
76d6615
Merge branch 'main' into dm/published-date
DarkaMaul Jan 28, 2025
dec6238
Revert un-needed changes
DarkaMaul Jan 28, 2025
56feeb0
Remove event handling
DarkaMaul Jan 28, 2025
6906096
Add more tests
DarkaMaul Jan 28, 2025
9397ef2
Rename from unpublished to staged
DarkaMaul Jan 28, 2025
32566d4
Merge branch 'main' into dm/published-date
woodruffw Jan 28, 2025
73363b1
Merge branch 'main' into dm/draft-header
DarkaMaul Jan 28, 2025
76ad6b7
Update PR
DarkaMaul Jan 28, 2025
b629c84
Merge branch 'dm/published-date' into dm/draft-header
DarkaMaul Jan 28, 2025
6d14433
Rebase PR on top of other changes
DarkaMaul Jan 28, 2025
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
Prev Previous commit
Next Next commit
Filter out unpublished releases
DarkaMaul committed Jan 22, 2025

Verified

This commit was signed with the committer’s verified signature.
commit d3f59b42e474baaa1aad80c824af0d003b44b011
16 changes: 16 additions & 0 deletions tests/unit/legacy/api/test_json.py
Original file line number Diff line number Diff line change
@@ -118,6 +118,13 @@ def test_all_non_prereleases_yanked(self, monkeypatch, db_request):
db_request.matchdict = {"name": project.normalized_name}
assert json.latest_release_factory(db_request) == release

def test_with_unpublished(self, db_request):
project = ProjectFactory.create()
release = ReleaseFactory.create(project=project, version="1.0")
ReleaseFactory.create(project=project, version="2.0", published=False)
db_request.matchdict = {"name": project.normalized_name}
assert json.latest_release_factory(db_request) == release

def test_project_quarantined(self, monkeypatch, db_request):
project = ProjectFactory.create(
lifecycle_status=LifecycleStatus.QuarantineEnter
@@ -191,6 +198,15 @@ def test_renders(self, pyramid_config, db_request, db_session):
)
]

ReleaseFactory.create(
project=project,
version="3.1",
description=DescriptionFactory.create(
content_type=description_content_type
),
published=False,
)

for urlspec in project_urls:
label, _, purl = urlspec.partition(",")
db_session.add(
77 changes: 53 additions & 24 deletions tests/unit/packaging/test_views.py
Original file line number Diff line number Diff line change
@@ -135,6 +135,19 @@ def test_only_yanked_release(self, monkeypatch, db_request):
assert resp is response
assert release_detail.calls == [pretend.call(release, db_request)]

def test_with_unpublished(self, monkeypatch, db_request):
project = ProjectFactory.create()
release = ReleaseFactory.create(project=project, version="1.0")
ReleaseFactory.create(project=project, version="1.1", published=False)

response = pretend.stub()
release_detail = pretend.call_recorder(lambda ctx, request: response)
monkeypatch.setattr(views, "release_detail", release_detail)

resp = views.project_detail(project, db_request)
assert resp is response
assert release_detail.calls == [pretend.call(release, db_request)]


class TestReleaseDetail:
def test_normalizing_name_redirects(self, db_request):
@@ -178,30 +191,45 @@ def test_normalizing_version_redirects(self, db_request):
def test_detail_rendered(self, db_request):
users = [UserFactory.create(), UserFactory.create(), UserFactory.create()]
project = ProjectFactory.create()
releases = [
ReleaseFactory.create(
project=project,
version=v,
description=DescriptionFactory.create(
raw="unrendered description",
html="rendered description",
content_type="text/html",
),
)
for v in ["1.0", "2.0", "3.0", "4.0.dev0"]
] + [
ReleaseFactory.create(
project=project,
version="5.0",
description=DescriptionFactory.create(
raw="plaintext description",
html="",
content_type="text/plain",
),
yanked=True,
yanked_reason="plaintext yanked reason",
)
]
releases = (
[
ReleaseFactory.create(
project=project,
version=v,
description=DescriptionFactory.create(
raw="unrendered description",
html="rendered description",
content_type="text/html",
),
)
for v in ["1.0", "2.0", "3.0", "4.0.dev0"]
]
+ [
ReleaseFactory.create(
project=project,
version="5.0",
description=DescriptionFactory.create(
raw="plaintext description",
html="",
content_type="text/plain",
),
yanked=True,
yanked_reason="plaintext yanked reason",
)
]
+ [
ReleaseFactory.create(
project=project,
version="5.1",
description=DescriptionFactory.create(
raw="unrendered description",
html="rendered description",
content_type="text/html",
),
published=False,
)
]
)
files = [
FileFactory.create(
release=r,
@@ -226,6 +254,7 @@ def test_detail_rendered(self, db_request):
"bdists": [],
"description": "rendered description",
"latest_version": project.latest_version,
# Non published version are not listed here
"all_versions": [
(r.version, r.created, r.is_prerelease, r.yanked, r.yanked_reason)
for r in reversed(releases)
8 changes: 6 additions & 2 deletions warehouse/legacy/api/json.py
Original file line number Diff line number Diff line change
@@ -62,7 +62,10 @@ def _json_data(request, project, release, *, all_releases):
)
)
.outerjoin(File)
.filter(Release.project == project)
.filter(
Release.project == project,
Release.published.is_(True),
)
)

# If we're not looking for all_releases, then we'll filter this further
@@ -206,7 +209,8 @@ def latest_release_factory(request):
.filter(
Project.lifecycle_status.is_distinct_from(
LifecycleStatus.QuarantineEnter
)
),
Release.published.is_(True),
)
.order_by(
Release.yanked.asc(),
2 changes: 1 addition & 1 deletion warehouse/locale/messages.pot
Original file line number Diff line number Diff line change
@@ -784,7 +784,7 @@ msgstr ""
msgid "Provide an Inspector link to specific lines of code."
msgstr ""

#: warehouse/packaging/views.py:352
#: warehouse/packaging/views.py:355
msgid "Your report has been recorded. Thank you for your help."
msgstr ""

6 changes: 5 additions & 1 deletion warehouse/packaging/models.py
Original file line number Diff line number Diff line change
@@ -454,7 +454,11 @@ def latest_version(self):
return (
orm.object_session(self)
.query(Release.version, Release.created, Release.is_prerelease)
.filter(Release.project == self, Release.yanked.is_(False))
.filter(
Release.project == self,
Release.yanked.is_(False),
Release.published.is_(True),
)
.order_by(Release.is_prerelease.nullslast(), Release._pypi_ordering.desc())
.first()
)
4 changes: 3 additions & 1 deletion warehouse/packaging/utils.py
Original file line number Diff line number Diff line change
@@ -53,9 +53,11 @@ def _simple_detail(project, request):
.join(Release)
.filter(Release.project == project)
# Exclude projects that are in the `quarantine-enter` lifecycle status.
# And exclude un-published releases from the index
.join(Project)
.filter(
Project.lifecycle_status.is_distinct_from(LifecycleStatus.QuarantineEnter)
Project.lifecycle_status.is_distinct_from(LifecycleStatus.QuarantineEnter),
Release.published.is_(True),
)
.all(),
key=lambda f: (packaging_legacy.version.parse(f.release.version), f.filename),
5 changes: 4 additions & 1 deletion warehouse/packaging/views.py
Original file line number Diff line number Diff line change
@@ -179,7 +179,10 @@ def project_detail(project, request):
try:
release = (
request.db.query(Release)
.filter(Release.project == project)
.filter(
Release.project == project,
Release.published.is_(True),
)
.order_by(
Release.yanked,
Release.is_prerelease.nullslast(),