diff --git a/.github/workflows/docs_deploy.yml b/.github/workflows/docs_deploy.yml index fac9c5f0ea06..9763e3cc472e 100644 --- a/.github/workflows/docs_deploy.yml +++ b/.github/workflows/docs_deploy.yml @@ -29,9 +29,21 @@ jobs: - name: Install dependencies run: tools/install_ubuntu_docs_dependencies.sh + - name: Determine GitHub branch name + run: | + # Tags like 1.0.0 and 1.0.0rc1 should point to their stable branch. We do this + # to reduce the diff in the qiskit/documentation repository between generating + # the API docs from a tag release versus a workflow_dispatch. + if [[ $GITHUB_REF_NAME =~ ^([0-9]+\.[0-9]+) ]]; then + BRANCH_NAME="stable/${BASH_REMATCH[1]}" + else + BRANCH_NAME="$GITHUB_REF_NAME" + fi + echo "Using branch '${BRANCH_NAME}' for GitHub source code links" + echo "QISKIT_DOCS_GITHUB_BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV + - name: Build documentation run: tox run -e docs - - name: Store built documentation artifact uses: actions/upload-artifact@v4 with: diff --git a/docs/conf.py b/docs/conf.py index a6b87822a205..f2fb4e0c1e53 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,6 +18,12 @@ import datetime import doctest +import importlib +import inspect +import os +import re +from pathlib import Path + project = "Qiskit" project_copyright = f"2017-{datetime.date.today().year}, Qiskit Development Team" @@ -39,7 +45,7 @@ "sphinx.ext.intersphinx", "sphinx.ext.doctest", # This is used by qiskit/documentation to generate links to github.com. - "sphinx.ext.viewcode", + "sphinx.ext.linkcode", "matplotlib.sphinxext.plot_directive", "reno.sphinxext", "sphinxcontrib.katex", @@ -155,3 +161,54 @@ # ---------------------------------------------------------------------------------- plot_html_show_formats = False + + +# ---------------------------------------------------------------------------------- +# Source code links +# ---------------------------------------------------------------------------------- + +REPO_ROOT = Path(__file__).resolve().parents[1] + + +def linkcode_resolve(domain, info): + if domain != "py": + return None + + module_name = info["module"] + if "qiskit" not in module_name: + return None + + try: + module = importlib.import_module(module_name) + except ModuleNotFoundError: + return None + + obj = module + for part in info["fullname"].split("."): + try: + obj = getattr(obj, part) + except AttributeError: + return None + + try: + full_file_name = inspect.getsourcefile(obj) + except TypeError: + return None + if full_file_name is None: + return None + try: + relative_file_name = Path(full_file_name).resolve().relative_to(REPO_ROOT) + file_name = re.sub(r"\.tox\/.+\/site-packages\/", "", str(relative_file_name)) + except ValueError: + return None + + try: + source, lineno = inspect.getsourcelines(obj) + except (OSError, TypeError): + linespec = "" + else: + ending_lineno = lineno + len(source) - 1 + linespec = f"#L{lineno}-L{ending_lineno}" + + github_branch = os.environ.get("QISKIT_DOCS_GITHUB_BRANCH_NAME", "main") + return f"https://github.com/Qiskit/qiskit/tree/{github_branch}/{file_name}{linespec}" diff --git a/tox.ini b/tox.ini index b9001f6db5d4..ef1e1a23ef60 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,15 @@ setenv = QISKIT_SUPRESS_PACKAGING_WARNINGS=Y QISKIT_TEST_CAPTURE_STREAMS=1 QISKIT_PARALLEL=FALSE -passenv = RAYON_NUM_THREADS, OMP_NUM_THREADS, QISKIT_PARALLEL, RUST_BACKTRACE, SETUPTOOLS_ENABLE_FEATURES, QISKIT_TESTS, QISKIT_IN_PARALLEL +passenv = + RAYON_NUM_THREADS + OMP_NUM_THREADS + QISKIT_PARALLEL + RUST_BACKTRACE + SETUPTOOLS_ENABLE_FEATURES + QISKIT_TESTS + QISKIT_IN_PARALLEL + QISKIT_DOCS_GITHUB_BRANCH_NAME deps = setuptools_rust # This is work around for the bug of tox 3 (see #8606 for more details.) -r{toxinidir}/requirements.txt