[LFXV2-2254] feat(lfx_one/scripts): add rename-project-slug Go migration script#44
[LFXV2-2254] feat(lfx_one/scripts): add rename-project-slug Go migration script#44andrest50 wants to merge 10 commits into
Conversation
…FXV2-2254) Adds a reusable standalone Go script for renaming a project slug across both LFX V2 data stores (OpenSearch and NATS KV). Previously each rename required manually running an OpenSearch query and a one-off committee-service script. This script consolidates both into a single dry-run-by-default command. - OpenSearch: audits matching record count in dry-run; applies a painless _update_by_query (rewriting data.project_slug, data.slug, tags, fulltext, name_and_aliases) when applied. - NATS KV: scans committee-members, committees, committee-settings, projects, and project-settings buckets with per-bucket slug field mapping, skipping lookup/ and slug/ index keys, with 3-attempt optimistic-lock retry. Jira: https://linuxfoundation.atlassian.net/browse/LFXV2-2254 Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Remove --opensearch-username, --opensearch-password, --opensearch-index, and --insecure-skip-tls-verify flags. The index is always "resources" and auth/TLS are not needed for the port-forward workflow. Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Build and ship darwin/arm64, darwin/amd64, and linux/amd64 binaries so the script can be run without a local Go toolchain installed. Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
…f 100 Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Resolves two moderate CVEs flagged by dependency-review CI: - GHSA-j5w8-q4qc-rx2x (unbounded memory consumption in x/crypto/ssh) - GHSA-f6x5-jh6r-wrfv (panic on malformed message in x/crypto/ssh/agent) Also rebuilds pre-built binaries with the patched dependency. Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
|
Warning Review limit reached
More reviews will be available in 13 minutes and 30 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
WalkthroughAdds a new standalone Go CLI script Changesrename-project-slug CLI tool
Sequence Diagram(s)sequenceDiagram
participant Operator
participant CLI as rename-project-slug CLI
participant OS as OpenSearch resources index
participant NATS as NATS JetStream KV
Operator->>CLI: run --old-slug foo --new-slug bar --target both
rect rgba(59, 130, 246, 0.5)
note over CLI,OS: OpenSearch path
CLI->>OS: POST _search (bool/should query, track_total_hits)
OS-->>CLI: total matching hits
alt apply mode
CLI->>OS: POST _update_by_query (Painless script rewrite)
OS-->>CLI: updated / noops / version_conflicts
end
end
rect rgba(34, 197, 94, 0.5)
note over CLI,NATS: NATS JetStream KV path
CLI->>NATS: Connect + JetStream context
loop each configured bucket
loop concurrent workers per bucket
CLI->>NATS: Keys() → candidate keys (exclude lookup/, slug/)
CLI->>NATS: Get(key) → JSON + revision
alt slug field matches
CLI->>NATS: Update(key, rewritten JSON, revision)
NATS-->>CLI: success or conflict
note over CLI,NATS: retry up to 3x on conflict, abort if slug changed
else no match
note over CLI: skip (errSlugMismatch)
end
end
end
end
CLI-->>Operator: totals (updated / skipped / failed)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
Adds a standalone rename-project-slug Go migration script under lfx_one/scripts/rename-project-slug/ to rename a project slug across OpenSearch (resources index) and NATS JetStream KV buckets, with dry-run behavior by default and bundled pre-built binaries.
Changes:
- Introduces a Go CLI (with tests) that can audit/apply slug rewrites in OpenSearch and NATS KV with configurable targeting and concurrency.
- Adds module metadata (
go.mod/go.sum) and ships pre-built binaries for common OS/arch targets. - Updates repo
.gitignoreto ignore Go test binaries generated underlfx_one/scripts/*/bin/.
Reviewed changes
Copilot reviewed 4 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| lfx_one/scripts/rename-project-slug/README.md | Documents script purpose/usage and migration behavior (needs a couple doc alignment fixes). |
| lfx_one/scripts/rename-project-slug/main.go | Implements OpenSearch _update_by_query and NATS KV scanning/updating logic (found a few correctness/security/UX issues). |
| lfx_one/scripts/rename-project-slug/main_test.go | Adds basic unit tests for argument parsing, bucket field mapping, and query construction. |
| lfx_one/scripts/rename-project-slug/go.mod | Defines the standalone module and dependencies (currently has an invalid go directive format). |
| lfx_one/scripts/rename-project-slug/go.sum | Locks dependency checksums for the standalone module. |
| .gitignore | Ignores per-script bin/*.test artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address review comments from copilot-pull-request-reviewer: - main.go: reject mixed positional + flag slug args to prevent accidental runs with unintended slugs (was silently ignoring flag values) - main.go: redact credentials from nc.ConnectedUrl() before logging, consistent with the existing redactNATSURL helper - main.go: downgrade per-record match log from Info to Debug — reduces noise on large buckets; progress summaries remain at Info - README.md: fix --concurrency default (10 → 50) to match code - README.md: add "Running the pre-built binary" section documenting the darwin/linux binaries already shipped in bin/ Resolves 5 copilot review threads. 3 license-compliance threads addressed in separate responses (standard golang.org/x/* BSD-3-Clause + patent grant). Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Review Feedback AddressedCommit: 69ebe91 Changes Made
No Change Needed
Threads Resolved8 of 8 unresolved threads addressed in this iteration. |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lfx_one/scripts/rename-project-slug/main.go`:
- Around line 365-371: The bucket migration failure handling in the loop
iterating through buckets (where migrateBucket is called) logs errors but
continues without tracking that a failure occurred, allowing the command to
return success despite incomplete migrations. Add a flag or error variable to
track whether any bucket migration has failed during the loop, and then check
this flag after the loop completes to ensure the overall command returns an
error if any bucket-level migration failure was encountered. This prevents
reporting success when cross-store rename operations are incomplete.
- Around line 196-202: The query in the should array includes search conditions
for object_ref and parent_refs fields containing the old slug pattern, but the
script does not include corresponding update operations to rewrite these fields.
Locate the update script logic (around lines 256-284) where other fields are
being rewritten and add update operations for both object_ref and parent_refs
fields that replace the old slug pattern (project: + oldSlug) with the new slug
pattern (project: + newSlug) to ensure these field references are properly
updated when the slug is renamed.
- Around line 105-113: The partitionArgs function currently only separates
tokens starting with "-" into the flags slice, but does not handle the values
that follow flag tokens. When a flag like "--target" is encountered, its
following value argument (like "nats") remains in the positional slice, causing
parsing failures. Modify the partitionArgs function to check if a flag argument
is followed by a value argument (one that does not start with "-"), and if so,
add both the flag and its value to the flags slice together. This ensures that
flag-value pairs are kept together in the flags slice and not split across
positional and flags slices.
In `@lfx_one/scripts/rename-project-slug/README.md`:
- Line 64: The README documentation table for the `--concurrency` parameter
shows an incorrect default value of `10`, while the actual default defined in
main.go is `50`. Update the documentation table entry for the `--concurrency`
parameter to change the default value from `10` to `50` to match the actual
implementation and ensure consistency between the documentation and the code.
- Around line 1-149: The README.md file contains 23 markdownlint MD060
validation errors caused by misaligned pipes and inconsistent spacing in
multiple Markdown tables throughout the document. Fix all tables in the file
including the "Required arguments" table, "Flags" table, "OpenSearch flags"
table, "NATS flags" table, and "NATS KV bucket mapping" table by ensuring pipes
are properly aligned vertically and have consistent spacing (one space on each
side of the pipe delimiter) in all rows and headers. Ensure every table follows
proper Markdown table formatting standards to resolve all validation errors.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fe8b8c87-a3f9-4f5c-b663-1d173a018c8b
⛔ Files ignored due to path filters (1)
lfx_one/scripts/rename-project-slug/go.sumis excluded by!**/*.sum
📒 Files selected for processing (8)
.gitignorelfx_one/scripts/rename-project-slug/README.mdlfx_one/scripts/rename-project-slug/bin/rename-project-slug-darwin-amd64lfx_one/scripts/rename-project-slug/bin/rename-project-slug-darwin-arm64lfx_one/scripts/rename-project-slug/bin/rename-project-slug-linux-amd64lfx_one/scripts/rename-project-slug/go.modlfx_one/scripts/rename-project-slug/main.golfx_one/scripts/rename-project-slug/main_test.go
…rs in README examples Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
- main.go (painless script): add object_ref and parent_refs rewrites to match what the query already searches on — previously these fields were matched but never rewritten, leaving stale slug references after a run (per coderabbitai) - main.go (runNATS): track bucket-level open/list failures in bucketErrors and fail the command after all buckets are attempted — previously a bucket failure was logged and silently skipped, allowing a successful exit code despite an incomplete migration (per coderabbitai) Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Review Feedback Addressed (iteration 2)Commit: f603bcf Changes Made
No Change Needed
Threads Resolved3 of 3 unresolved threads addressed in this iteration. |
Address review comments from copilot-pull-request-reviewer: - main.go: replace partitionArgs with flag.Parse()+flag.Args() so that space-separated flag forms (--target opensearch, --nats-url nats://...) are correctly parsed rather than treated as positional arguments - main.go: reject extra positional arguments — run() now returns an error when more than 2 positional args are provided, preventing silent misuse - main.go: fix dry-run summary labels — grand total header now prints "NATS KV Audit (dry-run, no writes)" and uses "Would update:" label; per-bucket summary also uses "Would update:" in dry-run mode - main.go: distinguish bucket-not-found from other errors — missing buckets are now logged at WARN level and skipped; other bucket failures remain at ERROR level, matching the README note about the projects bucket - main_test.go: remove TestPartitionArgs_* tests (function removed) - README.md: update Go requirement to 1.25+ to match go.mod directive - bin/: rebuild all platform binaries (darwin-arm64, darwin-amd64, linux-amd64) Resolves 6 review threads. https://claude.ai/claude-code Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Review Feedback AddressedCommit: 39f9f13 Changes Made
Threads Resolved6 of 6 unresolved threads addressed in this iteration. |
Address review comments from copilot-pull-request-reviewer: - main.go: add redactURL() helper and use it for the OpenSearch URL in logs, consistent with the existing NATS URL redaction; redactNATSURL now delegates to redactURL to avoid duplication - main.go: ErrBucketNotFound no longer increments bucketErrors — missing buckets are non-fatal warnings (per README); only genuine migration failures cause a non-zero exit - main.go: defer keys.Stop() on the KeyLister returned by ListKeys() so the underlying watcher is always cleaned up; note the KeyLister interface in nats.go v1.43.0 does not expose Error(), so error detection relies on the initial ListKeys() call and the errgroup per-record results - bin/: rebuild all platform binaries (darwin-arm64, darwin-amd64, linux-amd64) Resolves 3 of 4 review threads (streaming key approach deferred — see thread). https://claude.ai/claude-code Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Review Feedback AddressedCommit: 225da11 Changes Made
No Change Needed
Note on keys.Error()The Threads Resolved4 of 4 unresolved threads addressed in this iteration. |
Summary
lfx_one/scripts/rename-project-slug/that renames a project slug across both LFX V2 data stores in one command, dry-run by default_update_by_queryfrom LFXV2-2254 (rewritesdata.project_slug,data.slug,tags,fulltext,name_and_aliases)committee-members,committees,committee-settings,projects, andproject-settingsbuckets with per-bucket slug field mapping, skipping index keys, with optimistic-lock retrydarwin/arm64,darwin/amd64, andlinux/amd64so the script can be run without a Go toolchainTicket
LFXV2-2254