Skip to content

sphinx

sphinx #5434

Workflow file for this run

name: sphinx
# **How it works**
# ================
#
# After each __commit__ on the `main` branch, the documentation is built and deployed on the `S3:dev/` directory.
# After each __release__, the documentation is built and deployed to the `S3:version/` directory, the version being
# a subpart of the tag `MAJOR.MINOR.BUGFIX`: `MAJOR.MINOR`.
#
# For instance, with the following timeline:
#
# dev/ dev/ dev/ dev/ dev/
# 0.1/ 0.2/
# main -- x -- x -- x -- x -- x -- >
# | |
# tag 0.1 0.2
#
# The S3 bucket looks like:
# .
# ├── 0.1/
# ├── 0.2/
# ├── dev/
# ├── index.html
# └── versions.json
#
# **Q&A**
# =======
#
# ### `dev/`, why?
# It contains the most up-to-date documentation, i.e. the documentation of code that is not released but committed on the main branch.
#
# ### Version the documentation on `MAJOR.MINOR, why not on `MAJOR`?
# Currently, we add new features at a minor level. This way, we can separate documentation between two features.
#
# ### Only on release (not on release-candidate), why?
# The release-candidates are documented in the `dev/` directory. We don't want to create noise with explicit directory for such tags.
#
# ### How to change an old version of the documentation?
# You can create tags wherever you want, i.e. on separate branches.
# For example, you can create a branch from an old tag (`0.1.5`), modify the documentation and create a new tag (`0.1.6`).
# The corresponding documentation will be automatically updated (`0.1`).
#
# **Side-notes**
# ==============
#
# Only the 10 latest versions are listed in sphinx version-switcher to avoid overloading, but the bucket remains unchanged.
on:
pull_request:
push:
branches: [main]
tags: ['skore/[0-9]+.[0-9]+.[0-9]+']
merge_group:
types: [checks_requested]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
sphinx-changes:
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.filter.outputs.sphinx }}
permissions:
pull-requests: read
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Define if at least one file has changed
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
sphinx:
- '.github/actions/sphinx/**'
- '.github/workflows/sphinx.yml'
- 'examples/**'
- 'sphinx/**'
- 'skore/**'
sphinx-version:
runs-on: ubuntu-latest
needs: [sphinx-changes]
if: ${{ (github.event_name == 'push') || (needs.sphinx-changes.outputs.changes == 'true') }}
outputs:
SPHINX_VERSION: ${{ steps.sphinx-version.outputs.SPHINX_VERSION }}
SPHINX_RELEASE: ${{ steps.sphinx-version.outputs.SPHINX_RELEASE }}
steps:
- shell: bash
id: sphinx-version
run: |
set -u
if [[ "${GITHUB_EVENT_NAME}" != "push" ]] || [[ "${GITHUB_REF_TYPE}" != "tag" ]]; then
echo "SPHINX_VERSION=dev" >> "${GITHUB_OUTPUT}"
echo "SPHINX_RELEASE=0.0.0+dev" >> "${GITHUB_OUTPUT}"
exit 0
fi
set -e
if [[ "${GITHUB_REF_NAME}" =~ ^skore/((0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*))$ ]]; then
echo "SPHINX_VERSION=${BASH_REMATCH[2]}.${BASH_REMATCH[3]}" >> "${GITHUB_OUTPUT}"
echo "SPHINX_RELEASE=${BASH_REMATCH[1]}" >> "${GITHUB_OUTPUT}"
fi
sphinx-build:
runs-on: ubuntu-latest
needs: [sphinx-version]
if: ${{ (github.event_name == 'push') || (needs.sphinx-changes.outputs.changes == 'true') }}
permissions:
contents: read
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
lfs: 'true'
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: '3.12'
cache: 'pip'
- uses: ./.github/actions/sphinx/build
timeout-minutes: 60
with:
SPHINX_VERSION: ${{ needs.sphinx-version.outputs.SPHINX_VERSION }}
SPHINX_RELEASE: ${{ needs.sphinx-version.outputs.SPHINX_RELEASE }}
SPHINX_DOMAIN: ${{ vars.DOCUMENTATION_DOMAIN }}
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: sphinx-html-artifact
path: sphinx/build/html/
sphinx-deploy-html:
if: ${{ github.event_name == 'push' }}
runs-on: ubuntu-latest
needs: [sphinx-version, sphinx-build]
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
sparse-checkout: .github
- name: Download HTML artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: sphinx-html-artifact
path: html/
- name: Deploy HTML artifacts
uses: ./.github/actions/sphinx/deploy
with:
CONFIGURATION: ${{ secrets.RCLONE_CONFIG_DOCS }}
BUCKET: ${{ vars.DOCUMENTATION_BUCKET }}
SOURCE: html/
DESTINATION: ${{ needs.sphinx-version.outputs.SPHINX_VERSION }}/
sphinx-deploy-root-files:
if: ${{ (github.event_name == 'push') && (github.ref_type == 'tag') }}
runs-on: ubuntu-latest
needs: [sphinx-version, sphinx-build, sphinx-deploy-html]
permissions:
contents: read
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
sparse-checkout: .github
- shell: python
run: |
import os
import requests
import operator
import json
version = os.environ["SPHINX_VERSION"]
release = os.environ["SPHINX_RELEASE"]
url = os.environ["SPHINX_URL"]
# Retrieve history
response = requests.get(f"{url}/versions.json")
response.raise_for_status()
history = {version["name"]: version["version"] for version in response.json()}
# Add new version to history
history[version] = release
# Sort history, and always keep "dev" at the beginning
history = sorted(
history.items(),
key=lambda item: tuple(map(float, item[0].split("."))) if item[0] != "dev" else (float('inf'), 0),
reverse=True
)
# Rewrite the history with "dev" and the 10 latest versions
new = [
{
"name": version,
"version": release,
"url": f"{url}/{version}/",
"preferred": i == 1,
}
for i, (version, release) in enumerate(history[:11])
]
os.mkdir("artifacts")
with open("artifacts/versions.json", "w", encoding="utf-8") as file:
json.dump(new, file, ensure_ascii=False, indent=4)
with open("artifacts/index.html", "w", encoding="utf-8") as file:
file.write(
f"""
<head>
<meta http-equiv=\"refresh\" content=\"0; url={new[1]["url"]}\"/>
</head>
"""
)
env:
SPHINX_VERSION: ${{ needs.sphinx-version.outputs.SPHINX_VERSION }}
SPHINX_RELEASE: ${{ needs.sphinx-version.outputs.SPHINX_RELEASE }}
SPHINX_URL: https://${{ vars.DOCUMENTATION_DOMAIN }}
- uses: ./.github/actions/sphinx/deploy
with:
CONFIGURATION: ${{ secrets.RCLONE_CONFIG_DOCS }}
BUCKET: ${{ vars.DOCUMENTATION_BUCKET }}
ACTION: copy
SOURCE: artifacts/
DESTINATION:
sphinx-purge-cdn-cache:
runs-on: ubuntu-latest
#
# Using `if: ${{ (! cancelled()) && contains(needs.*.result, 'success') }}` at
# __job level__ doesn't work as expected. It always returns true if one of the needs
# , or unfortunately one of their **transitive** needs, satisfies the condition.
#
# https://github.com/actions/runner/issues/1540
#
if: ${{ (! cancelled()) && ((needs.sphinx-deploy-html.result == 'success') || (needs.sphinx-deploy-root-files == 'success')) }}
needs:
- sphinx-deploy-html
- sphinx-deploy-root-files
steps:
- shell: bash
run: |
curl --fail-with-body \
-X POST \
--url "https://api.bunny.net/pullzone/${PULLZONE}/purgeCache" \
--header "AccessKey: ${ACCESS_KEY}"
env:
PULLZONE: ${{ vars.BUNNY_PULLZONE }}
ACCESS_KEY: ${{ secrets.BUNNY_API_KEY }}
sphinx-clean-artifacts:
runs-on: ubuntu-latest
if: ${{ always() && (github.event_name != 'pull_request') }}
needs: [sphinx-version, sphinx-build, sphinx-deploy-html, sphinx-deploy-root-files]
steps:
- uses: geekyeggo/delete-artifact@f275313e70c08f6120db482d7a6b98377786765b # v5.1.0
with:
name: sphinx-html-artifact
sphinx:
needs:
- sphinx-changes
- sphinx-version
- sphinx-build
- sphinx-deploy-html
- sphinx-deploy-root-files
- sphinx-clean-artifacts
if: ${{ always() }}
runs-on: Ubuntu-latest
steps:
- shell: bash
run: |
[[ ${{ contains(needs.*.result, 'failure') }} = false ]]