Merge pull request #115 from ComfyAssets/chore/release-1.4.0
chore(release): 1.4.0 with a Registry package that has its nodes
This commit is contained in:
+33
-25
@@ -1,29 +1,37 @@
|
||||
# Files excluded from the Comfy Registry archive (gitignore syntax).
|
||||
# Everything here is development-only; the published node needs
|
||||
# __init__.py, kikotools/, web/, examples/, README, LICENSE, pyproject.toml.
|
||||
# Left out of the Comfy Registry package (comfy node publish). Git clones still
|
||||
# have everything. tests/unit/test_package_contents.py holds these rules to what
|
||||
# ComfyUI needs at run time; keep each one anchored to the root with a leading /.
|
||||
# An unanchored "tools/" also matched kikotools/tools/ and shipped 1.2.0 to 1.3.1
|
||||
# without their nodes.
|
||||
|
||||
# Test suite and tooling
|
||||
tests/
|
||||
scripts/
|
||||
.github/
|
||||
Makefile
|
||||
pytest.ini
|
||||
mypy.ini
|
||||
.flake8
|
||||
.pre-commit-config.yaml
|
||||
.secrets.baseline
|
||||
requirements-dev.txt
|
||||
# Development folders
|
||||
/tests/
|
||||
/scripts/
|
||||
/tools/
|
||||
/.github/
|
||||
/.ci-comfyui/
|
||||
/coverage/
|
||||
|
||||
# Reference / scratch code not imported by the node
|
||||
example.py
|
||||
# Docs, screenshots and example workflows used only on GitHub. ComfyUI only reads
|
||||
# example workflows from *.json directly inside examples/, and there are none.
|
||||
/docs/
|
||||
/examples/
|
||||
|
||||
# Development files
|
||||
/Makefile
|
||||
/pytest.ini
|
||||
/mypy.ini
|
||||
/.flake8
|
||||
/.pre-commit-config.yaml
|
||||
/.secrets.baseline
|
||||
/requirements-dev.txt
|
||||
/example.py
|
||||
/TESTING.md
|
||||
/.gitignore
|
||||
/.gitattributes
|
||||
|
||||
# Agent and contributor docs
|
||||
CLAUDE.md
|
||||
CONTRIBUTING.md
|
||||
CODE_OF_CONDUCT.md
|
||||
|
||||
tools/
|
||||
.ci-comfyui/
|
||||
coverage/
|
||||
TESTING.md
|
||||
AGENTS.md
|
||||
/CLAUDE.md
|
||||
/AGENTS.md
|
||||
/CONTRIBUTING.md
|
||||
/CODE_OF_CONDUCT.md
|
||||
|
||||
+11
-1
@@ -1,6 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
## 1.4.0
|
||||
|
||||
### Packaging
|
||||
|
||||
- The Comfy Registry package has its nodes again. An unanchored `tools/` rule in
|
||||
`.comfyignore` also matched `kikotools/tools/`, so the 1.2.0 to 1.3.1 packages
|
||||
shipped without the tool modules; installs from git were not affected. Every
|
||||
rule is now anchored to the root, and `tests/unit/test_package_contents.py`
|
||||
holds them to what ComfyUI needs.
|
||||
- `docs/` and `examples/` are left out of the package as well; they are only
|
||||
read on GitHub. The download goes from about 8.5 MB to about 0.26 MB.
|
||||
|
||||
### Local Image Loader
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
||||
[project]
|
||||
name = "kikotools"
|
||||
description = "Simple tools for ComfyUI"
|
||||
version = "1.3.1"
|
||||
version = "1.4.0"
|
||||
license = {text = "MIT"}
|
||||
dependencies = []
|
||||
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
"""What the Registry package leaves out.
|
||||
|
||||
``comfy node publish`` zips the tracked files minus ``.comfyignore``. These checks
|
||||
hold the two ways that can go wrong: a development folder creeping back into the
|
||||
download, or a rule that drops something ComfyUI needs at run time. An unanchored
|
||||
``tools/`` rule did the second for 1.2.0 to 1.3.1: it also matched kikotools/tools/,
|
||||
so those packages shipped without their nodes.
|
||||
"""
|
||||
|
||||
import ast
|
||||
import fnmatch
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
RUNTIME_DIRS = ("kikotools", "web")
|
||||
DEVELOPMENT = (
|
||||
"tests/unit/test_package_contents.py",
|
||||
"scripts/run_mypy.sh",
|
||||
"tools/testing/package.json",
|
||||
"docs/ui-migration.md",
|
||||
"examples/workflows/display_text_example.json",
|
||||
".github/workflows/publish.yml",
|
||||
"Makefile",
|
||||
"requirements-dev.txt",
|
||||
"CLAUDE.md",
|
||||
"AGENTS.md",
|
||||
)
|
||||
KEPT = (
|
||||
"__init__.py",
|
||||
"pyproject.toml",
|
||||
"requirements.txt",
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"CHANGELOG.md",
|
||||
"kikotools/tools/model_downloader/node.py",
|
||||
"web/kiko_local_image_loader.js",
|
||||
)
|
||||
|
||||
|
||||
def patterns():
|
||||
lines = (ROOT / ".comfyignore").read_text(encoding="utf-8").splitlines()
|
||||
return [line.strip() for line in lines if line.strip() and line[0] != "#"]
|
||||
|
||||
|
||||
def ignored(path):
|
||||
"""The rules this file allows: ``/folder/`` or a root file, both from the root."""
|
||||
for pattern in patterns():
|
||||
if pattern.endswith("/"):
|
||||
if path.startswith(pattern.lstrip("/")):
|
||||
return True
|
||||
elif fnmatch.fnmatchcase(path, pattern.lstrip("/")):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def test_every_rule_is_anchored_to_the_root():
|
||||
# Unanchored, "tools/" also drops kikotools/tools/ and "tests/" any nested tests/.
|
||||
for pattern in patterns():
|
||||
assert pattern.startswith("/"), pattern
|
||||
assert "!" not in pattern, pattern
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", DEVELOPMENT)
|
||||
def test_development_files_are_left_out(path):
|
||||
assert ignored(path)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", KEPT)
|
||||
def test_package_files_stay(path):
|
||||
assert not ignored(path)
|
||||
|
||||
|
||||
def test_runtime_folders_ship_whole():
|
||||
for folder in RUNTIME_DIRS:
|
||||
for file in (ROOT / folder).rglob("*"):
|
||||
if file.is_file() and "__pycache__" not in file.parts:
|
||||
relative = file.relative_to(ROOT).as_posix()
|
||||
assert not ignored(relative), relative
|
||||
|
||||
|
||||
def test_registry_matcher_agrees():
|
||||
"""comfy-cli matches with pathspec's gitwildmatch; check the rules with it too."""
|
||||
pathspec = pytest.importorskip("pathspec")
|
||||
spec = pathspec.PathSpec.from_lines("gitwildmatch", patterns())
|
||||
for folder in RUNTIME_DIRS:
|
||||
for file in (ROOT / folder).rglob("*.py"):
|
||||
assert not spec.match_file(file.relative_to(ROOT).as_posix()), file
|
||||
for path in DEVELOPMENT:
|
||||
assert spec.match_file(path), path
|
||||
|
||||
|
||||
def test_runtime_code_imports_nothing_left_out():
|
||||
sources = [ROOT / "__init__.py", *(ROOT / "kikotools").rglob("*.py")]
|
||||
for source in sources:
|
||||
tree = ast.parse(source.read_text(encoding="utf-8"))
|
||||
for node in ast.walk(tree):
|
||||
names = []
|
||||
if isinstance(node, ast.Import):
|
||||
names = [alias.name for alias in node.names]
|
||||
elif isinstance(node, ast.ImportFrom) and not node.level:
|
||||
names = [node.module or ""]
|
||||
for name in names:
|
||||
assert name.split(".")[0] not in (
|
||||
"tests",
|
||||
"scripts",
|
||||
"tools",
|
||||
"examples",
|
||||
), source
|
||||
Reference in New Issue
Block a user