Skip to content

Commit 7d5d87b

Browse files
committed
Merge tag '9.8.0' into rel
2 parents 36784bf + 9890ff4 commit 7d5d87b

File tree

84 files changed

+7596
-7063
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+7596
-7063
lines changed

CHANGELOG.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,40 @@
1+
Version 9.8.0
2+
-------------
3+
4+
:Date: March 07, 2023
5+
6+
* `@humitos <https://github.com/humitos>`__: Downloadable artifacts: make PDF and ePub opt-in by default (`#10115 <https://github.com/readthedocs/readthedocs.org/pull/10115>`__)
7+
* `@humitos <https://github.com/humitos>`__: Proxito: cacheops right model (`#10111 <https://github.com/readthedocs/readthedocs.org/pull/10111>`__)
8+
* `@stsewd <https://github.com/stsewd>`__: Docs: fix term reference (`#10110 <https://github.com/readthedocs/readthedocs.org/pull/10110>`__)
9+
* `@humitos <https://github.com/humitos>`__: Development: allow to define the logging level via an env variable (`#10109 <https://github.com/readthedocs/readthedocs.org/pull/10109>`__)
10+
* `@humitos <https://github.com/humitos>`__: Celery: cheat `job_status` view to return `finished` after 5 polls (`#10107 <https://github.com/readthedocs/readthedocs.org/pull/10107>`__)
11+
* `@humitos <https://github.com/humitos>`__: Proxito: use cacheops for 2 more models (`#10106 <https://github.com/readthedocs/readthedocs.org/pull/10106>`__)
12+
* `@github-actions[bot] <https://github.com/github-actions[bot]>`__: Dependencies: all packages updated via pip-tools (`#10104 <https://github.com/readthedocs/readthedocs.org/pull/10104>`__)
13+
* `@stsewd <https://github.com/stsewd>`__: Remove unused tests (`#10099 <https://github.com/readthedocs/readthedocs.org/pull/10099>`__)
14+
* `@stsewd <https://github.com/stsewd>`__: Canonical redirects: check if the project supports custom domains (`#10098 <https://github.com/readthedocs/readthedocs.org/pull/10098>`__)
15+
* `@stsewd <https://github.com/stsewd>`__: Fix .com tests (`#10097 <https://github.com/readthedocs/readthedocs.org/pull/10097>`__)
16+
* `@stsewd <https://github.com/stsewd>`__: Fix migration (`#10096 <https://github.com/readthedocs/readthedocs.org/pull/10096>`__)
17+
* `@benjaoming <https://github.com/benjaoming>`__: Docs: Move a reference and remove an empty paranthesis (`#10093 <https://github.com/readthedocs/readthedocs.org/pull/10093>`__)
18+
* `@benjaoming <https://github.com/benjaoming>`__: Docs: Update documentation for search.ignore (`#10091 <https://github.com/readthedocs/readthedocs.org/pull/10091>`__)
19+
* `@benjaoming <https://github.com/benjaoming>`__: Fix intersphinx references to myst-parser (updated in myst-parser 0.19) (`#10090 <https://github.com/readthedocs/readthedocs.org/pull/10090>`__)
20+
* `@stsewd <https://github.com/stsewd>`__: Update changelog with security fixes (`#10088 <https://github.com/readthedocs/readthedocs.org/pull/10088>`__)
21+
* `@humitos <https://github.com/humitos>`__: Analytics: add Plausible to our dashboard (`#10087 <https://github.com/readthedocs/readthedocs.org/pull/10087>`__)
22+
* `@humitos <https://github.com/humitos>`__: Docs: add Plausible (`#10086 <https://github.com/readthedocs/readthedocs.org/pull/10086>`__)
23+
* `@stsewd <https://github.com/stsewd>`__: Proxito: refactor canonical redirects (`#10069 <https://github.com/readthedocs/readthedocs.org/pull/10069>`__)
24+
* `@stsewd <https://github.com/stsewd>`__: Proxito: simplify caching logic (`#10067 <https://github.com/readthedocs/readthedocs.org/pull/10067>`__)
25+
* `@ericholscher <https://github.com/ericholscher>`__: Add X-Content-Type-Options as a custom domain header (`#10062 <https://github.com/readthedocs/readthedocs.org/pull/10062>`__)
26+
* `@stsewd <https://github.com/stsewd>`__: Proxito V2 (`#10044 <https://github.com/readthedocs/readthedocs.org/pull/10044>`__)
27+
* `@stsewd <https://github.com/stsewd>`__: Proxito: adapt unresolver to make it usable for proxito (`#10037 <https://github.com/readthedocs/readthedocs.org/pull/10037>`__)
28+
* `@agjohnson <https://github.com/agjohnson>`__: Add beta version of doc diff library for testing (`#9546 <https://github.com/readthedocs/readthedocs.org/pull/9546>`__)
29+
* `@davidfischer <https://github.com/davidfischer>`__: Support the new Google analytics gtag.js (`#7691 <https://github.com/readthedocs/readthedocs.org/pull/7691>`__)
30+
131
Version 9.7.0
232
-------------
333

