mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-10-14 05:20:46 +02:00
Automate Space pin and lengthen the ComfyUI waiter
This commit is contained in:
4 files changed
+206
-38
No files matched your search
@@ -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
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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"]
|
||||
|
||||
Reference in new issue
Block a user