From 01bad68bd1ab1193431c81345c9fae4658a99502 Mon Sep 17 00:00:00 2001 From: mario4tier Date: Mon, 23 Dec 2024 22:01:02 -0500 Subject: [PATCH] CI - Add post-release-docs.py to update website with latest version released --- README-DEVS.md | 56 +++++++++------------- docs/install.md | 2 +- scripts/merge.py | 2 +- scripts/post-release-docs.py | 88 +++++++++++++++++++++++++++++++++++ scripts/utilities/versions.py | 2 +- 5 files changed, 114 insertions(+), 36 deletions(-) create mode 100755 scripts/post-release-docs.py diff --git a/README-DEVS.md b/README-DEVS.md index 40b86a8f..c6edc0c9 100644 --- a/README-DEVS.md +++ b/README-DEVS.md @@ -1,5 +1,5 @@ # Instructions for TA-Lib maintainers -**If you only want to install and use TA-Lib, there is nothing here for you... check instead the main README.md file.** +**If you only want to install and use TA-Lib, there is nothing here for you... check instead https://ta-lib.org/install ** You must have python installed. @@ -12,17 +12,6 @@ Before committing, run ```scripts/sync.py``` to: Merge to main branch are done with ```scripts/merge.py``` by TA-Lib maintainers with the proper permissions. -## How to build with autotools -As needed, install dependencies: -```$ sudo apt install automake libtool autogen mcpp``` - -Build everything (includes gen_code and ta_regtest): -``` -$ cd ta-lib -$ autoreconf -fi -$ ./configure -$ make -``` ## How to update the "./configure" script This will do all the needed autotools steps: ```$ autoreconf -fi``` @@ -54,43 +43,44 @@ After ```make```, call ```ta_regtest``` located in ta-lib/src/tools Exit code is 0 on success -## How to package the library -Commit your source code changes in devs and... just let the Github action do all the repackaging for you. +## How to do a new release? -The produced packages will be written in ta-lib/dist. +Any dev with permission to merge to main branch can do a release. -It may take up to one day for the CI to regenerate and test **all** for all platforms. +(1) On the dev branch, edit the VERSION file in the root of the repos. -The rest of this section is only if you want to re-package locally. +(2) Run "./scripts/sync.py". This ensures your dev branch is up-to-date (among other things). -You can call the ```scripts/package.py``` to generate the packages for your hosting platform. +(3) Push to the dev branch. -You can test your packages with ```scripts/test-dist.py```. This verifies from a TA-Lib user perspective. Notably, this simulates a ta-lib-python user. +(4) Wait up to one day for the "nightly dev" Github action to succeed. This will regenerate and test for **all** platforms. As needed, you can instead manually trig it. -Try to avoid pushing your generated packages to the TA-Lib repo, but do not worry if you do. As needed, they will get overwritten by the "nightly dev" Github action. +(5) Merge dev into main with "./scripts/merge.py". At this point, the main branch is the release candidate with all the assets under "dist" folder. +(6) Wait up to one day for the "nightly main" Github action to succeed. This will perform few more consistency checks. As needed, you can instead manually trig it. -## How to do a new release? +(7) Manually trig the "Release (step-1)" Github action on main branch. This will tag, generate a draft release and attach all assets from the dist/ directory. -Any dev with permission to merge to main branch can do a release. +(8) Optionally edit the draft "Release notes" on the Github website and verify that everything looks fine. -(1) On the dev branch, edit the VERSION file in the root of the repos. +(9) Manually trig "Release (step 2)" Github action. This will make the release public, update the website and create a PR on homebrew-core. -(2) Run "./scripts/sync.py". This ensures your dev branch is up-to-date (among other things). +(10) Verify that https://ta-lib.org/install reflects the new version. -(3) Push to the dev branch. +(11) Monitor that the PR on homebrew-core is working as expected. The following formula will eventually be updated (may take an hour): +https://github.com/Homebrew/homebrew-core/blob/30106807361198c58a395de65547694427adf229/Formula/t/ta-lib.rb -(4) Wait up to one day for the "nightly dev" Github action to succeed. This will regenerate and test **all** the packages for **all** platforms. As needed, you can instead manually trig it. +## I want to modify the code... should I care to rebuild the packages? +No. -(5) Merge dev into main with "./scripts/merge.py". At this point, the main branch is the release candidate with all the assets under "dist" folder. +Commit your source code changes in devs and... just let the Github action do all the repackaging for you. -(6) Wait up to one day for the "nightly main" Github action to succeed. This will perform a last check that all assets are OK. As needed, you can instead manually trig it. +It may take up to one day for the CI to regenerate and test for **all** platforms. -(7) Manually trig the "publish-step-1" Github action on main branch. This will create the tag, draft release and attach all assets from the dist/ directory. +The rest of this section is only if you want to re-package locally. -(8) Edit the draft Release notes on the Github website. +You can call the ```scripts/package.py``` to generate the packages for your hosting platform. -(9) Manually trig "publish-step-2" Github action. This will make the release public. +You can test your packages with ```scripts/test-dist.py```. This verifies from a TA-Lib user perspective. Notably, this simulates a ta-lib-python user. -(10) Manually trig "publish-step-3". This will submit a PR to update homebrew for macOS users: -https://github.com/Homebrew/homebrew-core/blob/30106807361198c58a395de65547694427adf229/Formula/t/ta-lib.rb \ No newline at end of file +Try to avoid pushing your generated packages to the TA-Lib repo, but do not worry if you do. As needed, they will get overwritten by the "nightly dev" CI. diff --git a/docs/install.md b/docs/install.md index cb7f0c86..8ee8a131 100644 --- a/docs/install.md +++ b/docs/install.md @@ -95,7 +95,7 @@ Recommended for all debian-based distributions (e.g. Ubuntu, Mint...) 2. **Extract the Tarball**: ```bash tar -xzf ta-lib-0.6.1-src.tar.gz - cd ta-lib + cd ta-lib-0.6.1 ``` 3. **Build and Install**: diff --git a/scripts/merge.py b/scripts/merge.py index b3872aa7..0618df4a 100755 --- a/scripts/merge.py +++ b/scripts/merge.py @@ -31,7 +31,7 @@ def main(): # Make sure the dev branch is up-to-date with the remote. run_command(['git', 'fetch', 'origin', 'dev']) if run_command(['git', 'rev-parse', 'dev']) != run_command(['git', 'rev-parse', 'origin/dev']): - print("dev branch not up-to-date with remote. Do 'git push'.") + print("dev branch not up-to-date with remote. Do 'git pull'.") sys.exit(1) # Call sync to verify that dev is up-to-date with main. diff --git a/scripts/post-release-docs.py b/scripts/post-release-docs.py new file mode 100755 index 00000000..97a75dce --- /dev/null +++ b/scripts/post-release-docs.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +# Updates the website/documentation to match the latest release. +# +# Can be called directly, but more intended to be called by Github Actions. +# +import argparse +from dataclasses import dataclass +import json +import os +import re +import sys +import requests + +from utilities.files import calculate_file_sha256, path_join +from utilities.common import is_brew_installed, run_command, verify_git_repo_original + +try: + from github import Github, Auth +except ImportError: + print("This script requires the PyGithub library and it is not installed. Please do 'pip install PyGithub'") + sys.exit(1) + +def replace_version(file_path: str, version: str): + # Replace ALL "x.y.z" pattern with "version". + # + # This happens only if the pattern is surrounded by characters such as "v", "[",-", "_" or whitespaces... + # this is an heuristic logic to minimize changing unexpected text. + with open(file_path, 'r') as f: + content = f.read() + + # Define the regex pattern to match version numbers + pattern = r'(?<=[v/\[\-_\s])\d+\.\d+\.\d+(?=[/\]\-_\s])' + + # Replace the matched patterns with the new version + updated_content = re.sub(pattern, version, content) + + # Write the updated content back to the file only if there is a change + if content != updated_content: + with open(file_path, 'w') as f: + f.write(updated_content) + print(f"Updated version in {file_path} to {version}") + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description='Post-release documentation update') + parser.add_argument('--token', help='GitHub token for authentication', required=False) + args = parser.parse_args() + + # if an env GITHUB_TOKEN is defined... use it. + if not args.token and 'GITHUB_TOKEN' in os.environ: + args.token = os.getenv('GITHUB_TOKEN') + else: + print("Warning: No GITHUB_TOKEN env variable defined. Rate limit may fail the script.") + + if args.token: + print("Using GitHub token for authentication") + + # Will exit if run from a fork. + root_dir = verify_git_repo_original() + + try: + g = Github(args.token) if args.token else Github() + repos = g.get_repo("ta-lib/ta-lib") + gh_version_obj = repos.get_latest_release() + # Remove the 'v' prefix as needed + gh_version = gh_version_obj.title.lstrip('v') + + print(f"Github release version : {gh_version}") + + # Update version on the website installation page + website_dir = path_join(root_dir, 'docs') + install_md_file = path_join(website_dir, 'install.md') + replace_version(install_md_file, gh_version) + + except Exception as e: + print(f"Error: {e}") + sys.exit(1) + + + + + + + + + + diff --git a/scripts/utilities/versions.py b/scripts/utilities/versions.py index f29cfbd9..30b3856c 100644 --- a/scripts/utilities/versions.py +++ b/scripts/utilities/versions.py @@ -432,7 +432,7 @@ def calculate_sources_digest(root_dir: str, silent: bool = False) -> str: def sync_sources_digest(root_dir: str) -> Tuple[bool,str]: - calculated_digest = calculate_sources_digest(root_dir) + calculated_digest = calculate_sources_digest(root_dir, silent=True) # Update ta_common.h (touch only if different) current_digest = read_sources_digest(root_dir) if current_digest == calculated_digest: