Taskfile: - Add build-linux-arm64, build-darwin-amd64, build-darwin-arm64 targets - Rename build-linux to build-linux-amd64 (keep build-linux alias) - Rename Windows output to glint-<tag>-windows-amd64.exe for consistency - Add build-release task that builds all five platforms in one shot Formula/glint.rb: - Homebrew source-build formula; depends_on "go" => :build - tap: brew tap k3nny/glint https://github.com/k3nny/homebrew-glint - Includes basic test block (--version + lint a trivial pipeline) INSTALL.md: - Pre-built binary download instructions for all five platforms - Homebrew tap setup and formula update procedure - go install one-liner - Link to README integrations section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
glint
Disclaimer: This tool was built through iterative AI-assisted development with Claude. It is experimental, incomplete, and not intended for production use. Coverage of GitLab CI keywords is best-effort and may lag behind GitLab's evolving spec. Use it at your own discretion — no correctness guarantees are made. Contributions and bug reports are welcome.
A local tool to validate and lint .gitlab-ci.yml pipelines without needing a GitLab server.
What it does
- Lints — 45 rules covering pipeline structure, keyword constraints,
needs:/dependencies:graphs, expression reachability, and deprecations (GL001–GL045); runglint explain <ID>for any rule - Resolves includes — local files, HTTPS URLs, GitLab project templates, and CI/CD Catalog components, with offline cache support and HTTP proxy support (
--proxyflag orproxy:in.glint.yml) - Renders merged pipeline —
glint renderresolves all includes andextends:chains into a single flat YAML file, matching what GitLab CI actually processes - Simulates context —
--branch,--tag,--sourceflags evaluaterules:if:andonly/exceptto show which jobs would be active, manual, or skipped;--context branch=main --context branch=developprints a multi-column comparison table across multiple contexts in one run - Multiple output formats —
--format text(default, colorized and column-aligned),json,sarif(GitHub Code Scanning / GitLab SAST),junit,github(PR annotations); exits2on errors,10on warnings only - Project config —
.glint.ymlfor rule suppression, severity overrides, token/URL/proxy defaults;# glint: ignore RULEfor per-job inline suppression;--no-warnflag to suppress all warnings - Graph visualization —
glint graphprints a terminal job tree (default);glint graph includesemits a Mermaid include-dependency graph;glint graph pipelinerenders a GitLab CI-style SVG/PNG;--format mermaidor--format htmlfor alternative pipeline output;--no-skippedhides jobs that would not run in the given context - LSP server —
glint lspstarts a Language Server Protocol server over stdin/stdout; connect with any LSP client to get inline diagnostics (rule ID as code, error/warning severity) in VS Code, Neovim, Emacs, JetBrains, etc. - VS Code extension —
editors/vscode/wraps the LSP server; inline squiggles for every glint rule directly in the editor
See FEATURES.md for the complete feature reference and lint rules table, and ROADMAP.md for planned improvements.
Installation
See INSTALL.md for all options: pre-built binaries (Linux amd64/arm64, macOS Intel/Apple Silicon, Windows), Homebrew tap, and building from source.
Quick start (Linux/macOS, building from source):
git clone https://git.k3nny.fr/k3nny/glint
cd glint
go build -o glint ./cmd/glint/...
sudo mv glint /usr/local/bin/
Homebrew:
brew tap k3nny/glint https://github.com/k3nny/homebrew-glint
brew install glint
Requirements
Go 1.21 or later (when building from source). Pre-built binaries have no runtime dependencies.
Usage
glint [OPTIONS] <COMMAND>
Commands:
check Lint a pipeline file — exits 0 (clean), 2 (errors), or 10 (warnings only)
render Resolve all includes and extends into a single merged YAML file
graph Visualise the pipeline as a job tree or Mermaid graph
explain Show description and fix for a lint rule (e.g. glint explain GL007)
lsp Start a Language Server Protocol server (stdin/stdout)
Run glint <command> --help for all flags. See FEATURES.md for the
complete feature reference.
Integrations
Pre-commit hook
Add to .pre-commit-config.yaml in your repository to run glint automatically whenever .gitlab-ci.yml changes:
repos:
- repo: https://git.k3nny.fr/k3nny/glint
rev: v0.3.0
hooks:
- id: glint
Requires pre-commit and Go 1.21+. On first run, pre-commit builds glint from source automatically.
GitLab CI component
Copy templates/check.yml into your repository and include it as a local file, or publish this repository to a GitLab CI/CD Catalog and reference it as a component:
# As a local include (copy templates/check.yml to your repo first):
include:
- local: .gitlab/glint-check.yml
# As a Catalog component (after publishing to a GitLab instance):
include:
- component: $CI_SERVER_FQDN/k3nny/glint/check@v0.3.0
inputs:
stage: validate # optional, default: validate
allow_failure: true # optional, default: false
The component downloads the glint Linux binary, runs glint check, and respects all inputs defined in the spec: block.
GitHub Actions
Copy action.yml from this repository, or mirror this repo to GitHub as k3nny/glint and reference it directly:
- uses: k3nny/glint@v0.3.0
with:
file: .gitlab-ci.yml # optional, default: .gitlab-ci.yml
args: '--format sarif' # optional
The action downloads the glint Linux binary into $RUNNER_TEMP and runs glint check. Only Linux runners are supported (matches the available release binary).
VS Code extension
Clone this repository and load the extension from editors/vscode/:
cd editors/vscode
npm install # install dependencies (once)
npm run compile # compile TypeScript → out/
Then in VS Code: Run → Start Debugging (F5) — this opens an Extension Development Host with glint diagnostics active for any .gitlab-ci.yml you open.
Make sure glint is on your PATH, or set glint.executablePath in VS Code settings to the full path of the binary.
To package a .vsix for local installation:
task ext-package # produces glint-X.Y.Z.vsix
code --install-extension glint-X.Y.Z.vsix
Development
This project uses Task as a task runner.
task # list available tasks
task build # compile the binary
task test # run Go unit tests
task lint-go # run go vet
task validate # run the binary against all testdata fixtures
task ci # full check: vet → test → build → validate
task fuzz # run fuzz tests for the YAML parser (Ctrl-C to stop; FUZZ_TIME=60s to set duration)
task changelog # regenerate CHANGELOG.md from git history via git-cliff
task changelog-next # preview unreleased section (dry-run, no file written)
task ext-install # install VS Code extension npm dependencies
task ext-compile # compile the VS Code extension TypeScript source
task ext-package # package the VS Code extension as a .vsix
task build-linux-amd64 # cross-compile for Linux x86-64 (requires a tagged commit)
task build-linux-arm64 # cross-compile for Linux ARM64 (requires a tagged commit)
task build-darwin-amd64 # cross-compile for macOS Intel (requires a tagged commit)
task build-darwin-arm64 # cross-compile for macOS Apple Silicon (requires a tagged commit)
task build-windows # cross-compile for Windows x86-64 (requires a tagged commit)
task build-release # build all platform binaries at once (requires a tagged commit)
task clean # remove build artifacts
Optional tools:
- git-cliff — changelog generator used by
task changelog. Install withbrew install git-clifforcargo install git-cliff.
Project structure
.
├── cmd/glint/ # CLI entrypoint
├── internal/
│ ├── cicontext/ # CI variable context, rules:if: evaluator, job reachability
│ ├── fetcher/ # GitLab API client (project include fetching)
│ ├── graph/ # Mermaid and SVG/PNG graph generators
│ ├── linter/ # lint rules and findings
│ ├── model/ # pipeline data structures and YAML parser
│ └── resolver/ # extends: resolution and project include merging
├── testdata/ # sample pipelines used for manual validation
├── Taskfile.yml
└── go.mod
