Step 2: Deployment¶
The Docs-Versions-Menu package includes a docs-versions-menu
executable. This executable should be run in the root of the deployed
documentation. That is, the root of the gh-pages
branch when using
Github Pages.
The main purpose of the docs-versions-menu
command is to generate the
versions.json
file that the Sphinx extension
relies on, in the root of the deployed documentation.
Deployment with Github Actions¶
For projects on Github, using Github Actions to deploy to Github Pages is the best-supported option without any external dependencies. Set up your workflow with the following steps:
Build the documentation by invoking Sphinx directly or in any other way that is convenient (
make
,tox
, etc.). You may also want to create documentation artifacts, i.e., a zipped archive of the HTML documentation, and PDF or EPUB versions of the documentation. For example, you might use the following workflow step:- name: Build the docs id: build run: | set -x python -m pip install -e .[dev] python -m pip install zip-files export VERSION=$(python -c 'import docs_versions_menu; print(docs_versions_menu.__version__, end="")') python -m sphinx -W "docs/" -d "docs/_build/doctree" "docs/_build/html" python -m sphinx -W "docs/" -d "docs/_build/doctree" -b latex "docs/_build/latex" python docs/build_pdf.py docs/_build/latex/docsversionsmenu.tex python -m sphinx -W "docs/" -d "docs/_build/doctree" -b epub docs/_build/epub zip-folder --debug --auto-root --outfile "docs-versions-menu-$VERSION.zip" docs/_build/html mv docs/_build/latex/docsversionsmenu.pdf "docs-versions-menu-$VERSION.pdf" mv docs/_build/epub/DocsVersionsMenu.epub "docs-versions-menu-$VERSION.epub" touch docs/_build/html/_downloads echo ::set-output name=VERSION::$VERSION
Optionally, create a Github release and attach the documentation artifacts to it (see below)
Deploy the built HTML documentation to
gh-pages
:Check out the
gh-pages
branch and usersync
to transfer the built html documentation to the appropriate subfolder ingh-pages
.Run
docs-versions-menu
inside thegh-pages
rootCommit and push the changes on the
gh-pages
branch
For example, consider the following workflow step:
- name: Deploy documentation to gh-pages if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') shell: bash run: | set -x # Clone gh-pages git clone --branch gh-pages https://github.com/${{ github.repository }} gh-pages # Run rsync branch_name=$(echo ${GITHUB_REF##*/} | tr / -) rsync -av --delete "./docs/_build/html/" "./gh-pages/$branch_name/" # Run docs-versions-menu cd gh-pages docs-versions-menu # Commit and push git config user.name github-actions git config user.email github-actions@github.com git add -A --verbose git status git log --format=%B -n 1 | tee .git/_github_actions_commit_msg loglastline=$(cat .git/_github_actions_commit_msg | grep -v '^$' | tail -n1) logauthor=$(git log --format=%an -n 1) if [[ "$logauthor" == "github-actions"* && "$loglastline" == *"${{ github.ref }}"* ]]; then # we ammend if the previous commit was down by Github Actions and was based on the same branch/tag name echo "Amending previous commit" echo "Deployed from commit ${GITHUB_SHA} (${GITHUB_REF})" >> .git/_github_actions_commit_msg git commit --verbose --amend -F .git/_github_actions_commit_msg else echo "Making new commit" git commit --verbose -m "Auto-update from Github Actions Workflow" -m "Deployed from commit ${GITHUB_SHA} (${GITHUB_REF})" fi git log -n 1 git push --verbose --force https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/${{ github.repository }} gh-pages env: DOCS_VERSIONS_MENU_DEBUG: 'true' DOCS_VERSIONS_MENU_VERSIONS: '(<branches> != (master, rtd-theme)), (<releases>)[:-1], rtd-theme, (<releases>)[-1], master' DOCS_VERSIONS_MENU_LABEL: 'rtd-theme: v0.4.1 (rtd-theme)' DOCS_VERSIONS_MENU_WARNING: 'unreleased: (<branches> != rtd-theme), <local-releases>' GITHUB_ACTOR: ${{ secrets.GITHUB_ACTOR }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Note that a Github action is automatically authenticated to upload/download artifacts and to have push-access to the underlying repository.
See docs-versions-menu’s own workflow file for a full example from which the above snippets originate.
Github Releases¶
The version menu supports showing Download links. For a project using Github Actions, the easiest solution for hosting the linked files is as “assets” of a Release on Github.
The Github CLI (gh
) utility makes it easy to automate creating a release
via a workflow from an annotated git tag. Create an annotated tag with e.g.,
git tag --annotate v0.5.0
Or, even better, if you have gpg signing set up,
git tag --sign v0.5.0
Use e.g. “Release 0.5.0” as the subject of the tag message, and the release notes in markdown format as the body of the tag message. Then push it with
git push --tags
Consider the following example snippet from docs-versions-menu’s workflow that automates creating a Release.
- name: Make a Github release and set _downloads links
shell: bash
if: startsWith(github.ref, 'refs/tags/v')
run: |
set -x
git fetch --tags --force # restore tag info that actions/checkout pruned
tag_name="${GITHUB_REF##*/}"
release_title=$(git tag -l --format='%(contents:subject)' "$tag_name")
git tag -l --format='%(contents:body)' "$tag_name" | tee RELEASE_NOTES.md
gh release create "$tag_name" ./docs-versions-menu-${{ steps.build.outputs.VERSION }}.* --notes-file RELEASE_NOTES.md --title="$release_title"
epub=$(gh api "repos/${{ github.repository }}/releases/tags/$tag_name" | jq '.assets[] | .browser_download_url' | sed 's/"//g' | grep 'epub$')
pdf=$(gh api "repos/${{ github.repository }}/releases/tags/$tag_name" | jq '.assets[] | .browser_download_url' | sed 's/"//g' | grep 'pdf$')
zip=$(gh api "repos/${{ github.repository }}/releases/tags/$tag_name" | jq '.assets[] | .browser_download_url' | sed 's/"//g' | grep 'zip$')
echo "[html]: $zip" >> docs/_build/html/_downloads
echo "[epub]: $epub" >> docs/_build/html/_downloads
echo "[pdf]: $pdf" >> docs/_build/html/_downloads
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
This extracts the release notes from the tag message, and attaches local asset
files ./docs-versions-menu-${{ steps.build.outputs.VERSION }}.*
(zip, pdf,
epub) that were created earlier in the workflow. It then obtains the public URL
for those assets from the Github API with help from the jq utility and writes
them to a _downloads
file that docs-versions-menu
will process
later.
Deployment with Travis and Doctr¶
When using Travis to deploy to Github Pages via Doctr, the
docs-versions-menu
command should be invoked through
doctr deploy
’s --command
flag. As the explicit purpose of Docs-Versions-Menu
is to enable documentation for multiple versions of a package at the same time,
you’ll likely want to invoke doctr deploy
also with the
--no-required-master
and --build-tags
options.
For example, your .travis.yml
file might include the following
for deploying previously built documentation:
if [ ! -z "$TRAVIS_TAG" ]; then DEPLOY_DIR="$TRAVIS_TAG"; else DEPLOY_DIR="$TRAVIS_BRANCH"; fi
doctr deploy --command=docs-versions-menu --no-require-master --build-tags "$DEPLOY_DIR"
Note
Originally, docs-versions-menu
was named doctr-versions-menu
and
targeted the above workflow. However, as of 2021, Travis no longer provides
free services to open source projects and should be avoided.
Deployment to a static webhost¶
When deploying the documentation not to Github Pages, but directly to a
static webhost, you will likely want to invoke rsync in your continuous
integration (e.g., Github Actions workflow) to upload the documentation to
the appropriate subfolder in the server’s webroot. After the call to rsync
,
invoke the docs-versions-menu
executable to run in the root of the deployed
documentation, via ssh
.
Interactive maintenance¶
Unless --no-write-versions-py
is given or
DOCS_VERSIONS_MENU_WRITE_VERSIONS_PY=false
is set, running
docs-versions-menu
will generate a script versions.py
. Running this
script again installs the Docs-Versions-Menu package into a temporary virtual
environment and runs docs-versions-menu
with the same options that created
versions.py
in the first place.
The intent behind this is to allow for for manual, interactive maintenance, on
the gh-pages
branch or in the server’s webroot. For example, you may
occasionally want to remove folders for outdated branches or pre-releases from
the gh-pages
branch, or update existing download links. After any such
change, run the versions.py
script to updates versions.json
.
Remember that each folder on the gh-pages
branch generally contains its own
docs-versions-menu.js
script. Switching a project to a new major version
of docs-versions-menu
, if that version changes the internal data structure of
versions.json
, may require updating the docs-versions-menu.js
script
in existing folders by hand.