UN-3479 [FEAT] CLI restructure with user-group cloning + share-state replication by chandrasekharan-zipstack · Pull Request #19 · Zipstack/unstract-python-client · GitHub
Skip to content

UN-3479 [FEAT] CLI restructure with user-group cloning + share-state replication - #19

Merged
chandrasekharan-zipstack merged 4 commits into
mainfrom
feat/unstract-cli-groups
Jun 15, 2026
Merged

UN-3479 [FEAT] CLI restructure with user-group cloning + share-state replication#19
chandrasekharan-zipstack merged 4 commits into
mainfrom
feat/unstract-cli-groups

Conversation

@chandrasekharan-zipstack

Copy link
Copy Markdown
Contributor

Summary

  • CLI restructure: unstract Click group with clone as first subcommand; click/rich moved from optional extra to core (fixes broken-by-default ImportError)
  • User-group cloning: new group phase (runs first) clones org user groups by name with reuse-on-match; optional --clone-group-members flag (email-matched, missing users skipped and reported)
  • Share-state replication: after each resource create, its sharing state (users by email / groups by name / org-wide flag) is applied via the share endpoint; non-fatal warnings channel on report
  • Service account detection: via backend's is_service_account field with email-suffix fallback for older backends

Test Plan

  • Unit tests: uv run pytest → 184 passed (167 pre-existing + 17 new)
  • E2E on GKE dev namespace: full clone of seeded org (3 groups incl. empty, memberships, group/user/org shares) verified via API on target
  • Dry-run: full plan incl. would-skip warnings with zero writes
  • Rerun: adopts instead of duplicates

Dependencies

  • Companion backend PR: Zipstack/unstract feat/org-migration-platform-api-gaps (service-account group management)
  • Older backends: group phase fails cleanly (403s), everything else clones

README

  • Added concise "Unstract CLI" section describing unstract clone usage and optional --clone-group-members flag

🤖 Generated with Claude Code

chandrasekharan-zipstack and others added 2 commits June 11, 2026 17:56
Replace the 'unstract-clone' console script with a top-level 'unstract'
Click group ('unstract clone' is now the canonical invocation), promote
click/rich from the 'clone' extra into core dependencies (the extra is
removed), and document the CLI — usage, env promotion use case, main
options and exit codes — in the README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New 'group' phase (runs first): clones org user groups by name with
idempotent merge — a like-named target group is always reused, never
renamed or errored — and records int-pk remaps for downstream phases.
Opt-in --clone-group-members matches members to target users by email,
bulk-adds the hits and reports the misses as warnings; service accounts
(@platform.internal) never migrate.

After each shareable resource lands (adapter, connector, workflow,
pipeline, api_deployment, custom_tool), its source share state is
mirrored via POST /{resource}/{id}/share/: shared_groups through the
group remap (axis omitted with a warning when the group phase is
excluded), shared_to_org as-is, shared_users via id -> email -> target
id (missing users skipped + warned). shared_users stays stripped from
create POSTs (SERVER_MANAGED). Users/groups listings are memoised per
run; dry-run never POSTs. Reports gain a non-fatal warnings channel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chandrasekharan-zipstack
chandrasekharan-zipstack marked this pull request as ready for review June 12, 2026 04:32
Empty Prompt Studio projects cannot be exported (backend guard), so
they have no source registry entry and no workflow references. The
phase previously republished unconditionally, turning these into
counted failures on every run. Now the source registry lookup runs
first and the export + remap are skipped when no entry exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Comment thread src/unstract/clone/sharing.py
Comment thread src/unstract/clone/client.py Outdated
…rd None group listing

- _cached: a raced _FETCH_FAILED no longer shadows a peer's successful
  listing (would silently no-op all share replication for the run).
- list_groups: 'or {}' guard mirrors list_users so a None response can't
  raise AttributeError.
- Add regression tests for both race directions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chandrasekharan-zipstack
chandrasekharan-zipstack merged commit c88a682 into main Jun 15, 2026
3 checks passed
@chandrasekharan-zipstack
chandrasekharan-zipstack deleted the feat/unstract-cli-groups branch June 15, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants