Add CLI commands for repository enrollment management - #697
Conversation
Review: #697Head SHA: e129f33 SummaryThis PR adds FindingsCriticalNone. HighNone. MediumNone. Low
Info
FooterOutcome: approve Previous runReview: #697Head SHA: b051b4b SummaryThis PR adds FindingsMedium
Low
Info
FooterOutcome: comment-only Previous run (2)Review: #697Head SHA: ef04484 SummaryThis PR cleanly implements the enable/disable repository enrollment commands as specified in #695. The code follows existing patterns in admin.go, uses the shared FindingsMedium
Low
Info
FooterOutcome: comment-only Previous run (3)Review: #697Head SHA: b5d5e91 SummaryThis PR adds FindingsCriticalNone. HighNone. MediumNone. Low
Info
FooterOutcome: approve Previous run (4)Review: #697Head SHA: 6be0cd0 SummaryThis PR adds well-structured FindingsMedium
Low
Info
FooterOutcome: comment-only Previous run (5)Review: #697Head SHA: 5e84e9f SummaryThis PR adds well-structured FindingsMedium
Low
Info
FooterOutcome: comment-only Previous run (6)Review: #697Head SHA: df788c3 SummarySolid implementation of CLI commands for repository enrollment management. The code follows existing patterns in FindingsMedium
Low
Info
FooterOutcome: comment-only Previous run (7)Review: #697Head SHA: a091b4f SummaryThis is a well-structured PR that adds dedicated FindingsMedium
Low
FooterOutcome: comment-only Previous run (8)Review: #697Head SHA: 7ae576c SummaryThis PR adds well-structured FindingsMedium
Low
Info
FooterOutcome: comment-only Previous run (9)Review: #697Head SHA: 98e6c0e SummaryThe new FindingsHigh
Medium
Low
Info
FooterOutcome: request-changes Previous run (10)Review: #697Head SHA: 18f8cf8 SummaryThe PR adds FindingsCritical
Medium
Low
Info
FooterOutcome: request-changes Previous run (11)Review: #697Head SHA: f866608 SummaryThe PR adds FindingsHigh
Medium
Low
FooterOutcome: request-changes |
Fixes three issues identified in the code review: 1. **Add comprehensive unit tests**: Created business-logic tests for runReposEnable and runReposDisable covering enable/disable scenarios, error cases, --all flag behavior, config updates, and edge cases. Uses forge.FakeClient pattern for isolation. 2. **Extract shared logic**: Refactored ~70% duplicated code between enable/disable functions into helper functions: - loadRepoConfig(): Verifies .fullsend exists, reads/parses config.yaml - saveRepoConfig(): Marshals config, commits changes, triggers workflow This eliminates duplication and makes the code more maintainable. 3. **Add symmetric validation**: Added organization-level repository existence validation to runReposDisable, matching the validation in runReposEnable. This prevents typos in repo names from passing silently. All new tests pass. The refactoring preserves existing behavior while reducing code duplication and improving test coverage. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixes critical, medium, and low priority issues from the review: **Critical - Test/Code Mismatch:** - Remove test assertion for --repo flag removal (belongs in PR fullsend-ai#698, not this PR) - This PR only adds repos enable/disable commands, doesn't touch install command **Medium - Intent Alignment:** - Change --all behavior to ignore positional repo arguments instead of rejecting them - Update validation: when --all is set, positional args are silently ignored - Update tests to verify --all ignores positional args rather than erroring **Medium - Code Duplication:** - Extract shared cobra setup into newReposSubcommand() helper - Define reposRunFunc type for enable/disable operation signatures - Reduces duplicate code from ~160 lines to ~30 lines - Enable and disable commands now use the same setup logic **Low - Deterministic Output:** - Sort repository lists when using --all to ensure deterministic commit diffs - Add sort.Strings() calls in both enable and disable operations - Import "sort" package **Low - Test Brittleness:** - Change TestReposCommand_HasSubcommands to match command names instead of full Use strings - Use sub.Name() instead of sub.Use to avoid fragility from usage text changes All tests pass. The refactoring preserves behavior while addressing reviewer concerns. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…on decisions Resolves remaining low-priority review comments: **Code Comments (Low Issue #3):** - Document intentional asymmetry between enable --all and disable --all - enable --all: discovers current org repos via ListOrgRepos - disable --all: iterates cfg.Repos (handles deleted repos needing cleanup) **Concurrency Safety (Low Issue #4):** - Document read-modify-write pattern in loadRepoConfig - Acknowledge lack of optimistic concurrency control - Explain why this is acceptable for admin CLI usage - Note that production systems would use conditional writes (ETags) **Remaining Action Items:** - PR description needs manual update on GitHub to replace "mutual exclusivity enforcement" with "when --all is set, positional repository arguments are silently ignored" All tests pass (unrelated flake in run_test.go due to network timeout). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Yeah, I think this is backward. |
|
@rh-hemartin Your review feedback has been addressed:
All tests pass. Ready for re-review. |
Site previewPreview: https://1094c1ca-site.fullsend-ai.workers.dev Commit: |
5ac5149 to
df788c3
Compare
df788c3 to
5e84e9f
Compare
Fixes three issues identified in the code review: 1. **Add comprehensive unit tests**: Created business-logic tests for runReposEnable and runReposDisable covering enable/disable scenarios, error cases, --all flag behavior, config updates, and edge cases. Uses forge.FakeClient pattern for isolation. 2. **Extract shared logic**: Refactored ~70% duplicated code between enable/disable functions into helper functions: - loadRepoConfig(): Verifies .fullsend exists, reads/parses config.yaml - saveRepoConfig(): Marshals config, commits changes, triggers workflow This eliminates duplication and makes the code more maintainable. 3. **Add symmetric validation**: Added organization-level repository existence validation to runReposDisable, matching the validation in runReposEnable. This prevents typos in repo names from passing silently. All new tests pass. The refactoring preserves existing behavior while reducing code duplication and improving test coverage. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixes critical, medium, and low priority issues from the review: **Critical - Test/Code Mismatch:** - Remove test assertion for --repo flag removal (belongs in PR fullsend-ai#698, not this PR) - This PR only adds repos enable/disable commands, doesn't touch install command **Medium - Intent Alignment:** - Change --all behavior to ignore positional repo arguments instead of rejecting them - Update validation: when --all is set, positional args are silently ignored - Update tests to verify --all ignores positional args rather than erroring **Medium - Code Duplication:** - Extract shared cobra setup into newReposSubcommand() helper - Define reposRunFunc type for enable/disable operation signatures - Reduces duplicate code from ~160 lines to ~30 lines - Enable and disable commands now use the same setup logic **Low - Deterministic Output:** - Sort repository lists when using --all to ensure deterministic commit diffs - Add sort.Strings() calls in both enable and disable operations - Import "sort" package **Low - Test Brittleness:** - Change TestReposCommand_HasSubcommands to match command names instead of full Use strings - Use sub.Name() instead of sub.Use to avoid fragility from usage text changes All tests pass. The refactoring preserves behavior while addressing reviewer concerns. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…on decisions Resolves remaining low-priority review comments: **Code Comments (Low Issue #3):** - Document intentional asymmetry between enable --all and disable --all - enable --all: discovers current org repos via ListOrgRepos - disable --all: iterates cfg.Repos (handles deleted repos needing cleanup) **Concurrency Safety (Low Issue #4):** - Document read-modify-write pattern in loadRepoConfig - Acknowledge lack of optimistic concurrency control - Explain why this is acceptable for admin CLI usage - Note that production systems would use conditional writes (ETags) **Remaining Action Items:** - PR description needs manual update on GitHub to replace "mutual exclusivity enforcement" with "when --all is set, positional repository arguments are silently ignored" All tests pass (unrelated flake in run_test.go due to network timeout). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
ralphbean
left a comment
There was a problem hiding this comment.
Good implementation overall — the shared newReposSubcommand factory, extracted loadRepoConfig/saveRepoConfig helpers, and comprehensive test suite are well done. The intentional asymmetry between enable --all (discovers org repos) and disable --all (iterates config entries) is a smart design choice.
Two changes requested and two notes for consideration.
[moderate] TestAdminCommand_HasSubcommands not updated for new subcommands
TestAdminCommand_HasSubcommands (admin_test.go:17-25) asserts that admin has install, uninstall, and analyze subcommands, but does not check for enable and disable. If someone removes the cmd.AddCommand(newEnableCmd()) line, no test catches it. Please add:
assert.True(t, names["enable"], "expected enable subcommand")
assert.True(t, names["disable"], "expected disable subcommand")
ggallen
left a comment
There was a problem hiding this comment.
Thread 1 (disable validation): Fixed in 6be0cd0. The disable operation now validates against config instead of GitHub, allowing cleanup of repos that have been deleted from the org. Updated test to verify this behavior.
Thread 2 (unused yolo parameter): Acknowledged as minor/deferred. The yolo flag remains in the shared function signature for consistency, even though enable doesn't use it. This could be refactored in a future PR if needed.
Thread 3 (documentation): Fixed in 6be0cd0. Added documentation for the confirmation prompt and the flag to skip it for scripted usage.
ggallen
left a comment
There was a problem hiding this comment.
Thread 1 (disable validation): Fixed in 6be0cd0. The disable operation now validates against config instead of GitHub, allowing cleanup of repos that have been deleted from the org. Updated test TestRunDisableRepos_AllowsRepoNotInConfig to verify this behavior.
Thread 2 (unused yolo parameter): Acknowledged as minor/deferred. The yolo flag remains in the shared function signature for consistency, even though enable does not use it. This could be refactored in a future PR if needed.
Thread 3 (documentation): Fixed in 6be0cd0. Added documentation for the --all confirmation prompt and the --yolo flag to skip it for scripted usage.
…on decisions Resolves remaining low-priority review comments: **Code Comments (Low Issue #3):** - Document intentional asymmetry between enable --all and disable --all - enable --all: discovers current org repos via ListOrgRepos - disable --all: iterates cfg.Repos (handles deleted repos needing cleanup) **Concurrency Safety (Low Issue #4):** - Document read-modify-write pattern in loadRepoConfig - Acknowledge lack of optimistic concurrency control - Explain why this is acceptable for admin CLI usage - Note that production systems would use conditional writes (ETags) **Remaining Action Items:** - PR description needs manual update on GitHub to replace "mutual exclusivity enforcement" with "when --all is set, positional repository arguments are silently ignored" All tests pass (unrelated flake in run_test.go due to network timeout). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…le/disable repos' Address PR review feedback from @rh-hemartin referencing issue fullsend-ai#495. The command structure is now: - fullsend admin enable repos <org> [repo...] - fullsend admin disable repos <org> [repo...] This structure provides better extensibility for future commands like 'fullsend admin enable auto-enrollment' by organizing enable/disable as the verb and repos as one of several possible objects. Changes: - Replaced newReposCmd() with newEnableCmd() and newDisableCmd() - Renamed newReposEnableCmd() to newEnableReposCmd() - Renamed newReposDisableCmd() to newDisableReposCmd() - Updated command paths in all tests from 'admin repos enable/disable' to 'admin enable/disable repos' - Updated documentation in docs/guides/admin/installation.md Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…confirmation Addresses review comment from fullsend-ai-review bot. Changes: 1. Restore --repo flag test assertion in TestInstallCmd_Flags - The flag exists in production code and should be tested 2. Add confirmation prompt for 'disable --all' operations - Added --yolo flag to skip confirmation (consistent with uninstall command) - Prompts user to type organization name to confirm disabling all repos - Updated reposRunFunc signature to include yolo parameter 3. Rename methods for consistency with command structure - runReposEnable -> runEnableRepos - runReposDisable -> runDisableRepos - Test functions updated accordingly All tests pass. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1. Add enable/disable subcommand assertions to TestAdminCommand_HasSubcommands - Prevents regression if commands are accidentally removed 2. Fix disable to handle deleted repos gracefully - Remove GitHub validation for disable (cleanup operation) - Check config instead - warn if repo not in config but don't error - Unlike enable, disable must work for repos already deleted from GitHub - Update test: TestRunDisableRepos_ErrorWhenRepoNotFound -> TestRunDisableRepos_AllowsRepoNotInConfig 3. Document disable --all confirmation prompt and --yolo flag - Add docs for interactive confirmation (type org name) - Document --yolo to skip prompt for scripted usage - Update validation description (config not GitHub) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Addresses review feedback from comment #4390357820 (Medium priority): Add helpful hints to API operation errors suggesting users check their token scopes. When enable/disable commands fail with API errors (e.g., ListOrgRepos, GetRepo, GetFileContent, CreateOrUpdateFile, DispatchWorkflow), the CLI now suggests running: gh auth refresh -s repo gh auth refresh -s workflow This provides better UX than raw API errors while avoiding the complexity of full preflight scope verification for these lightweight commands. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix disable repos to actually skip repos not in config (add continue statement) - Clarify documentation wording: change "validates" to "warns but does not reject" This addresses review feedback from: - fullsend-ai#697 (review) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
b5d5e91 to
ef04484
Compare
|
fullsend review is working on this — view logs |
ggallen
left a comment
There was a problem hiding this comment.
Review feedback addressed in ef04484:
-
Disable repos skipping behavior: Fixed the misleading "skipping" message. The code now actually skips repos not in config by adding a
continuestatement and only appending repos that exist in config toreposToDisable. -
Documentation clarity: Changed the wording from "validates repository names against the config" to "warns (but does not reject) repository names not found in the config" to accurately describe the behavior.
The changes ensure that when disabling repos, the command correctly handles repos that have been deleted from GitHub while still being present in config (cleanup scenario), and repos that never existed in config are properly skipped with a warning.
Address review feedback from PR fullsend-ai#698: - Fix command syntax in enrollment guidance message (enable repos -> repos enable) - Update validateEnabledRepos docstring to remove --repo reference - Update runInstall comment to remove --repo reference These changes ensure consistency with PR fullsend-ai#697's command structure (fullsend admin repos enable/disable) and reflect that repos now come from the enrollment prompt rather than a --repo flag. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed all references from "fullsend admin repos enable" to "fullsend admin enable repos" to match the actual command structure implemented in PR fullsend-ai#697. Fixed in two locations: - Line 223: CLI output message when no repos enrolled during install - Line 921: promptEnrollment function help text Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
/review |
|
fullsend review is working on this — view logs |
1. Remove --yolo flag from enable repos command since it has no confirmation prompt. Modified newReposSubcommand to accept a withYolo parameter that controls whether the flag is added. 2. Clarify confirmation prompt documentation in installation.md to explicitly state that users must type the exact organization name when prompted. 3. Improve error handling for non-TTY stdin by checking if stdin is a terminal before prompting. If not, provide a clear error message suggesting --yolo for non-interactive environments. Addresses review feedback in fullsend-ai#697 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
fullsend review is working on this — view logs |
Fixed 3 issues from the latest review: 1. Medium - Unused yolo parameter: Added comment to runEnableRepos explaining that yolo is accepted for signature compatibility with reposRunFunc but unused since enable has no confirmation prompt. 2. Medium - Sequential API calls: Refactored repo validation to call ListOrgRepos once and validate against the result set instead of making one GetRepo call per repository. This reduces O(n) API calls to O(1) for the validation step. 3. Low - Non-deterministic test setup: Added sort.Strings calls in setupTestConfig to ensure deterministic ordering despite map iteration being non-deterministic, preventing potential test flakes. Addresses review feedback in fullsend-ai#697 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
fullsend review is working on this — view logs |
Summary
Implements #695 by adding dedicated CLI commands to manage repository enrollment state in the
.fullsendconfig repository.Changes
fullsend admin repos enable <org> [repo...]andfullsend admin repos disable <org> [repo...]--allis set, positional repository arguments are silently ignoredTest plan
--allignores positional arguments (both enable and disable)Related
Closes #695
🤖 Generated with Claude Code