From 73d573d715979df0a37bb81e7e3c9d5607ff469e Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 21 Mar 2023 10:56:56 +0100 Subject: [PATCH 1/8] Build: export `READTHEDOCS_CANONICAL_URL` variable This variable communicates what's the canonical URL for the version it's running the build. It will allow doctool/theme authors to implement the correct HTML tag required: ``` ``` Note the final `href` on each page will be `READTHEDOCS_CANONICAL_URL` + `page`. Closes https://github.com/readthedocs/readthedocs-ops/issues/1320 --- readthedocs/api/v2/serializers.py | 10 ++++++++++ readthedocs/builds/models.py | 3 ++- readthedocs/doc_builder/director.py | 6 ++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/readthedocs/api/v2/serializers.py b/readthedocs/api/v2/serializers.py index aad6ac57c43..4a26b164e62 100644 --- a/readthedocs/api/v2/serializers.py +++ b/readthedocs/api/v2/serializers.py @@ -5,6 +5,7 @@ from rest_framework import serializers from readthedocs.api.v2.utils import normalize_build_command +from readthedocs.builds.constants import EXTERNAL from readthedocs.builds.models import Build, BuildCommandResult, Version from readthedocs.oauth.models import RemoteOrganization, RemoteRepository from readthedocs.projects.models import Domain, Project @@ -124,11 +125,20 @@ class VersionAdminSerializer(VersionSerializer): """Version serializer that returns admin project data.""" project = ProjectAdminSerializer() + canonical_url = serializers.SerializerMethodField() build_data = serializers.JSONField(required=False, write_only=True) + def get_canonical_url(self, obj): + return obj.project.get_docs_url( + lang_slug=obj.project.language, + version_slug=obj.slug, + external=obj.type == EXTERNAL, + ) + class Meta(VersionSerializer.Meta): fields = VersionSerializer.Meta.fields + [ "build_data", + "canonical_url", ] diff --git a/readthedocs/builds/models.py b/readthedocs/builds/models.py index dc83b11c34b..cf35e24f841 100644 --- a/readthedocs/builds/models.py +++ b/readthedocs/builds/models.py @@ -601,7 +601,8 @@ class Meta: proxy = True def __init__(self, *args, **kwargs): - self.project = APIProject(**kwargs.pop('project', {})) + self.project = APIProject(**kwargs.pop("project", {})) + self.canonical_url = kwargs.pop("canonical_url", None) # These fields only exist on the API return, not on the model, so we'll # remove them to avoid throwing exceptions due to unexpected fields for key in ['resource_uri', 'absolute_url', 'downloads']: diff --git a/readthedocs/doc_builder/director.py b/readthedocs/doc_builder/director.py index f42a5548752..4d8f3edc3dc 100644 --- a/readthedocs/doc_builder/director.py +++ b/readthedocs/doc_builder/director.py @@ -615,6 +615,12 @@ def get_build_env_vars(self): } ) + env.update( + { + "READTHEDOCS_CANONICAL_URL": self.data.version.canonical_url, + } + ) + # Update environment from Project's specific environment variables, # avoiding to expose private environment variables # if the version is external (i.e. a PR build). From d3f1bff0df39bb164aafd9839b2f06c431099ac5 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 21 Mar 2023 11:04:27 +0100 Subject: [PATCH 2/8] Docs: document `READTHEDOCS_CANONICAL_URL` Add it to the reference page. --- docs/user/reference/environment-variables.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/user/reference/environment-variables.rst b/docs/user/reference/environment-variables.rst index 1fe48af3f91..3de5d343567 100644 --- a/docs/user/reference/environment-variables.rst +++ b/docs/user/reference/environment-variables.rst @@ -44,6 +44,15 @@ All :doc:`build processes ` have the following environment variables au :Example: ``/home/docs/checkouts/readthedocs.org/user_builds/project/envs/version`` +.. envvar:: READTHEDOCS_CANONICAL_URL + + Canonical URL for the version it's currently building. + If the project has configured a :doc:`custom domain ` (e.g. ``docs.example.com``) it will be used in the resulting canonical URL. + Otherwise, the default domain will be exposed (e.g. ``.readthedocs.io``) + + :Example: ``https://docs.example.com/en/latest/`` + :Example: ``https://docs.readthedocs.io/ja/stable/`` + .. seealso:: :doc:`/environment-variables` From 39c1fd3359ede3b89230002e7b728ee9c62aca68 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 21 Mar 2023 12:03:29 +0100 Subject: [PATCH 3/8] Docs: add another example --- docs/user/reference/environment-variables.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/user/reference/environment-variables.rst b/docs/user/reference/environment-variables.rst index 3de5d343567..c424511b231 100644 --- a/docs/user/reference/environment-variables.rst +++ b/docs/user/reference/environment-variables.rst @@ -52,6 +52,7 @@ All :doc:`build processes ` have the following environment variables au :Example: ``https://docs.example.com/en/latest/`` :Example: ``https://docs.readthedocs.io/ja/stable/`` + :Example: ``https://example--17.org.readthedocs.build/fr/17/`` .. seealso:: From 58c49c3c5c39542323cb1062ce5867d7b8ff372c Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 21 Mar 2023 12:04:04 +0100 Subject: [PATCH 4/8] Test: check the `READTHEDOCS_CANONICAL_URL` is present --- readthedocs/projects/tests/test_build_tasks.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readthedocs/projects/tests/test_build_tasks.py b/readthedocs/projects/tests/test_build_tasks.py index d9a637edc74..11b7212d60a 100644 --- a/readthedocs/projects/tests/test_build_tasks.py +++ b/readthedocs/projects/tests/test_build_tasks.py @@ -301,6 +301,11 @@ def test_get_env_vars(self, load_yaml_config, build_environment, config, externa # Local and Circle are different values. # We only check it's present, but not its value. READTHEDOCS_VIRTUALENV_PATH=mock.ANY, + READTHEDOCS_CANONICAL_URL=self.project.get_docs_url( + lang_slug=self.project.language, + version_slug=self.version.slug, + external=external, + ), ) if not external: expected_build_env_vars["PRIVATE_TOKEN"] = "a1b2c3" From 04088d5478f3687dfe9a692e18948f2c51a4d538 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 21 Mar 2023 12:06:29 +0100 Subject: [PATCH 5/8] Apply suggestions from code review Co-authored-by: Benjamin Balder Bach --- docs/user/reference/environment-variables.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/user/reference/environment-variables.rst b/docs/user/reference/environment-variables.rst index c424511b231..1b60a2ee107 100644 --- a/docs/user/reference/environment-variables.rst +++ b/docs/user/reference/environment-variables.rst @@ -46,9 +46,11 @@ All :doc:`build processes ` have the following environment variables au .. envvar:: READTHEDOCS_CANONICAL_URL - Canonical URL for the version it's currently building. + Canonical base URL for the version that is built. If the project has configured a :doc:`custom domain ` (e.g. ``docs.example.com``) it will be used in the resulting canonical URL. - Otherwise, the default domain will be exposed (e.g. ``.readthedocs.io``) + Otherwise, your project's :ref:`default subdomain ` will be used. + +The path for the language and version is appended to the domain, so the final canonical base URLs can look like the following examples. :Example: ``https://docs.example.com/en/latest/`` :Example: ``https://docs.readthedocs.io/ja/stable/`` From 5fde482ea7082dd6b3b3686bfe35d21e1b5afcbd Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 21 Mar 2023 12:17:27 +0100 Subject: [PATCH 6/8] Update docs/user/reference/environment-variables.rst Co-authored-by: Benjamin Balder Bach --- docs/user/reference/environment-variables.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/reference/environment-variables.rst b/docs/user/reference/environment-variables.rst index 1b60a2ee107..0087d6b1468 100644 --- a/docs/user/reference/environment-variables.rst +++ b/docs/user/reference/environment-variables.rst @@ -50,7 +50,7 @@ All :doc:`build processes ` have the following environment variables au If the project has configured a :doc:`custom domain ` (e.g. ``docs.example.com``) it will be used in the resulting canonical URL. Otherwise, your project's :ref:`default subdomain ` will be used. -The path for the language and version is appended to the domain, so the final canonical base URLs can look like the following examples. + The path for the language and version is appended to the domain, so the final canonical base URLs can look like the following examples: :Example: ``https://docs.example.com/en/latest/`` :Example: ``https://docs.readthedocs.io/ja/stable/`` From 5bb3d74db63e3a45af788e04b46a6f0344155891 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 21 Mar 2023 12:31:27 +0100 Subject: [PATCH 7/8] Docs: fix references --- docs/user/canonical-urls.rst | 2 +- docs/user/custom-domains.rst | 2 +- docs/user/reference/environment-variables.rst | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/user/canonical-urls.rst b/docs/user/canonical-urls.rst index 520b9a701ee..eac1a40e8c4 100644 --- a/docs/user/canonical-urls.rst +++ b/docs/user/canonical-urls.rst @@ -34,7 +34,7 @@ The canonical URL takes the following into account: * The default version of your project (usually "latest" or "stable"). * The canonical :doc:`custom domain ` if you have one, - otherwise the default :ref:`subdomain ` will be used. + otherwise the default :ref:`subdomain ` will be used. For example, if you have a project named ``example-docs`` with a custom domain ``https://docs.example.com``, diff --git a/docs/user/custom-domains.rst b/docs/user/custom-domains.rst index 4f2ca51cbfa..3a13b136e05 100644 --- a/docs/user/custom-domains.rst +++ b/docs/user/custom-domains.rst @@ -5,7 +5,7 @@ You can serve your documentation project from your own domain, for instance ``docs.example.com``. This is great for maintaining a consistent brand for your product and its documentation. -.. _default_subdomain: +.. _default-subdomain: .. rubric:: Default subdomains diff --git a/docs/user/reference/environment-variables.rst b/docs/user/reference/environment-variables.rst index 0087d6b1468..68bbfb532af 100644 --- a/docs/user/reference/environment-variables.rst +++ b/docs/user/reference/environment-variables.rst @@ -48,8 +48,8 @@ All :doc:`build processes ` have the following environment variables au Canonical base URL for the version that is built. If the project has configured a :doc:`custom domain ` (e.g. ``docs.example.com``) it will be used in the resulting canonical URL. - Otherwise, your project's :ref:`default subdomain ` will be used. - + Otherwise, your project's :ref:`default subdomain ` will be used. + The path for the language and version is appended to the domain, so the final canonical base URLs can look like the following examples: :Example: ``https://docs.example.com/en/latest/`` From 4687f094413f57100323cdabfb52c948ff202d33 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 21 Mar 2023 12:37:49 +0100 Subject: [PATCH 8/8] Test: check for `canonical_url` on Version endpoint --- readthedocs/rtd_tests/tests/test_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index 0063f76ab40..78cbc24983d 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -2442,6 +2442,7 @@ def test_get_version_by_id(self): "built": False, "id": 18, "active": True, + "canonical_url": "http://readthedocs.org/docs/pip/en/0.8/", "project": { "analytics_code": None, "analytics_disabled": False,