Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
116 changes: 97 additions & 19 deletions .github/workflows/publish_docs_to_pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ on:
push:
branches:
- main
tags:
- v*

permissions:
contents: write

jobs:
build:
build-and-deploy:
if: github.repository_owner == 'numpy'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
# The deploy step below checks out gh-pages and pushes to it.
fetch-depth: 0
- uses: actions/setup-python@v7
with:
Expand All @@ -24,32 +25,109 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install .[doc]
- name: Determine docs version
id: version
run: |
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
VERSION="${GITHUB_REF#refs/tags/v}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "is_release=true" >> $GITHUB_OUTPUT
echo "docs_path=version/$VERSION" >> $GITHUB_OUTPUT
else
echo "version=dev" >> $GITHUB_OUTPUT
echo "is_release=false" >> $GITHUB_OUTPUT
echo "docs_path=dev" >> $GITHUB_OUTPUT
fi
- name: Build documentation with Sphinx
env:
DOCS_VERSION: ${{ steps.version.outputs.version }}
run: |
cd doc
make html
mv build/html /tmp
mv build/html /tmp/html
cd ..
- name: Deploy to gh-pages branch
env:
DOCS_PATH: ${{ steps.version.outputs.docs_path }}
IS_RELEASE: ${{ steps.version.outputs.is_release }}
VERSION: ${{ steps.version.outputs.version }}
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
echo "Checking out gh-pages branch"
git fetch origin gh-pages
git checkout gh-pages
echo "Removing old dev documentation"
git clean -xdf .
cd dev
git rm -r '*'
cd ..
echo "Committing emptied dev directory"
git commit -m "Remove old dev documentation"
mkdir -p dev
cd dev
echo "Copying /tmp/html here"
cp -v -r /tmp/html/* .
echo "Adding new dev documentation"

if [ "$IS_RELEASE" = "true" ]; then
mkdir -p "$DOCS_PATH"
rm -rf "${DOCS_PATH:?}"/*
else
git clean -xdf .
if [ -d "dev" ]; then
cd dev
git rm -r '*' || true
cd ..
git commit -m "Remove old dev documentation" || true
fi
mkdir -p dev
fi

cp -r /tmp/html/* "$DOCS_PATH/"

# Generate versions.json by scanning existing version directories
python3 << 'EOF'
import json
import os
from packaging.version import Version, InvalidVersion

base_url = "https://numpy.org/numpy-financial"
versions = []

# Add dev entry
if os.path.isdir('dev'):
versions.append({"name": "dev", "version": "dev", "url": f"{base_url}/dev/"})

# Scan version/ directory for released versions
if os.path.isdir('version'):
release_versions = []
for name in os.listdir('version'):
if os.path.isdir(f'version/{name}'):
try:
release_versions.append((Version(name), name))
except InvalidVersion:
pass
# Sort by version descending
release_versions.sort(reverse=True)
# Find the highest non-prerelease version for stable
stable_name = next((name for ver, name in release_versions if not ver.is_prerelease), None)
for ver, name in release_versions:
entry = {"name": name, "version": name, "url": f"{base_url}/version/{name}/"}
if name == stable_name:
entry["name"] = f"{name} (stable)"
entry["preferred"] = True
versions.append(entry)

os.makedirs('_static', exist_ok=True)
with open('_static/versions.json', 'w') as f:
json.dump(versions, f, indent=4)
EOF

# Update latest symlink on releases
if [ "$IS_RELEASE" = "true" ]; then
rm -f latest
ln -s "version/$VERSION" latest
git add latest
fi

git add -A .
git commit -m "Add new dev documentation"
echo "Pushing new documentation to origin"
git push -v origin gh-pages
if git diff --cached --quiet; then
echo "No changes to commit"
elif [ "$IS_RELEASE" = "true" ]; then
git commit -m "Add documentation for version $VERSION"
git push -v origin gh-pages
elif [ "$VERSION" = "dev" ]; then
git commit -m "Update dev documentation"
git push -v origin gh-pages
else
echo "Unexpected state: IS_RELEASE=$IS_RELEASE, VERSION=$VERSION"
exit 1
fi
32 changes: 13 additions & 19 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,19 @@ PyPI trusted publishing. Do not build or upload artifacts by hand.
- paste the contents of ${CHANGES} in the `Describe this release section`
- if pre-release check the box labelled `Set as a pre-release`

- Publish the documentation for the release. A GH workflow builds
`dev/` from `main`; the released versions have to be published by
hand. Skip this step for a pre-release.

- wait for the workflow to rebuild `dev/` from the release
commit, and check that https://numpy.org/numpy-financial/dev/
shows ${VERSION}. Do this before the version bump below, which
returns `dev/` to a development version.

- in a clone of the `gh-pages` branch, copy those docs to their
permanent location and point `latest` at them:

cp -r dev version/${VERSION}
git add version/${VERSION}
git rm -rf latest
ln -s version/${VERSION} latest
git add latest

- commit and push `gh-pages`
- Publish the documentation for the release. The `Publish docs to gh-pages`
workflow automatically builds and deploys versioned documentation when
a `v*` tag is pushed:

- Dev docs are deployed to `/dev/` from `main` branch pushes
- Release docs are deployed to `/version/${VERSION}/` from `v*` tags
- The workflow regenerates `_static/versions.json` by scanning existing
directories, marking the highest non-prerelease version as stable

Verify the deployment:
- Check https://numpy.org/numpy-financial/version/${VERSION}/ shows
the new version's documentation
- Check the version switcher dropdown includes the new version

- Update https://github.com/numpy/numpy-financial/milestones:

Expand Down
38 changes: 37 additions & 1 deletion doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

import os
from datetime import datetime

import numpy_financial

# -- Path setup --------------------------------------------------------------
Expand All @@ -20,7 +23,7 @@
# -- Project information -----------------------------------------------------

project = 'numpy-financial'
copyright = '2023, numpy-financial developers'
copyright = f'2005-{datetime.now().year}, NumPy Developers'
author = 'numpy-financial developers'


Expand Down Expand Up @@ -61,3 +64,36 @@

html_logo = "_static/numpy_financial_logov.svg"
html_favicon = "_static/numpy_financial_favicon.png"

# -- Version switcher configuration ------------------------------------------

# Determine the version string for the switcher.
# Must match a "version" field in versions.json for the dropdown to show it selected.
#
# In production (CI), DOCS_VERSION is set explicitly:
# - "dev" for main branch builds (deployed to /dev/)
# - "X.Y.Z" for release tag builds (deployed to /version/X.Y.Z/)
#
# For local development, default to showing stable version to test the typical UX.
if os.environ.get("DOCS_VERSION"):
# CI sets this explicitly based on branch/tag
switcher_version = os.environ["DOCS_VERSION"]
else:
# Local development: show stable version (1.1.0) as default for UX testing
# This matches what users see when visiting the main docs site
switcher_version = "1.1.0"

# versions.json is generated dynamically on gh-pages by the CI workflow.
# Always use the absolute URL (local development requires internet access).
json_url = "https://numpy.org/numpy-financial/_static/versions.json"

html_theme_options = {
"github_url": "https://github.com/numpy/numpy-financial",
# Navbar layout: theme switcher, version switcher, then GitHub icon
"navbar_end": ["theme-switcher", "version-switcher", "navbar-icon-links"],
"switcher": {
"json_url": json_url,
"version_match": switcher_version,
},
"show_version_warning_banner": True,
}
Loading