diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml
new file mode 100644
index 0000000..88b9e36
--- /dev/null
+++ b/.pre-commit-hooks.yaml
@@ -0,0 +1,11 @@
+- id: glint
+ name: glint — validate GitLab CI pipeline
+ description: >-
+ Lint .gitlab-ci.yml with glint before committing. Catches misconfigured
+ stages, invalid keywords, broken needs: graphs, deprecated patterns, and
+ more — without a GitLab server.
+ entry: glint check
+ language: golang
+ files: '(^|/)\.gitlab-ci\.yml$'
+ pass_filenames: true
+ minimum_pre_commit_version: '3.0.0'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7638b9d..74ee42d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This project uses [Semantic Versioning](https://semver.org).
+## [0.2.28] - 2026-06-26
+
+### Added
+
+- **Pre-commit hook** — `.pre-commit-hooks.yaml` defines a `glint` hook with `language: golang`; pre-commit builds glint from source automatically on first run and re-runs `glint check` on any staged `.gitlab-ci.yml` changes. Reference: `repo: https://git.k3nny.fr/k3nny/glint, rev: v0.2.28`.
+
+- **GitLab CI component** (`templates/check.yml`) — a GitLab CI/CD Catalog–compatible component that downloads the glint Linux binary and runs `glint check` as a pipeline job. Accepts inputs: `stage` (default `validate`), `pipeline_file` (default `.gitlab-ci.yml`), `version` (default `latest`), `allow_failure` (default `false`), and `extra_args`. Can also be used as a plain local or remote include without the Catalog.
+
+- **GitHub Actions composite action** (`action.yml`) — downloads the glint Linux binary into `$RUNNER_TEMP`, adds it to `$GITHUB_PATH`, and runs `glint check`. Inputs: `version`, `file`, `args`. Mirror this repository to GitHub as `k3nny/glint` to reference it as `uses: k3nny/glint@v0.2.28`.
+
## [0.2.27] - 2026-06-25
### Added
diff --git a/README.md b/README.md
index ceb0710..ad1ecfe 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
-
+
> **Disclaimer:** This tool was built through iterative AI-assisted development with [Claude](https://claude.ai). 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.
@@ -32,7 +32,7 @@ See [FEATURES.md](FEATURES.md) for the complete feature reference and lint rules
## Installation
```bash
-git clone https://git.k3nny.fr/glint
+git clone https://git.k3nny.fr/k3nny/glint
cd glint
go build -o glint ./cmd/glint/...
```
@@ -58,6 +58,54 @@ Run `glint --help` for all flags. See [USAGE.md](USAGE.md) for full
examples covering output formats, context simulation, remote includes, cache,
graph modes, and project configuration.
+## Integrations
+
+### Pre-commit hook
+
+Add to `.pre-commit-config.yaml` in your repository to run glint automatically whenever `.gitlab-ci.yml` changes:
+
+```yaml
+repos:
+ - repo: https://git.k3nny.fr/k3nny/glint
+ rev: v0.2.28
+ hooks:
+ - id: glint
+```
+
+Requires [pre-commit](https://pre-commit.com) and Go 1.21+. On first run, pre-commit builds glint from source automatically.
+
+### GitLab CI component
+
+Copy [`templates/check.yml`](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:
+
+```yaml
+# 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.2.28
+ 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`](action.yml) from this repository, or mirror this repo to GitHub as `k3nny/glint` and reference it directly:
+
+```yaml
+- uses: k3nny/glint@v0.2.28
+ 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).
+
## Development
This project uses [Task](https://taskfile.dev) as a task runner.
diff --git a/ROADMAP.md b/ROADMAP.md
index ad9a49f..68f5e5f 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -98,9 +98,9 @@ The SVG renderer and terminal tree cover the basic layout. These would bring it
## CI / editor integration
-- **GitLab CI template** — a `.gitlab-ci.yml` snippet that runs `glint` as a pipeline-validation job before the real pipeline executes; publishable to the GitLab CI/CD Catalog
-- **GitHub Actions action** — `uses: k3nny/glint@v1` wrapper for repositories that mirror or manage GitLab pipelines from GitHub
-- **Pre-commit hook** — entry for [pre-commit](https://pre-commit.com) so `glint` runs automatically on `git commit` when `.gitlab-ci.yml` changes
+- ~~**GitLab CI template**~~ — ✓ shipped v0.2.28; `templates/check.yml` is a GitLab CI/CD Catalog component with `spec:` inputs for stage, file, version, allow_failure, and extra args; also usable as a plain local/remote include
+- ~~**GitHub Actions action**~~ — ✓ shipped v0.2.28; `action.yml` composite action downloads the glint Linux binary and runs `glint check`; mirror to GitHub as `k3nny/glint` to reference as `uses: k3nny/glint@v0.2.28`
+- ~~**Pre-commit hook**~~ — ✓ shipped v0.2.28; `.pre-commit-hooks.yaml` defines `language: golang` hook; pre-commit builds glint from source on first run and re-runs on staged `.gitlab-ci.yml` changes
- **LSP server** — `glint lsp` mode exposing diagnostics over the Language Server Protocol; enables inline squiggles in VS Code, JetBrains, Neovim, etc. without a dedicated extension
- **VS Code extension** — thin wrapper around the LSP server with syntax highlighting for `.gitlab-ci.yml`
diff --git a/action.yml b/action.yml
new file mode 100644
index 0000000..fb95206
--- /dev/null
+++ b/action.yml
@@ -0,0 +1,62 @@
+# GitHub Actions composite action — glint pipeline validator
+#
+# To use this action, mirror this repository to GitHub as k3nny/glint, then:
+#
+# - uses: k3nny/glint@v0.2.28
+# with:
+# file: .gitlab-ci.yml # optional
+#
+# Alternatively, copy this file into your own repository and reference it
+# as a local action:
+#
+# - uses: ./.github/actions/glint
+
+name: 'glint'
+description: 'Validate a GitLab CI pipeline file with glint'
+author: 'k3nny'
+
+branding:
+ icon: 'check-circle'
+ color: 'orange'
+
+inputs:
+ version:
+ description: >-
+ glint release tag to install (e.g. 'v0.2.28'). Defaults to 'latest'
+ which resolves to the newest published release.
+ required: false
+ default: 'latest'
+ file:
+ description: 'Path to the pipeline file to validate.'
+ required: false
+ default: '.gitlab-ci.yml'
+ args:
+ description: 'Additional arguments passed to glint check (e.g. --format sarif).'
+ required: false
+ default: ''
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Install glint
+ shell: bash
+ env:
+ GLINT_VERSION: ${{ inputs.version }}
+ run: |
+ set -euo pipefail
+ if [ "$GLINT_VERSION" = "latest" ]; then
+ GLINT_VERSION=$(curl -sf \
+ "https://git.k3nny.fr/api/v1/repos/k3nny/glint/releases?limit=1" \
+ | grep '"tag_name"' | head -1 | cut -d'"' -f4)
+ fi
+ DEST="$RUNNER_TEMP/glint-bin"
+ mkdir -p "$DEST"
+ URL="https://git.k3nny.fr/k3nny/glint/releases/download/${GLINT_VERSION}/glint-${GLINT_VERSION}-linux-amd64"
+ curl -sfL "$URL" -o "$DEST/glint"
+ chmod +x "$DEST/glint"
+ echo "$DEST" >> "$GITHUB_PATH"
+ "$DEST/glint" --version
+
+ - name: Run glint check
+ shell: bash
+ run: glint check ${{ inputs.args }} "${{ inputs.file }}"
diff --git a/templates/check.yml b/templates/check.yml
new file mode 100644
index 0000000..9fde94b
--- /dev/null
+++ b/templates/check.yml
@@ -0,0 +1,62 @@
+# glint — GitLab CI/CD Catalog component
+#
+# Validates a pipeline file with glint before the rest of the pipeline runs.
+#
+# Usage (after publishing to a GitLab instance as a Catalog component):
+#
+# include:
+# - component: $CI_SERVER_FQDN/k3nny/glint/check@v0.2.28
+# inputs:
+# stage: validate # optional — see inputs below
+#
+# Or as a plain remote include (no Catalog required):
+#
+# include:
+# - remote: https://raw.githubusercontent.com/.../templates/check.yml
+#
+# Or copy this file into your repository and use a local include.
+
+spec:
+ inputs:
+ stage:
+ description: "Stage in which to run the glint validation job."
+ default: validate
+ pipeline_file:
+ description: "Path to the pipeline file to validate."
+ default: .gitlab-ci.yml
+ version:
+ description: >-
+ glint release tag to download (e.g. 'v0.2.28'). Use 'latest' to
+ always pull the newest release — not recommended for production
+ pipelines since it may break on a new release.
+ default: latest
+ allow_failure:
+ description: "Set to true to let the job fail without blocking the pipeline."
+ default: false
+ extra_args:
+ description: "Additional arguments passed to 'glint check' (e.g. '--format sarif')."
+ default: ""
+
+---
+glint:check:
+ stage: $[[ inputs.stage ]]
+ image: alpine:3.19
+ variables:
+ GLINT_VERSION: "$[[ inputs.version ]]"
+ GLINT_FILE: "$[[ inputs.pipeline_file ]]"
+ GLINT_ARGS: "$[[ inputs.extra_args ]]"
+ before_script:
+ - apk add --no-cache curl
+ - |
+ if [ "$GLINT_VERSION" = "latest" ]; then
+ GLINT_VERSION=$(curl -sf \
+ "https://git.k3nny.fr/api/v1/repos/k3nny/glint/releases?limit=1" \
+ | grep '"tag_name"' | head -1 | cut -d'"' -f4)
+ fi
+ URL="https://git.k3nny.fr/k3nny/glint/releases/download/${GLINT_VERSION}/glint-${GLINT_VERSION}-linux-amd64"
+ curl -sfL "$URL" -o /usr/local/bin/glint
+ chmod +x /usr/local/bin/glint
+ glint --version
+ script:
+ - glint check $GLINT_ARGS "$GLINT_FILE"
+ allow_failure: $[[ inputs.allow_failure ]]