Interactive GitLab CI/CD workflows for Neovim powered by `glab` and GitLab APIs.
Browse pipelines, inspect jobs, view logs, download artifacts, and trigger CI actions directly from Neovim.
nvim-gitlab is intentionally focused on GitLab CI/CD workflows.
Current features include:
- Pipeline browsing
- Pipeline details
- Job browsing
- Job details
- Job logs
- Job retry
- Pipeline re-run
- Artifact downloads
Merge Requests, Issues, and project management features are currently out of scope.
- Neovim 0.12+
- git
- glab (required)
- yq with YAML-to-JSON single- and multi-document support (required for CI discovery)
- MunifTanjim/nui.nvim (required)
- nvim-telescope/telescope.nvim (optional; used when
picker = "telescope")
GITLAB_TOKEN is optional when glab is already authenticated. It is required
only when using :GitlabAuth. CI discovery probes the installed yq for its
generic YAML-to-JSON single- and multi-document transcoding capabilities.
{
"mm4cN/nvim-gitlab",
dependencies = { "MunifTanjim/nui.nvim" },
config = function()
require("gitlab").setup()
end,
}use({
"mm4cN/nvim-gitlab",
requires = { "MunifTanjim/nui.nvim" },
config = function()
require("gitlab").setup()
end,
})MiniDeps.add({
source = "mm4cN/nvim-gitlab",
depends = { "MunifTanjim/nui.nvim" },
})
require("gitlab").setup()vim.pack.add({
{ src = "https://github.com/MunifTanjim/nui.nvim" },
{ src = "https://github.com/mm4cN/nvim-gitlab" },
})
require("gitlab").setup()require("gitlab").setup({
glab_binary = "glab",
ci_file = ".gitlab-ci.yml",
picker = "vim_ui", -- default picker backend
scratch_height = 15, -- scratch buffer height
gitlab_token_env = "GITLAB_TOKEN",
artifacts_dir = "gitlab-artifacts",
extract_artifacts = true,
notification = {
-- Optional; defaults to vim.notify.
handler = function(message, level, opts)
vim.notify(message, level, opts)
end,
},
})The notification handler is backend-agnostic, so it can delegate to Noice, Snacks, nvim-notify, or another implementation without adding a plugin dependency to nvim-gitlab.
To enable Telescope integration:
require("gitlab").setup({
picker = "telescope",
})If Telescope is not installed, gitlab.nvim automatically falls back to vim.ui.select().
With Telescope enabled, pickers provide additional features:
- Preview pane showing available actions and selected item details
- Custom keybindings for quick actions (e.g.,
<C-r>to re-run a pipeline directly from the picker)
- Picker backend abstraction
- Telescope picker backend
- vim.ui fallback picker backend
- Run GitLab pipelines
- List project pipelines
- Show latest pipeline status
- Open pipeline details
- Re-run pipelines
- Cross-project pipeline runner with project/ref pickers, CI inputs, and pipeline variables
- Browse and operate on pipelines from any accessible project
- List jobs for the latest pipeline
- Open job details
- View job logs
- Retry jobs
- Play manual jobs
- Download job artifacts
- Pipeline → Job drilldown
- Reusable scratch window
- View history navigation (
b) - Context-aware actions
- Lightweight API for exposing pipeline status to statuslines
- Current-branch pipeline status with caching
- Native statusline and lualine integration examples
- Required and optional dependency diagnostics
- glab authentication and GitLab API validation
- CI configuration validation
:checkhealth gitlab
:GitlabHealth
:GitlabAuth:GitlabCiValidate:GitlabPipelineRun
:GitlabPipelineStatus
:GitlabPipelineList:GitlabJobListThe pipeline runner uses a compatible yq only to transcode YAML documents to
JSON. Lua discovers spec:inputs from the root .gitlab-ci.yml and legacy
described variables from GitLab's include-expanded merged CI YAML. Discovery
reports single- and multi-document capability failures separately. Successful
strategy probing is cached for the current Neovim session.
Pipeline fields with configured options use selection menus (j/k or arrow
keys). Tab and Shift-Tab continue across editable and selection fields. Option
labels are normalized for display, while selected values are submitted without
destructive sanitization.
The runner uses a fixed-height, scrollable form beside a non-focusable keybinding legend. Tab and Shift-Tab move between fields and automatically scroll the destination into view. The scrollbar indicates the current position when the form contains more fields than fit in the viewport.
Runner-wide actions are available from Project, Ref, input, variable, and option fields:
<C-p>select a project<C-r>select a ref for the current project<C-s>run the pipelineaadd a variable anddremove a user-added variable (normal mode)qor<Esc>close the runner
Enter remains field-local: it commits Project/Ref edits and retains the native interaction of the focused field; it is not the Run shortcut. Selecting another project resolves its canonical GitLab path, switches Ref to its default branch, and refreshes CI discovery while preserving manually added variables.
In :GitlabPipelineList, press <C-p> to select another accessible project.
The active project is shown in the picker prompt, and pipeline/job details,
logs, artifacts, refreshes, and reruns retain that selected project context.
Refreshable pipeline and job views support:
rRefresh current view<CR>Open detailsLOpen logsADownload artifactsRRetry job / Re-run pipeline (auto-refreshes view)PPlay manual job (auto-refreshes view)bNavigate backqClose view
The supported Lua API is:
require("gitlab").setup(opts)— configure and initialize the plugin.require("gitlab.statusline").get()— return cached statusline data without blocking.require("gitlab.statusline").clear_cache()— clear statusline context and pipeline caches.
Other gitlab.* modules are internal implementation details and may change.
The plugin provides a lightweight API for displaying current-branch pipeline status in your statusline.
require("gitlab.statusline").get()Returns a table with pipeline status information:
status— Raw pipeline status string (success, failed, running, pending, etc.)icon— Single Unicode character representing the statustext— Ready-to-use Nerd Font string, such as: ✓ successpipeline_id— Numeric pipeline IDwatch_count— Number of active pipeline watches, omitted when zerowatch_text— Formatted watch indicator, such asWatching: 2, omitted when zero
When watches are active, text appends | Watching: N. The leading GitLab
glyph requires a Nerd Font. The watch indicator
is available even when the current-branch pipeline status is unavailable.
Otherwise, an empty table {} is returned when no pipeline is found or on
error.
vim.o.statusline = "%{%v:lua.require('gitlab.statusline').get().text or ''%}"require("lualine").setup({
sections = {
lualine_x = {
function()
return require("gitlab.statusline").get().text or ""
end,
},
},
})Results are cached for 60 seconds per project+branch pair.
make testTests run headlessly via Neovim and require no GitLab credentials or network access.
- Artifact browser
- Pipeline filtering
- Pipeline search