Skip to content

Print a warning when the CLI is out of date#7

Merged
ellismg merged 2 commits intoAzure:mainfrom
ellismg:ellismg/add-up-to-date-check
Jul 8, 2022
Merged

Print a warning when the CLI is out of date#7
ellismg merged 2 commits intoAzure:mainfrom
ellismg:ellismg/add-up-to-date-check

Conversation

@ellismg
Copy link
Copy Markdown
Member

@ellismg ellismg commented Jul 7, 2022

This changes adds an update to date check to our CLI. It works by
fetching the latest version of the CLI from a well-known location and
prints a warning if it is larger. To improve user precived
performance, we run the logic to fetch the latest version in parallel
with the command the user is running and we cache the value we fetch
for 24 hours.

If the CLI is out of date, a warning like the following is printed
when the command completes:

warning: your version of azd is out of date, you have 0.0.1-beta.1686705 but the latest version is 0.0.1-beta.1686706

To update to the latest version, run:
powershell -c "Set-ExecutionPolicy Bypass Process -Force; irm 'https://aka.ms/install-azd.ps1' | iex"

When run on non windows platforms, the bash invocation is printed
instead.

This behavior may be disabled by setting AZD_SKIP_UPDATE_CHECK to
true.

This changes adds an update to date check to our CLI. It works by
fetching the latest version of the CLI from a well-known location and
prints a warning if it is larger. To improve user precived
performance, we run the logic to fetch the latest version in parallel
with the command the user is running and we cache the value we fetch
for 24 hours.

If the CLI is out of date, a warning like the following is printed
when the command completes:

```
warning: your version of azd is out of date, you have 0.0.1-beta.1686705 but the latest version is 0.0.1-beta.1686706

To update to the latest version, run:
powershell -c "Set-ExecutionPolicy Bypass Process -Force; irm 'https://aka.ms/install-azd.ps1' | iex"
```

When run on non windows platforms, the `bash` invocation is printed
instead.

This behavior may be disabled by setting AZD_SKIP_UPDATE_CHECK to
`true`.
Move to a new format for the aka.ms link for the latest version that
will give us more flexibility when we want to also include channel
information as part of the update check.

Also, set a custom User Agent as we do on other requests that we make.
@azure-sdk
Copy link
Copy Markdown
Collaborator

VSCode Extension Installation Instructions

  1. Download the extension at https://azuresdkreleasepreview.blob.core.windows.net/azd/vscode/pr/7/azure-dev-0.1.0.vsix
  2. Extract the extension from the compressed file
  3. In vscode
    a. Open "Extensions" (Ctrl+Shift+X)
    b. Click the ...\ menu at top of Extensions sidebar
    c. Click "Install from VSIX"
    d. Select location of downloaded file

@azure-sdk
Copy link
Copy Markdown
Collaborator

Azure Dev CLI Install Instructions

Install scripts

Make sure you've uninstalled the npm package if it's still on your system using npm uninstall -g @azure/az-dev-cli

MacOS/Linux

May elevate using sudo on some platforms and configurations

curl -fsSL https://azuresdkreleasepreview.blob.core.windows.net/azd/standalone/pr/7/uninstall-azd.sh | bash;
curl -fsSL https://azuresdkreleasepreview.blob.core.windows.net/azd/standalone/pr/7/install-azd.sh | bash -s -- --base-url https://azuresdkreleasepreview.blob.core.windows.net/azd/standalone/pr/7 --version '' --verbose

Windows

powershell -c "Set-ExecutionPolicy Bypass Process; irm 'https://azuresdkreleasepreview.blob.core.windows.net/azd/standalone/pr/7/uninstall-azd.ps1' > uninstall-azd.ps1; ./uninstall-azd.ps1;"
powershell -c "Set-ExecutionPolicy Bypass Process; irm 'https://azuresdkreleasepreview.blob.core.windows.net/azd/standalone/pr/7/install-azd.ps1' > install-azd.ps1; ./install-azd.ps1 -BaseUrl 'https://azuresdkreleasepreview.blob.core.windows.net/azd/standalone/pr/7' -Version '' -Verbose;"

Standalone Binary

Container

docker run -it azdevcliextacr.azurecr.io/azure-dev:pr-7

@ellismg ellismg merged commit f603549 into Azure:main Jul 8, 2022
jongio added a commit that referenced this pull request Apr 21, 2026
mq follow-up to de57ff4 addressing secops + smells/arch findings on
the H1 (cross-process .env race) fix:

