Skip to content

Conversation

@nicolas-goudry
Copy link

Description

This PR gates the ora spinner behind a TTY check so VitePress behaves correctly in non-interactive environments (e.g., Nix builds).

Without this, the spinner remains enabled in non‑TTY contexts and suppress/overwrite error output, making build failures appear to "hang" indefinitely.

Why this is needed

  • Animated terminal UIs assume an interactive TTY. In non‑TTY contexts, ora's frame updates and cursor control can interfere with output and error reporting. This actually hides build errors and looks like a hang
  • This change preserves the same behavior for interactive terminals, and prints clear, non-interactive output in non‑TTY environments

Minimal public reproduction (Nix + GitHub Actions)

  • Repo: ora-nix-issue-demo
  • It uses a tiny script that rejects a promise after a short delay
  • Two modes:
    • Problematic: spinner force enabled in a non‑TTY, error is hidden, looks like a hang
    • Fixed: spinner gated by TTY, error shows reliably
  • Includes both a Nix expression and a GitHub Actions workflow to reproduce in non-interactive contexts

Impact

  • No breaking changes for interactive use
  • In non‑TTY environments, errors are visible and builds no longer appear to hang

Linked Issues

N/A

Additional Context

N/A

@brc-dd
Copy link
Member

brc-dd commented Oct 25, 2025

Ora is disabled by default if stderr is non-TTY or it's in CI. It effectively uses this condition as default value of isEnabled:

  return Boolean(
    process.stderr && process.stderr.isTTY &&
    process.env.TERM !== 'dumb' &&
    !('CI' in process.env)
  )

In your example, are you sure it's not working with the default value? The condition in your example should be isEnabled: withFix ? !!process.stdin.isTTY : undefined (the default value is not true)

@nicolas-goudry
Copy link
Author

Thanks for your quick answer.

As per my tests, when VitePress runs inside a Nix build, it hangs until build timeout (IIRC last time I let the build run through the night and it timed out after ~5h).

If I refer to your code sample, when running inside a Nix build, the spinner is enabled since all conditions evaluate to true:

TERM: xterm-256color
CI: undefined
stdout is tty? true
stderr is tty? true
stdin is tty? undefined

The only fix I can think of, without updating the code, is to set the CI variable inside the Nix build (which I currently do).

I get that this fix is solving a very Nix-specific issue, so I would understand if wouldn't wish to proceed with it. I can live with having to set the CI variable (even empty) in my Nix build.

@brc-dd
Copy link
Member

brc-dd commented Oct 29, 2025

I'm fine with adjusting the value of isEnabled. I'm more curious about why it hangs. Might be better to create an issue the ora repo too if it's hanging with just ora.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants