Skip to content

Commit

Permalink
CI - Add post-release-docs.py to update website with latest version r…
Browse files Browse the repository at this point in the history
…eleased
  • Loading branch information
mario4tier committed Dec 24, 2024
1 parent 5b33919 commit 01bad68
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 36 deletions.
56 changes: 23 additions & 33 deletions README-DEVS.md
Original file line number Diff line number Diff line change
@@ -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.

Expand All @@ -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```
Expand Down Expand Up @@ -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
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.
2 changes: 1 addition & 1 deletion docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -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**:
Expand Down
2 changes: 1 addition & 1 deletion scripts/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
88 changes: 88 additions & 0 deletions scripts/post-release-docs.py
Original file line number Diff line number Diff line change
@@ -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)










2 changes: 1 addition & 1 deletion scripts/utilities/versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 01bad68

Please sign in to comment.