mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
a155a1ca80
The choco dir was renamed from choco/blenderbim to choco/bonsai back in 2024 (Rename choco dir), but choco_release.py's BLENDERBIM_DIR constant was never updated, so the daily choco release job crashes immediately with FileNotFoundError trying to os.chdir into the now nonexistent choco/blenderbim directory. Release tags also moved from a bare blenderbim-YYMMDD scheme to bonsai-X.Y.Z-alphaYYMMDDHHMM, so the tag-prefix strip used to build the package version still looked for the old "blenderbim-" prefix and left it untouched, embedding the raw tag (including the already-present "-alpha" segment) into the nuspec version field, which the template then doubled up with its own "-alpha" suffix, producing an invalid NuGet version string. Both are fixed together since the second bug would otherwise surface as soon as the first one is unblocked. The pre-commit black hook also reformatted pre-existing whitespace drift in choco_release.py (this file sits outside CI's lint scope, so it had never been auto-formatted before); that reformatting is incidental to satisfying the local hook, not part of the fix itself. Generated with the assistance of an AI coding tool.
238 lines
7.8 KiB
Python
238 lines
7.8 KiB
Python
# commands to run it on a generic ubuntu 2404 oci container:
|
|
"""
|
|
apt update && apt install git wget curl ptpython mono-devel micro
|
|
mkdir -p /home/runner/work/IfcOpenShell && cd /home/runner/work/IfcOpenShell
|
|
git clone https://github.com/IfcOpenShell/IfcOpenShell
|
|
cd /home/runner/work/IfcOpenShell/IfcOpenShell/choco/bonsai/
|
|
micro choco_release.py # paste this script, comment out push command
|
|
export CHOCO_TOKEN="secret_choco_release_token"
|
|
python3 choco_release.py
|
|
"""
|
|
|
|
import datetime
|
|
import hashlib
|
|
import os
|
|
import pathlib
|
|
import re
|
|
import subprocess
|
|
from typing import NoReturn
|
|
from urllib import request
|
|
|
|
from github import Github
|
|
|
|
|
|
def get_repo_tag_names() -> list[str]:
|
|
git_return = subprocess.check_output("git tag -l", text=True)
|
|
tag_names = [tag_name for tag_name in git_return.split("\n") if tag_name]
|
|
print(f"{len(tag_names)} tag_names found in repo")
|
|
return tag_names
|
|
|
|
|
|
def request_repo_info(url: str):
|
|
req = request.Request(url)
|
|
resp = request.urlopen(req)
|
|
if not resp.status == 200:
|
|
print(f"[ERROR] could not contact server: {url}")
|
|
quit(1)
|
|
return resp
|
|
|
|
|
|
def get_choco_package_info() -> str:
|
|
resp = request_repo_info(URL_CHOCO_PACKAGE)
|
|
html_txt = str(resp.read())
|
|
return html_txt
|
|
|
|
|
|
def get_latest_choco_blender_version() -> list:
|
|
html_txt = get_choco_package_info()
|
|
return re.findall(RE_BLENDER_VERSION_MIN_MAJ_PAT, html_txt)
|
|
|
|
|
|
def get_file_sha256_hash(file_path: str) -> str:
|
|
BLOCKSIZE = 65536
|
|
hasher = hashlib.sha256()
|
|
|
|
with open(file_path, "rb") as input_file:
|
|
buffer = input_file.read(BLOCKSIZE)
|
|
while len(buffer) > 0:
|
|
hasher.update(buffer)
|
|
buffer = input_file.read(BLOCKSIZE)
|
|
|
|
return hasher.hexdigest()
|
|
|
|
|
|
def quit_with_error_message(message: str) -> NoReturn:
|
|
print(f"ERROR: {message}")
|
|
quit(0)
|
|
|
|
|
|
def get_release_zip(tag: str) -> tuple[str, str]:
|
|
g = Github()
|
|
repo = g.get_repo("IfcOpenShell/IfcOpenShell")
|
|
release = repo.get_release(tag)
|
|
for asset in release.get_assets():
|
|
asset_name = asset.name
|
|
if python_version not in asset_name:
|
|
continue
|
|
if TARGET_OS not in asset_name:
|
|
continue
|
|
return (asset_name, asset.browser_download_url)
|
|
raise Exception(f"Couldn't find the release matching '{python_version}' and '{TARGET_OS}' in tag '{tag}'.")
|
|
|
|
|
|
def run(command: str) -> None:
|
|
subprocess.check_output(command)
|
|
|
|
|
|
start = datetime.datetime.now()
|
|
|
|
URL_CHOCO_PACKAGE = "https://community.chocolatey.org/packages/blender"
|
|
URL_BLENDER_CMAKE = (
|
|
"https://raw.githubusercontent.com/blender/blender/{}/build_files/cmake/Modules/FindPythonLibsUnix.cmake"
|
|
)
|
|
RE_BLENDER_VERSION_MIN_MAJ = r"Latest Version.+<span>Blender (\d+\.\d+)\..+</span>"
|
|
RE_BLENDER_VERSION_MIN_MAJ_PAT = r"Latest Version.+<span>Blender (\d+\.\d+\.\d+)</span>"
|
|
RE_BLENDER_PYTHON_VERSION_MAJ_MIN = r"\(_PYTHON_VERSION_SUPPORTED (\d+\.\d+)\)"
|
|
|
|
BLENDERBIM_DIR = pathlib.Path("/home/runner/work/IfcOpenShell/IfcOpenShell/choco/bonsai/")
|
|
|
|
print("_____ check choco release needed?")
|
|
|
|
os.chdir(BLENDERBIM_DIR)
|
|
|
|
blenderbim_date_yesterday = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%y%m%d")
|
|
should_release = False
|
|
target_release_tag = ""
|
|
TARGET_OS = "windows-x64"
|
|
|
|
git_status = subprocess.check_output("git status", text=True)
|
|
print(git_status)
|
|
|
|
for tag_name in get_repo_tag_names():
|
|
print(tag_name)
|
|
if blenderbim_date_yesterday in tag_name:
|
|
should_release = True
|
|
target_release_tag = tag_name
|
|
print(f"found {tag_name=} - {should_release=}")
|
|
break
|
|
|
|
if not should_release:
|
|
print(f"INFO: no blenderbim release tags found for {blenderbim_date_yesterday} -> no choco release today.")
|
|
quit(0)
|
|
print(f"{should_release=}")
|
|
|
|
if not os.environ.get("CHOCO_TOKEN"):
|
|
quit_with_error_message("could retrieve CHOCO_TOKEN env var")
|
|
choco_token = os.environ["CHOCO_TOKEN"]
|
|
|
|
print("\n_____ get blender info")
|
|
# blender_version_min_maj_pat - from chocolatey.org
|
|
latest_blender_release_maj_min_pat = get_latest_choco_blender_version()
|
|
if not latest_blender_release_maj_min_pat:
|
|
quit_with_error_message("could not determine blender_version_min_maj_pat")
|
|
latest_blender_release_maj_min_pat = latest_blender_release_maj_min_pat[0]
|
|
print(f"{latest_blender_release_maj_min_pat=}")
|
|
|
|
# blender_version_min_maj - from chocolatey.org
|
|
blender_version_min_maj = latest_blender_release_maj_min_pat.rsplit(".", 1)[0]
|
|
print(f"{blender_version_min_maj=}")
|
|
|
|
# blender_python_version_maj_min - from blender repo
|
|
python_version = ""
|
|
latest_blender_version_tag = f"v{latest_blender_release_maj_min_pat}"
|
|
resp = request_repo_info(URL_BLENDER_CMAKE.format(latest_blender_version_tag))
|
|
html_txt = str(resp.read())
|
|
found = re.findall(RE_BLENDER_PYTHON_VERSION_MAJ_MIN, html_txt)
|
|
if not found:
|
|
quit_with_error_message("could not determine blender_python_version_maj_min")
|
|
|
|
blender_python_version_maj_min = found[0]
|
|
print(f"{blender_python_version_maj_min=}")
|
|
python_version = f"py{found[0].replace('.', '')}"
|
|
print(f"{python_version=}")
|
|
|
|
blenderbim_build_version = target_release_tag.replace("bonsai-", "")
|
|
|
|
# url_blenderbim_py3x_win_zip
|
|
release_zip_file_name, url_blenderbim_py3x_win_zip = get_release_zip(target_release_tag)
|
|
subprocess.check_call(f"wget {url_blenderbim_py3x_win_zip} --no-verbose")
|
|
|
|
# sha256sum_blenderbim_py310_win_zip
|
|
sha256sum_blenderbim_py3x_win_zip = get_file_sha256_hash(release_zip_file_name)
|
|
|
|
print("\n_____ fill dynamic chocolatey package parameters")
|
|
HERE_DIR = pathlib.Path(__file__).parent.absolute()
|
|
# print(f"[INFO] HERE_DIR: {HERE_DIR}")
|
|
|
|
topics = {
|
|
"spec": {
|
|
"path": HERE_DIR / "blenderbim.nuspec",
|
|
"key_values": {
|
|
"latest_blender_version_maj_min_pat": latest_blender_release_maj_min_pat,
|
|
"blenderbim_build_version": blenderbim_build_version,
|
|
},
|
|
},
|
|
"install": {
|
|
"path": HERE_DIR / "tools" / "chocolateyinstall.ps1",
|
|
"key_values": {
|
|
"url_blenderbim_py3x_win_zip": url_blenderbim_py3x_win_zip,
|
|
"sha256sum_blenderbim_py3x_win_zip": sha256sum_blenderbim_py3x_win_zip,
|
|
"latest_blender_version_maj_min": blender_version_min_maj,
|
|
},
|
|
},
|
|
"uninstall": {
|
|
"path": HERE_DIR / "tools" / "chocolateyuninstall.ps1",
|
|
"key_values": {
|
|
"latest_blender_version_maj_min": blender_version_min_maj,
|
|
},
|
|
},
|
|
}
|
|
|
|
for topic, info in topics.items():
|
|
print(f" {topic}:")
|
|
with open(info["path"], encoding="utf-8") as txt:
|
|
content = txt.read()
|
|
|
|
for key, value in info["key_values"].items():
|
|
# print(f"[INFO] replace: {env_var_name}")
|
|
if not key in content:
|
|
print(f" {key=} not found in {info['path']}")
|
|
content = content.replace(key, value)
|
|
|
|
with open(info["path"], "w", encoding="utf-8") as txt:
|
|
txt.write(content)
|
|
print(f" written: {info['path']}")
|
|
|
|
print("[INFO] inserting dynamic chocolatey package parameters successful")
|
|
|
|
|
|
print("\n_____ build choco.exe with mono")
|
|
|
|
choco_version = "1.1.0"
|
|
run(f"wget https://github.com/chocolatey/choco/archive/refs/tags/{choco_version}.tar.gz --quiet")
|
|
run(f"tar -xzf {choco_version}.tar.gz")
|
|
print("choco tar unpack successful")
|
|
os.chdir("choco-1.1.0")
|
|
run("./build.sh")
|
|
|
|
run("cp -r build_output/chocolatey /opt/chocolatey")
|
|
os.chdir(BLENDERBIM_DIR)
|
|
|
|
if pathlib.Path("/opt/chocolatey/choco.exe").exists():
|
|
print("choco build successful")
|
|
|
|
print("\n_____ build choco pack")
|
|
|
|
run("mono /opt/chocolatey/choco.exe pack --allow-unofficial")
|
|
run(
|
|
'mono /opt/chocolatey/choco.exe setapikey --key="{choco_token}" --source="https://push.chocolatey.org/" --allow-unofficial'
|
|
)
|
|
|
|
print("\n_____ build choco push")
|
|
run(
|
|
'mono /opt/chocolatey/choco.exe push --source="https://push.chocolatey.org/" --key="$CHOCO_TOKEN" --allow-unofficial --verbose'
|
|
)
|
|
|
|
print(f"choco push of version: {target_release_tag} successful!")
|
|
print(f"it took: {datetime.datetime.now() - start}")
|