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

Hosting: manual integrations via build contract #10127

Merged
merged 43 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5b28071
Hosting: manual integrations via build contract
humitos Mar 8, 2023
e18b40f
Use a single script to load everything
humitos Mar 8, 2023
7754d5f
Include Read the Docs analytics to integrations
humitos Mar 8, 2023
2925ed9
Initial work for hosting features
humitos Mar 8, 2023
3385649
External version banner and doc-diff integration
humitos Mar 8, 2023
1e391b8
Old version warning
humitos Mar 8, 2023
6afca0b
Do not inject doc-diff on search page
humitos Mar 8, 2023
7ce98a4
Inject old version warning only for non-external versions
humitos Mar 8, 2023
3ca96ec
Comments!
humitos Mar 8, 2023
f4f1268
More comments
humitos Mar 8, 2023
a596512
Build: pass `PATH` environment variable to Docker container
humitos Mar 9, 2023
33fdb2b
Lint: for some reason fails at CircleCI otherwise
humitos Mar 9, 2023
4ced5c3
Merge branch 'humitos/build-cmd-environment' of github.com:readthedoc…
humitos Mar 9, 2023
ea2af4c
Feature flag for new hosting integrations
humitos Mar 10, 2023
79b7393
Load `readthedocs-build.yaml` and generate `readthedocs-data.html`
humitos Mar 10, 2023
17effaf
Load READTHEDOCS_DATA async
humitos Mar 10, 2023
2b9cdbf
Absolute proxied API path
humitos Mar 10, 2023
0116f41
Remove duplicated code
humitos Mar 10, 2023
d5130cc
New approach using `readthedocs-client.js` and `/_/readthedocs-config…
humitos Mar 11, 2023
761e3b6
Do not require `readthedocs-build.YAML` for now
humitos Mar 11, 2023
bd9f70e
Expand the JSON response with more data
humitos Mar 13, 2023
842a228
Remove non-required files and rely on `readthedocs-client.js` only
humitos Mar 13, 2023
2ad30cc
Improve helper text
humitos Mar 13, 2023
89662fa
Builds: save `readthedocs-build.yaml` into database
humitos Mar 13, 2023
f83eee6
Use `Version.build_data` from the endpoint
humitos Mar 13, 2023
d14115a
Flyout: return data required to generate flyout dynamically
humitos Mar 13, 2023
067bb4c
Updates to the API
humitos Mar 14, 2023
17c1af3
Minor updates
humitos Mar 15, 2023
53366aa
Update the javascript client compiled version
humitos Mar 15, 2023
0f89186
doc-diff object returned
humitos Mar 16, 2023
48de597
Build: check if the YAML file exists before trying to open it
humitos Mar 16, 2023
4b05e77
Proxito: don't inject the header if the feature is turned off
humitos Mar 16, 2023
e90af75
Merge branch 'main' of github.com:readthedocs/readthedocs.org into hu…
humitos Mar 16, 2023
364de9c
Test: add hosting integrations tests
humitos Mar 16, 2023
c1cf8cb
Remove JS
humitos Mar 20, 2023
3930915
Load the javascript from a local server for now
humitos Mar 20, 2023
2d7b6fe
Update URL to remove .json from it
humitos Mar 20, 2023
ab43635
Remove non-required f-string
humitos Mar 20, 2023
85ab2e7
Allow saving `build_data` via API endpoint
humitos Mar 20, 2023
3439e24
Merge branch 'main' of github.com:readthedocs/readthedocs.org into hu…
humitos Mar 20, 2023
6154c7f
Lint
humitos Mar 20, 2023
0e8f245
Migrate nodejs installation to asdf
humitos Mar 20, 2023
a6c5977
Change port to match `npm run dev` from readthedocs-client
humitos Mar 20, 2023
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
7 changes: 7 additions & 0 deletions dockerfiles/nginx/proxito.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ server {
proxy_hide_header Content-Security-Policy;
set $content_security_policy $upstream_http_content_security_policy;
add_header Content-Security-Policy $content_security_policy always;

# Inject our own script dynamically
# TODO: decide where is the best place to do this
sub_filter '</head>' '<script language="javascript" src="http://devthedocs.org/static/core/js/integrations.js"></script>\n</head>';
# sub_filter_types text/html;
sub_filter_last_modified on;
sub_filter_once on;
}
humitos marked this conversation as resolved.
Show resolved Hide resolved

# Serve 404 pages here
Expand Down
26 changes: 26 additions & 0 deletions readthedocs/core/static/core/js/integrations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Unique entry point that our servers will inject

let link = document.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", "/_/static/css/readthedocs-doc-embed.css");
document.head.appendChild(link);

let embed = document.createElement("script");
embed.setAttribute("async", "async");
embed.setAttribute("src", "/_/static/javascript/readthedocs-doc-embed.js");
document.head.appendChild(embed);

let analytics = document.createElement("script");
analytics.setAttribute("async", "async");
analytics.setAttribute("src", "/_/static/javascript/readthedocs-analytics.js");
document.head.appendChild(analytics);

let hosting = document.createElement("script");
hosting.setAttribute("async", "async");
hosting.setAttribute("src", "/_/static/core/js/readthedocs-hosting.js");
document.head.appendChild(hosting);

// TODO: insert search-as-you-type once it becomes a JS library
// decoupled from Sphinx.
// See https://github.com/readthedocs/readthedocs-sphinx-search/issues/67
1 change: 1 addition & 0 deletions readthedocs/core/static/core/js/readthedocs-doc-diff.js

Large diffs are not rendered by default.

75 changes: 75 additions & 0 deletions readthedocs/core/static/core/js/readthedocs-hosting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
function injectExternalVersionWarning() {
// TODO: make all these banners (injected HTML) templates that users can override with their own.
// This way, we allow customization of the look&feel without compromising the logic.
let admonition = `
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>
This page
<a class="reference external" href="${ window.location.protocol }//${ window.location.hostname }/projects/${ READTHEDOCS_DATA.project }/builds/${ READTHEDOCS_DATA.build.id }/">was created </a>
from a pull request
(<a class="reference external" href="${ READTHEDOCS_DATA.repository_url }/pull/${ READTHEDOCS_DATA.version }">#${ READTHEDOCS_DATA.version }</a>).
</p>
</div>
`;

let main = document.querySelector('[role=main]');
let node = document.createElement("div");
node.innerHTML = admonition;
main.insertBefore(node, main.firstChild);
}

function injectDocDiff() {
let docdiff = document.createElement("script");
docdiff.setAttribute("async", "async");
docdiff.setAttribute("src", "/_/static/core/js/readthedocs-doc-diff.js");
document.head.appendChild(docdiff);
}

function injectOldVersionWarning() {
// TODO: compute if the user is reading the latest version or not before showing the warning.
let admonition = `
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>
This page documents version
<a class="reference" href="${ window.location.protocol }//${ window.location.hostname }/${ READTHEDOCS_DATA.language }/${ READTHEDOCS_DATA.version }/">${ READTHEDOCS_DATA.version }</a>.
The latest version is
<a class="reference" href="${ window.location.protocol }//${ window.location.hostname }/${ READTHEDOCS_DATA.language }/${ READTHEDOCS_DATA.version }/">${ READTHEDOCS_DATA.version }</a>.
</p>
</div>
`;

// Borrowed and adapted from:
// https://github.com/readthedocs/readthedocs.org/blob/7ce98a4d4f34a4c1845dc6e3e0e5112af7c39b0c/readthedocs/core/static-src/core/js/doc-embed/version-compare.js#L1
let main = document.querySelector('[role=main]');
let node = document.createElement("div");
node.innerHTML = admonition;
main.insertBefore(node, main.firstChild);
}


window.addEventListener("load", (event) => {
// TODO: use the proxied API here
// "repository_url" could be retrived using the API, but there are some CORS issues and design decisions
// that it's probably smart to avoid and just rely on a fixed value from the build output :)
if (READTHEDOCS_DATA.build.external_version === true) {
injectExternalVersionWarning();

if (READTHEDOCS_DATA.features.docdiff.enabled === true) {
if(!window.location.pathname.endsWith("search.html")) {
// Avoid injecting doc-diff on search page because it doesn't make sense
injectDocDiff();
}
}
}
else {
// TODO: there some data we need from `/api/v2/footer_html/`,
// like `is_highest` and `show_version_warning`.
// However, this call is happening inside the `readthedocs-doc-embed.js`.
// We could make the call again here for now as demo,
// but it would be good to refactor that code
// Inject old version warning only for non-external versions
injectOldVersionWarning();
}
});