Skip to content

Commit d8795ea

Browse files
authored
Merge branch 'gsoc-19-pr-builder' into pr-build-tab
2 parents fa192a1 + 5a05b6c commit d8795ea

19 files changed

+144
-88
lines changed

docs/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def get_version():
5454
default_role = 'obj'
5555
intersphinx_mapping = {
5656
'python': ('https://python.readthedocs.io/en/latest/', None),
57-
'django': ('https://django.readthedocs.io/en/1.9.x/', None),
57+
'django': ('https://django.readthedocs.io/en/1.11.x/', None),
5858
'sphinx': ('https://sphinx.readthedocs.io/en/latest/', None),
5959
}
6060
htmlhelp_basename = 'ReadTheDocsdoc'

docs/features/sitemaps.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ and communicate them additional information about each URL of the project:
1212
Read the Docs automatically generates a sitemap for each project that hosts
1313
to improve results when performing a search on these search engines.
1414
This allow us to prioritize results based on the version number, for example
15-
to show ``latest`` as the top result followed by ``stable`` and then all the project's
15+
to show ``stable`` as the top result followed by ``latest`` and then all the project's
1616
versions sorted following semver_.
1717

1818
.. _semver: https://semver.org/

docs/guides/environment-variables.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ To define an environment variable, you need to
1717
.. note::
1818

1919
Values will never be exposed to users, even to owners of the project.
20-
Once you create an environment variable you won't be able to see its value anymore because of security purposes.
20+
Once you create an environment variable, you won't be able to see its value anymore for security purposes.
2121

2222
After adding an environment variable from your project's admin, you can access it from your build process using Python,
2323
for example:

readthedocs/api/v3/mixins.py

+2-7
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,12 @@ def get_queryset(self):
8181
4. raise a ``NotFound`` exception otherwise
8282
"""
8383

84-
# NOTE: ``super().get_queryset`` produces the filter by ``NestedViewSetMixin``
85-
# we need to have defined the class attribute as ``queryset = Model.objects.all()``
84+
# We need to have defined the class attribute as ``queryset = Model.objects.all()``
8685
queryset = super().get_queryset()
8786

8887
# Detail requests are public
8988
if self.detail:
9089
return self.detail_objects(queryset, self.request.user)
9190

9291
# List view are only allowed if user is owner of parent project
93-
listing_objects = self.listing_objects(queryset, self.request.user)
94-
if listing_objects:
95-
return listing_objects
96-
97-
raise NotFound
92+
return self.listing_objects(queryset, self.request.user)

readthedocs/builds/admin.py

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class BuildAdmin(admin.ModelAdmin):
4444
'type',
4545
'state',
4646
'date',
47+
'length'
4748
)
4849
list_filter = ('type', 'state', 'success')
4950
list_select_related = ('project', 'version')

readthedocs/builds/constants.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131
('dash', _('Dash')),
3232
)
3333

34+
# Manager name for Internal Versions or Builds.
35+
# ie: Versions and Builds Excluding pull request/merge request Versions and Builds.
36+
INTERNAL = 'internal'
37+
# Manager name for External Versions or Builds.
38+
# ie: Only pull request/merge request Versions and Builds.
39+
EXTERNAL = 'external'
40+
3441
BRANCH = 'branch'
3542
TAG = 'tag'
3643
PULL_REQUEST = 'pull_request'
@@ -39,7 +46,7 @@
3946
VERSION_TYPES = (
4047
(BRANCH, _('Branch')),
4148
(TAG, _('Tag')),
42-
(PULL_REQUEST, _('Pull Request')),
49+
(EXTERNAL, _('External')),
4350
(UNKNOWN, _('Unknown')),
4451
)
4552

readthedocs/builds/managers.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
STABLE,
2020
STABLE_VERBOSE_NAME,
2121
TAG,
22-
PULL_REQUEST,
22+
EXTERNAL,
2323
)
2424
from .querysets import VersionQuerySet, BuildQuerySet
2525

@@ -91,24 +91,24 @@ class InternalVersionManagerBase(VersionManagerBase):
9191
"""
9292
Version manager that only includes internal version.
9393
94-
It will exclude PULL_REQUEST type from the queries
94+
It will exclude pull request/merge request versions from the queries
9595
and only include BRANCH, TAG, UNKONWN type Versions.
9696
"""
9797

9898
def get_queryset(self):
99-
return super().get_queryset().exclude(type=PULL_REQUEST)
99+
return super().get_queryset().exclude(type=EXTERNAL)
100100

101101

102102
class ExternalVersionManagerBase(VersionManagerBase):
103103

104104
"""
105105
Version manager that only includes external version.
106106
107-
It will only include PULL_REQUEST type Versions in the queries.
107+
It will only include pull request/merge request Versions in the queries.
108108
"""
109109

110110
def get_queryset(self):
111-
return super().get_queryset().filter(type=PULL_REQUEST)
111+
return super().get_queryset().filter(type=EXTERNAL)
112112

113113

114114
class VersionManager(SettingsOverrideObject):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.21 on 2019-06-17 19:43
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('builds', '0007_add-automation-rules'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='version',
17+
name='type',
18+
field=models.CharField(choices=[('branch', 'Branch'), ('tag', 'Tag'), ('external', 'External'), ('unknown', 'Unknown')], default='unknown', max_length=20, verbose_name='Type'),
19+
),
20+
migrations.AlterField(
21+
model_name='versionautomationrule',
22+
name='version_type',
23+
field=models.CharField(choices=[('branch', 'Branch'), ('tag', 'Tag'), ('external', 'External'), ('unknown', 'Unknown')], max_length=32, verbose_name='Version type'),
24+
),
25+
]

readthedocs/builds/models.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
INTERNAL,
4242
LATEST,
4343
NON_REPOSITORY_VERSIONS,
44-
PULL_REQUEST,
44+
EXTERNAL,
4545
STABLE,
4646
TAG,
4747
VERSION_TYPES,
@@ -126,7 +126,7 @@ class Version(models.Model):
126126
objects = VersionManager.from_queryset(VersionQuerySet)()
127127
# Only include BRANCH, TAG, UNKONWN type Versions.
128128
internal = InternalVersionManager.from_queryset(VersionQuerySet)()
129-
# Only include PULL_REQUEST type Versions.
129+
# Only include EXTERNAL type Versions.
130130
external = ExternalVersionManager.from_queryset(VersionQuerySet)()
131131

132132
class Meta:
@@ -162,7 +162,7 @@ def vcs_url(self):
162162
Generate VCS (github, gitlab, bitbucket) URL for this version.
163163
164164
Branch/Tag Example: https://github.com/rtfd/readthedocs.org/tree/3.4.2/.
165-
Pull Request Example: https://github.com/rtfd/readthedocs.org/pull/9999/.
165+
Pull/merge Request Example: https://github.com/rtfd/readthedocs.org/pull/9999/.
166166
"""
167167
url = ''
168168
if self.slug == STABLE:
@@ -172,7 +172,7 @@ def vcs_url(self):
172172
else:
173173
slug_url = self.slug
174174

