From 29b881dd104b51d81497f20dff2a14940fcc22ed Mon Sep 17 00:00:00 2001 From: azfoo <45888544+azfoo@users.noreply.github.com> Date: Fri, 20 Mar 2026 18:22:26 +0000 Subject: [PATCH 1/7] fix: zip mac can't seem to release without zipping --- .github/workflows/build.yml | 3 +++ scripts/deploy.py | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 80de32e0..dee15306 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,6 +77,9 @@ jobs: echo "\n\nStarting CLI..." echo "gtimeout 10 ${{ steps.build-exe.outputs.out-filepath }}/Contents/MacOS/${{ steps.build-exe.outputs.out-filename }} --user-interface=cli" | bash || true + zip -r9 ${{ steps.build-exe.outputs.zip-filepath }} ${{ steps.build-exe.outputs.out-filepath }} || true + rm -rf ${{ steps.build-exe.outputs.out-filepath }} + - name: Test executable [Windows] if: runner.os == 'Windows' shell: bash diff --git a/scripts/deploy.py b/scripts/deploy.py index 10b0461d..264aec7b 100644 --- a/scripts/deploy.py +++ b/scripts/deploy.py @@ -255,16 +255,16 @@ def build(): _build_exe() if os.environ.get("GITHUB_OUTPUT"): if "mac" in build_os: - os.rename( - outdir / "exe" / "tilia.app", - outdir / "exe" / (out_filename + ".app"), - ) - out_filepath = outdir / "exe" / (out_filename + ".app") + out_filepath = outdir / "exe" / "tilia.app" else: out_filepath = outdir / "exe" / out_filename with open(os.environ["GITHUB_OUTPUT"], "a") as f: f.write(f"out-filepath={out_filepath.as_posix()}\n") f.write(f"out-filename={out_filename}\n") + if "mac" in build_os: + f.write( + f"zip-filepath={outdir.as_posix()}/exe/{out_filename}.zip\n" + ) os.chdir(old_dir) dotenv.set_key(".tilia.env", "ENVIRONMENT", old_env_var) except Exception as e: From c469648c250e24e147e56a19586c04066babfd75 Mon Sep 17 00:00:00 2001 From: azfoo <45888544+azfoo@users.noreply.github.com> Date: Sat, 21 Mar 2026 20:50:57 +0000 Subject: [PATCH 2/7] ci: check release count --- .github/workflows/build.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dee15306..02ed9db9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -123,7 +123,6 @@ jobs: deploy: name: Create release - continue-on-error: true needs: build runs-on: "ubuntu-latest" permissions: @@ -166,9 +165,22 @@ jobs: - name: Upload uses: "softprops/action-gh-release@v2" + id: release with: tag_name: ${{github.ref_name}} make_latest: ${{github.event_name == 'push'}} generate_release_notes: true files: | build/*/exe/TiLiA-v* + + - name: Check output + run: | + echo "Counting assets released..." + if [ -n "${{ fromJSON(steps.release.outputs.assets)[3].id }}" ] && [ -z "${{ fromJSON(steps.release.outputs.assets)[4].id }}" ]; + then + echo "4 assets found!" + else + echo "::error::Incorrect number of assets! Potential errors in build." + echo assets: ${{ steps.release.outputs.assets }} + exit 1; + fi; From 477bf7e336032ba1f5e4d3ac0bb891baa146f21f Mon Sep 17 00:00:00 2001 From: azfoo <45888544+azfoo@users.noreply.github.com> Date: Mon, 23 Mar 2026 18:32:58 +0000 Subject: [PATCH 3/7] feat: one step less --- CONTRIBUTING.md | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f38a0488..ee2a5bb4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,6 +33,6 @@ You need Python >=3.10 to build and test TiLiA. You will also need to have ffmpe # Developing for TiLiA For a better development experience, we recommend the installation of a few more packages: ``` -pip install --group dev --group testing +pip install --group dev pre-commit install ``` diff --git a/pyproject.toml b/pyproject.toml index 07a377ff..d270bb1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,6 +62,7 @@ ci-tests = [ dev = [ "icecream>=2.1.0", "pre-commit", + {include-group = "testing"}, ] testing = [ "pytest>=8.0.0", From 79cbf44b8b920115fd93c6edc73a746998152aa9 Mon Sep 17 00:00:00 2001 From: azfoo <45888544+azfoo@users.noreply.github.com> Date: Mon, 23 Mar 2026 18:33:45 +0000 Subject: [PATCH 4/7] fix: version warning --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index d270bb1d..f1f7fa50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ description = "A GUI for creating and visualizing annotations over audio and vid readme = "README.md" requires-python = ">=3.10,<3.14" dependencies = [ + "chardet<6.0.0", "colorama~=0.4.6", "httpx~=0.28.1", "isodate~=0.7.2", From 62a5c958742734db024734bf24957e739de12b06 Mon Sep 17 00:00:00 2001 From: azfoo <45888544+azfoo@users.noreply.github.com> Date: Mon, 23 Mar 2026 18:34:21 +0000 Subject: [PATCH 5/7] fix: skip hanging tests --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index f1f7fa50..448c4695 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,7 @@ ci-tests = [ "coverage-badge>=1.0.0", "ruff>=0.15.0", "pytest-cov>=6.0.0", + "pytest-timeout", ] dev = [ "icecream>=2.1.0", @@ -92,6 +93,7 @@ env = [ "ENVIRONMENT=test", "QT_QPA_PLATFORM=offscreen", ] +timeout = 10 [tool.ruff] exclude = ["tilia/dev"] From e2a28f21dade21825c044cd190a930fd8cafd890 Mon Sep 17 00:00:00 2001 From: azfoo <45888544+azfoo@users.noreply.github.com> Date: Tue, 24 Mar 2026 00:18:06 +0000 Subject: [PATCH 6/7] fix: finding package --- scripts/deploy.py | 18 ++++++++++++++++++ tilia/timelines/base/timeline.py | 12 +++--------- tilia/ui/timelines/base/timeline.py | 10 ++-------- tilia/utils.py | 10 ++++++++++ 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/scripts/deploy.py b/scripts/deploy.py index 264aec7b..a04a7752 100644 --- a/scripts/deploy.py +++ b/scripts/deploy.py @@ -166,6 +166,23 @@ def _create_lib() -> Path: return lib / tilia +def _get_implicit_imports(): + from tilia.utils import get_sibling_packages + + tls = [ + tl + ".timeline" + for tl in get_sibling_packages( + "tilia.timelines.base.timeline", + (Path(__file__).parent.parent / "tilia/timelines/base/timeline").as_posix(), + ) + ] + tluis = get_sibling_packages( + "tilia.ui.timelines.base.timeline", + (Path(__file__).parent.parent / "tilia/ui/timelines/base/timeline").as_posix(), + ) + return tls + tluis + + def _update_yml(): if not Path(pkg_cfg).exists(): return @@ -191,6 +208,7 @@ def _update_yml(): }, {"include-metadata": ["TiLiA"]}, ], + "implicit-imports": [{"depends": _get_implicit_imports()}], } ) diff --git a/tilia/timelines/base/timeline.py b/tilia/timelines/base/timeline.py index 2d4b65a8..6a221d39 100644 --- a/tilia/timelines/base/timeline.py +++ b/tilia/timelines/base/timeline.py @@ -3,10 +3,8 @@ import functools import bisect import importlib -import os from abc import ABC from enum import Enum, auto -from pathlib import Path from typing import Any, Callable, TYPE_CHECKING, TypeVar, Generic, Set from tilia.timelines import serialize @@ -16,6 +14,7 @@ SetTimelineDataError, GetTimelineDataError, ) +from tilia.utils import get_sibling_packages from .validators import ( validate_string, validate_read_only, @@ -137,15 +136,10 @@ def subclasses(cls): @classmethod def ensure_subclasses_are_available(cls): - timelines_dir = Path(os.path.dirname(__file__)).parent - packages = [ - "tilia.timelines." + d.name + ".timeline" - for d in timelines_dir.iterdir() - if d.is_dir() and d.name not in ["base", "__pycache__", "collection"] - ] + packages = get_sibling_packages(__name__, __file__) for pkg in packages: try: - importlib.import_module(pkg) + importlib.import_module(pkg + ".timeline") except ModuleNotFoundError: print(f"Could not find timeline class in {pkg}.") diff --git a/tilia/ui/timelines/base/timeline.py b/tilia/ui/timelines/base/timeline.py index 8d011197..e1307474 100644 --- a/tilia/ui/timelines/base/timeline.py +++ b/tilia/ui/timelines/base/timeline.py @@ -1,9 +1,7 @@ from __future__ import annotations import functools import importlib -import os from abc import ABC -from pathlib import Path from typing import ( Any, TYPE_CHECKING, @@ -30,6 +28,7 @@ get_copy_data_from_element, ) from tilia.ui import commands +from tilia.utils import get_sibling_packages from ..view import TimelineView from ...coords import time_x_converter from ...windows import WindowKind @@ -118,12 +117,7 @@ def subclasses(cls): @classmethod def ensure_subclasses_are_available(cls): - timelines_dir = Path(os.path.dirname(__file__)).parent - packages = [ - "tilia.ui.timelines." + d.name - for d in timelines_dir.iterdir() - if d.is_dir() and d.name not in ["base", "__pycache__"] - ] + packages = get_sibling_packages(__name__, __file__) for pkg in packages: importlib.import_module(pkg) diff --git a/tilia/utils.py b/tilia/utils.py index 5b0766d1..758594f0 100644 --- a/tilia/utils.py +++ b/tilia/utils.py @@ -9,6 +9,16 @@ def get_tilia_class_string(self: Any) -> str: return self.__class__.__name__ + "-" + str(id(self)) +def get_sibling_packages(m_name: str, m_file: str): + parent_path = Path(os.path.dirname(m_file)).parent + parent_package = ".".join(m_name.split(".")[:-2]) + return [ + ".".join([parent_package, d.name]) + for d in parent_path.iterdir() + if d.is_dir() and d.name not in ["base", "collection", "__pycache__"] + ] + + def open_with_os(path: Path) -> None: if not os.path.exists(path): raise FileNotFoundError(f"File not found: {path}") From a4151c16ca9d879676e2bb025b8cbc26ba1f13e1 Mon Sep 17 00:00:00 2001 From: azfoo <45888544+azfoo@users.noreply.github.com> Date: Wed, 25 Mar 2026 14:18:34 +0000 Subject: [PATCH 7/7] fix: finding package --- tilia/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tilia/utils.py b/tilia/utils.py index 758594f0..77d1f60d 100644 --- a/tilia/utils.py +++ b/tilia/utils.py @@ -2,6 +2,7 @@ import subprocess import sys from pathlib import Path +from pkgutil import iter_modules from typing import Any @@ -14,8 +15,8 @@ def get_sibling_packages(m_name: str, m_file: str): parent_package = ".".join(m_name.split(".")[:-2]) return [ ".".join([parent_package, d.name]) - for d in parent_path.iterdir() - if d.is_dir() and d.name not in ["base", "collection", "__pycache__"] + for d in iter_modules([parent_path]) + if d.ispkg and d.name not in ["base", "collection", "__pycache__"] ]