34+
**This release contains one security fix. For more information, see:**
35+
36+
- `GHSA-h4cf-8gv8-4chf <https://github.com/readthedocs/readthedocs.org/security/advisories/GHSA-h4cf-8gv8-4chf>`__
37+
438
:Date: February 28, 2023
539

640
* `@humitos <https://github.com/humitos>`__: Celery: delete Telemetry data that's at most 3 months older (`#10079 <https://github.com/readthedocs/readthedocs.org/pull/10079>`__)
@@ -49,6 +83,10 @@ Version 9.6.0
4983
Version 9.5.0
5084
-------------
5185

86+
**This release contains one security fix. For more information, see:**
87+
88+
- `GHSA-mp38-vprc-7hf5 <https://github.com/readthedocs/readthedocs.org/security/advisories/GHSA-mp38-vprc-7hf5>`__
89+
5290
:Date: February 13, 2023
5391

5492
* `@agjohnson <https://github.com/agjohnson>`__: Bump to latest common (`#10019 <https://github.com/readthedocs/readthedocs.org/pull/10019>`__)
@@ -81,6 +119,10 @@ Version 9.5.0
81119
Version 9.4.0
82120
-------------
83121

122+
**This release contains one security fix. For more information, see:**
123+
124+
- `GHSA-5w8m-r7jm-mhp9 <https://github.com/readthedocs/readthedocs.org/security/advisories/GHSA-5w8m-r7jm-mhp9>`__
125+
84126
:Date: February 07, 2023
85127

86128
* `@agjohnson <https://github.com/agjohnson>`__: Fix ordering of filter for most recently built project (`#9992 <https://github.com/readthedocs/readthedocs.org/pull/9992>`__)

