/ .github / utils / create_unstable_docs_docusaurus.py
create_unstable_docs_docusaurus.py
  1  """
  2  This script creates an unstable documentation version at the time of branch-off for a new Haystack release.
  3  
  4  Between branch-off and the actual release, two unstable doc versions coexist.
  5  If we branch off for 2.20, we have:
  6  1. the target unstable version, 2.20-unstable (lives in docs-website/versioned_docs/version-2.20-unstable)
  7  2. the next unstable version, 2.21-unstable (lives in docs-website/docs)
  8  
  9  This script takes care of all the necessary updates to the documentation website.
 10  """
 11  
 12  import argparse
 13  import json
 14  import os
 15  import re
 16  import shutil
 17  import subprocess
 18  import sys
 19  import tempfile
 20  
 21  VERSION_VALIDATOR = re.compile(r"^[0-9]+\.[0-9]+$")
 22  
 23  
 24  if __name__ == "__main__":
 25      parser = argparse.ArgumentParser()
 26      parser.add_argument(
 27          "-v", "--new-version", help="The new unstable version that is being created (e.g. 2.20).", required=True
 28      )
 29      args = parser.parse_args()
 30  
 31      if VERSION_VALIDATOR.match(args.new_version) is None:
 32          sys.exit("Version must be formatted like so <major>.<minor>")
 33  
 34      target_version = f"{args.new_version}"  # e.g., "2.20" - the target release version
 35      major, minor = args.new_version.split(".")
 36  
 37      target_unstable = f"{target_version}-unstable"  # e.g., "2.20-unstable"
 38      next_unstable = f"{major}.{int(minor) + 1}-unstable"  # e.g., "2.21-unstable" - next cycle
 39  
 40      versions = [
 41          folder.replace("version-", "")
 42          for folder in os.listdir("docs-website/versioned_docs")
 43          if os.path.isdir(os.path.join("docs-website/versioned_docs", folder))
 44      ]
 45  
 46      # Check if the versions we're about to create already exist in versioned_docs
 47      if target_version in versions:
 48          sys.exit(f"{target_version} already exists (already released). Aborting.")
 49      if target_unstable in versions:
 50          print(f"{target_unstable} already exists. Nothing to do.")
 51          sys.exit(0)
 52  
 53      # Create new unstable from the currently existing one.
 54      # The new unstable will be made stable at a later time by another workflow
 55      print(f"Creating new unstable version {target_unstable} from main")
 56  
 57      ### Docusaurus updates
 58  
 59      # copy docs to versioned_docs/version-target_unstable
 60      shutil.copytree("docs-website/docs", f"docs-website/versioned_docs/version-{target_unstable}")
 61  
 62      # copy reference to reference_versioned_docs/version-target_unstable
 63      shutil.copytree("docs-website/reference", f"docs-website/reference_versioned_docs/version-{target_unstable}")
 64  
 65      # generate versioned_sidebars/version-target_unstable-sidebars.json from the current sidebars.js
 66      with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as tmp:
 67          tmp_path = tmp.name
 68      subprocess.run(
 69          ["node", "docs-website/scripts/extract_sidebar.mjs", "docs-website/sidebars.js", tmp_path], check=True
 70      )
 71      docs_sidebar_dest = f"docs-website/versioned_sidebars/version-{target_unstable}-sidebars.json"
 72      shutil.move(tmp_path, docs_sidebar_dest)
 73  
 74      # generate reference_versioned_sidebars/version-target_unstable-sidebars.json from the current reference-sidebars.js
 75      ref_sidebar_dest = f"docs-website/reference_versioned_sidebars/version-{target_unstable}-sidebars.json"
 76      with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as tmp:
 77          tmp_path = tmp.name
 78      subprocess.run(
 79          ["node", "docs-website/scripts/extract_sidebar.mjs", "docs-website/reference-sidebars.js", tmp_path], check=True
 80      )
 81      shutil.move(tmp_path, ref_sidebar_dest)
 82  
 83      # add unstable version to versions.json
 84      with open("docs-website/versions.json") as f:
 85          versions_list = json.load(f)
 86      versions_list.insert(0, target_unstable)
 87      with open("docs-website/versions.json", "w") as f:
 88          json.dump(versions_list, f)
 89  
 90      # add unstable version to reference_versions.json
 91      with open("docs-website/reference_versions.json") as f:
 92          reference_versions_list = json.load(f)
 93      reference_versions_list.insert(0, target_unstable)
 94      with open("docs-website/reference_versions.json", "w") as f:
 95          json.dump(reference_versions_list, f)
 96  
 97      # in docusaurus.config.js, replace the target unstable version with the next unstable version
 98      with open("docs-website/docusaurus.config.js") as f:
 99          config = f.read()
100      config = config.replace(f"label: '{target_unstable}'", f"label: '{next_unstable}'")
101      with open("docs-website/docusaurus.config.js", "w") as f:
102          f.write(config)