mirror of
				https://github.com/deepset-ai/haystack.git
				synced 2025-11-04 03:39:31 +00:00 
			
		
		
		
	Enhance release_docs.py (#4459)
This commit is contained in:
		
							parent
							
								
									cfb8dfd470
								
							
						
					
					
						commit
						dbdb682225
					
				
							
								
								
									
										184
									
								
								.github/utils/release_docs.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										184
									
								
								.github/utils/release_docs.py
									
									
									
									
										vendored
									
									
								
							@ -1,135 +1,107 @@
 | 
				
			|||||||
"""
 | 
					import os
 | 
				
			||||||
Use the Readme API to create fork a new version of the docs and also to rename the latest unstable.
 | 
					import re
 | 
				
			||||||
For example, if Readme currently has v1.9 and v1.10-unstable, and this script is used to release v1.10,
 | 
					import sys
 | 
				
			||||||
Readme will then contain v1.9, v1.10 (forked from v1.10-unstable) and v1.11-unstable (renamed from v1.10-unstable).
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import base64
 | 
					import base64
 | 
				
			||||||
import argparse
 | 
					import argparse
 | 
				
			||||||
import requests
 | 
					import requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def assert_valid_version(new_version):
 | 
					VERSION_VALIDATOR = re.compile(r"^[0-9]+\.[0-9]+$")
 | 
				
			||||||
    if not new_version.startswith("v"):
 | 
					
 | 
				
			||||||
        raise ValueError("Version must start with 'v'")
 | 
					
 | 
				
			||||||
    if not new_version[1:].replace(".", "").replace("-latest", "").isdigit():
 | 
					class ReadmeAuth(requests.auth.AuthBase):
 | 
				
			||||||
        raise ValueError("Version must be a number")
 | 
					    def __call__(self, r):
 | 
				
			||||||
    return True
 | 
					        r.headers["authorization"] = f"Basic {readme_token()}"
 | 
				
			||||||
 | 
					        return r
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def readme_token():
 | 
				
			||||||
 | 
					    api_key = os.getenv("RDME_API_KEY", None)
 | 
				
			||||||
 | 
					    if not api_key:
 | 
				
			||||||
 | 
					        raise Exception("RDME_API_KEY env var is not set")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    api_key = f"{api_key}:"
 | 
				
			||||||
 | 
					    return base64.b64encode(api_key.encode("utf-8")).decode("utf-8")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_versions():
 | 
					def get_versions():
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Return all versions currently published in Readme.io.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
    url = "https://dash.readme.com/api/v1/version"
 | 
					    url = "https://dash.readme.com/api/v1/version"
 | 
				
			||||||
    headers = {"Accept": "application/json", "Authorization": api_key_b64}
 | 
					    res = requests.get(url, auth=ReadmeAuth(), timeout=30)
 | 
				
			||||||
    response = requests.get(url, headers=headers)
 | 
					    res.raise_for_status()
 | 
				
			||||||
    return [v["version"] for v in response.json()]
 | 
					    return [v["version_clean"] for v in res.json()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def create_version(new_version, fork_from_version, is_stable=False):
 | 
					def create_new_unstable(current, new):
 | 
				
			||||||
    url = "https://dash.readme.com/api/v1/version"
 | 
					    """
 | 
				
			||||||
    payload = {
 | 
					    Create new version by copying current.
 | 
				
			||||||
        "is_beta": False,
 | 
					
 | 
				
			||||||
        "version": new_version,
 | 
					    :param current: Existing current unstable version
 | 
				
			||||||
        "from": fork_from_version,
 | 
					    :param new: Non existing new unstable version
 | 
				
			||||||
        "is_hidden": False,
 | 
					    """
 | 
				
			||||||
        "is_stable": is_stable,
 | 
					    url = "https://dash.readme.com/api/v1/version/"
 | 
				
			||||||
    }
 | 
					    payload = {"is_beta": False, "version": new, "from": current, "is_hidden": False, "is_stable": False}
 | 
				
			||||||
    headers = {"Accept": "application/json", "Content-Type": "application/json", "Authorization": api_key_b64}
 | 
					    res = requests.post(url, json=payload, auth=ReadmeAuth(), timeout=30)
 | 
				
			||||||
    response = requests.post(url, json=payload, headers=headers)
 | 
					    res.raise_for_status()
 | 
				
			||||||
    print("create_version()")
 | 
					 | 
				
			||||||
    print(response.text)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def update_version_name(old_unstable_name, new_unstable_name):
 | 
					def promote_unstable_to_stable(unstable, stable):
 | 
				
			||||||
    url = "https://dash.readme.com/api/v1/version/{}".format(old_unstable_name)
 | 
					    """
 | 
				
			||||||
    payload = {"is_beta": False, "version": new_unstable_name, "from": old_unstable_name, "is_hidden": False}
 | 
					    Rename the current unstable to stable and set it as stable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    headers = {"accept": "application/json", "content-type": "application/json", "authorization": api_key_b64}
 | 
					    :param unstable: Existing unstable version
 | 
				
			||||||
 | 
					    :param stable: Non existing new stable version
 | 
				
			||||||
    response = requests.put(url, json=payload, headers=headers)
 | 
					    """
 | 
				
			||||||
    print(response.text)
 | 
					    url = f"https://dash.readme.com/api/v1/version/{unstable}"
 | 
				
			||||||
 | 
					    payload = {"is_beta": False, "version": stable, "from": unstable, "is_hidden": False, "is_stable": True}
 | 
				
			||||||
 | 
					    res = requests.put(url, json=payload, auth=ReadmeAuth(), timeout=30)
 | 
				
			||||||
 | 
					    res.raise_for_status()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def generate_new_unstable_name(unstable_version_name):
 | 
					def calculate_new_unstable(version):
 | 
				
			||||||
    version_digits_str = unstable_version_name[1:].replace("-unstable", "")
 | 
					    # version must be formatted like so <major>.<minor>
 | 
				
			||||||
    version_digits_split = version_digits_str.split(".")
 | 
					    major, minor = version.split(".")
 | 
				
			||||||
    version_digits_split[1] = str(int(version_digits_split[1]) + 1)
 | 
					    return f"{major}.{int(minor) + 1}.0-unstable"
 | 
				
			||||||
    incremented_version_digits = ".".join(version_digits_split)
 | 
					 | 
				
			||||||
    new_unstable = "v" + incremented_version_digits + "-unstable"
 | 
					 | 
				
			||||||
    return new_unstable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_categories(version):
 | 
					 | 
				
			||||||
    url = "https://dash.readme.com/api/v1/categories?perPage=10&page=1"
 | 
					 | 
				
			||||||
    headers = {"accept": "application/json", "x-readme-version": version, "authorization": api_key_b64}
 | 
					 | 
				
			||||||
    response = requests.get(url, headers=headers)
 | 
					 | 
				
			||||||
    return response.text
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def hide_version(depr_version):
 | 
					 | 
				
			||||||
    url = "https://dash.readme.com/api/v1/version/{}".format(depr_version)
 | 
					 | 
				
			||||||
    payload = {"is_beta": False, "version": depr_version, "from": "", "is_hidden": True}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    headers = {"accept": "application/json", "content-type": "application/json", "authorization": api_key_b64}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    response = requests.put(url, json=payload, headers=headers)
 | 
					 | 
				
			||||||
    print(response.text)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def generate_new_depr_name(depr_name):
 | 
					 | 
				
			||||||
    version_digits_str = depr_name[1:]
 | 
					 | 
				
			||||||
    version_digits_split = version_digits_str.split(".")
 | 
					 | 
				
			||||||
    version_digits_split[1] = str(int(version_digits_split[1]) + 1)
 | 
					 | 
				
			||||||
    incremented_version_digits = ".".join(version_digits_split)
 | 
					 | 
				
			||||||
    new_depr = "v" + incremented_version_digits + "-and-older"
 | 
					 | 
				
			||||||
    return new_depr
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_old_and_older_name(versions):
 | 
					 | 
				
			||||||
    ret = []
 | 
					 | 
				
			||||||
    for v in versions:
 | 
					 | 
				
			||||||
        if v.endswith("-and-older"):
 | 
					 | 
				
			||||||
            ret.append(v)
 | 
					 | 
				
			||||||
    if len(ret) == 1:
 | 
					 | 
				
			||||||
        return ret[0]
 | 
					 | 
				
			||||||
    return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def generate_new_and_older_name(old):
 | 
					 | 
				
			||||||
    digits_str = old[1:].replace("-and-older", "")
 | 
					 | 
				
			||||||
    digits_split = digits_str.split(".")
 | 
					 | 
				
			||||||
    digits_split[1] = str(int(digits_split[1]) + 1)
 | 
					 | 
				
			||||||
    incremented_digits = ".".join(digits_split)
 | 
					 | 
				
			||||||
    new = "v" + incremented_digits + "-and-older"
 | 
					 | 
				
			||||||
    return new
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    # Comments below are for a case where we are releasing new_version="v1.9".
 | 
					 | 
				
			||||||
    # This requires for v1.9-unstable and v1.8 to exist in Readme.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    parser = argparse.ArgumentParser()
 | 
					    parser = argparse.ArgumentParser()
 | 
				
			||||||
    parser.add_argument(
 | 
					    parser.add_argument(
 | 
				
			||||||
        "-v", "--version", help="The new minor version that is being released (e.g. v1.9.1).", required=True
 | 
					        "-v", "--new-version", help="The new minor version that is being released (e.g. 1.9).", required=True
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    parser.add_argument("-k", "--key", help="The Readme API key for Haystack documentation.", required=True)
 | 
					 | 
				
			||||||
    args = parser.parse_args()
 | 
					    args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    api_key = args.key
 | 
					    if VERSION_VALIDATOR.match(args.new_version) is None:
 | 
				
			||||||
    api_key += ":"
 | 
					        sys.exit("Version must be formatted like so <major>.<minor>")
 | 
				
			||||||
    api_key_b64 = "Basic " + base64.b64encode(api_key.encode("utf-8")).decode("utf-8")
 | 
					
 | 
				
			||||||
 | 
					    # This two are the version that we must have published in the end
 | 
				
			||||||
 | 
					    new_stable = f"{args.new_version}.0"
 | 
				
			||||||
 | 
					    new_unstable = calculate_new_unstable(args.new_version)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    new_version = args.version
 | 
					 | 
				
			||||||
    # Drop the patch version, e.g. v1.9.1 -> v1.9
 | 
					 | 
				
			||||||
    new_version = ".".join(new_version.split(".")[:2])
 | 
					 | 
				
			||||||
    versions = get_versions()
 | 
					    versions = get_versions()
 | 
				
			||||||
 | 
					    new_stable_is_published = new_stable in versions
 | 
				
			||||||
 | 
					    new_unstable_is_published = new_unstable in versions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    curr_unstable = new_version + "-unstable"
 | 
					    if new_stable_is_published and new_unstable_is_published:
 | 
				
			||||||
    assert new_version[1:] not in versions, "Version {} already exists in Readme.".format(new_version[1:])
 | 
					        # If both versions are published there's nothing to do.
 | 
				
			||||||
    assert curr_unstable[1:] in versions, "Version {} does not exist in Readme.".format(curr_unstable[1:])
 | 
					        # We fail gracefully.
 | 
				
			||||||
 | 
					        print(f"Both new version {new_stable} and {new_unstable} are already published.")
 | 
				
			||||||
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					    elif new_stable_is_published or new_unstable_is_published:
 | 
				
			||||||
 | 
					        # Either new stable or unstable is already published, it's to risky to
 | 
				
			||||||
 | 
					        # proceed so we abort the publishing process.
 | 
				
			||||||
 | 
					        sys.exit(f"Either version {new_stable} or {new_unstable} are already published. Too risky to proceed.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # create v1.9 forked from v1.9-unstable
 | 
					    # This version must exist since it's the one we're trying to promote
 | 
				
			||||||
    create_version(new_version=new_version, fork_from_version=curr_unstable, is_stable=False)
 | 
					    # to stable.
 | 
				
			||||||
 | 
					    current_unstable = f"{new_stable}-unstable"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # rename v1.9-unstable to v1.10-unstable
 | 
					    if current_unstable not in versions:
 | 
				
			||||||
    new_unstable = generate_new_unstable_name(curr_unstable)
 | 
					        sys.exit(f"Can't find version {current_unstable} to promote to {new_stable}")
 | 
				
			||||||
    update_version_name(curr_unstable, new_unstable)
 | 
					
 | 
				
			||||||
 | 
					    # First we create new unstable from the currently existing one
 | 
				
			||||||
 | 
					    create_new_unstable(current_unstable, new_unstable)
 | 
				
			||||||
 | 
					    # Then we promote the current unstable to stable since it's the one being published
 | 
				
			||||||
 | 
					    promote_unstable_to_stable(current_unstable, new_stable)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								.github/workflows/minor_version_release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/minor_version_release.yml
									
									
									
									
										vendored
									
									
								
							@ -49,9 +49,9 @@ jobs:
 | 
				
			|||||||
      - name: Install release_docs.py dependencies
 | 
					      - name: Install release_docs.py dependencies
 | 
				
			||||||
        run: pip install requests
 | 
					        run: pip install requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # Note that patch versions all sync to the one readme minor version
 | 
					 | 
				
			||||||
      # e.g. Haystack 1.9.1 and 1.9.2 both map to Readme 1.9
 | 
					 | 
				
			||||||
      - name: Release Readme version
 | 
					      - name: Release Readme version
 | 
				
			||||||
 | 
					        env:
 | 
				
			||||||
 | 
					          RDME_API_KEY: ${{ secrets.README_API_KEY }}
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          git checkout main
 | 
					          git checkout main
 | 
				
			||||||
          python ./.github/utils/release_docs.py --version v${{ steps.versions.outputs.current_release_minor }} --key ${{ secrets.README_API_KEY }}
 | 
					          python ./.github/utils/release_docs.py --new-version ${{ steps.versions.outputs.current_release_minor }}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user