feat: add studioctl apps search#18824
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe pull request adds API-key authorisation for the Designer repository search endpoint and implements a complete CLI interface for searching app repositories. Changes span backend authorisation, HTTP client implementation, service abstraction, CLI command handling, and comprehensive test coverage with documentation. ChangesApp Repository Search Implementation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes The PR spans multiple layers (backend, HTTP client, service, CLI command, tests, docs) with mixed complexity. Backend changes are minimal and focused (two-line authorisation attribute addition). CLI implementation is substantial (281 lines in apps.go) with flag parsing, output formatting, and error handling, but follows established patterns. Client implementation is straightforward HTTP request/response handling. Test coverage is comprehensive and uses standard Go idioms. No logic density issues, but variety across file types and functional areas requires contextual understanding of each layer's role in the end-to-end feature. Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
get a review from a subagent on this |
|
Subagent review completed. Findings:
Residual risk noted:
Follow-up done:
Pushed follow-up commit: |
|
Follow-up on the red Designer backend CI run:
Verification run locally: dotnet test src/Designer/backend/tests/Designer.Tests/Designer.Tests.csproj --no-restore --filter FullyQualifiedName~RepositoryServiceTests.CopyRepository_TargetExistsLocally_InitialCloneMoved --logger "console;verbosity=normal"
# Passed: 1
dotnet test src/Designer/backend/Designer.sln --filter "(Category!=GiteaIntegrationTest)&(Category!=StudioOidcGiteaIntegrationTest)&(Category!=DbIntegrationTest)&(FullyQualifiedName!~AppDevelopmentController)&(FullyQualifiedName!~PreviewController)&(FullyQualifiedName!~PolicyControllerTests)&(FullyQualifiedName!~DataModelsController)&(FullyQualifiedName!~ResourceAdminController)&(FullyQualifiedName!~TextController)&(FullyQualifiedName!~RepositoryController)" -v m --no-build
# Passed: 831, Skipped: 1 |
|
Hmm we should discuss the design here. Because this kind of search just lists actual apps, if we want to support search through code, e.g. references to som .NET symbol for example across apps, where would we put that? |
|
I agree this is worth separating conceptually. My read is:
So I think the current command is still defensible if we treat My preference for this PR: keep |
|
apps grep sounds OK actually so lets proceed with this. Also update cli changelog.md file since this is a user-facing change, use "Added" section |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@src/cli/internal/cmd/apps_internal_test.go`:
- Around line 23-36: The httptest handler currently calls t.Fatalf from its
goroutine (unsafe); instead create an error channel (e.g. errCh := make(chan
error, 1) before creating the server), replace each t.Fatalf inside the
http.HandlerFunc with sending an error (errCh <- fmt.Errorf(...)) and return,
and after the test finishes (after server.Close or after the request is made)
check the channel and call t.Fatalf or t.Error from the test goroutine if an
error was received; update references to appsSearchTestQuery and the handler
function accordingly and ensure the handler returns immediately after sending to
errCh to avoid further processing.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 133de500-dc10-44db-8847-c70e6f608d39
📒 Files selected for processing (12)
src/Designer/backend/src/Designer/Controllers/RepositoryController.cssrc/Designer/backend/tests/Designer.Tests/Controllers/RepositoryController/SearchAuthMetadataTests.cssrc/Designer/backend/tests/Designer.Tests/Services/RepositoryServiceTests.cssrc/cli/CHANGELOG.mdsrc/cli/README.mdsrc/cli/internal/cmd/app/service.gosrc/cli/internal/cmd/apps.gosrc/cli/internal/cmd/apps_internal_test.gosrc/cli/internal/cmd/root.gosrc/cli/internal/cmd/root_test.gosrc/cli/internal/studio/client.gosrc/cli/internal/studio/client_test.go
21e0eaa to
f626768
Compare
f626768 to
7b94be4
Compare
7b94be4 to
07b02ae
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/cli/internal/cmd/apps.go (1)
177-185: ⚡ Quick winNormalise accepted
--sort/--ordervalues before sending the request.Line 177 and Line 183 validate case-insensitively, but raw values are forwarded later. Lowercasing after validation avoids downstream case-sensitivity surprises.
Proposed patch
if !isSupportedAppsSearchSort(flags.sort) { return flags, "", false, fmt.Errorf( "%w: --sort must be one of alpha, created, updated, size, or id", ErrInvalidFlagValue, ) } if !isSupportedAppsSearchOrder(flags.order) { return flags, "", false, fmt.Errorf("%w: --order must be asc or desc", ErrInvalidFlagValue) } + flags.sort = strings.ToLower(flags.sort) + flags.order = strings.ToLower(flags.order) query := strings.TrimSpace(strings.Join(fs.Args(), " ")) return flags, query, false, nil }🤖 Prompt for 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. In `@src/cli/internal/cmd/apps.go` around lines 177 - 185, After validating flags.sort with isSupportedAppsSearchSort and flags.order with isSupportedAppsSearchOrder, normalize the accepted values by lowercasing flags.sort and flags.order before they are forwarded in the request; update the code around the validation block that reads flags.sort and flags.order (the variables validated by isSupportedAppsSearchSort and isSupportedAppsSearchOrder) so the values are reassigned to their lowercase equivalents (e.g., flags.sort = strings.ToLower(flags.sort) and flags.order = strings.ToLower(flags.order)) immediately after the corresponding validations to prevent downstream case-sensitivity issues.
🤖 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.
Nitpick comments:
In `@src/cli/internal/cmd/apps.go`:
- Around line 177-185: After validating flags.sort with
isSupportedAppsSearchSort and flags.order with isSupportedAppsSearchOrder,
normalize the accepted values by lowercasing flags.sort and flags.order before
they are forwarded in the request; update the code around the validation block
that reads flags.sort and flags.order (the variables validated by
isSupportedAppsSearchSort and isSupportedAppsSearchOrder) so the values are
reassigned to their lowercase equivalents (e.g., flags.sort =
strings.ToLower(flags.sort) and flags.order = strings.ToLower(flags.order))
immediately after the corresponding validations to prevent downstream
case-sensitivity issues.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 80e13b1e-3adf-46f7-837e-65654a210cd0
📒 Files selected for processing (12)
src/Designer/backend/src/Designer/Controllers/RepositoryController.cssrc/Designer/backend/tests/Designer.Tests/Controllers/RepositoryController/SearchAuthMetadataTests.cssrc/Designer/backend/tests/Designer.Tests/Services/RepositoryServiceTests.cssrc/cli/CHANGELOG.mdsrc/cli/README.mdsrc/cli/internal/cmd/app/service.gosrc/cli/internal/cmd/apps.gosrc/cli/internal/cmd/apps_internal_test.gosrc/cli/internal/cmd/root.gosrc/cli/internal/cmd/root_test.gosrc/cli/internal/studio/client.gosrc/cli/internal/studio/client_test.go
✅ Files skipped from review due to trivial changes (1)
- src/cli/CHANGELOG.md
Description
Adds
studioctl apps searchfor finding app repositories visible to the authenticated user.The CLI uses the existing stored Designer API key and calls the Designer API endpoint
/designer/api/repos/searchrather than calling the Gitea API directly. To support that, the Designer repository search endpoint now allows API-key authentication with[AllowApiKey].Verification
Automated checks run:
Manual testing against local Designer backend:
Note:
node ./development/setup.jsstarted the local Postgres/Gitea/fake-Ansattporten containers, but the fullstudio_designerDocker image build failed during frontendyarn --immutabledue Puppeteer/Cypress postinstall build failures. I therefore ran the Designer backend from source against those local containers for the manual API/CLI test.cc @martinothamar
Summary by CodeRabbit
Release Notes
New Features
apps searchcommand to the CLI for discovering app repositories in Altinn Studio with filtering, sorting, and pagination options. Results can be displayed as a table or JSON.Documentation