dockerfiles/nginx/proxito.conf.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ server {
8282
add_header Access-Control-Allow-Headers $access_control_allow_headers always;
8383
set $x_frame_options $upstream_http_x_frame_options;
8484
add_header X-Frame-Options $x_frame_options always;
85+
set $x_content_type_options $upstream_http_x_content_type_options;
86+
add_header X-Content-Type-Options $x_content_type_options always;
8587
# Minio sets this header on the response, and we don't want to copy it to the response
8688
proxy_hide_header Content-Security-Policy;
8789
set $content_security_policy $upstream_http_content_security_policy;

docs/_static/js/readthedocs-doc-diff.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/_templates/layout.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{% extends "!layout.html" %}
22

3+
{% block extrahead %}
4+
{{ super() }}
5+
6+
{% if READTHEDOCS %}
7+
<script defer data-domain="{{ plausible_domain }}" src="https://plausible.io/js/script.js"></script>
8+
{% endif %}
9+
{% endblock extrahead %}
310

411
{% block document %}
512
{{ super() }}

docs/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767

6868
master_doc = "index"
6969
copyright = "Read the Docs, Inc & contributors"
70-
version = "9.7.0"
70+
version = "9.8.0"
7171
release = version
7272
exclude_patterns = ["_build", "shared", "_includes"]
7373
default_role = "obj"
@@ -150,6 +150,9 @@
150150
html_css_files = ["css/custom.css", "css/sphinx_prompt_css.css"]
151151
html_js_files = ["js/expand_tabs.js"]
152152

153+
if os.environ.get("READTHEDOCS_VERSION_TYPE") == "external":
154+
html_js_files.append("js/readthedocs-doc-diff.js")
155+
153156
html_logo = "img/logo.svg"
154157
html_theme_options = {
155158
"logo_only": True,
@@ -160,6 +163,8 @@
160163
# TODO: remove once we support different rtd config
161164
# files per project.
162165
"conf_py_path": f"/docs/{docset}/",
166+
# Use to generate the Plausible "data-domain" attribute from the template
167+
"plausible_domain": f"{os.environ.get('READTHEDOCS_PROJECT')}.readthedocs.io",
163168
}
164169

165170
hoverxref_auto_ref = True

docs/user/automatic-redirects.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Good practice ✅
6161
keep original file names rather than going for low-impact URL renaming.
6262
Renaming an article's title is great for the reader and great for SEO,
6363
but this does not have to involve the URL.
64-
* Establish your understanding of the *latest* and *:term:`default version`* of your documentation at the beginning. Changing their meaning is very disruptive to incoming links.
64+
* Establish your understanding of the *latest* and :term:`default version` of your documentation at the beginning. Changing their meaning is very disruptive to incoming links.
6565
* Keep development versions :ref:`hidden <versions:Hidden>` so people do not find them on search engines by mistake.
6666
This is the best way to ensure that nobody links to URLs that are intended for development purposes.
6767
* Use a :ref:`version warning <versions:Version warning>` to ensure the reader is aware in case they are reading an old (archived) version.

docs/user/config-file/v2.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -751,13 +751,13 @@ check :ref:`config-file/v2:search.ignore`.
751751
search.ignore
752752
`````````````
753753

754-
Don't index files matching a pattern.
755-
This is, you won't see search results from these files.
754+
List of paths to ignore and exclude from the search index.
755+
Paths matched will not be included in search results.
756756

757757
:Type: ``list`` of patterns
758758
:Default: ``['search.html', 'search/index.html', '404.html', '404/index.html']``
759759

760-
Patterns are matched against the final html pages produced by the build
760+
Patterns are matched against the relative path of html files produced by the build
761761
(you should try to match `index.html`, not `docs/index.rst`).
762762
Patterns can include some special characters:
763763

@@ -771,13 +771,13 @@ Patterns can include some special characters:
771771
772772
search:
773773
ignore:
774-
# Ignore a single file
774+
# Ignore a single file in the root of the output directory
775775
- 404.html
776776
777777
# Ignore all files under the search/ directory
778778
- search/*
779779
780-
# Ignore all files that end with ref.html
780+
# Ignore all files named ref.html nested inside one or more sub-folders
781781
- '*/ref.html'
782782
783783
.. code-block:: yaml

docs/user/guides/cross-referencing-with-sphinx.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ with two markup options: reStructuredText and MyST (Markdown).
2929
- If you are not familiar with reStructuredText,
3030
check :doc:`sphinx:usage/restructuredtext/basics` for a quick introduction.
3131
- If you want to learn more about the MyST Markdown dialect,
32-
check out :doc:`myst-parser:syntax/syntax`.
32+
check out :doc:`myst-parser:syntax/reference`.
3333

3434
.. contents:: Table of contents
3535
:local:

docs/user/guides/jupyter.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ However, there are some differences between them:
331331
whereas MyST-NB uses `MyST-Parser`_
332332
to directly convert the Markdown text to docutils AST.
333333
Therefore, nbsphinx assumes `pandoc flavored Markdown <https://pandoc.org/MANUAL.html#pandocs-markdown>`_,
334-
whereas MyST-NB uses :doc:`MyST flavored Markdown <myst-parser:syntax/syntax>`.
334+
whereas MyST-NB uses :doc:`MyST flavored Markdown <myst-parser:index>`.
335335
Both Markdown flavors are mostly equal,
336336
but they have some differences.
337337
- nbsphinx executes each notebook during the parsing phase,

docs/user/guides/migrate-rest-myst.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ and some others in reStructuredText, for whatever reason.
2727
Luckily, Sphinx supports reading both types of markup at the same time without problems.
2828

2929
To start using MyST in your existing Sphinx project,
30-
first {ref}``install the `myst-parser` Python package <myst-parser:intro.md#installation>``
31-
and then {ref}`enable it on your configuration <myst-parser:intro.md#enable-myst-in-sphinx>`:
30+
first [install the `myst-parser` Python package](https://myst-parser.readthedocs.io/en/stable/intro.html#installation)
31+
and then [enable it on your configuration](https://myst-parser.readthedocs.io/en/stable/intro.html#enable-myst-in-sphinx):
3232

3333
```{code-block} py
3434
:caption: conf.py

docs/user/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ You can find out more about our all the :doc:`features </reference/features>` in
9191
First steps
9292
-----------
9393

94-
Are you new to software documentation
95-
or are you looking to use your existing docs with Read the Docs?
94+
Are you new to software documentation?
95+
Are you looking to use your existing docs with Read the Docs?
9696
Learn about documentation authoring tools such as Sphinx and MkDocs
9797
to help you create fantastic documentation for your project.
9898

docs/user/user-defined-redirects.rst

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
.. old label
2-
.. _User-defined Redirects:
3-
41
Custom and built-in redirects on Read the Docs
52
==============================================
63

@@ -16,7 +13,7 @@ the bad user experience of a 404 page is usually best to avoid.
1613
Allows for simple and long-term sharing of external references to your documentation.
1714

1815
`User-defined redirects`_ ⬇️
19-
Makes it easier to move contents around (see: )
16+
Makes it easier to move contents around
2017

2118
.. seealso::
2219

@@ -95,6 +92,8 @@ They are intended to be easy and short for people to type.
9592

9693
You can reach these docs at https://docs.rtfd.io.
9794

95+
.. old label
96+
.. _User-defined Redirects:
9897

9998
User-defined redirects
10099
----------------------

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "readthedocs",
3-
"version": "9.7.0",
3+
"version": "9.8.0",
44
"description": "Read the Docs build dependencies",
55
"author": "Read the Docs, Inc <[email protected]>",
66
"scripts": {

readthedocs/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Read the Docs."""
22

33

4-
__version__ = "9.7.0"
4+
__version__ = "9.8.0"

readthedocs/analytics/proxied_api.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88

99
from readthedocs.analytics.models import PageView
1010
from readthedocs.api.v2.permissions import IsAuthorizedToViewVersion
11+
from readthedocs.core.mixins import CDNCacheControlMixin
1112
from readthedocs.core.unresolver import UnresolverError, unresolve
1213
from readthedocs.core.utils.extend import SettingsOverrideObject
1314
from readthedocs.projects.models import Project
1415

1516

16-
class BaseAnalyticsView(APIView):
17+
class BaseAnalyticsView(CDNCacheControlMixin, APIView):
1718

1819
"""
1920
Track page views.
@@ -25,6 +26,9 @@ class BaseAnalyticsView(APIView):
2526
- absolute_uri: Full path with domain.
2627
"""
2728

29+
# We always want to hit our analytics endpoint,
30+
# so we capture all views/interactions.
31+
cache_response = False
2832
http_method_names = ['get']
2933
permission_classes = [IsAuthorizedToViewVersion]
3034

readthedocs/analytics/tests.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ def test_invalid_uri(self):
128128
self.client.get(url, HTTP_HOST=self.host)
129129
assert PageView.objects.all().count() == 0
130130

131+
def test_cache_headers(self):
132+
resp = self.client.get(self.url, HTTP_HOST=self.host)
133+
self.assertEqual(resp.status_code, 200)
134+
self.assertEqual(resp["CDN-Cache-Control"], "private")
135+
131136
def test_increase_page_view_count(self):
132137
assert (
133138
PageView.objects.all().count() == 0

readthedocs/api/v2/views/task_views.py

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,45 @@
11
"""Endpoints relating to task/job status, etc."""
22

33
import structlog
4-
4+
from django.core.cache import cache
55
from django.urls import reverse
6-
from redis import ConnectionError
76
from rest_framework import decorators, permissions
87
from rest_framework.renderers import JSONRenderer
98
from rest_framework.response import Response
109

11-
from readthedocs.core.utils.tasks import TaskNoPermission, get_public_task_data
1210
from readthedocs.oauth import tasks
1311

14-
1512
log = structlog.get_logger(__name__)
1613

17-
SUCCESS_STATES = ('SUCCESS',)
18-
FAILURE_STATES = (
19-
'FAILURE',
20-
'REVOKED',
21-
)
22-
FINISHED_STATES = SUCCESS_STATES + FAILURE_STATES
23-
STARTED_STATES = ('RECEIVED', 'STARTED', 'RETRY') + FINISHED_STATES
24-
25-
26-
def get_status_data(task_name, state, data, error=None):
27-
data = {
28-
'name': task_name,
29-
'data': data,
30-
'started': state in STARTED_STATES,
31-
'finished': state in FINISHED_STATES,
32-
# When an exception is raised inside the task, we keep this as SUCCESS
33-
# and add the exception message into the 'error' key
34-
'success': state in SUCCESS_STATES and error is None,
35-
}
36-
if error is not None:
37-
data['error'] = error
38-
return data
39-
4014

4115
@decorators.api_view(['GET'])
4216
@decorators.permission_classes((permissions.AllowAny,))
4317
@decorators.renderer_classes((JSONRenderer,))
4418
def job_status(request, task_id):
45-
try:
46-
task_name, state, public_data, error = get_public_task_data(
47-
request,
48-
task_id,
49-
)
50-
except (TaskNoPermission, ConnectionError):
51-
return Response(get_status_data('unknown', 'PENDING', {}),)
52-
return Response(get_status_data(task_name, state, public_data, error),)
19+
"""Retrieve Celery task function state from frontend."""
20+
# HACK: always poll up to N times and after that return the sync has
21+
# finished. This is a way to avoid re-enabling Celery result backend for now.
22+
# TODO remove this API and RemoteRepo sync UI when we have better auto syncing
23+
poll_n = cache.get(task_id, 0)
24+
poll_n += 1
25+
cache.set(task_id, poll_n, 5 * 60)
26+
finished = poll_n == 5
27+
28+
data = {
29+
"name": "sync_remote_repositories",
30+
"data": {},
31+
"started": True,
32+
"finished": finished,
33+
"success": finished,
34+
}
35+
return Response(data)
5336

5437

5538
@decorators.api_view(['POST'])
5639
@decorators.permission_classes((permissions.IsAuthenticated,))
5740
@decorators.renderer_classes((JSONRenderer,))
5841
def sync_remote_repositories(request):
42+
"""Trigger a re-sync of remote repositories for the user."""
5943
result = tasks.sync_remote_repositories.delay(user_id=request.user.id,)
6044
task_id = result.task_id
6145
return Response({

readthedocs/builds/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,16 @@ def is_private(self):
217217
return self.project.external_builds_privacy_level == PRIVATE
218218
return self.privacy_level == PRIVATE
219219

220+
@property
221+
def is_public(self):
222+
"""
223+
Check if the version is public (taking external versions into consideration).
224+
225+
This is basically ``is_private`` negated,
226+
``is_private`` understands both normal and external versions
227+
"""
228+
return not self.is_private
229+
220230
@property
221231
def is_external(self):
222232
return self.type == EXTERNAL

0 commit comments

Comments
 (0)