175-
if self.type == PULL_REQUEST:
175+
if self.type == EXTERNAL:
176176
if 'github' in self.project.repo:
177177
url = f'/pull/{slug_url}/'
178178

@@ -252,14 +252,14 @@ def commit_name(self):
252252
# the actual tag name.
253253
return self.verbose_name
254254

255-
if self.type == PULL_REQUEST:
256-
# If this version is a Pull Request, the identifier will
255+
if self.type == EXTERNAL:
256+
# If this version is a EXTERNAL version, the identifier will
257257
# contain the actual commit hash. which we can use to
258258
# generate url for a given file name
259259
return self.identifier
260260

261261
# If we came that far it's not a special version
262-
# nor a branch, tag or Pull Request.
262+
# nor a branch, tag or EXTERNAL version.
263263
# Therefore just return the identifier to make a safe guess.
264264
log.debug(
265265
'TODO: Raise an exception here. Testing what cases it happens',

readthedocs/core/urls/subdomain.py

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
serve_docs,
4747
name='docs_detail',
4848
),
49+
4950
]
5051

5152
groups = [subdomain_urls]

readthedocs/core/views/serve.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,27 @@ def inner_view( # noqa
111111
def redirect_project_slug(request, project, subproject): # pylint: disable=unused-argument
112112
"""Handle / -> /en/latest/ directs on subdomains."""
113113
urlparse_result = urlparse(request.get_full_path())
114+
115+
# When accessing docs.customdomain.org/projects/subproject/ and the
116+
# ``subproject`` is a single-version, we don't have to redirect but to serve
117+
# the index file instead.
118+
if subproject and subproject.single_version:
119+
try:
120+
# HACK: this only affects corporate site and won't be hit on the
121+
# community. This can be removed once the middleware incorporates
122+
# more data or redirects happen outside this application
123+
# See: https://github.com/rtfd/readthedocs.org/pull/5690
124+
log.warning('Serving docs for a single-version subproject instead redirecting')
125+
from readthedocsinc.core.views import serve_docs as corporate_serve_docs # noqa
126+
return corporate_serve_docs(request, project, project.slug, subproject, subproject.slug)
127+
except Exception:
128+
log.exception('Error trying to redirect a single-version subproject')
129+
114130
return HttpResponseRedirect(
115131
resolve(
116132
subproject or project,
117133
query_params=urlparse_result.query,
118-
)
134+
),
119135
)
120136

121137

readthedocs/projects/admin.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,8 @@ class ImportedFileAdmin(admin.ModelAdmin):
312312
"""Admin view for :py:class:`ImportedFile`."""
313313

314314
raw_id_fields = ('project', 'version')
315-
list_display = ('path', 'name', 'version')
316-
search_fields = ('project', 'path')
315+
list_display = ('path', 'version', 'build')
316+
search_fields = ('project__slug', 'version__slug', 'path', 'build')
317317

318318

319319
class DomainAdmin(admin.ModelAdmin):

readthedocs/rtd_tests/tests/test_doc_serving.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from django.urls import reverse
1111
from mock import mock_open, patch
1212

13-
from readthedocs.builds.constants import LATEST, PULL_REQUEST, INTERNAL
13+
from readthedocs.builds.constants import LATEST, EXTERNAL, INTERNAL
1414
from readthedocs.builds.models import Version
1515
from readthedocs.core.middleware import SubdomainMiddleware
1616
from readthedocs.core.views import server_error_404_subdomain
@@ -259,6 +259,16 @@ def test_sitemap_xml(self):
259259
project=self.public,
260260
active=True
261261
)
262+
# This is a EXTERNAL Version
263+
external_version = fixture.get(
264+
Version,
265+
identifier='pr-version',
266+
verbose_name='pr-version',
267+
slug='pr-9999',
268+
project=self.public,
269+
active=True,
270+
type=EXTERNAL
271+
)
262272
# This also creates a Version `latest` Automatically for this project
263273
translation = fixture.get(
264274
Project,
@@ -317,7 +327,7 @@ def test_sitemap_xml(self):
317327
self.assertNotContains(
318328
response,
319329
self.public.get_docs_url(
320-
version_slug=pr_version.slug,
330+
version_slug=external_version.slug,
321331
lang_slug=self.public.language,
322332
private=True,
323333
),

0 commit comments

Comments
 (0)