Skip to content

Commit

Permalink
Add docs version switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
GDYendell committed Aug 2, 2023
1 parent 57c34c8 commit ef6c54b
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 11 deletions.
11 changes: 11 additions & 0 deletions .github/pages/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>

<head>
<title>Redirecting to master branch</title>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=./master/index.html">
<link rel="canonical" href="master/index.html">
</head>

</html>
99 changes: 99 additions & 0 deletions .github/pages/make_switcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import json
import logging
from argparse import ArgumentParser
from pathlib import Path
from subprocess import CalledProcessError, check_output
from typing import List, Optional


def report_output(stdout: bytes, label: str) -> List[str]:
ret = stdout.decode().strip().split("\n")
print(f"{label}: {ret}")
return ret


def get_branch_contents(ref: str) -> List[str]:
"""Get the list of directories in a branch."""
stdout = check_output(["git", "ls-tree", "-d", "--name-only", ref])
return report_output(stdout, "Branch contents")


def get_sorted_tags_list() -> List[str]:
"""Get a list of sorted tags in descending order from the repository."""
stdout = check_output(["git", "tag", "-l", "--sort=-v:refname"])
return report_output(stdout, "Tags list")


def get_versions(ref: str, add: Optional[str], remove: Optional[str]) -> List[str]:
"""Generate the file containing the list of all GitHub Pages builds."""
# Get the directories (i.e. builds) from the GitHub Pages branch
try:
builds = set(get_branch_contents(ref))
except CalledProcessError:
builds = set()
logging.warning(f"Cannot get {ref} contents")

# Add and remove from the list of builds
if add:
builds.add(add)
if remove:
assert remove in builds, f"Build '{remove}' not in {sorted(builds)}"
builds.remove(remove)

# Get a sorted list of tags
tags = get_sorted_tags_list()

# Make the sorted versions list from main branches and tags
versions: List[str] = []
for version in ["master", "main"] + tags:
if version in builds:
versions.append(version)
builds.remove(version)

# Add in anything that is left to the bottom
versions += sorted(builds)
print(f"Sorted versions: {versions}")
return versions


def write_json(path: Path, repository: str, versions: str):
org, repo_name = repository.split("/")
struct = [
dict(version=version, url=f"https://{org}.github.io/{repo_name}/{version}/")
for version in versions
]
text = json.dumps(struct, indent=2)
print(f"JSON switcher:\n{text}")
path.write_text(text)


def main(args=None):
parser = ArgumentParser(
description="Make a versions.txt file from gh-pages directories"
)
parser.add_argument(
"--add",
help="Add this directory to the list of existing directories",
)
parser.add_argument(
"--remove",
help="Remove this directory from the list of existing directories",
)
parser.add_argument(
"repository",
help="The GitHub org and repository name: ORG/REPO",
)
parser.add_argument(
"output",
type=Path,
help="Path of write switcher.json to",
)
args = parser.parse_args(args)

# Write the versions file
versions = get_versions("origin/gh-pages", args.add, args.remove)
write_json(args.output, args.repository, versions)


if __name__ == "__main__":
main()
22 changes: 14 additions & 8 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
name: Docs CI
on:
push:
branches:
- master
- docs
pull_request:

jobs:
deploy:
docs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
Expand All @@ -26,12 +23,21 @@ jobs:
- name: Build Docs
run: pip install ./python[dev] && sphinx-build -ET docs/ docs/build/html/

- name: Publish Docs
if: github.event_name == 'push'
- name: Sanitize ref name for docs version
run: echo "DOCS_VERSION=${GITHUB_REF_NAME//[^A-Za-z0-9._-]/_}" >> $GITHUB_ENV

- name: Move to versioned directory
run: mv docs/build/html .github/pages/$DOCS_VERSION

- name: Write switcher.json
run: python .github/pages/make_switcher.py --add $DOCS_VERSION ${{ github.repository }} .github/pages/switcher.json

- name: Publish Docs to gh-pages
if: github.event_name == 'push' && github.actor != 'dependabot[bot]'
# We pin to the SHA, not the tag, for security reasons.
# https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions
uses: peaceiris/actions-gh-pages@068dc23d9710f1ba62e86896f84735d869951305 # v3.8.0
uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3.9.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/build/html/
publish_dir: .github/pages
keep_files: true
43 changes: 43 additions & 0 deletions .github/workflows/docs_clean.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Docs Cleanup CI

# delete branch documentation when a branch is deleted
# also allow manually deleting a documentation version
on:
delete:
workflow_dispatch:
inputs:
version:
description: "documentation version to DELETE"
required: true
type: string

jobs:
remove:
if: github.event.ref_type == 'branch' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: gh-pages

- name: removing documentation for branch ${{ github.event.ref }}
if: ${{ github.event_name != 'workflow_dispatch' }}
run: echo "REF_NAME=${{ github.event.ref }}" >> $GITHUB_ENV

- name: manually removing documentation version ${{ github.event.inputs.version }}
if: ${{ github.event_name == 'workflow_dispatch' }}
run: echo "REF_NAME=${{ github.event.inputs.version }}" >> $GITHUB_ENV

- name: Sanitize ref name for docs version
run: echo "DOCS_VERSION=${REF_NAME//[^A-Za-z0-9._-]/_}" >> $GITHUB_ENV

- name: update index and push changes
run: |
rm -r $DOCS_VERSION
python make_switcher.py --remove $DOCS_VERSION ${{ github.repository }} switcher.json
git config --global user.name 'GitHub Actions Docs Cleanup CI'
git config --global user.email '[email protected]'
git commit -am "Removing redundant docs version $DOCS_VERSION"
git push
24 changes: 21 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

from pathlib import Path
from subprocess import check_output
import sys

import odin_data
import requests

# -- General configuration ------------------------------------------------

Expand Down Expand Up @@ -127,18 +129,34 @@
# a list of builtin themes.
#
html_theme = "pydata_sphinx_theme"

# Options for theme
github_repo = project
github_user = "odin-detector"

switcher_json = f"https://{github_user}.github.io/{github_repo}/switcher.json"
switcher_exists = requests.get(switcher_json).ok
if not switcher_exists:
print(
"*** Can't read version switcher, is GitHub pages enabled? \n"
" Once Docs CI job has successfully run once, set the "
"Github pages source branch to be 'gh-pages' at:\n"
f" https://github.com/{github_user}/{github_repo}/settings/pages",
file=sys.stderr,
)

# Options for theme
html_theme_options = dict(
logo=dict(
text=project,
),
github_url=f"https://github.com/{github_user}/{github_repo}",
secondary_sidebar_items=["page-toc", "edit-this-page", "sourcelink"],
use_edit_page_button=True,
navbar_end=["theme-switcher", "icon-links"],
switcher=dict(
json_url=switcher_json,
version_match=version,
),
check_switcher=False,
navbar_end=["theme-switcher", "icon-links", "version-switcher"],
external_links=[
dict(
name="Release Notes",
Expand Down

0 comments on commit ef6c54b

Please sign in to comment.