Skip to content

feat(status): add exit-code flag - #563

Merged
jongio merged 1 commit into
mainfrom
idea-status-exit-code
Jul 28, 2026
Merged

feat(status): add exit-code flag#563
jongio merged 1 commit into
mainfrom
idea-status-exit-code

Conversation

@jongio

@jongio jongio commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Adds azd app status --exit-code so scripts can fail when the app runner is not active while keeping normal status output.

Validation:

  • go build ./...
  • go test ./...

Closes #560

@jongio jongio added the idea Feature idea from the idea pipeline label Jul 25, 2026
@jongio jongio self-assigned this Jul 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Website Preview

Your PR preview is ready!

📎 Preview URL: https://jongio.github.io/azd-app/pr/563/

This preview will be automatically cleaned up when the PR is closed.

github-actions Bot added a commit that referenced this pull request Jul 25, 2026
@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.33333% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.89%. Comparing base (60f9885) to head (7b2796d).

Files with missing lines Patch % Lines
cli/src/cmd/app/commands/status.go 83.33% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #563      +/-   ##
==========================================
+ Coverage   61.83%   61.89%   +0.05%     
==========================================
  Files         224      224              
  Lines       29418    29429      +11     
==========================================
+ Hits        18192    18216      +24     
+ Misses       9978     9962      -16     
- Partials     1248     1251       +3     
Flag Coverage Δ
unittests 61.89% <83.33%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cli/src/cmd/app/commands/status.go 84.47% <83.33%> (-0.15%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@wbreza wbreza left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — Approve ✅

Summary: Adds an --exit-code flag to azd app status that returns a non-zero exit code when the app runner is not active. Clean, well-scoped, and well-tested (2 files, ~30 lines). The primary scripting/CI use case is correct: not-running → exit 1, running → exit 0.

What I liked:

  • The JSON path prints the report before returning the exit-code error, so machine-readable output stays clean while still signaling status via the exit code. Nice separation.
  • The statusExitCodeError helper is small, pure, and the test covers all three branches (flag off, flag on + running, flag on + not running) plus flag registration.
  • Error message routes through the existing main.go error path, yielding os.Exit(1).

Non-blocking observations (Low):

  1. Redundant messaging in text mode. When not running with --exit-code, the user sees App is not running on stdout and app runner is not active on stderr (two phrasings of the same state). Functionally fine; consider reusing a single phrasing for polish.
  2. --watch + --exit-code interaction is silent. In text mode, --watch returns before statusExitCodeError is reached, so --exit-code is silently ignored (watch is long-lived/interactive, so this is reasonable — just undocumented). Worth a one-line note in help text or a docs mention.

Neither observation blocks merge. Approving.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e02217cd-ffed-496e-b8ea-848a781cda64
@jongio
jongio force-pushed the idea-status-exit-code branch from 9d5dde2 to 7b2796d Compare July 27, 2026 22:21
github-actions Bot added a commit that referenced this pull request Jul 27, 2026
@jongio

jongio commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author
  1. Redundant messaging in text mode. When not running with --exit-code, the user sees App is not running on stdout and app runner is not active on stderr (two phrasings of the same state). Functionally fine; consider reusing a single phrasing for polish.

Agreed — fixed in 7b2796d.

statusExitCodeError now returns app is not running, which matches both surfaces already in this file:

  • the text report (statusTextLines"App is not running"), and
  • the sibling dashboardURLFromStatusReport error, which already used app is not running.

So stdout and stderr now describe the same state with the same phrasing, and the wording is consistent with the rest of status.go rather than introducing a third variant.

To keep the two from drifting apart again, TestStatusExitCodeError now asserts the exact message instead of only require.Error.

@wbreza wbreza left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review (re-review) — Approve ✅

Re-reviewed at HEAD 7b2796d (new commit since my prior approval on 9d5dde2). The update rebases onto newer main (which added --dashboard-url) and addresses both non-blocking notes from my last pass:

  • Consistent wording — the exit-code error is now "app is not running", aligned with the text report, and a test asserts the exact message.
  • Documented --watch interaction — the Long help and flag usage now state --exit-code is ignored with --watch ("ignored with --watch" / "It is ignored by the interactive --watch view").

Verification:

  • JSON path still prints the report before applying the exit-code error, keeping machine output clean.
  • statusExitCodeError remains a pure helper; test covers all three branches (flag off, on+running, on+not-running) plus flag registration.
  • --watch returns before the exit-code check, matching the now-documented behavior.

Trivial (non-blocking): the code comment says the error "matches the text report … the same way," but the display string is App is not running (capitalized) vs the error app is not running (lowercase). The lowercase error is correct Go convention — no change needed; just noting the comment is slightly loose on casing.

Zero Critical/High/Medium findings. Approving.

@jongio

jongio commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author
  1. --watch + --exit-code interaction is silent. In text mode, --watch returns before statusExitCodeError is reached, so --exit-code is silently ignored (watch is long-lived/interactive, so this is reasonable — just undocumented). Worth a one-line note in help text or a docs mention.

Agreed — documented in 7b2796d.

Kept the behavior as-is for exactly the reason you gave: --watch only ends on Ctrl+C, so a "did the app exit non-zero" gate has no meaningful semantics there. The fix is documentation, in two places:

Flag help:

--exit-code   Return a non-zero exit code when the app is not running (ignored with --watch)

Long help:

Pass --exit-code to exit non-zero when the app is not running, which is handy in
scripts and CI. It is ignored by the interactive --watch view.

The phrasing follows the existing azd app outdated --exit-code convention ("Return a non-zero exit code when ...") so the two flags read the same way.

One note on scope: this only applies to the interactive text view. With the global --json flag, --watch is already ignored in favour of a single snapshot, so --exit-code still works there — which the existing long-help line about --json already covers.

@jongio

jongio commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

Rebase + CI note

Rebased onto main (7b2796d) — the branch was behind and had become CONFLICTING.

main had since added --dashboard-url to the same command, which collided with this PR in status.go and status_test.go. Resolution keeps both flags: statusDashboardURL and statusExitCode now sit side by side in the var block, both flag registrations are present, and TestNewStatusCommand asserts both. Git auto-merged the runStatus body cleanly, so --dashboard-url still short-circuits before the exit-code check — which is correct, since that path already returns app is not running when the app is down.

Local validation on the rebased tree:

  • go build ./... — clean
  • gofmt — clean
  • golangci-lint run ./src/cmd/app/commands/... — 0 issues
  • go test ./src/cmd/app/commands/ ./src/internal/portmanager/ — both pass

On the red Windows check: the failure was TestGetProcessOnPort_WithActivePort in internal/portmanager, which this PR does not touch. It is an environment flake on the hosted runner — getProcessOnPort took 5.08s (hit commandTimeout), tripping the elapsed > 3s assertion at process_timeout_test.go:62 before the t.Skipf on line 67 could take effect. Because t.Skip does not clear an already-recorded t.Errorf, the test reports FAIL rather than SKIP. main is green and the package passes locally, so I have left it alone rather than widen this PR; the push above triggers a fresh run.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Test This PR

A preview build (0.20.0-pr563) is ready for testing!

🌐 Website Preview

Live Preview: https://jongio.github.io/azd-app/pr/563/

One-Line Install (Recommended)

PowerShell (Windows):

iex "& { $(irm https://raw.githubusercontent.com/jongio/azd-app/main/cli/scripts/install-pr.ps1) } -PrNumber 563 -Version 0.20.0-pr563"

Bash (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/jongio/azd-app/main/cli/scripts/install-pr.sh | bash -s 563 0.20.0-pr563

Uninstall

When you're done testing:

PowerShell (Windows):

iex "& { $(irm https://raw.githubusercontent.com/jongio/azd-app/main/cli/scripts/uninstall-pr.ps1) } -PrNumber 563"

Bash (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/jongio/azd-app/main/cli/scripts/uninstall-pr.sh | bash -s 563

Build Info:

What to Test:
Please review the PR description and test the changes described there.

@jongio

jongio commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

Trivial (non-blocking): the code comment says the error "matches the text report … the same way," but the display string is App is not running (capitalized) vs the error app is not running (lowercase). The lowercase error is correct Go convention — no change needed; just noting the comment is slightly loose on casing.

Good catch, and you're right on both counts — thanks for calling it out precisely.

To confirm the intent for anyone reading later: the casing difference is deliberate, not an oversight. statusTextLines renders App is not running as display text at the start of a line, while the error stays lowercase because Go error strings are conventionally uncapitalized (ST1005 / the staticcheck rule enforced by our .golangci.yml). So the two intentionally differ in case while describing the same state — which is exactly the consistency the change was after.

Agreed the comment's "the same way" is loose about that. Taking your "no change needed" at face value and leaving it as-is rather than spending another full CI cycle and review round on a five-word comment tweak on an approved, green PR. Happy to fold the tightening into the next change that touches this file.

@jongio
jongio merged commit 4042c75 into main Jul 28, 2026
20 checks passed
github-actions Bot added a commit that referenced this pull request Jul 28, 2026
jongio added a commit that referenced this pull request Jul 29, 2026
The 15 commits that landed on main while this branch was open added CLI
surface the docs gate correctly rejected. Resolve the cli-reference.md
conflict by keeping both sides, then backfill everything the gate found.

Commands documented:
- open (#552), including cli/docs/commands/open.md and the URL resolution order
- website reference pages for hooks (#515) and remove (#511), which shipped
  without generated pages

Flags documented:
- run --env (#498), run --no-deps (#544)
- logs --summary (#491), logs --min-level (#527), logs --no-timestamps (#561)
- status --exit-code (#563)
- env --prefix (#490)

Also fix the gofumpt failure in env_test.go that currently breaks
mage preflight on main.

mage preflight passes clean. Docs gate covers 31 commands, website
validation covers 27.

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

idea Feature idea from the idea pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add status --exit-code for scripts

2 participants