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
3 changes: 3 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ build:
- libxcb-xinerama0
- libxcb-xfixes0
jobs:
pre_install:
# Development builds may require a Sigima version not yet released on PyPI
- "python scripts/rtd_install_sigima.py"
pre_build:
# Start Xvfb before building docs
- "Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &"
Expand Down
106 changes: 106 additions & 0 deletions scripts/rtd_install_sigima.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# -*- coding: utf-8 -*-
"""
Install the development version of Sigima for Read the Docs builds.

SigimaX is developed alongside Sigima: development branches and pull requests
may require a Sigima version which is not yet published on PyPI, so installing
``sigimax[doc]`` from PyPI alone would fail.

This script mirrors the GitHub Actions test workflows:

- tag builds and the ``main`` branch: nothing is done, Sigima is installed from
PyPI by the regular ``python.install`` step;
- other branches and pull requests: Sigima is installed from the GitHub branch
with the same name as the SigimaX branch if it exists, otherwise from
``develop``. The regular ``python.install`` step then keeps this version as it
already satisfies SigimaX requirements.

It is intended to be run as a ``build.jobs.pre_install`` step and only relies
on the standard library and ``git``.
"""

from __future__ import annotations

import os
import subprocess
import sys

SIGIMA_REPO = "https://github.com/DataLab-Platform/Sigima.git"
SIGIMAX_REPO = "https://github.com/DataLab-Platform/SigimaX.git"
DEFAULT_BRANCH = "develop"
RELEASE_BRANCH = "main"


def get_remote_branches(url: str) -> dict[str, str]:
"""Return the branches of a remote Git repository.

Args:
url: Remote repository URL

Returns:
Mapping of branch names to the commit hash of their head
"""
output = subprocess.run(
["git", "ls-remote", "--heads", url],
capture_output=True,
text=True,
check=True,
).stdout
branches = {}
for line in output.splitlines():
commit, ref = line.split("\t", 1)
branches[ref.removeprefix("refs/heads/")] = commit
return branches


def get_sigimax_branch() -> str | None:
"""Return the SigimaX branch being built, if it can be determined.

For pull request builds, Read the Docs only provides the pull request number,
so the branch is the one of the SigimaX repository whose head is the commit
being built.

Returns:
Branch name, or None for tag builds and pull requests from forks
"""
version_type = os.environ.get("READTHEDOCS_VERSION_TYPE")
if version_type == "branch":
return os.environ["READTHEDOCS_GIT_IDENTIFIER"]
if version_type == "external":
commit = os.environ["READTHEDOCS_GIT_COMMIT_HASH"]
for branch, head in get_remote_branches(SIGIMAX_REPO).items():
if head == commit:
return branch
return None


def main() -> None:
"""Install Sigima from GitHub for development builds."""
version_type = os.environ.get("READTHEDOCS_VERSION_TYPE")
if version_type not in ("branch", "external"):
print(f"Version type {version_type!r}: Sigima will be installed from PyPI")
return
sigimax_branch = get_sigimax_branch()
if sigimax_branch == RELEASE_BRANCH:
print(f"Branch {RELEASE_BRANCH!r}: Sigima will be installed from PyPI")
return
if sigimax_branch in get_remote_branches(SIGIMA_REPO):
sigima_branch = sigimax_branch
else:
sigima_branch = DEFAULT_BRANCH
print(f"SigimaX branch: {sigimax_branch!r} -> Sigima branch: {sigima_branch!r}")
subprocess.run(
[
sys.executable,
"-m",
"pip",
"install",
"--no-cache-dir",
f"sigima @ git+{SIGIMA_REPO}@{sigima_branch}",
],
check=True,
)


if __name__ == "__main__":
main()
Loading