Automate Space pin and lengthen the ComfyUI waiter

This commit is contained in:
Victor Kuznetsov committed 2026-09-11 10:19:25 -07:00
1 parent b03a65bcb3
commit b2e46ee8db
4 files changed
+206 -38

No files matched your search

+132 -3
View File
@@ -114,10 +114,100 @@ jobs:
needs: resolve
runs-on: ubuntu-latest
steps:
- name: Factory-rebuild the HuggingFace Space
- name: Bump the Space pin, then factory-rebuild
env:
GH_TOKEN: ${{ secrets.RAIW_HF_SPACE_TOKEN }}
HF_TOKEN: ${{ secrets.HF_TOKEN }}
VERSION: ${{ needs.resolve.outputs.version }}
run: |
set -euo pipefail
repo=wiltodelta/raiw-hf-space
workflow=pin-library.yml
if [ -z "${GH_TOKEN:-}" ]; then
echo "RAIW_HF_SPACE_TOKEN secret is not set; skipping the pin bump."
else
dispatched_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
gh workflow run "$workflow" \
--repo "$repo" \
--ref main \
--raw-field library_version="$VERSION"
run_id=""
for attempt in $(seq 1 30); do
run_id=$(
gh run list \
--repo "$repo" \
--workflow "$workflow" \
--event workflow_dispatch \
--limit 10 \
--json databaseId,createdAt \
| python3 -c '
import json
import sys
dispatched_at = sys.argv[1]
runs = json.load(sys.stdin)
print(next(
(run["databaseId"] for run in runs if run["createdAt"] >= dispatched_at),
"",
))
' "$dispatched_at"
)
if [ -n "$run_id" ]; then
break
fi
echo "Space pin run not visible yet (attempt $attempt), waiting..."
sleep 2
done
if [ -z "$run_id" ]; then
echo "::error::The dispatched Space pin run did not appear"
exit 1
fi
for attempt in $(seq 1 180); do
read -r status conclusion <<< "$(
gh run view "$run_id" \
--repo "$repo" \
--json status,conclusion \
--jq '[.status, (.conclusion // "")] | @tsv'
)"
if [ "$status" = "completed" ]; then
if [ "$conclusion" = "success" ]; then
echo "Space pin run $run_id succeeded"
break
fi
echo "::error::Space pin run $run_id completed with $conclusion"
exit 1
fi
echo "Space pin run $run_id is $status (attempt $attempt), waiting..."
sleep 5
done
if [ "${status:-}" != "completed" ]; then
echo "::error::Space pin run $run_id did not finish in time"
exit 1
fi
echo "Waiting for the Space requirements pin to show $VERSION..."
pinned=""
for attempt in $(seq 1 40); do
reqs=$(curl -fsSL \
"https://huggingface.co/spaces/wiltodelta/remove-ai-watermarks/raw/main/requirements.txt" \
|| true)
pinned=$(printf '%s\n' "$reqs" \
| sed -n 's/^remove-ai-watermarks==\([0-9][0-9a-zA-Z.]*\).*/\1/p' \
| head -1)
echo " attempt $attempt: Space pin=$pinned"
if [ "$pinned" = "$VERSION" ]; then
break
fi
sleep 15
done
if [ "$pinned" != "$VERSION" ]; then
echo "::error::Space requirements.txt still pinned to ${pinned:-<none>}, not $VERSION"
exit 1
fi
fi
python3 -m pip install --quiet huggingface_hub
python3 - <<'PY'
import os
@@ -217,7 +307,12 @@ jobs:
exit 1
fi
for attempt in $(seq 1 180); do
# 0.40.0's node sync finished after this waiter: 180 * 5s is 15 min,
# and the node suite plus registry upload ran longer. Keep the
# workflow wait, then accept a registry row for this library version
# so a late-but-published node is not reported as a missing release.
version="${{ needs.resolve.outputs.version }}"
for attempt in $(seq 1 360); do
read -r status conclusion <<< "$(
gh run view "$run_id" \
--repo "$repo" \
@@ -235,5 +330,39 @@ jobs:
echo "ComfyUI sync run $run_id is $status (attempt $attempt), waiting..."
sleep 5
done
echo "::error::ComfyUI sync run $run_id did not finish in time"
echo "ComfyUI sync run $run_id did not finish in time; checking the registry."
python3 -m pip install --quiet packaging
if curl -fsSL "https://api.comfy.org/nodes/remove-ai-watermarks/versions" \
| VERSION="$version" python3 -c '
import json, os, sys
from packaging.requirements import InvalidRequirement, Requirement
from packaging.utils import canonicalize_name
from packaging.version import Version
version = os.environ["VERSION"]
target = Version(version)
def requires_release(value):
try:
requirement = Requirement(value)
except InvalidRequirement:
return False
return (
canonicalize_name(requirement.name) == "remove-ai-watermarks"
and requirement.url is None
and requirement.marker is None
and target in requirement.specifier
and any(s.operator == ">=" and Version(s.version) == target for s in requirement.specifier)
)
matches = [
v for v in json.load(sys.stdin)
if any(requires_release(d) for d in (v.get("dependencies") or []))
]
if not matches:
sys.exit(1)
newest = max(matches, key=lambda v: v.get("createdAt") or "")
print("%s %s" % (newest.get("version"), newest.get("status")))
'; then
echo "Registry already lists a node for $version; the wait timed out after publish."
exit 0
fi
echo "::error::ComfyUI sync run $run_id did not finish in time and the registry has no node for $version"
exit 1
+36 -23
View File
@@ -49,10 +49,14 @@ Do these in order after the skill is on the default branch.
4. **Awesome-list PRs.** Hand-curated GitHub lists are how people browse skills
today. One accurate PR per list, with the scope sentence intact.
- `ComposioHQ/awesome-claude-skills`: submitted 2026-09-05 as PR 1841
(Creative & Media); no maturity bar in its contribution rules.
(Creative & Media); no maturity bar in its contribution rules. Rechecked
2026-09-11: still open, CI green, no review comments, waiting on the
list maintainers.
- `heilcheng/awesome-agent-skills`: submitted 2026-09-09 as PR 483 under
Community Skills > Media. The skill's three concrete input/output examples
satisfy the list's working-example requirement.
satisfy the list's working-example requirement. Rechecked 2026-09-11:
still open; the only check failure is their Vercel deploy authorization,
which a contributor cannot grant.
- `VoltAgent/awesome-agent-skills`: DEFERRED. Its CONTRIBUTING rejects
brand-new skills ("give your skill time to mature and gain users before
submitting"). The skill now has real installs and shipped releases, but
@@ -67,29 +71,31 @@ Do these in order after the skill is on the default branch.
with `claude plugin validate` first. SUBMITTED 2026-09-07 for Claude Code
only (strict validation passed; Apache 2.0; description carries the
scope boundary; platform selection limited to Claude Code because Cowork
was not tested). Pending review; the team may reach out by email. The
official Anthropic marketplace is
curated and has no application.
was not tested). Pending review; the team may reach out by email.
Rechecked 2026-09-11: `platform.claude.com/plugins` is 404, and
`claude.ai/directory` is the MCP connector catalog, not plugins; a search
there does not list this skill. Do not open a second submission. The
official Anthropic marketplace is curated and has no application.
6. **ClawHub.** `clawhub login` then `clawhub skill publish` from
`skills/remove-ai-watermarks/`. LISTED 2026-09-09: versions 1.0.5 and 1.0.6,
submitted by the `clawhub` job in `distribute.yml` during the 0.39.0 and
0.39.1 releases, are public. A green job proves only a submission, so read
the catalog itself:
`skills/remove-ai-watermarks/`. LISTED 2026-09-09: versions 1.0.5, 1.0.6,
and 1.0.8, submitted by the `clawhub` job in `distribute.yml` during the
0.39.0, 0.39.1, and 0.40.0 releases, are public. A green job proves only a
submission, so read the catalog itself:
`clawhub search remove-ai-watermarks` returns the row and
`https://clawhub.ai/api/v1/skills/remove-ai-watermarks` reports
`latestVersion.version` 1.0.6, while its `/versions` endpoint returns those
two published versions. The earlier 1.0.3 and 1.0.4 submissions never became
`latestVersion.version` 1.0.8, while its `/versions` endpoint returns
1.0.5, 1.0.6, and 1.0.8. The earlier 1.0.3 and 1.0.4 submissions never became
public and do not appear in that version list, so they were bypassed rather
than recovered. The issue that tracked
them, openclaw/clawhub#3643, was closed by the reporter on 2026-09-09 once
than recovered. 1.0.7 was a post-0.39.1 bump that never reached ClawHub.
The issue that tracked 1.0.3 and 1.0.4, openclaw/clawhub#3643, was closed
by the reporter on 2026-09-09 once
1.0.5 went through; nothing upstream was confirmed fixed, and it is the
fifth report of this shape (#3624, #3466, #3351, #3284), so treat a stalled
submission as recurring and file a fresh one rather than assuming the
pipeline is repaired. Release-time publishing is automated (see
[release-and-distribution.md](release-and-distribution.md)), and the job
fires only on a published GitHub Release: a skill version bumped after a
release reaches ClawHub with the next one. 0.40.0 publishes 1.0.8; 1.0.7 was
the post-0.39.1 bump and is not a ClawHub version. Do not publish by
release reaches ClawHub with the next one. Do not publish by
hand to close that gap. The listing records the license as MIT-0 while
`SKILL.md` declares Apache-2.0, and that is not a listing error to repair:
MIT-0 is a platform-wide constant in ClawHub's own client
@@ -114,16 +120,23 @@ Do these in order after the skill is on the default branch.
[Submit your Claude Code plugin to OpenAI](https://developers.openai.com/plugins/guides/submit-claude-plugin).
8. **AgenticSkills.** SUBMITTED 2026-09-09 as review issue 174 under AI/ML
Development. The submission carries the user-owned-content boundary and
links to the repository rather than hosting a separate copy.
links to the repository rather than hosting a separate copy. Rechecked
2026-09-11: the public index still does not list it (`/skills/remove-ai-watermarks`
is 404; search for `wiltodelta` returns 0 of 192). Their form promises a
48-hour review; that window has passed. Issue 174 is not a public GitHub
issue. Do not open a second submission. Followed up 2026-09-11 through
their contact form as a listing correction.
9. **AI Skills Catalog.** SUBMITTED 2026-09-09 as reference 2 under Video Media,
with Codex as the primary agent and every supported harness marked compatible.
The catalog reviews source quality, security, license, and compatibility
before publication. Once accepted, treat material skill-version updates as
manual because the catalog stores compatible packages in addition to source
metadata and does not promise that a GitHub change refreshes those packages.
Use the update route supplied with acceptance; if none is supplied, contact
the catalog or resubmit, then verify the live result. Do not open a duplicate
while the initial review is pending.
Rechecked 2026-09-11: the public catalog at skillscatalog.ai shows 0 skills
from 0 publishers, `/api/featured` returns 401, and `/api/auth/session`
returns 500, so a stranger cannot confirm the listing. Do not open a
duplicate while that initial review is pending. Once accepted, treat
material skill-version updates as manual because the catalog stores
compatible packages in addition to source metadata and does not promise
that a GitHub change refreshes those packages. Use the update route
supplied with acceptance; if none is supplied, contact the catalog or
resubmit, then verify the live result.
The conditional update actions for every catalog are part of the canonical
release checklist in
+25 -12
View File
@@ -11,7 +11,7 @@ A release is complete only after all four published surfaces are verified:
|---|---|---|
| PyPI | The `remove-ai-watermarks` wheel and source distribution | `publish.yml` |
| Homebrew | The `remove-ai-watermarks` formula in `wiltodelta/homebrew-tap` | `distribute.yml` |
| Hugging Face Space | The Space demo deployed on the new release through a requirements-pin bump in `wiltodelta/raiw-hf-space` | `raiw-hf-space` sync workflow; the pin bump is manual, `distribute.yml` only re-installs the pinned version |
| Hugging Face Space | The Space demo deployed on the new release through a requirements-pin bump in `wiltodelta/raiw-hf-space` | `distribute.yml` dispatches `pin-library.yml` in that repo, waits for the Hub `requirements.txt` pin, then factory-rebuilds; `sync-to-hf.yml` mirrors the pin onto the Space |
| ComfyUI Registry | A compatible release of `wiltodelta/ComfyUI-remove-ai-watermarks` with its own node version | `distribute.yml` and the node repository's workflows |
The GitHub Release is the trigger and release record for this flow. Conda is
@@ -62,16 +62,20 @@ PyPI API token from the repository.
waits for the matching source distribution to appear on PyPI, then:
- updates the Homebrew tap formula URL and SHA-256;
- triggers a factory rebuild of the Hugging Face Space: this re-installs the
version pinned in the Space repo, it does NOT upgrade the demo;
- bumps the Hugging Face Space pin and factory-rebuilds the demo on that pin;
- synchronizes, tests, versions, and publishes the ComfyUI nodes.
Upgrading the Hugging Face Space is a separate, manual step: bump
`remove-ai-watermarks[visible,heif]` in `wiltodelta/raiw-hf-space` (`pyproject.toml`,
`uv lock`, and the re-exported `requirements.txt`), then push. That repository's
`sync-to-hf.yml` mirrors the files onto the Space, which rebuilds on the new
pin. Its callback smoke tests run in that repository's CI on every push; they
are the scenario check for the demo surface.
Upgrading the Hugging Face Space is dispatched from `distribute.yml`: it runs
`pin-library.yml` in `wiltodelta/raiw-hf-space`, which bumps
`remove-ai-watermarks[visible,heif]` in `pyproject.toml`, refreshes `uv.lock`,
and pushes. That repository's `sync-to-hf.yml` then mirrors the files onto the
Space. `distribute.yml` waits for the Hub `requirements.txt` pin to match,
then factory-rebuilds. The `RAIW_HF_SPACE_TOKEN` repository secret is a
fine-grained token limited to the Space repository, with Contents write and
Actions write. Without the secret the pin bump is skipped and only the
factory rebuild runs, which reinstalls whatever version is already pinned.
The Space repo's callback smoke tests still run on every push; they are the
scenario check for the demo surface.
The Hugging Face **model** `wiltodelta/raiw-photo-classify` is not part of that
release fan-out. It holds the photo-classify freeze weights. The library extra
@@ -253,9 +257,18 @@ failure.
The ComfyUI sync run can fail the same way on its own: it resolves the version
from the PyPI JSON API (which updates first) but installs the test dependency
with pip against the simple index, whose CDN edges lag by minutes. Rerun the
failed `distribute.yml` comfyui job once the simple index lists the release;
nothing about the release itself is wrong.
with pip against the simple index, whose CDN edges lag by minutes. The
`distribute.yml` waiter also has a clock: 0.40.0's node suite finished after
the 15-minute poll, so the job now waits 30 minutes and then accepts a
registry row that already requires this library version. Rerun the failed
`comfyui` job only when the registry still has no such row.
The automatic `verify-release.yml` run after `distribute.yml` checks the
Hugging Face Space pin. When `RAIW_HF_SPACE_TOKEN` is set, that pin lands
during distribution. Without the secret, bump the pin by dispatching
`pin-library.yml` in `wiltodelta/raiw-hf-space` and then dispatch
`verify-release.yml` with the release version. Do not read a missing Space
pin as a broken PyPI or Homebrew publish.
If the release changed CLI routing, extras, exit codes, mark keys, or the
intended-use boundary, confirm `skills/remove-ai-watermarks/` still matches.
+13
View File
@@ -164,6 +164,19 @@ def test_distributed_version_reads_the_flat_single_artifact_layout(tmp_path: Pat
assert "version=0.37.0" in (tmp_path / "output").read_text()
def test_comfyui_waiter_outlasts_the_node_suite_then_reads_the_registry() -> None:
script = _step("distribute.yml", "comfyui", "Sync and publish the ComfyUI nodes")["run"]
assert "seq 1 360" in script
assert "api.comfy.org/nodes/remove-ai-watermarks/versions" in script
def test_space_pin_is_dispatched_before_the_factory_rebuild() -> None:
script = _step("distribute.yml", "hf-space", "Bump the Space pin, then factory-rebuild")["run"]
assert "pin-library.yml" in script
assert "RAIW_HF_SPACE_TOKEN secret is not set" in script
assert "restart_space" in script
@pytest.mark.skipif(os.name != "posix" or shutil.which("bash") is None, reason="Executes an Ubuntu Bash workflow")
def test_clawhub_uses_local_install(tmp_path: Path) -> None:
script = _step("distribute.yml", "clawhub", "Publish the agent skill when its version moved")["run"]