- Make lockPath unexported (was LockPath; no external callers).
- Replace osPermDir local const with osutil.PermissionDirectory.
- Extract acquireEnvLock(ctx, env) + releaseEnvLock helpers; both
  Reload and Save now share one code path.
- Use TryLockContext(ctx, 50ms) instead of unbounded Lock(): a wedged
  flock holder (e.g. hung 'azd env set' subprocess; LockFileEx on
  Windows is not signal-aware) no longer freezes azd; Ctrl-C and
  context deadlines now cancel the wait. (secops M-1)
- manager.Get's remote-fallback Save now releases saveMu via defer
  inside a closure instead of two Unlock sites. (smells/arch #7)

No behavior change for the happy path; tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jongio added a commit that referenced this pull request Apr 21, 2026
mq follow-up to de57ff4 addressing secops + smells/arch findings on
the H1 (cross-process .env race) fix:

- Make lockPath unexported (was LockPath; no external callers).
- Replace osPermDir local const with osutil.PermissionDirectory.
- Extract acquireEnvLock(ctx, env) + releaseEnvLock helpers; both
  Reload and Save now share one code path.
- Use TryLockContext(ctx, 50ms) instead of unbounded Lock(): a wedged
  flock holder (e.g. hung 'azd env set' subprocess; LockFileEx on
  Windows is not signal-aware) no longer freezes azd; Ctrl-C and
  context deadlines now cancel the wait. (secops M-1)
- manager.Get's remote-fallback Save now releases saveMu via defer
  inside a closure instead of two Unlock sites. (smells/arch #7)

No behavior change for the happy path; tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jongio added a commit that referenced this pull request Apr 22, 2026
mq follow-up to de57ff4 addressing secops + smells/arch findings on
the H1 (cross-process .env race) fix:

- Make lockPath unexported (was LockPath; no external callers).
- Replace osPermDir local const with osutil.PermissionDirectory.
- Extract acquireEnvLock(ctx, env) + releaseEnvLock helpers; both
  Reload and Save now share one code path.
- Use TryLockContext(ctx, 50ms) instead of unbounded Lock(): a wedged
  flock holder (e.g. hung 'azd env set' subprocess; LockFileEx on
  Windows is not signal-aware) no longer freezes azd; Ctrl-C and
  context deadlines now cancel the wait. (secops M-1)
- manager.Get's remote-fallback Save now releases saveMu via defer
  inside a closure instead of two Unlock sites. (smells/arch #7)

No behavior change for the happy path; tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jongio added a commit that referenced this pull request Apr 23, 2026
mq follow-up to de57ff4 addressing secops + smells/arch findings on
the H1 (cross-process .env race) fix:

- Make lockPath unexported (was LockPath; no external callers).
- Replace osPermDir local const with osutil.PermissionDirectory.
- Extract acquireEnvLock(ctx, env) + releaseEnvLock helpers; both
  Reload and Save now share one code path.
- Use TryLockContext(ctx, 50ms) instead of unbounded Lock(): a wedged
  flock holder (e.g. hung 'azd env set' subprocess; LockFileEx on
  Windows is not signal-aware) no longer freezes azd; Ctrl-C and
  context deadlines now cancel the wait. (secops M-1)
- manager.Get's remote-fallback Save now releases saveMu via defer
  inside a closure instead of two Unlock sites. (smells/arch #7)

No behavior change for the happy path; tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jongio added a commit that referenced this pull request Apr 27, 2026
mq follow-up to de57ff4 addressing secops + smells/arch findings on
the H1 (cross-process .env race) fix:

- Make lockPath unexported (was LockPath; no external callers).
- Replace osPermDir local const with osutil.PermissionDirectory.
- Extract acquireEnvLock(ctx, env) + releaseEnvLock helpers; both
  Reload and Save now share one code path.
- Use TryLockContext(ctx, 50ms) instead of unbounded Lock(): a wedged
  flock holder (e.g. hung 'azd env set' subprocess; LockFileEx on
  Windows is not signal-aware) no longer freezes azd; Ctrl-C and
  context deadlines now cancel the wait. (secops M-1)
- manager.Get's remote-fallback Save now releases saveMu via defer
  inside a closure instead of two Unlock sites. (smells/arch #7)

No behavior change for the happy path; tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
vhvb1989 added a commit that referenced this pull request Apr 27, 2026
Addresses review comments on PR #7795:

- #5/#6: Wrap portal URLs in output.WithLinkFormat across all
  user-facing emission sites; extract printLeaveRunningMessage helper
  to deduplicate the leave-running prompt body.

- #7: After the top-level deployment reaches Canceled, walk the
  operations tree to discover descendant (nested) deployments,
  best-effort cancel any that are still non-terminal, and wait for
  them to reach a terminal state. The whole interrupt flow now lives
  under a single 5-minute global budget (previously 2-minute terminal
  timeout). If one or more nested deployments remain non-terminal at
  budget exhaustion, azd surfaces them by name with portal links and
  records a new 'cancel_timed_out_nested' telemetry value (still
  ErrDeploymentCancelTimeout).

- #9: Fix misleading 'second Ctrl+C is treated as a force-exit'
  comment in console.go — the second additional press arms the
  force-exit latch (and is suppressed); the next press triggers exit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jongio added a commit that referenced this pull request Apr 30, 2026
mq follow-up to de57ff4 addressing secops + smells/arch findings on
the H1 (cross-process .env race) fix:

- Make lockPath unexported (was LockPath; no external callers).
- Replace osPermDir local const with osutil.PermissionDirectory.
- Extract acquireEnvLock(ctx, env) + releaseEnvLock helpers; both
  Reload and Save now share one code path.
- Use TryLockContext(ctx, 50ms) instead of unbounded Lock(): a wedged
  flock holder (e.g. hung 'azd env set' subprocess; LockFileEx on
  Windows is not signal-aware) no longer freezes azd; Ctrl-C and
  context deadlines now cancel the wait. (secops M-1)
- manager.Get's remote-fallback Save now releases saveMu via defer
  inside a closure instead of two Unlock sites. (smells/arch #7)

No behavior change for the happy path; tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
vhvb1989 added a commit that referenced this pull request Apr 30, 2026
…7795)

* feat(provision): prompt to cancel Azure deployment on Ctrl+C (Bicep)

When a user presses Ctrl+C during 'azd provision' or 'azd up' while a
Bicep deployment is in flight on Azure, azd now pauses and asks whether
to leave the Azure deployment running (default) or to cancel it via the
ARM Cancel API and wait for a terminal state.

- pkg/input: register-able interrupt handler stack with re-entrant
  Ctrl+C suppression while a handler is running.
- pkg/azapi + pkg/infra: Cancel methods on DeploymentService /
  Deployment for both subscription- and resource-group-scoped
  deployments. Deployment Stacks return 'not supported' (no Cancel API
  surface today).
- pkg/infra/provisioning: typed sentinel errors for the 4 outcomes
  (leave running / canceled / cancel timed out / cancel too late) plus
  telemetry attribute provision.cancellation.
- pkg/infra/provisioning/bicep: interactive prompt + cancel-and-poll
  flow with 30s cancel-request timeout and 2-min terminal-state wait.
- cmd/middleware + internal/cmd: bypass agent troubleshooting and map
  sentinels to telemetry codes.
- docs/provision-cancellation.md: user-facing behavior, outcomes,
  provider scope, telemetry, and non-interactive fallback.

Terraform and Deployment Stacks are out of scope and unchanged.

Closes #2810

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address Copilot review feedback (iteration 1)

- pkg/input: LIFO test now invokes handlers and asserts distinct call
  counts to prove ordering.
- pkg/infra/provisioning: add ErrDeploymentCancelFailed sentinel so the
  cancel-request-failure path no longer misclassifies as a timeout;
  wire it through error middleware skip-list and telemetry mapping.
- pkg/infra: switch new TestScopeCancel subtests to t.Context().

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address Copilot review feedback (iteration 2)

- pkg/azapi: add typed ErrCancelNotSupported sentinel; stack
  CancelSubscriptionDeployment / CancelResourceGroupDeployment now
  return it instead of an opaque string.
- pkg/infra/provisioning/bicep: interrupt handler treats
  ErrCancelNotSupported as the safer 'leave running' outcome (matches
  documented stacks behavior + telemetry). Cancel-request error path
  routes through terminalToOutcome when the deployment is already in a
  terminal state, so the portal URL and consistent messaging are
  surfaced. Canceled terminal branch now prints the portal URL too.
- pkg/infra/provisioning: ErrDeploymentCancelFailed doc comment now
  references errors.Is/errors.As (matches the multi-%w joined-error
  wrapping pattern used here).
- pkg/infra/provisioning/bicep/bicep_provider: tear down the interrupt
  handler immediately after deployModule returns (sync.OnceFunc) to
  avoid a small window where a late Ctrl+C could surface the prompt
  over post-processing output.
- internal/cmd/errors: map ErrCancelNotSupported in classifySentinel.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: close interrupt-vs-natural-completion race (iteration 3)

If Ctrl+C arrives but the ARM deployment happens to finish naturally
before the user picks an option in the prompt, the previous design
could take the success path and silently drop the interrupt.

- installDeploymentInterruptHandler now exposes a 'started' channel
  that is closed the instant Ctrl+C is received, before the prompt is
  shown. deployCtx is also cancelled immediately so PollUntilDone
  unblocks ASAP.
- BicepProvider.Deploy block-receives the outcome whenever 'started'
  is closed (instead of a non-blocking drain), so the user's choice is
  always honored regardless of who wins the race.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: re-entrant Ctrl+C suppression hardening (iteration 4)

- pkg/input/console: watchTerminalInterrupt now reserves the running
  slot before consulting the handler stack so re-entrant Ctrl+C is
  suppressed even if the stack is briefly empty (e.g. handler popped
  but still executing the prompt).
- pkg/infra/provisioning/bicep/bicep_provider: defer cleanup until
  after the interrupt outcome is received so a second Ctrl+C during
  the prompt is still suppressed; the no-interrupt path tears down
  immediately as before.
- pkg/infra/provisioning/cancel: doc reads 'sentinel errors' instead
  of 'typed errors' to match the implementation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address Copilot review feedback (iteration 5)

- pkg/input/interrupt: enforce strict LIFO when popping handlers
  (only pop when this handler is still top-of-stack), so out-of-order
  pops never accidentally remove unrelated newer handlers.
- pkg/infra/provisioning/bicep/interrupt: defensive default in
  terminalToOutcome now stops the spinner and emits a warning with
  the observed state and portal URL, leaving the UI clean if an
  unexpected terminal state is ever observed.
- pkg/infra/provisioning/bicep/interrupt: treat
  DeploymentProvisioningStateDeleted as terminal in the cancel poll
  so we don't keep polling until the deadline if the deployment is
  deleted out from under us. Test updated accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address Copilot review feedback (iteration 6)

- pkg/infra/provisioning/bicep/interrupt: wrap the interrupt handler
  closure with sync.OnceValue so close(started), cancelDeploy() and
  the outcome channel send all run at most once. Combined with the
  in-flight guard from tryStartInterruptHandler and the strict LIFO
  pop, additional Ctrl+C signals after the prompt completes can no
  longer panic or block on the buffered channel.
- pkg/infra/provisioning/bicep/interrupt: print the portal URL on
  the prompt-failure leave-running path so the user always has a
  link to follow up when the URL is available.
- docs/provision-cancellation: clarify that the portal URL is
  printed when available (not 'in every case').

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address Copilot review feedback (iteration 7)

- pkg/input/interrupt: nil out the popped slot before truncating
  the interrupt stack so the GC can reclaim the popped handler and
  any state it captured, even before the underlying array is
  reallocated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address Copilot review feedback (iteration 8)

- pkg/input/console: run the registered interrupt handler inline on
  the signal goroutine instead of in a nested goroutine. This
  removes the scheduling window where SIGINT was received but the
  handler had not yet run, which could let a deploy goroutine
  complete naturally and silently drop the Ctrl+C. Re-entrant signals
  remain suppressed via tryStartInterruptHandler.
- pkg/infra/provisioning/bicep/interrupt: switch the cancel poll
  loop to a time.Ticker and move the wait before each Get, so a
  slow Get cannot produce back-to-back ARM polls (preventing
  throttling).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address review findings from wbreza and jongio on PR #7795

Fixes from wbreza's review:
- H1/N1: Race between deploy-success and interrupt handler — replaced
  select-based check with atomic CAS state machine (deployStateRunning →
  deployStateInterrupting or deployStateCompleted) so the handler and
  Deploy goroutine never conflict.
- H2: Panic in interrupt handler — added recover() with stack trace
  logging in watchTerminalInterrupt so a handler panic doesn't leave the
  process unkillable.
- H3: Second Ctrl+C force-exit — added forceExitPending counter in
  interrupt.go; second suppressed Ctrl+C while a handler is running
  triggers os.Exit(130) matching POSIX convention (kubectl, terraform).
- M13: terminalToOutcome now a BicepProvider method with ctx as first
  parameter per AGENTS.md convention.
- L7: Spelling consistency — 'Cancelling' → 'Canceling' to match ARM
  API and codebase convention.
- L8: Removed stray blank line in cmd/middleware/error.go.

Fixes from jongio's review:
- N1: Same race fix as H1 above (CAS state machine).
- N2: Panic recovery (defense-in-depth per Jon's suggestion).
- N3: Test cleanup — added t.Cleanup() for PushInterruptHandler pops
  and finishInterruptHandler to prevent global state leaks on assertion
  failure.

Fixes from Copilot bot review:
- Unbounded Get call in cancel-request error path — added
  context.WithTimeout wrapper (30s).
- DeploymentUrl fetch in prompt — added timeout to prevent indefinite
  blocking on slow/unreachable ARM.
- Deleted state mismatch — added explicit case in terminalToOutcome for
  DeploymentProvisioningStateDeleted.
- Test cleanup in interrupt_test.go (same as N3 above).

New tests:
- TestForceExitCounter: validates force-exit on 2nd suppressed Ctrl+C.
- TestForceExitCounter_ResetsOnNewHandler: ensures counter resets
  between handler lifecycles.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test(bicep): add unit tests for interrupt prompt/cancel/install flow

Addresses follow-up review feedback from @wbreza on PR #7795:

- Adds targeted unit tests for runInterruptPrompt,
  cancelAndAwaitTerminal, and installDeploymentInterruptHandler
  using a programmable fake infra.Deployment and the existing
  MockConsole. Tests cover the leave-running, cancel,
  prompt-failure, URL-fetch-failure, cancel-not-supported,
  cancel-failed-with-fallback-Get, polled-canceled, and
  poll-timeout paths, plus the markCompleted/interrupt CAS race.
- Promotes cancelRequestTimeout, cancelTerminalTimeout, and
  cancelPollInterval from const to package-level var so unit
  tests can shrink them to keep the suite sub-second.
- Logs the post-cancel Get error when the cancel API itself
  failed and the fallback Get also fails (it was previously
  silently dropped, hurting production diagnosability).
- Exposes input.SnapshotInterruptStack as a test-only helper so
  cross-package tests can invoke the registered handler without
  installing the OS signal pipeline.

Refs: #7933 (follow-up
for replacing the process-global interrupt state with an
injectable InterruptBroker).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* perf(bicep): issue first cancel-poll Get immediately

Previously cancelAndAwaitTerminal entered a ticker-driven loop that
waited cancelPollInterval (5s in production) BEFORE every Get,
including the first one issued right after the cancel API succeeded.
For deployments that Azure transitions to Canceled quickly (e.g.
deployments that just started), the user saw a needless ~5s pause
before azd reported the cancellation.

Fix: do an immediate Get right after the cancel request returns; only
the subsequent retries are ticker-spaced. This preserves the original
'no back-to-back Gets' guarantee for the slow path while removing the
unnecessary delay on the fast path.

Adds TestCancelAndAwaitTerminal_FirstGetIsImmediate which sets
cancelPollInterval to a deliberately large value and asserts the call
returns in well under a poll interval when the first Get already
returns Canceled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat(bicep): wait for nested deployments after cancel + URL formatting

Addresses review comments on PR #7795:

- #5/#6: Wrap portal URLs in output.WithLinkFormat across all
  user-facing emission sites; extract printLeaveRunningMessage helper
  to deduplicate the leave-running prompt body.

- #7: After the top-level deployment reaches Canceled, walk the
  operations tree to discover descendant (nested) deployments,
  best-effort cancel any that are still non-terminal, and wait for
  them to reach a terminal state. The whole interrupt flow now lives
  under a single 5-minute global budget (previously 2-minute terminal
  timeout). If one or more nested deployments remain non-terminal at
  budget exhaustion, azd surfaces them by name with portal links and
  records a new 'cancel_timed_out_nested' telemetry value (still
  ErrDeploymentCancelTimeout).

- #9: Fix misleading 'second Ctrl+C is treated as a force-exit'
  comment in console.go — the second additional press arms the
  force-exit latch (and is suppressed); the next press triggers exit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* ux(bicep): clearer interrupt copy + per-state telemetry split

Addresses customer-experience review on PR #7795 (kristenwomack):

- R1/R11 Branch terminalToOutcome by state. Succeeded is reframed as a
  *success* ("completed successfully before cancellation took effect —
  your resources are deployed") so users who Ctrl+C suspecting a hang
  aren't told their successful deployment was a 'too-late' failure.
  Failed/Deleted get distinct copy. Telemetry value split into
  cancel_raced_succeeded / _failed / _deleted; cancel_too_late kept as
  the fallback for unexpected terminal states.
- R2 Non-interactive prompt fallback now always emits a breadcrumb
  (portal URL when available, otherwise 'find it under
  Subscription → Deployments') plus the az-deployment-cancel hint, so
  CI runs can't silently leak abandoned Azure deployments.
- R3 Prompt title is now active and names the cause: 'You pressed
  Ctrl+C. An Azure deployment is still running — what do you want to
  do?'.
- R4 Prompt help text and leave-running message no longer drop the
  pointer when the URL fetch fails — they degrade to a portal-search
  hint that includes the deployment name.
- R9 Replace the leaking Go duration in the cancel-timeout message
  ('within 5m0s') with prose ('within 5 minutes'). Title updated to
  'Azure is still canceling — azd will exit'.
- R10 Cancel-failed copy reframed: 'Couldn't cancel — Azure deployment
  is still running. The cancel request was rejected by Azure. The
  deployment will continue.'
- R15 'Deployment was deleted' message now explains it's unusual and
  suggests checking audit logs.
- R16 Leave-running path always prints the
  'az deployment sub|group cancel --name <n>' hint so users have a
  copy-pasteable next step.

Docs (provision-cancellation.md) and the ProvisionCancellationKey field
comment updated to describe the new telemetry values.

R5 (option ordering), R6 (5-min wait UX), R7 (discoverability),
R8 (docs site), R12 (skip prompt for Stacks), R13 (a11y),
R14 (color/WCAG) are tracked in a follow-up issue.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jongio added a commit that referenced this pull request Apr 30, 2026
mq follow-up to de57ff4 addressing secops + smells/arch findings on
the H1 (cross-process .env race) fix:

- Make lockPath unexported (was LockPath; no external callers).
- Replace osPermDir local const with osutil.PermissionDirectory.
- Extract acquireEnvLock(ctx, env) + releaseEnvLock helpers; both
  Reload and Save now share one code path.
- Use TryLockContext(ctx, 50ms) instead of unbounded Lock(): a wedged
  flock holder (e.g. hung 'azd env set' subprocess; LockFileEx on
  Windows is not signal-aware) no longer freezes azd; Ctrl-C and
  context deadlines now cancel the wait. (secops M-1)
- manager.Get's remote-fallback Save now releases saveMu via defer
  inside a closure instead of two Unlock sites. (smells/arch #7)

No behavior change for the happy path; tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jongio added a commit that referenced this pull request May 2, 2026
mq follow-up to de57ff4 addressing secops + smells/arch findings on
the H1 (cross-process .env race) fix:

- Make lockPath unexported (was LockPath; no external callers).
- Replace osPermDir local const with osutil.PermissionDirectory.
- Extract acquireEnvLock(ctx, env) + releaseEnvLock helpers; both
  Reload and Save now share one code path.
- Use TryLockContext(ctx, 50ms) instead of unbounded Lock(): a wedged
  flock holder (e.g. hung 'azd env set' subprocess; LockFileEx on
  Windows is not signal-aware) no longer freezes azd; Ctrl-C and
  context deadlines now cancel the wait. (secops M-1)
- manager.Get's remote-fallback Save now releases saveMu via defer
  inside a closure instead of two Unlock sites. (smells/arch #7)

No behavior change for the happy path; tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
vhvb1989 added a commit that referenced this pull request May 7, 2026
- Add Suggestion: assertion to functional tests (wbreza #1)
- Consolidate PreflightCheckLink into ux.PreflightReportLink,
  eliminating duplicate type and manual conversion (wbreza #2)
- Add 7 table-driven edge case tests for writeItem (wbreza #5)
- Fix PR description Before block (wbreza #7)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants