Skip to content

feat(environments): cross-environment bulk operations#5536

Draft
markphelps wants to merge 31 commits into
v2from
feat/cross-env-operations
Draft

feat(environments): cross-environment bulk operations#5536
markphelps wants to merge 31 commits into
v2from
feat/cross-env-operations

Conversation

@markphelps
Copy link
Copy Markdown
Collaborator

@markphelps markphelps commented Mar 9, 2026

Summary

This PR simplifies the v2 copy/apply API surface and extends BulkApplyResources to target multiple environments in a single request.

Changes

  • Removed CopyResource from EnvironmentsService.
  • Kept 2 RPCs:
    • CopyNamespace
    • BulkApplyResources
  • Removed CopyResourceRequest / CopyResourceResponse proto messages.
  • Extended BulkApplyResourcesRequest with environment_keys (optional target environments list).
  • Extended BulkApplyNamespaceResult with environment_key so responses are unambiguous across environment+namespace targets.
  • Updated server execution to apply operations across all target environments (Pro-gated), while preserving revision behavior for the primary environment_key path binding.
  • Updated authz request generation for bulk apply to include all targeted environments.
  • Regenerated environments artifacts:
    • rpc/v2/environments/environments.pb.go
    • rpc/v2/environments/environments_grpc.pb.go
    • rpc/v2/environments/environments.pb.gw.go
    • rpc/v2/environments/openapi.yaml
  • Updated v2 SDK/UI copy flows and integration coverage to use BulkApplyResources instead of /resources/copy from earlier commits in this branch.

Naming Note

BulkApplyResources remains the RPC name because it supports non-copy operations (CREATE, UPDATE, DELETE, UPSERT) in addition to copy-like workflows.

Backward Compatibility

This is a v2 pre-release API shape change in PR scope (not yet live), so removing CopyResource and extending BulkApplyResources is intentional.

Additional Notes

  • Branch: feat/cross-env-operations
  • Latest commit: f0196732

Add CopyResource, CopyNamespace, and BulkApplyResources RPCs to the
EnvironmentsService along with supporting enums (ConflictStrategy,
BulkOperation, OperationStatus) and request/response messages.

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Add Validate() methods for CopyResourceRequest, CopyNamespaceRequest,
and BulkApplyResourcesRequest to enforce required fields. Add Request()
methods for authorization, requiring appropriate read/update permissions
on source and target environments.

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Same-environment copy (across namespaces) remains available to all
users. Only cross-environment copy requires a Pro license.

Also removes dead copyFlag/copySegment client-side mutations that
were replaced by the server-side CopyResource RPC.

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Add CopyResource, CopyNamespace, and BulkApplyResources to both
the gRPC SDK wrapper and the HTTP transport client.

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Document that v1/v2 SDK .sdk.gen.go files are now maintained by
hand (no longer generated via protoc plugin). Covers the three-layer
architecture and step-by-step guide for adding new RPCs.

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 9, 2026

The latest Buf updates on your PR. Results from workflow Proto / proto-lint (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedMar 28, 2026, 12:40 AM

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 9, 2026

Codecov Report

❌ Patch coverage is 71.47335% with 91 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.00%. Comparing base (556cdbe) to head (dae7115).

Files with missing lines Patch % Lines
internal/server/environments/server.go 71.38% 63 Missing and 28 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##               v2    #5536      +/-   ##
==========================================
+ Coverage   60.70%   61.00%   +0.29%     
==========================================
  Files         141      141              
  Lines       14023    14339     +316     
==========================================
+ Hits         8513     8747     +234     
- Misses       4784     4823      +39     
- Partials      726      769      +43     
Flag Coverage Δ
integrationtests 33.19% <22.57%> (-1.36%) ⬇️
unittests 53.27% <69.59%> (+1.66%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

markphelps and others added 6 commits March 9, 2026 20:30
When using SKIP or FAIL conflict strategies, the copy operations
previously called tgtEnv.Update() even when no writes were needed,
causing "cannot create empty commit: clean working tree" errors.

Now we pre-check resource existence via View() and only call Update()
when there are actual resources to write (create or overwrite).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
…ror message

The integration test expects the conflict error message to contain
"already exists", but ErrAlreadyExistsf only stores the format string
as-is without adding a prefix. Updated the format string to include
"already exists" for consistency with the CopyResource error path.

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
@markphelps markphelps marked this pull request as ready for review March 12, 2026 22:50
@markphelps markphelps requested a review from a team as a code owner March 12, 2026 22:50
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Mar 12, 2026
@markphelps markphelps changed the title Feat/cross env operations feat(environments): cross-environment bulk operations Mar 12, 2026
@markphelps markphelps added the v2 Flipt v2 label Mar 12, 2026
@markphelps markphelps marked this pull request as draft March 12, 2026 22:51
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Resolve conflicts in generated protobuf and SDK files by
regenerating from proto definitions after merge.

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
- Return error for unknown bulk operation instead of silent success
- Validate source_environment_key and source_namespace_key in CopyNamespaceRequest
- Cap publisher goroutines at 100 via semaphore (restores concurrency limit)
- Chain revisions sequentially in bulk copy UI instead of parallel requests

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Add a read-only "Environments" tab showing a flag's state across all
base environments. Each environment row fetches the flag independently
via GetResource, displaying enabled/disabled state, variant/rule/rollout
counts, and a drift indicator for structural differences.

- Extract shared compare helpers to ui/src/utils/compare.ts
- Add FlagEnvironments component with per-environment row queries
- Add "Environments" tab to both variant and boolean flag tab arrays
- Add 20 unit tests for compare utility functions
- Refactor Compare.tsx to import from shared utils

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
- Add dark mode classes to Compare page Pro upsell banner
- Add flex-wrap to FlagEnvironments rows for narrow screens
- Replace "Loading..." text with animated skeleton placeholders

Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files. v2 Flipt v2

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant