Commit 5b97985
feat: azd init -t auto-creates project directory like git clone (#7290)
* Add auth pre-flight validation for agents (#7234)
Add --check flag to 'azd auth token' for lightweight auth validation.
Agents can call 'azd auth token --check' to validate authentication
state with exit code 0 (valid) or non-zero (invalid) without producing
standard output. This prevents costly retry loops where agents
speculatively call auth token and parse errors.
Enhance 'azd auth status --output json' to include expiresOn field,
giving agents machine-readable token expiry information for proactive
re-authentication.
Improve LoginGuardMiddleware to wrap ErrNoCurrentUser with actionable
ErrorWithSuggestion guidance, while preserving original error types for
cancellations and transient failures.
Changes:
- cmd/auth_token.go: Add --check flag with early-exit validation
- cmd/auth_token_test.go: Add 3 test cases (check success/failure/not-logged-in)
- cmd/auth_status.go: Populate ExpiresOn from token validation
- pkg/contracts/auth.go: Add ExpiresOn field to StatusResult
- cmd/middleware/login_guard.go: Wrap ErrNoCurrentUser with suggestion
Fixes #7234
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review feedback: remove redundant branches, add expiresOn tests
- Remove redundant 'if a.flags.check' branches in auth_token.go that
duplicated the same return (Copilot review comment #2)
- Add StatusResult JSON serialization tests verifying expiresOn is
present when authenticated and omitted when unauthenticated
(Copilot review comment #3)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Refactor: replace auth token --check with auth status exit code (#7234)
Instead of adding a --check flag to the hidden 'auth token' command,
make the existing 'auth status --output json' command agent-friendly:
- Exit non-zero when unauthenticated in machine-readable mode, so
agents can rely on exit code without parsing output
- expiresOn field already added to StatusResult in this PR
- Remove --check flag and its tests (net -90 lines)
Agents can now validate auth with:
azd auth status --output json
# exit 0 + JSON with expiresOn = valid
# exit 1 + JSON with status:unauthenticated = invalid
This is more discoverable than a hidden flag on a hidden command.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Remove tmp/ from tracking, add to .gitignore
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Revert "Remove tmp/ from tracking, add to .gitignore"
This reverts commit 7253f21.
* Remove tmp/ files from PR (not part of #7234)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review: exit non-zero in both modes, fix double output
Per @JeffreyCA feedback:
- Return auth.ErrNoCurrentUser when unauthenticated in both JSON and
interactive modes (exit non-zero in all cases)
- In JSON mode, format output before returning error to avoid double-print
- In interactive mode, show status UX then exit non-zero
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Revert non-zero exit for unauthenticated status
Per @vhvb1989 feedback: unauthenticated is a valid result, not a
command failure. Non-zero exit should only be for unexpected errors.
The expiresOn and LoginGuardMiddleware improvements remain.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: azd init -t auto-creates project directory like git clone
When using azd init -t <template>, automatically create a project
directory named after the template and initialize inside it, similar
to how git clone creates a directory.
Changes:
- Add optional [directory] positional argument to azd init
- Auto-derive folder name from template path (git clone conventions)
- Create directory, os.Chdir into it, run full init pipeline inside
- Pass "." to use current directory (preserves existing behavior)
- Show cd hint after init so users know how to enter the project
- Add DeriveDirectoryName() helper with path traversal protection
- Validate target directory: prompt if non-empty, error with --no-prompt
Fixes #7289
Related to #4032
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review: path safety, help text, efficient dir check, cd quoting
- Use Readdirnames(1) instead of os.ReadDir for efficient empty check
- Update help text/snapshots to reflect template auto-directory behavior
- Fix DeriveDirectoryName to return 'new-project' for '.'/'..' inputs
- Quote cd hint path when it contains whitespace
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix review: validate before mkdir, resolve local paths, reject stray arg
- Move init-mode validation before directory creation to prevent
orphaned directories on conflicting flags
- Resolve local template paths to absolute before os.Chdir so that
relative paths like ../my-template resolve against original CWD
- Reject positional [directory] arg when not in template mode with
a clear error message
- Export LooksLikeLocalPath for use outside the templates package
- Remove duplicate validation code (branch check, mode count)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix bare error: wrap with ErrInvalidFlagCombination sentinel
The Test_RunMethodsNoBareErrors test flagged the positional directory
argument error as a bare fmt.Errorf without %w wrapping. Wrapped with
ErrInvalidFlagCombination sentinel to produce meaningful telemetry.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Strip URL query params and fragments from derived directory names
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix init test: check azure.yaml in template subdirectory
init -t creates a subdirectory named after the template (like git
clone), so azure.yaml lives at targetDir/todo-nodejs-mongo/azure.yaml,
not targetDir/azure.yaml. Added templateDir field to test table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Re-trigger CI (Test_parseExecutableFiles passes locally)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Test_parseExecutableFiles CI failure
Replace ostest.Chdir (raw os.Chdir) with t.Chdir in
detect_confirm_test.go. The t.Chdir API integrates properly with Go
1.26's testing framework for process-wide cwd changes, preventing
subtle test state corruption that caused subsequent tests in the same
package to fail on CI.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix CI test failures in initializer tests
Remove t.Parallel() from Test_detectConfirm_confirm which conflicts with
t.Chdir() added by this PR. Go 1.26 panics when both are used together,
causing all tests in the package to fail.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Re-trigger CI (ADO Linux infra failure)
* Re-trigger CI
* Address review feedback: cleanup on failure, error handling, logging, tests
- [High] Add deferred cleanup to remove created directory and restore CWD
on init failure, matching git clone's behavior
- [Medium] Handle Readdirnames error properly instead of discarding it;
only treat io.EOF as empty directory
- [Low] Log when DeriveDirectoryName falls back to 'new-project' default
- [Low] Add test case for DeriveDirectoryName with empty string input
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: update constructor test and apply go fix modernizations
- Add missing args parameter to newInitAction call in coverage test
- Apply go fix: strings.Split -> strings.SplitSeq in process_darwin.go
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: re-record functional test playback recordings
Re-record all functional test recordings against live Azure
(eastus2, Bicep 0.42.1) to fix stale playback failures caused
by Bicep version bump.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: update Test_CLI_Init_CanUseTemplate for auto-create directory
The test was checking the parent directory for git history and
template files, but with the auto-create directory feature, template
init now creates a subdirectory derived from the template name.
Update assertions to check the cosmos-dotnet-core-todo-app subdirectory.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: address review feedback on init auto-create directory
Thread 1 (hemarina): Remove [directory] from Use line to avoid confusing
error when users type 'azd init mydir' without --template. Improved the
error message and suggestion to guide users clearly.
Thread 2 (hemarina): Replace the interactive confirmation prompt in
validateTargetDirectory with a warning message. The downstream template
initialization handles overwrite confirmation, avoiding redundant prompts.
Thread 3 (jongio): In --no-prompt mode, default to CWD when no positional
arg is given, preserving backward compatibility for existing automation.
Scripts doing 'azd init -t foo --no-prompt' continue to place files in CWD.
Users can pass an explicit positional arg to opt into directory creation.
Thread 4 (jongio): Added TODO comment for --filter tag interactive selection
to derive directory name after template selection in a follow-up.
Thread 5 (jongio): Reject absolute paths in the positional directory argument
to prevent creating directories outside the working tree and avoid dangerous
os.RemoveAll on cleanup.
Thread 6 (jongio): Added FailedInitCleansUpDirectory test that verifies the
auto-created directory is removed and CWD is restored when init fails.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: add path traversal protection and backward-compat guards to init auto-create directory
- Reject '..' traversal in positional directory arg to prevent
MkdirAll/RemoveAll outside the working tree
- Only auto-create directory in interactive TTY mode; CI, piped stdin,
--no-prompt, and AI agent invocations default to CWD (no breaking change)
- Make agent detection injectable on initAction for test isolation
- Add SetTerminal() to MockConsole for TTY simulation in tests
- 5 new tests covering traversal, non-TTY, and nested subdirectory cases
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: address review feedback — pre-existing dir safety, self-targeting, .env comment
- Track whether target directory existed before creation; only RemoveAll
on failure if we actually created it (jongio feedback)
- Detect self-targeting when local template path resolves to same
directory as the derived target; fall back to CWD (jongio feedback)
- Add comment explaining .env loading after chdir is intentional
- 2 new tests: FailedInitPreservesPreExistingDirectory,
LocalTemplateSelfTargetFallsBackToCwd
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: functional tests expect CWD in non-TTY, cross-platform abs path test
- Test_CLI_Init_CanUseTemplate: use dir directly since functional tests
run as non-TTY subprocesses where auto-directory doesn't activate
- Test_CLI_Init_WithCwdAutoCreate: expect files in -C target dir, not
a template subdirectory (--no-prompt disables auto-create)
- AbsolutePathIsRejected: use filepath.Join(os.TempDir(), ...) for
cross-platform absolute path (Windows needs drive letter)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent f3b3fc8 commit 5b97985
27 files changed
Lines changed: 352879 additions & 15186 deletions
File tree
- cli/azd
- cmd
- testdata
- internal/repository
- pkg/templates
- test
- functional
- testdata/recordings
- Test_DeploymentStacks
- Test_StorageBlobClient
- mocks/mockinput
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
218 | 218 | | |
219 | 219 | | |
220 | 220 | | |
| 221 | + | |
221 | 222 | | |
222 | 223 | | |
223 | 224 | | |
| |||
0 commit comments