-
-
Notifications
You must be signed in to change notification settings - Fork 29
Served both documentation majors from one combined site built on every branch. #3052
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
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
620c497
Fixed the documentation build breaking on merge to main.
AlexSkrypnyk 53e740e
Assembled the versioned docs into a disposable workspace.
AlexSkrypnyk 05dbc90
Addressed code review: corrected the 'assemble-docs' usage description.
AlexSkrypnyk 85445b1
Served each major's static assets alongside its documentation.
AlexSkrypnyk b35d25f
Built the combined documentation site in a single disposable directory.
AlexSkrypnyk d87f84e
Installed the combined site's own dependencies instead of linking them.
AlexSkrypnyk 9a704dd
Drove the combined docs site from an environment variable.
AlexSkrypnyk fb822ca
Built the combined docs site on every branch and moved version resolu…
AlexSkrypnyk ae3ac8f
Re-triggered CI to clear a flaky check.
AlexSkrypnyk 4147545
Addressed code review: decoded served paths with 'rawurldecode()'.
AlexSkrypnyk 50c685b
Sourced each major's documentation from the branch that ships it.
AlexSkrypnyk 7b2e9c4
Addressed code review: kept the other major's binary through the stat…
AlexSkrypnyk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # The combined documentation site built by `ahoy docs-combined`. It is a | ||
| # generated copy of `docs/` carrying both majors, rebuilt from scratch on every | ||
| # run and safe to delete at any time. | ||
| /docs_combined |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| #!/usr/bin/env bash | ||
| ## | ||
| # Assemble the combined documentation site, serving both majors from one build. | ||
| # | ||
| # Produces a complete, self-contained Docusaurus site in 'docs_combined/'. The | ||
| # current major is served at '/docs' with its assets at '/img'; the other major | ||
| # is served at '/docs/v{other}' with its assets at '/v{other}/img'. | ||
| # | ||
| # This checkout supplies the documentation for the major it ships | ||
| # ('VORTEX_DOCS_MAJOR'); the other major is read from its own branch. So a | ||
| # branch off 'main' is built as the current major and '{other}.x' is fetched, | ||
| # while a branch off '{other}.x' is built as the other major and 'main' is | ||
| # fetched. Everything the assembly writes stays inside 'docs_combined/', which | ||
| # is disposable - 'docs/' is only ever read. | ||
| # | ||
| # @usage | ||
| # cd .vortex && ./docs/.utils/assemble-combined-docs.sh | ||
|
|
||
| set -eu | ||
| set -o pipefail | ||
| [ "${VORTEX_DEBUG-}" = "1" ] && set -x | ||
|
|
||
| # The major served as the site's default version at the bare '/docs'. | ||
| VORTEX_CURRENT_MAJOR="${VORTEX_CURRENT_MAJOR:-1}" | ||
|
|
||
| # The major this checkout ships. Defaults to the current major, which is the | ||
| # major that lives on the default branch. | ||
| VORTEX_DOCS_MAJOR="${VORTEX_DOCS_MAJOR:-${VORTEX_CURRENT_MAJOR}}" | ||
|
|
||
| ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../" && pwd)" | ||
| DOCS_DIR="${ROOT_DIR}/.vortex/docs" | ||
| COMBINED_DIR="${ROOT_DIR}/.vortex/docs_combined" | ||
|
|
||
| sed_opts=(-i) && [ "$(uname)" = "Darwin" ] && sed_opts=(-i '') | ||
|
|
||
| for major in "${VORTEX_CURRENT_MAJOR}" "${VORTEX_DOCS_MAJOR}"; do | ||
| case "${major}" in | ||
| 1 | 2) ;; | ||
| *) | ||
| echo "ERROR: Invalid major '${major}'. Expected 1 or 2." >&2 | ||
| exit 1 | ||
| ;; | ||
| esac | ||
| done | ||
|
|
||
| case "${VORTEX_CURRENT_MAJOR}" in | ||
| 1) other_major=2 ;; | ||
| 2) other_major=1 ;; | ||
| esac | ||
|
|
||
| # The current major lives on the default branch; every other major lives on its | ||
| # own '{N}.x' branch. Whichever side this checkout does not supply is fetched. | ||
| if [ "${VORTEX_DOCS_MAJOR}" = "${VORTEX_CURRENT_MAJOR}" ]; then | ||
| default_ref="" | ||
| other_ref="origin/${other_major}.x" | ||
| else | ||
| default_ref="origin/main" | ||
| other_ref="" | ||
| fi | ||
|
|
||
| fetch_ref="${default_ref}${other_ref}" | ||
| fetch_branch="${fetch_ref#origin/}" | ||
|
|
||
| git -C "${ROOT_DIR}" fetch origin "${fetch_branch}" --depth=1 || { | ||
| echo "ERROR: Failed to fetch the ${fetch_branch} branch." >&2 | ||
| exit 1 | ||
| } | ||
|
|
||
| git -C "${ROOT_DIR}" rev-parse --verify "${fetch_ref}" >/dev/null || { | ||
| echo "ERROR: The ${fetch_branch} branch does not exist." >&2 | ||
| exit 1 | ||
| } | ||
|
|
||
| ## | ||
| # Replace a directory with a major's documentation tree. | ||
| # | ||
| # $1 - directory to populate. | ||
| # $2 - subdirectory of the documentation to read ('content' or 'static'). | ||
| # $3 - git ref to read from, or empty to read this checkout. | ||
| ## | ||
| populate() { | ||
| local dest="${1}" | ||
| local tree="${2}" | ||
| local ref="${3}" | ||
|
|
||
| rm -rf "${dest}" | ||
| mkdir -p "${dest}" | ||
|
|
||
| if [ -z "${ref}" ]; then | ||
| cp -R "${DOCS_DIR}/${tree}/." "${dest}/" | ||
| else | ||
| git -C "${ROOT_DIR}" archive "${ref}:.vortex/docs/${tree}" | tar -x -C "${dest}" | ||
| fi | ||
|
|
||
| [ -n "$(ls -A "${dest}")" ] || { | ||
| echo "ERROR: No '${tree}' found in ${ref:-this checkout}." >&2 | ||
| exit 1 | ||
| } | ||
| } | ||
|
|
||
| rm -rf "${COMBINED_DIR}" | ||
| mkdir -p "${COMBINED_DIR}" | ||
|
|
||
| # The combined site is a copy of this one, so it builds with the same config, | ||
| # components and sidebars. Generated and installed directories are excluded and | ||
| # rebuilt inside it, so it depends on nothing outside itself. | ||
| rsync -a \ | ||
| --exclude '/node_modules' \ | ||
| --exclude '/build' \ | ||
| --exclude '/.docusaurus' \ | ||
| --exclude '/.docusaurus-dev' \ | ||
| --exclude '/.logs' \ | ||
| "${DOCS_DIR}/" "${COMBINED_DIR}/" | ||
|
|
||
| yarn --cwd="${COMBINED_DIR}" install --frozen-lockfile | ||
|
|
||
| # Snapshot the current major, whose assets stay at the bare static root. | ||
| populate "${COMBINED_DIR}/content" content "${default_ref}" | ||
| populate "${COMBINED_DIR}/static" static "${default_ref}" | ||
|
|
||
| # 'VORTEX_DOCS_COMBINED' stays unset here: the snapshot the combined config | ||
| # expects does not exist until this command creates it. | ||
| yarn --cwd="${COMBINED_DIR}" docusaurus docs:version "${VORTEX_CURRENT_MAJOR}.x" | ||
|
|
||
| # Hand 'content/' over to the other major. Both majors record their own demo | ||
| # videos and diagrams under the same 'static/img' names, so the other major's | ||
| # assets get their own '/v{other}' prefix instead of losing to the current | ||
| # major's copies. | ||
| other_static_dir="${COMBINED_DIR}/static/v${other_major}" | ||
|
|
||
| # The other major's binary is built into 'static/v{other}' before the assembly | ||
| # runs and is not tracked on any branch, so replacing that directory with the | ||
| # branch's own static tree would discard it. | ||
| staged_other_install="${DOCS_DIR}/static/v${other_major}/install" | ||
| [ -f "${staged_other_install}" ] || staged_other_install="" | ||
|
|
||
| populate "${COMBINED_DIR}/content" content "${other_ref}" | ||
| populate "${other_static_dir}" static "${other_ref}" | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| [ -z "${staged_other_install}" ] || cp "${staged_other_install}" "${other_static_dir}/install" | ||
|
|
||
| # Every branch authors its docs against the bare '/docs' mount, so an absolute | ||
| # link lands on the current major once the content is served at '/docs/v{other}'. | ||
| # Re-point those links at the major they were written for. A link that already | ||
| # names a version is left as authored, so the alternation skips '/v' followed by | ||
| # a digit. | ||
| find "${COMBINED_DIR}/content" -type f \( -name '*.md' -o -name '*.mdx' \) -exec \ | ||
| sed -E "${sed_opts[@]}" "s%\]\(/docs([)#?]|/[^v]|/v[^0-9])%](/docs/v${other_major}\1%g" {} + | ||
|
|
||
| # Asset references are written against the bare static root for the same reason. | ||
| # Each directory the other major ships is remapped, so a new asset directory on | ||
| # that branch is carried over without editing this script. Markdown targets and | ||
| # JSX attribute values are the two forms an asset path appears in. | ||
| for asset_dir in "${other_static_dir}"/*/; do | ||
| [ -d "${asset_dir}" ] || continue | ||
|
|
||
| asset_name="$(basename "${asset_dir}")" | ||
|
|
||
| find "${COMBINED_DIR}/content" -type f \( -name '*.md' -o -name '*.mdx' \) -exec \ | ||
| sed -E "${sed_opts[@]}" "s%([\"'(])/${asset_name}/%\1/v${other_major}/${asset_name}/%g" {} + | ||
| done | ||
|
|
||
| VORTEX_DOCS_COMBINED=1 VORTEX_CURRENT_MAJOR="${VORTEX_CURRENT_MAJOR}" yarn --cwd="${COMBINED_DIR}" run build | ||
|
|
||
| echo "Combined documentation site built at ${COMBINED_DIR}/build" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| <?php | ||
|
|
||
| /** | ||
| * @file | ||
| * Router for the PHP built-in server serving a built Docusaurus site. | ||
| * | ||
| * Docusaurus emits a directory per route, so a request without a trailing | ||
| * slash has to resolve to that directory's 'index.html'. The built-in server | ||
| * only does so for a trailing slash, and returns its own 404 page rather than | ||
| * the site's. | ||
| * | ||
| * @usage | ||
| * php -S localhost:8000 -t <build-dir> serve-router.php | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| $doc_root = $_SERVER['DOCUMENT_ROOT']; | ||
| $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); | ||
| $path = is_string($path) ? rawurldecode($path) : '/'; | ||
|
|
||
| // Reject traversal outside the build directory before touching the filesystem. | ||
| if (str_contains($path, '..')) { | ||
| http_response_code(400); | ||
|
|
||
| return TRUE; | ||
| } | ||
|
|
||
| $target = $doc_root . $path; | ||
|
|
||
| // Serve an existing file as-is and let the server set the content type. | ||
| if (is_file($target)) { | ||
| return FALSE; | ||
| } | ||
|
|
||
| $index = rtrim($target, '/') . '/index.html'; | ||
|
|
||
| if (is_file($index)) { | ||
| header('Content-Type: text/html; charset=UTF-8'); | ||
| readfile($index); | ||
|
|
||
| return TRUE; | ||
| } | ||
|
|
||
| // Fall back to the site's own 404 page so navigation errors look like the site. | ||
| $not_found = $doc_root . '/404.html'; | ||
|
|
||
| http_response_code(404); | ||
|
|
||
| if (is_file($not_found)) { | ||
| header('Content-Type: text/html; charset=UTF-8'); | ||
| readfile($not_found); | ||
| } | ||
|
|
||
| return TRUE; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.