Skip to content

feat(ci): Add headless Neovim smoke tests with isolated XDG paths #15

Description

@cursor

Summary

Add lightweight CI coverage for the nvim/ configuration by running Neovim in headless mode against an isolated config/data/cache layout (via XDG_* overrides).

The goal is a small safety net when editing Neovim/Lua config — not a full editor E2E suite.

Problem

Today, .github/workflows/test.yml exercises Bun/TypeScript tests and shell helpers, but does not validate the Neovim setup at all.

That means changes under nvim/ can break startup, lazy.nvim bootstrap, or health checks without CI catching it. Validation is manual: symlink config, open nvim, wait for plugins, eyeball errors.

For a config built on lazy.nvim with many plugins (LSP, treesitter, telescope, etc.), even a basic "does this still start cleanly?" check would improve confidence.

Purpose / Rationale

  • Catch regressions in init.lua and lua/core/* before merge
  • Verify the config works in a fresh, non-interactive environment (closer to CI/agents than a developer's warmed-up machine)
  • Establish a pattern for isolated testing that does not depend on ~/.config, ~/.local/share/nvim, or a specific home directory layout
  • Keep CI fast and low-maintenance — smoke/health level, not full LSP/treesitter matrix testing

What "good enough" might look like (examples, not a spec)

Illustrative patterns seen in other repos — implementation details intentionally left open:

# Isolated paths so CI doesn't touch a real home dir
export XDG_CONFIG_HOME="$PWD/.ci-config"
export XDG_DATA_HOME="$PWD/.ci-data"
export XDG_CACHE_HOME="$PWD/.ci-cache"

# Point at repo nvim config, then headless smoke
nvim --headless -c "lua print('startup ok')" +qa
nvim --headless "+Lazy! sync" +qa
nvim --headless -c "checkhealth" +qa

Neovim install options others use: release tarball, rhysd/action-setup-vim, or apt — pick what fits.

Scope (suggested)

In scope:

  • Headless startup smoke test for nvim/ config
  • XDG_* isolation in CI (and locally via just test-nvim or similar)
  • Optional lazy.nvim bootstrap check (sync or restore)
  • Optional checkhealth with sensible failure criteria

Out of scope (for now):

  • Full plugin/LSP/treesitter behavior testing
  • Interactive UI/keymap testing
  • Multi-OS matrix unless there's a clear need
  • Testing Mason auto-installs, DAP, or language servers end-to-end

Context in this repo

  • Config lives in nvim/ (lazy.nvim-based, pins Neovim 0.12.2 in README)
  • README mentions nvim --headless "+Lazy! restore" +qa but lazy-lock.json is gitignored — worth considering whether reproducible CI needs a committed lockfile (separate decision)
  • symlinks.sh wires nvim~/.config/nvim on real machines; CI should use the override pattern instead

Acceptance Criteria

  • CI runs at least one headless Neovim check when nvim/** changes (or on all PRs — TBD)
  • Tests use isolated XDG_CONFIG_HOME / XDG_DATA_HOME / XDG_CACHE_HOME (or equivalent)
  • A failed config startup or lazy bootstrap fails the workflow
  • Local reproduction is documented or runnable via just (exact recipe TBD)
  • Scope stays small — no sprawling plugin test matrix

References

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions