fix(init): skip API key prompt when credentials already exist#234
fix(init): skip API key prompt when credentials already exist#234Tasfia-17 wants to merge 1 commit into
Conversation
Add --skip-if-configured to testsprite setup (and the deprecated init alias). When the active profile already has a saved API key and no explicit key source (--api-key or --from-env) is given, the interactive prompt is skipped and the existing key is reused. Motivation: re-running setup to refresh the agent skill -- a common pattern in dotfiles, onboarding scripts, and CI bootstraps -- currently always re-prompts for the key, even when credentials were already configured. The flag makes setup idempotent for the credential step. Behaviour: - runConfigure short-circuits with status:already_configured when skipIfConfigured is true and existingProfile.apiKey is present. - runInit relaxes the non-interactive guard and the --output json guard when skipWillApply is true, so the flag works in CI (isTTY=false) and JSON mode without requiring a separate --api-key. - --api-key always overwrites, regardless of --skip-if-configured. - --from-env always overwrites, regardless of --skip-if-configured. - --dry-run is unaffected (no network, no writes; preview only). New tests (8 cases across auth.test.ts and init.test.ts): - skips prompt and returns early when credentials exist (text + JSON) - proceeds to prompt when no credentials exist - allows isTTY=false CI runs when skip applies - --api-key overwrites despite skip flag - --from-env overwrites despite skip flag Closes TestSprite#206
WalkthroughAdds a ChangesskipIfConfigured behavior
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as init/setup CLI
participant runInit
participant runConfigure
participant Credentials
User->>CLI: testsprite setup --skip-if-configured
CLI->>runInit: invoke with skipIfConfigured
runInit->>Credentials: read saved apiKey
alt saved key exists
runInit->>runConfigure: call with skipIfConfigured=true
runConfigure->>Credentials: readProfile
runConfigure-->>runInit: already_configured (no prompt, no network call)
else no saved key
runInit->>runConfigure: call with skipIfConfigured=false
runConfigure->>runConfigure: prompt user, validate via GET /me
runConfigure->>Credentials: writeProfile
runConfigure-->>runInit: success
end
runInit-->>CLI: summary output
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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/commands/init.ts`:
- Around line 526-530: Document the new --skip-if-configured flag in
DOCUMENTATION.md, following the existing --from-env option patterns. Describe
profile resolution, skipping credential prompts only when credentials already
exist, behavior with --yes and JSON output for scriptable use, and the
conditions under which exit code 5 still applies.
- Around line 239-245: The key-source preview logic in the init command
incorrectly treats skipIfConfigured as unconditional. Update the expression near
opts.apiKey/opts.fromEnv/opts.skipIfConfigured so that this case describes the
conditional behavior—use saved credentials if available, otherwise
prompt—instead of reporting skip-if-configured as the selected source.
- Around line 207-214: Move the `savedKey` lookup using `readProfile()` behind
the non-dry-run guard, and only perform it when `opts.skipIfConfigured` is
enabled and needed for `skipWillApply`; ensure `--dry-run` does not read
credentials before its preview branch or trigger credential read 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 8fd9e19b-bf09-4b61-bb9c-b09828249da7
⛔ Files ignored due to path filters (1)
test/__snapshots__/help.snapshot.test.ts.snapis excluded by!**/*.snap,!**/*.snap
📒 Files selected for processing (4)
src/commands/auth.test.tssrc/commands/auth.tssrc/commands/init.test.tssrc/commands/init.ts
| const credentialsPath = deps.credentialsPath; | ||
| const savedKey = credentialsPath | ||
| ? readProfile(opts.profile, { path: credentialsPath })?.apiKey | ||
| : readProfile(opts.profile)?.apiKey; | ||
| const skipWillApply = Boolean(opts.skipIfConfigured) && Boolean(savedKey) && !hasKeySource; | ||
| // Non-interactive guard: no TTY + no key source → exit 5. Skipped under | ||
| // --dry-run, which is documented to work without credentials or network. | ||
| if (!isTTY && !hasKeySource && !opts.dryRun) { | ||
| if (!isTTY && !hasKeySource && !skipWillApply && !opts.dryRun) { |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the target file and inspect surrounding context.
git ls-files src/commands/init.ts
wc -l src/commands/init.ts
sed -n '160,260p' src/commands/init.ts
# Find definitions/usages for readProfile, dry-run handling, and skip-if-configured.
rg -n "function readProfile|const readProfile|readProfile\(" src -S
rg -n "dryRun|skipIfConfigured|resolveReportedEndpoint|credentialsPath" src/commands/init.ts src -SRepository: TestSprite/testsprite-cli
Length of output: 50382
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect readProfile implementation and its error behavior.
sed -n '1,260p' src/lib/credentials.ts
# Show the init dry-run block with a bit more context around the early credential read.
sed -n '200,290p' src/commands/init.tsRepository: TestSprite/testsprite-cli
Length of output: 10442
Avoid reading credentials before the dry-run branch.
readProfile() can throw on unreadable credentials, so this eager lookup can make --dry-run fail before emitting its preview. Resolve savedKey only when !opts.dryRun and --skip-if-configured needs it.
🤖 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/commands/init.ts` around lines 207 - 214, Move the `savedKey` lookup
using `readProfile()` behind the non-dry-run guard, and only perform it when
`opts.skipIfConfigured` is enabled and needed for `skipWillApply`; ensure
`--dry-run` does not read credentials before its preview branch or trigger
credential read errors.
| opts.apiKey | ||
| ? 'flag' | ||
| : opts.fromEnv | ||
| ? 'env' | ||
| : opts.skipIfConfigured | ||
| ? 'skip-if-configured' | ||
| : 'prompt' |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Make the dry-run key-source preview conditional.
With --skip-if-configured but no saved key, this reports skip-if-configured, while a real run will prompt. Describe it as conditional (for example, “saved credentials if available; otherwise prompt”) rather than as the selected source.
🤖 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/commands/init.ts` around lines 239 - 245, The key-source preview logic in
the init command incorrectly treats skipIfConfigured as unconditional. Update
the expression near opts.apiKey/opts.fromEnv/opts.skipIfConfigured so that this
case describes the conditional behavior—use saved credentials if available,
otherwise prompt—instead of reporting skip-if-configured as the selected source.
| .option('-y, --yes', 'Non-interactive: accept all defaults, never prompt') | ||
| .option( | ||
| '--skip-if-configured', | ||
| 'Skip the API key prompt when credentials already exist for this profile (CI-safe idempotent re-run)', | ||
| ); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Document the new public flag before release.
Update DOCUMENTATION.md with --skip-if-configured behavior, including profile resolution, non-interactive/JSON output, and when exit code 5 still applies. As per path instructions, this flag should follow the existing --from-env documentation patterns and document its JSON/scriptable behavior.
🤖 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/commands/init.ts` around lines 526 - 530, Document the new
--skip-if-configured flag in DOCUMENTATION.md, following the existing --from-env
option patterns. Describe profile resolution, skipping credential prompts only
when credentials already exist, behavior with --yes and JSON output for
scriptable use, and the conditions under which exit code 5 still applies.
Source: Path instructions
Summary
Running
testsprite setupalways re-prompts for the API key even whencredentials are already saved in
~/.testsprite/credentials. This makesre-running setup (a common pattern for refreshing the agent skill in
dotfiles and CI bootstraps) unnecessarily disruptive.
This PR adds
--skip-if-configuredtotestsprite setup(and thedeprecated
initalias). When the active profile already has a savedAPI key and no explicit key source (
--api-keyor--from-env) isgiven, the interactive prompt is skipped and the existing key is reused.
Changes
src/commands/auth.ts-- AddedskipIfConfiguredtoConfigureOptions.runConfigureshort-circuits withstatus: already_configuredbefore prompting when the flag is set and a saved key exists.src/commands/init.ts-- Added--skip-if-configuredflag toaddSetupOptions.runInitcomputesskipWillApplyand relaxes the non-interactive guard and the--output jsonguard when skip applies. Cleared when--api-keyis explicitly given so explicit keys always overwrite.src/commands/auth.test.ts-- 4 new test cases.src/commands/init.test.ts-- 4 new test cases.test/__snapshots__/help.snapshot.test.ts.snap-- Updated snapshot.Behaviour
testsprite setupwith a valid saved profile skips the key prompt.--skip-if-configuredwithisTTY=falseworks in CI without exit 5.--api-keyalways overwrites regardless of the flag.--from-envalways overwrites regardless of the flag.--dry-runis unaffected (no network, no writes).--output jsonworks without the prompt-corruption guard firing.Tests
All 1868 tests pass. Coverage stays above 80%.
Closes #206
Summary by CodeRabbit
New Features
--skip-if-configuredoption to setup and initialization commands.Bug Fixes