Skip to content

Commit

Permalink
support multiple versions for docs (nasa#675)
Browse files Browse the repository at this point in the history
  • Loading branch information
trey0 authored Feb 9, 2023
1 parent a3ae212 commit 967c098
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 20 deletions.
84 changes: 67 additions & 17 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name: Build and Push Documentation to gh-pages Branch

on:
push:
branches: ['develop']
branches: ['develop', 'master', 'ros2']
workflow_dispatch:

jobs:
Expand All @@ -16,31 +16,81 @@ jobs:
uses: actions/checkout@v3
with:
path: repo/

- name: Build docker image with dependencies + build docs
run: docker build repo -f repo/scripts/docker/documentation.Dockerfile
-t astrobee:documentation

- name: Checkout gh-pages
uses: actions/checkout@v3
with:
path: docs/
path: gh-pages/
ref: gh-pages
- name: Build docker image with dependencies + build docs
run: docker build repo -f repo/scripts/docker/documentation.Dockerfile
-t astrobee:documentation

- name: Replace old documentation with new
- name: Create/replace documentation for the current branch
run: |
(cd docs && git rm -r "*")
cp repo/doc/documentation.html docs/index.html
cp repo/doc/documentation.html docs/documentation.html
cp repo/doc/README.md docs/README.md
docker cp $(docker create --rm astrobee:documentation):/repo/doc/html docs/html
set -x
export BRANCH=$(cd repo && git branch --show-current)
# Make gh-pages checkout an orphan commit so we don't keep useless history.
(cd gh-pages && git checkout --orphan fresh)
# Install generated docs to a version folder based on branch name.
(cd gh-pages && git rm -rf --ignore-unmatch "v/$BRANCH")
mkdir -p gh-pages/v/
docker cp $(docker create --rm astrobee:documentation):/repo/doc/html "gh-pages/v/$BRANCH"
(cd gh-pages && git add --all "v/$BRANCH")
if [ "$BRANCH" == "develop" ]; then
# Update the few files at root level (mostly redirects)
(cd gh-pages && git rm -f --ignore-unmatch index.html documentation.html README.md 404.html .nojekyll)
cp repo/doc/documentation.html gh-pages/index.html
cp repo/doc/documentation.html gh-pages/documentation.html
cp repo/doc/README.md gh-pages/
cp repo/doc/404.html gh-pages/
touch gh-pages/.nojekyll
cp repo/doc/style/doc_version_select.js gh-pages/
(cd gh-pages && git add index.html documentation.html README.md 404.html .nojekyll doc_version_select.js)
# Set up HTML redirect to generated docs in the legacy path to
# avoid broken URL references
(cd gh-pages && git rm -rf --ignore-unmatch html)
python repo/doc/scripts/copy_html_link.py -v gh-pages/v/develop gh-pages/html
(cd gh-pages && git add --all html)
fi
# If the commit is tagged, copy generated docs to a version
# folder based on the tag. Copy rather than symlink so the tag
# folder will remain valid later when the branch folder is
# updated. Note: If you want to manually remove an obsolete docs
# version, use git to check out the gh-pages branch, remove the
# relevant folder, and push back to origin. Also, this action
# only triggers when the branch is pushed, and it detects only
# the tags that are present at that time. So you should either
# (1) push the branch and its tag in the same push call
# (easiest), or (2) manually trigger the CI workflow to run on
# the relevant branch again, after it has been tagged.
(cd repo && git fetch origin --tags)
for tag in $(cd repo && git tag --points-at HEAD | xargs echo); do
(cd gh-pages && git rm -rf --ignore-unmatch "v/$tag")
cp -r "gh-pages/v/$BRANCH" "gh-pages/v/$tag"
(cd gh-pages && git add --all "v/$tag")
done
# Auto-detect which docs versions are available. The script here
# has additional logic to ensure that develop, master, and ros2
# are at the beginning of the list if they are present.
all_versions=$(ls "gh-pages/v/" | sort | perl -e '@dirs = <STDIN>; chomp @dirs; %dirs_hash = map { $_ => 1 } @dirs; @head = grep { exists($dirs_hash{$_}) } ("develop", "master", "ros2"); %head_hash = map { $_ => 1 } @head; @tail = grep { !exists($head_hash{$_}) } @dirs; @versions = (@head, @tail); print "var allVersions = [\"", join("\", \"",@versions), "\"];\n";')
# Replace versions line specified in doc_version_select.js.
perl -i -ple "\$_ = '$all_versions' if /^var allVersions/;" gh-pages/doc_version_select.js
(cd gh-pages && git add doc_version_select.js)
- name: Commit and Push
run: |
cd docs
git add index.html documentation.html README.md
git add --all html/
EMAIL=`git show -s --format='%ae' HEAD`
NAME=`git show -s --format='%an' HEAD`
cd gh-pages
EMAIL=`git show -s --format='%ae' gh-pages`
NAME=`git show -s --format='%an' gh-pages`
git config user.email "$EMAIL"
git config user.name "$NAME"
{ git commit -m "Automatic update for $GITHUB_SHA." || true; }
git push origin gh-pages
git push -f origin HEAD:gh-pages
2 changes: 1 addition & 1 deletion astrobee.doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ PROJECT_NUMBER = 0.16.7
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.

PROJECT_BRIEF = "Flight software for the Astrobee robot operating inside the International Space Station."
PROJECT_BRIEF = "Flight software for the Astrobee robots operating inside the International Space Station."

# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
Expand Down
47 changes: 47 additions & 0 deletions doc/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Page not found - Astrobee software documentation</title>
<style type="text/css" media="screen">
body {
background-color: #f1f1f1;
margin: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.container { margin: 50px auto 40px auto; width: 600px; text-align: center; }

a { color: #4183c4; text-decoration: none; }
a:hover { text-decoration: underline; }

h1 { width: 800px; position:relative; left: -100px; letter-spacing: -1px; line-height: 60px; font-size: 60px; font-weight: 100; margin: 0px 0 50px 0; text-shadow: 0 1px 0 #fff; }
p { color: rgba(0, 0, 0, 0.5); margin: 20px 0; line-height: 1.6; }

ul { list-style: none; margin: 25px 0; padding: 0; }
li { display: table-cell; font-weight: bold; width: 1%; }

#suggestions {
margin-top: 35px;
color: #ccc;
}
#suggestions a {
color: #666666;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
}

</style>
</head>
<body>
<div class="container">
<h1>404</h1>

<p><strong>Sorry, that page does not exist!</strong></p>

<p>If you got here by using the menu at the top to change what version of the Astrobee software you want documentation for, please note that different software versions may define different documentation pages in some cases.</p>

<div id="suggestions"><a href="/astrobee/v/develop/">[ Return to the Astrobee documentation root ]</a>.</div>
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion doc/README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Please visit the [Astrobee Documentation](https://nasa.github.io/astrobee/documentation.html)
Please visit the [Astrobee Documentation](https://nasa.github.io/astrobee/v/develop/)
2 changes: 1 addition & 1 deletion doc/documentation.html
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv=Refresh content="0;url=html/index.html"></head></html>
<html><head><meta http-equiv=Refresh content="0;url=v/develop/"></head></html>
87 changes: 87 additions & 0 deletions doc/scripts/copy_html_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python
# Copyright (c) 2017, United States Government, as represented by the
# Administrator of the National Aeronautics and Space Administration.
#
# All rights reserved.
#
# The Astrobee platform is licensed under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""
Recursively copy a folder as "HTML symlinks" -- this means writing files
in the target folder with the same relative paths as in the source
folder, but instead of copying the file content, each output file is a
minimal HTML page that will redirect to the original file in the source
folder.
"""

import argparse
import os

HTML_TEMPLATE = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv=Refresh content="0;url={}"></head></html>
""".lstrip()


def copy_html_link(src_path_in, tgt_path_in, verbose):
src_path = os.path.realpath(src_path_in)
tgt_path = os.path.realpath(tgt_path_in)
src_rel_tgt = os.path.relpath(src_path, tgt_path)
count = 0
for dir_path, dirs, files in os.walk(src_path):
dir_path_suffix = dir_path.replace(src_path, "")
dir_path_suffix = dir_path_suffix.lstrip("/")
for f in files:
if not dir_path_suffix:
depth = 0
else:
depth = len(dir_path_suffix.split("/"))
up_depth = "/".join([".."] * depth)
src_f_rel_tgt_f = os.path.join(up_depth, src_rel_tgt, dir_path_suffix, f)
out_path = os.path.join(tgt_path, dir_path_suffix, f)
out_dir = os.path.dirname(out_path)
if not os.path.isdir(out_dir):
os.makedirs(out_dir, exist_ok=True)
with open(out_path, "w") as out:
out.write(HTML_TEMPLATE.format(src_f_rel_tgt_f))
count += 1
if verbose:
print("%s -> %s" % (out_path, src_f_rel_tgt_f))
print("wrote %s HTML redirect files" % count)


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
"src_path",
type=str,
help="source path",
)
parser.add_argument(
"tgt_path",
type=str,
help="target path",
)
parser.add_argument(
"-v",
"--verbose",
action="store_true",
default=False,
help="make output more verbose",
)

args = parser.parse_args()

copy_html_link(args.src_path, args.tgt_path, args.verbose)
53 changes: 53 additions & 0 deletions doc/style/doc_version_select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

// The line below will be replaced to include any additional
// auto-detected versions. See script in docs.yaml.
var allVersions = ["develop", "master", "ros2"];

function buildSelect(currentVersion) {
if (!allVersions.includes(currentVersion)) {
allVersions.unshift(currentVersion);
}

// couldn't get external CSS stylesheet to apply here for some reason
var buf = ['<span id="versionselectorlabel">Astrobee Version:</span><select id="versionselector" style="font-size: 100%; padding: 3px 5px 3px 5px; margin-left: 5px;">'];
for (version of allVersions) {
buf.push('<option value="' + version + '"');
if (version == currentVersion) {
buf.push(' selected="selected"');
}
buf.push(">" + version + "</option>");
}
buf.push("</select>");

return buf.join("");
}

function detectCurrentVersion() {
const version_regex = /\/v\/(.*)\//;
var match = version_regex.exec(window.location.pathname);
if (match) {
return match[1];
} else {
return "(unknown)";
}
}

function onSelectorChange() {
var selector = document.getElementById("versionselector");
var currentVersion = detectCurrentVersion();
var selectedVersion = selector.value;
window.location.pathname = window.location.pathname.replace(currentVersion, selectedVersion);
}

function initVersionSelector() {
var currentVersion = detectCurrentVersion();
var projNumDiv = document.getElementById("projectnumber");
projNumDiv.innerHTML = buildSelect(currentVersion);
var selector = document.getElementById("versionselector");
// couldn't get external CSS stylesheet to apply here for some reason
document.getElementById('projectnumber').style = "position: relative; top: -0.3em;";

selector.addEventListener("change", onSelectorChange);
}

initVersionSelector();
1 change: 1 addition & 0 deletions doc/style/freeflyer_footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
$generatedby&#160;<a href="http://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
<script type="text/javascript" src="/astrobee/doc_version_select.js"></script>
</body>
</html>

0 comments on commit 967c098

Please sign in to comment.