feat(plugin): install via release wheel URLs#260
Conversation
- release.yml: serialize tag-push runs (concurrency group), validate tag→PEP-440 normalization against an allowlist instead of silent passthrough, and fail the patch step if `.mcp.json` has zero URL matches (catches a silent no-op when main's URL shape drifts). - README.md: scope the `@latest` / `--with #subdirectory=` claims to the snippets that still use them; describe /pipefy:install as the curl-installer delegate it now is. - packages/mcp/README.md: fix dead "Quick install" cross-reference. - CHANGELOG.md: describe the wiring blocks as duplicated across both READMEs (they weren't moved — b8069bd reverted the move).
There was a problem hiding this comment.
Solid release-train step: wheel URLs drop the git-clone cost, the workflow guards (PEP 440 allowlist, n == 0, concurrency, git checkout $GITHUB_SHA) look thoughtful, and CI plus a local unit run (2916 passed) are green. One inline on /pipefy:install — everything else is coordination notes for the train you already documented.
Also noted
- F2 —
.mcp.jsonpinsv0.2.0-beta.2before the tag exists: Replacinggit+@latestwith hard-coded release URLs will 404 for the Claude Code plugin ondevuntil the tag ships and assets upload. Fine as infrastructure-only step 1; just don't smoke-test the plugin ondevbetween merge and release. - F3 — CHANGELOG wording: The Unreleased bullet says paste-into-config wheel blocks landed in both READMEs, but only
packages/mcp/README.mdgot the new subsection after the root README revert — worth tightening so release notes match the diff.
Switch `.mcp.json` and `commands/install.md` from `uvx --from git+...@latest#subdirectory=...` to direct GitHub Release wheel URLs. Eliminates the full git clone + setuptools build pass that every plugin install or `--refresh` previously paid per workspace member (sdk, auth, infra, mcp). The release workflow gains a step that, after creating the GitHub Release, patches `.mcp.json`, `commands/install.md`, `.claude-plugin/plugin.json`, and `.claude-plugin/marketplace.json` on `main` to point at the just-cut tag's wheels and commits the result. README MCP-client wiring blocks (Cursor, Claude Desktop, Codex) show the same wheel-URL shape with `<TAG>` and `<VERSION>` placeholders; the curl installer (#231) will resolve them automatically once it ships. Closes #234.
- Drop the `if: startsWith(github.ref_name, 'v')` guard on the new
manifest-patch step. The workflow trigger is already `tags: ["v*"]`,
so the conditional was always true.
- Restructure the empty-diff check as `if !; else` so the no-op path
doesn't `exit 0` early. The new `git checkout ${GITHUB_SHA}` line
needs to run on both branches.
- After pushing to main, `git checkout ${GITHUB_SHA}` so the working
tree is back at the tag commit. Subsequent steps (Stage PyPI / Smoke /
Upload) use untracked dist/ paths and are unaffected today, but a
future step that reads tracked files would otherwise silently see
main's tip instead of the tag.
- Document the PEP 440 normalization's scope inline.
- Alphabetize the package list in `commands/install.md`'s description
frontmatter.
- release.yml: serialize tag-push runs (concurrency group), validate tag→PEP-440 normalization against an allowlist instead of silent passthrough, and fail the patch step if `.mcp.json` has zero URL matches (catches a silent no-op when main's URL shape drifts). - README.md: scope the `@latest` / `--with #subdirectory=` claims to the snippets that still use them; describe /pipefy:install as the curl-installer delegate it now is. - packages/mcp/README.md: fix dead "Quick install" cross-reference. - CHANGELOG.md: describe the wiring blocks as duplicated across both READMEs (they weren't moved — b8069bd reverted the move).
e3dd7e5 to
4f22047
Compare
There was a problem hiding this comment.
Solid release-train step: wheel URLs drop the git-clone cost on every plugin install/refresh, and the release workflow guards (PEP 440 allowlist, n == 0, concurrency, git checkout $GITHUB_SHA) are thoughtful. Review included a local checkout of head 4f22047 — uv run pytest -m "not integration" (2955 passed) and ruff check green; CI on the PR is green.
The earlier /pipefy:install → main/install.sh thread is resolved (#269); v0.2.0-beta.2 wheels are on the release, so the forward-pinned .mcp.json is fine to merge.
Also noted
- CHANGELOG: Unreleased bullet claims wiring blocks in both READMEs; only
packages/mcp/README.mdchanged — inline onCHANGELOG.md. - root README: Line 91 still describes
/pipefy:installasuv tool install; this PR'scommands/install.mddelegates toinstall.sh— inline oncommands/install.mdwith a nudge to update rootREADME.md.
After merge: smoke claude plugin install pipefy@pipefy and /pipefy:install against the pinned wheels.
…s at pipefy/ai-toolkit #271 (org rename) landed in main while this branch carried the release-wheel work. Resolved .mcp.json and commands/install.md to keep the wheel-URL and install.sh-delegation behavior from this branch, and repointed the new paste-into-config wheel URLs in packages/mcp/README.md (added here, so they auto-merged still on the old org) to pipefy/ai-toolkit.
Summary
.mcp.jsonandcommands/install.mdfromuvx --from git+...@latest#subdirectory=...to direct GitHub Release wheel URLs. Eliminates the full git clone + setuptools build pass that every plugin install or--refreshpaid per workspace member (sdk, auth, infra, mcp)..github/workflows/release.ymlthat, after creating the GitHub Release, patches.mcp.json,commands/install.md,.claude-plugin/plugin.json, and.claude-plugin/marketplace.jsononmainto point at the just-cut tag's wheels, and commits the result.<TAG>and<VERSION>placeholders. Curl installer (install: one-command curl installer (CLI + MCP + skills + client config) #231) is the path that resolves these automatically once it ships.Design notes
pipefy_<pkg>-<version>-py3-none-any.whlform. No renamed-stable copies. URLs are version-pinned, and the workflow rewrites them per release.pipefy-infrais an explicit--with. uvx will not auto-resolve a workspace-only transitive dep from PyPI pre-v1.mainbranches would surface stale URLs, and the README install blocks are documentation rather than a programmatic install path. Placeholders + the curl installer (install: one-command curl installer (CLI + MCP + skills + client config) #231) cover the user-facing path.mainis currently off (gh api repos/.../branches/main/protection→ 404), so the workflow can push directly. If branch protection lands later, swap the push for agh pr createfallback.Test plan
python3 -c "ver='0.2.0-beta.2'; print(ver.replace('-beta.', 'b').replace('-rc.', 'rc').replace('-alpha.', 'a'))"returns0.2.0b2. Same derivation handles-rc.,-alpha., plain1.0.0..mcp.jsonparses as valid JSON.release.ymlparses as valid YAML.uv run pytestpasses (2916 passed, 46 skipped).devandv0.2.0-beta.2ships, smokeclaude plugin install pipefy@pipefyand/pipefy:install— both should resolve viareleases/download/...URLs with no git clone.Out of scope
git+#subdirectory=form. Separate follow-up.docs/setup.md(deleted in[Unreleased]; issue text was stale).Release sequencing
This is step 1 of the v0.2.0-beta.2 release train. Bump PR (
chore/release-v0.2.0-beta.2→dev) follows, then thedev → mainrelease PR.