diff --git a/.github/workflows/ci-blenderbim-choco.yml b/.github/workflows/ci-blenderbim-choco.yml index 24fb9f1005..ed95040ce2 100644 --- a/.github/workflows/ci-blenderbim-choco.yml +++ b/.github/workflows/ci-blenderbim-choco.yml @@ -33,7 +33,7 @@ jobs: strategy: fail-fast: false matrix: - pyver: [py311] + pyver: [py312] config: - { name: "Windows Build", @@ -43,59 +43,12 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 # https://github.com/actions/setup-python with: - python-version: '3.11.9' # Version range or exact version of a Python version to use, using SemVer's version range syntax + python-version: '3.12.4' # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - run: echo ${{ env.DATE }} - - name: Check in release tags if we should do a choco release - id: do_choco + - name: Check in release tags if we should do a choco release and perform release if needed + id: do_choco_release run: | cd /home/runner/work/IfcOpenShell/IfcOpenShell/choco/blenderbim/ && - echo "check GITHUB_ENV is present: $GITHUB_ENV" && - echo "::set-output name=choco_release::$(python3 check_release_needed.py)" && - echo $choco_release >> $GITHUB_STEP_SUMMARY && - echo $target_release_tag >> $GITHUB_STEP_SUMMARY - - - name: Fill chocolatey scripts on win with latest blender python - if: ${{steps.do_choco.outputs.choco_release}} == 'do_choco_release' - run: | - cd /home/runner/work/IfcOpenShell/IfcOpenShell/choco/blenderbim/ && - echo "check GITHUB_ENV is present: $GITHUB_ENV" && - yesterday_non_iso="$(date --date='yesterday' +'%y%m%d' | tr -d '\n')" && - python3 check_release_needed.py && - echo "choco_release : $choco_release" && - echo "target_release_tag: $target_release_tag" && - target_os=${{ matrix.config.short_name }} && - latest_blender_python_version_maj_min=$(python3 check_repo_infos.py --latest_blender_python_version_maj_min?) && - echo "latest_blender_python_version_maj_min?: $latest_blender_python_version_maj_min" && - pyver=$(python3 /home/runner/work/IfcOpenShell/IfcOpenShell/choco/blenderbim/check_repo_infos.py --pyver?) && - export latest_blender_version_maj_min=$(python3 check_repo_infos.py --latest_blender_release_maj_min?) && - export latest_blender_version_maj_min_pat=$(python3 check_repo_infos.py --latest_blender_release_maj_min_pat?) && - echo latest_blender_version_maj_min_pat?: $latest_blender_version_maj_min_pat && - export blenderbim_build_version="${{ env.major }}.${{ env.minor }}.$yesterday_non_iso" && - export url_blenderbim_py3x_win_zip="https://github.com/IfcOpenShell/IfcOpenShell/releases/download/$target_release_tag/$target_release_tag-$pyver-$target_os.zip" && - wget $url_blenderbim_py3x_win_zip --no-verbose && - export sha256sum_blenderbim_py3x_win_zip=$( sha256sum $target_release_tag-$pyver-$target_os.zip --tag | cut -d ' ' -f 4 | tr -d '\n') && - echo sha256sum_blenderbim_py3x_win_zip: $sha256sum_blenderbim_py3x_win_zip && - python3 fill_dynamic_parameters.py && - echo __build choco with mono && - mkdir /tmp/choco/ && - cd /tmp/choco/ && - wget "https://github.com/chocolatey/choco/archive/refs/tags/$choco_version.tar.gz" --quiet && - tar -xzf "$choco_version.tar.gz" && - cd choco-$choco_version && - chmod +x build.sh zip.sh && - ./build.sh && - cp -r build_output/chocolatey /opt/chocolatey && - cd /home/runner/work/IfcOpenShell/IfcOpenShell/choco/blenderbim/ && - echo __choco pack && - mono /opt/chocolatey/choco.exe pack --allow-unofficial && - echo __choco set apiKey && - mono /opt/chocolatey/choco.exe setapikey --key="$CHOCO_TOKEN" --source="https://push.chocolatey.org/" --allow-unofficial # && - echo __choco push && - mono /opt/chocolatey/choco.exe push --source="https://push.chocolatey.org/" --key="$CHOCO_TOKEN" --allow-unofficial --verbose - - - name: Inform user about not packaging - if: ${{steps.do_choco.outputs.choco_release}} != 'do_choco_release' - run: | - echo "no releases found today ${{ env.DATE }}, therefore choco packaging is skipped." + python3 choco_release.py diff --git a/choco/blenderbim/choco_release.py b/choco/blenderbim/choco_release.py new file mode 100644 index 0000000000..8f9cd59b63 --- /dev/null +++ b/choco/blenderbim/choco_release.py @@ -0,0 +1,212 @@ +# commands to run and test 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/blenderbim/ +export CHOCO_TOKEN="secret_choco_release_token" +python3 choco_release.py +""" +import datetime +import hashlib +import os +import pathlib +import re +from urllib import request + + +def get_repo_tag_names(): + git_return = os.popen("git tag -l").read() + return [tag_name for tag_name in git_return.split("\n") if tag_name] + + +def set_github_env_var(key: str, value: str): + env_file_path = os.getenv('GITHUB_ENV') + with open(env_file_path, "a") as env_file: + _ = env_file.write(f"{key}={value}" + "\n") + + +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_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): + 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): + print(f"ERROR: {message}") + quit(0) + + +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" +URL_IFCOS_RELEASES = "https://github.com/IfcOpenShell/IfcOpenShell/releases/download/" +RE_BLENDER_VERSION_MIN_MAJ = r"Latest Version.+Blender (\d+\.\d+)\..+" +RE_BLENDER_VERSION_MIN_MAJ_PAT = r"Latest Version.+Blender (\d+\.\d+\.\d+)" +RE_BLENDER_PYTHON_VERSION_MAJ_MIN = r"\(_PYTHON_VERSION_SUPPORTED (\d+\.\d+)\)" + +print("_____ check choco release needed?") + +blenderbim_date_yesterday = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%y%m%d") +should_release = False +target_release_tag = "" +target_os = "win" + +for tag_name in get_repo_tag_names(): + 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_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 +html_txt = get_choco_package_info() +blender_version_min_maj = re.findall(RE_BLENDER_VERSION_MIN_MAJ, html_txt) +if not blender_version_min_maj: + quit_with_error_message("could not determine blender_version_min_maj") +blender_version_min_maj = blender_version_min_maj [0] +print(f"{blender_version_min_maj=}") + +# blender_python_version_maj_min - from blender repo +# pyver +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 = f"0.0.{blenderbim_date_yesterday}" + +# url_blenderbim_py3x_win_zip +release_zip_file_name = f"{target_release_tag}-{python_version}-{target_os}.zip" + +url_blenderbim_py3x_win_zip = f"{URL_IFCOS_RELEASES}{target_release_tag}/{release_zip_file_name}" + +os.popen(f"wget {url_blenderbim_py3x_win_zip} --no-verbose").read() + +# 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 with mono") + +choco_version = "1.1.0" +os.popen(f"wget https://github.com/chocolatey/choco/archive/refs/tags/{choco_version}.tar.gz --quiet").read() +os.popen(f"tar -xzf {choco_version}.tar.gz").read() +print("choco tar unpack successful") +os.chdir("choco-1.1.0") +os.popen("./build.sh").read() + +os.popen("cp -r build_output/chocolatey /opt/chocolatey").read() +os.chdir("/home/runner/work/IfcOpenShell/IfcOpenShell/choco/blenderbim/") + +if pathlib.Path("/opt/chocolatey/choco.exe").exists(): + print("choco build successful") + +print("\n_____ build choco pack") + +os.popen("mono /opt/chocolatey/choco.exe pack --allow-unofficial").read() +os.popen('mono /opt/chocolatey/choco.exe setapikey --key="{choco_token}" --source="https://push.chocolatey.org/" --allow-unofficial').read() + +print("\n_____ build choco push") +os.popen('mono /opt/chocolatey/choco.exe push --source="https://push.chocolatey.org/" --key="$CHOCO_TOKEN" --allow-unofficial --verbose').read() + +print(f"choco push of version: {target_release_tag} successful!") +print(f"it took: {datetime.datetime.now() - start}")