Skip to content

About

Language-agnostic code quality control tool with Git hooks A code quality control tool built in Go, distributed as a single binary with no external runtime dependencies. Provides enhanced visual feedback with spinners, execution timing, and structured JSON output.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

59 Commits

Folders and files

Repository files navigation

en pt-br

Go Quality Gate Logo

Go Quality Gate

Go Version License CI Release Docker PRs Welcome

Language-agnostic code quality control tool with Git hooks

A code quality control tool built in Go, distributed as a single binary with no external runtime dependencies. Provides enhanced visual feedback with spinners, execution timing, and structured JSON output.

✨ Key Features

  • πŸ—οΈ Single Binary: Zero runtime dependencies (Python, Node.js)
  • πŸ”§ Automatic Setup: Installs quality tools automatically
  • 🌍 Multi-language: Supports multiple languages in the same repository
  • πŸ“Š Observability: Spinners, timing, and real-time visual feedback
  • πŸ”’ Built-in Security: Secret scanning plus Python dependency vulnerability audit (pip-audit) in commit/push workflow
  • ⚑ Native Performance: Instant execution without interpreters
  • πŸš€ CI/CD Ready: Clean JSON output for automation pipelines
  • πŸ€– MCP Server: Model Context Protocol support for AI coding agents (Claude, Cursor, etc.)

πŸš€ Quick Start

πŸ“– New here? The Usage Guide walks through setup and the daily commit flow in a few minutes.

1. Installation

Option A: Download Pre-built Binary (Recommended)

# Download the latest release for your platform
# Linux (x64)
wget https://github.com/dmux/go-quality-gate/releases/latest/download/quality-gate-linux-amd64
chmod +x quality-gate-linux-amd64
sudo mv quality-gate-linux-amd64 /usr/local/bin/quality-gate

# Linux (ARM64)
wget https://github.com/dmux/go-quality-gate/releases/latest/download/quality-gate-linux-arm64
chmod +x quality-gate-linux-arm64
sudo mv quality-gate-linux-arm64 /usr/local/bin/quality-gate

# macOS (Intel)
wget https://github.com/dmux/go-quality-gate/releases/latest/download/quality-gate-darwin-amd64
chmod +x quality-gate-darwin-amd64
sudo mv quality-gate-darwin-amd64 /usr/local/bin/quality-gate

# macOS (Apple Silicon)
wget https://github.com/dmux/go-quality-gate/releases/latest/download/quality-gate-darwin-arm64
chmod +x quality-gate-darwin-arm64
sudo mv quality-gate-darwin-arm64 /usr/local/bin/quality-gate

# Windows (download .exe from releases page)
# https://github.com/dmux/go-quality-gate/releases/latest

Option B: Using Go Install

go install github.com/dmux/go-quality-gate/cmd/quality-gate@latest

To upgrade later, run quality-gate --update, which runs the same go install ...@latest and prints the version it moved to.

Option C: Using Docker

# Run directly with Docker
docker run --rm ghcr.io/dmux/go-quality-gate:latest --version

# Create alias for easier usage
echo 'alias quality-gate="docker run --rm -v $(pwd):/workspace -w /workspace ghcr.io/dmux/go-quality-gate:latest"' >> ~/.bashrc
source ~/.bashrc

Option D: Build from Source

# Clone and build
git clone https://github.com/dmux/go-quality-gate.git
cd go-quality-gate
make build

# Install hooks in your project
./quality-gate --install

2. Configuration

Create a quality.yml in your project:

# Generate initial configuration based on your project
./quality-gate --init

3. Usage

# Automatic execution via Git hooks
git commit -m "feat: new feature"

# Manual execution
./quality-gate pre-commit

# JSON output for CI/CD
./quality-gate --output=json pre-commit

# Auto-fix
./quality-gate --fix pre-commit

# Run as Model Context Protocol (MCP) Server for AI Agents
./quality-gate mcp

βš™οΈ Configuration (quality.yml)

tools:
  - name: "Gitleaks"
    check_command: "gitleaks version"
    install_command: "go install github.com/zricethezav/gitleaks/v8@latest"
  - name: "Ruff (Python)"
    check_command: "ruff --version"
    install_command: "pip install ruff"
  - name: "Pip-Audit (Python Dependency Audit)"
    check_command: "pip-audit --version"
    install_command: "pip install pip-audit"

hooks:
  security:
    pre-commit:
      - name: "πŸ”’ Security Check"
        command: "gitleaks detect --no-git --source . --verbose"
        output_rules:
          on_failure_message: "Secret leak detected!"

  python-backend:
    pre-commit:
      - name: "🎨 Format Check (Ruff)"
        command: "ruff format ./backend --check"
        fix_command: "ruff format ./backend"
        output_rules:
          show_on: failure
          on_failure_message: "Run './quality-gate --fix' to format."
      - name: "πŸ›‘οΈ Dependency Audit (pip-audit)"
        command: "pip-audit -r requirements.txt --aliases"
        fix_command: "pip-audit --fix -r requirements.txt"
        output_rules:
          show_on: failure
          on_failure_message: "Vulnerable dependencies found! Run './quality-gate --fix' or upgrade manually."
    pre-push:
      - name: "πŸ›‘οΈ Dependency Audit (pip-audit)"
        command: "pip-audit -r requirements.txt --aliases"
        fix_command: "pip-audit --fix -r requirements.txt"
        output_rules:
          show_on: failure
          on_failure_message: "Vulnerable dependencies found! Run './quality-gate --fix' or upgrade manually."

  typescript-frontend:
    pre-commit:
      - name: "🎨 Format Check (Prettier)"
        command: "npx prettier --check 'frontend/**/*.{ts,tsx}'"
        fix_command: "npx prettier --write 'frontend/**/*.{ts,tsx}'"

The pip-audit dependency audit runs on both pre-commit and pre-push and needs network access (PyPI/OSV). Committing offline? Skip the gate with QG_SKIP="offline" git commit … or drop the audit commands from your quality.yml.

πŸ“˜ How to Use

1. Build

go build -o quality-gate ./cmd/quality-gate

This will create an executable named quality-gate in the current directory.

2. Install Git Hooks

./quality-gate --install

The program will automatically configure pre-commit and pre-push hooks.

3. Advanced Commands

  • ./quality-gate --init: (Experimental) Analyzes your project structure and generates an initial quality.yml file with suggestions
  • ./quality-gate --fix: Executes automatic fix commands (fix_command) defined in your quality.yml
  • ./quality-gate pre-commit --output=json: Executes the specified hook and returns the result in JSON format

4. Configuration (quality.yml)

The configuration is divided into two main sections:

  • tools: List of tools required for the project

    • name: Human-readable tool name
    • check_command: Command that returns success (exit code 0) if the tool is installed
    • install_command: Command executed to install the tool if check_command fails
  • hooks: Quality check configuration

Tool Validation Cache

On the first pre-commit or pre-push execution, Quality Gate runs each configured check_command and installs any missing tool with its install_command. After every tool has been successfully validated, it stores a SHA-256 hash of the tools configuration in:

.git/quality-gate/tools.sha256

Subsequent executions skip the installation checks while the configuration is unchanged. Changing a tool's name, check_command, or install_command, as well as adding, removing, or reordering tools, invalidates the cache and causes all tools to be validated again.

The cache is only updated after a successful validation. If it is missing, outdated, unreadable, or cannot be written, Quality Gate falls back to checking the tools normally without blocking the configured hooks. To force a new validationβ€”for example, after manually uninstalling a toolβ€”delete the cache file before running a hook:

rm .git/quality-gate/tools.sha256

Complete Example

tools:
  - name: "Gitleaks"
    check_command: "gitleaks version"
    install_command: "go install github.com/zricethezav/gitleaks/v8@latest"
  - name: "Ruff (Python Linter/Formatter)"
    check_command: "ruff --version"
    install_command: "pip install ruff"
  - name: "Pip-Audit (Python Dependency Audit)"
    check_command: "pip-audit --version"
    install_command: "pip install pip-audit"
  - name: "Prettier (Code Formatter)"
    check_command: "npx prettier --version"
    install_command: "npm install --global prettier"

hooks:
  security:
    pre-commit:
      - name: "πŸ”’ Security Check (Gitleaks)"
        command: "gitleaks detect --no-git --source . --verbose"
        output_rules:
          on_failure_message: "Secret leak detected! Review code before committing."

  python-backend:
    pre-commit:
      - name: "🎨 Format Check (Ruff)"
        command: "ruff format ./backend --check"
        fix_command: "ruff format ./backend"
        output_rules:
          show_on: failure
          on_failure_message: "Code formatting issue. Run './quality-gate --fix' to fix."
      - name: "πŸ§ͺ Tests (Pytest)"
        command: "pytest ./backend"
        output_rules:
          show_on: always
      - name: "πŸ›‘οΈ Dependency Audit (pip-audit)"
        command: "pip-audit -r requirements.txt --aliases"
        fix_command: "pip-audit --fix -r requirements.txt"
        output_rules:
          show_on: failure
          on_failure_message: "Vulnerable dependencies found! Run './quality-gate --fix' or upgrade manually."
    pre-push:
      - name: "πŸ›‘οΈ Dependency Audit (pip-audit)"
        command: "pip-audit -r requirements.txt --aliases"
        fix_command: "pip-audit --fix -r requirements.txt"
        output_rules:
          show_on: failure
          on_failure_message: "Vulnerable dependencies found! Run './quality-gate --fix' or upgrade manually."

  typescript-frontend:
    pre-commit:
      - name: "🎨 Format Check (Prettier)"
        command: "npx prettier --check 'frontend/**/*.{ts,tsx}'"
        fix_command: "npx prettier --write 'frontend/**/*.{ts,tsx}'"

With --parallel, the three pre-commit hooks above (Gitleaks, Ruff format check, Pytest) run concurrently instead of one after another β€” useful here since Pytest can be the slow one. Run with: ./quality-gate --parallel pre-commit

πŸ“‹ Available Commands

Command Description Example
--install Installs Git hooks in repository ./quality-gate --install
--init Generates initial quality.yml with intelligent analysis ./quality-gate --init
--fix Executes automatic fixes ./quality-gate --fix pre-commit
--install --global Gates every repository of the user (global core.hooksPath) ./quality-gate --install --global
verify Verifies commit watermarks (for CI) ./quality-gate verify --range origin/main..HEAD
doctor Checks hooks, binary and quality.yml are in place ./quality-gate doctor
mcp Runs as an MCP server for AI integration ./quality-gate mcp
--version, -v Shows version information ./quality-gate --version
--update Updates quality-gate to the latest version (via Go) ./quality-gate --update
--output=json Structured output for CI/CD ./quality-gate --output=json pre-commit
--parallel Runs independent hooks concurrently (opt-in) ./quality-gate --parallel pre-commit

πŸ“Š Version Information

# Simple version
./quality-gate --version
# Output: quality-gate version 1.4.0

# JSON version with build details
./quality-gate --version --output json
# Output:
{
  "version": "1.4.0",
  "build_date": "2025-10-21T16:34:44Z",
  "git_commit": "f7b01a2"
}

πŸ” Enforcement and Commit Watermark

Client-side hooks can always be bypassed (git commit --no-verify, deleting the hook). quality-gate therefore works in two layers:

1. Watermark on the client. When every pre-commit check passes, quality-gate records an attestation bound to the exact staged content (git write-tree). The commit-msg hook then appends a trailer:

feat: add login

Quality-Gate: v1.4.0; tree=db228f6d…; config=sha256:4feac6c2…; checks=3/3
  • --no-verify skips both hooks, so the commit has no trailer.
  • Amending or rebasing without re-running the checks changes the tree, so the trailer no longer matches.
  • Need to bypass on purpose? QG_SKIP="prod hotfix" git commit … skips the checks but records Quality-Gate-Skipped: prod hotfix for auditing.

2. Enforcement on the server. quality-gate verify checks every commit of a range and fails on missing, stale or malformed watermarks:

quality-gate verify --range origin/main..HEAD                    # strict
quality-gate verify --range origin/main..HEAD --policy allow-skip # accept QG_SKIP commits
quality-gate verify --range origin/main..HEAD --output json

Use the bundled GitHub Action, then mark the job as a required status check in the branch protection / ruleset of main:

name: Quality Gate
on: pull_request
jobs:
  quality-gate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: dmux/go-quality-gate@main
        with:
          policy: strict        # or allow-skip
          run-checks: "true"    # re-run the checks, so a hand-written trailer cannot pass

The client watermark stops casual bypasses; it is not a cryptographic proof, since anyone can type a trailer. The required CI check, which also re-runs the gates, is what makes the gate mandatory. Squash merges create a new commit without a trailer, so verify the pull request commits, not the merge commit.

Committing step by step

quality-gate --install   # once per repository (installs pre-commit, commit-msg, pre-push)
quality-gate doctor      # confirm binary, hooks and quality.yml are in place

git add .
git commit -m "feat: add login"
  1. pre-commit runs the checks. A failure blocks the commit; on success the staged tree and quality.yml hashes are stored.
  2. You write the message.
  3. commit-msg confirms nothing changed and appends the Quality-Gate: trailer (πŸ” Commit watermarked by quality-gate.).
  4. The commit is created. Check it with git log -1 --format='%(trailers)' or quality-gate verify --range HEAD.
Situation Result
git commit --no-verify No trailer β†’ missing in CI
QG_SKIP="reason" git commit Quality-Gate-Skipped: reason β†’ accepted only with --policy allow-skip
--amend / rebase that changes content without the hooks Old trailer no longer matches β†’ tree-mismatch
Staged content changed between checks and message No trailer, with a warning β€” commit again
Commit through the MCP server Watermarked as well

The commit-msg hook never blocks a commit; enforcement happens in CI.

Making installation automatic

  • quality-gate --install --global sets a global core.hooksPath whose hooks act only in repositories that contain a quality.yml (and still run repository-local hooks). It can be distributed to every machine by IT/MDM.
  • Add quality-gate --install to the project bootstrap ("prepare" script in package.json, make setup, etc.).
  • quality-gate doctor reports missing or tampered hooks.
  • The MCP server records the attestation too, so commits made by AI agents are watermarked.

🎯 JSON Output for CI/CD

{
  "status": "success",
  "results": [
    {
      "hook": {
        "Name": "πŸ”’ Security Check",
        "Command": "gitleaks detect --source ."
      },
      "success": true,
      "output": "",
      "duration_ms": 150,
      "duration": "150ms"
    }
  ]
}

πŸ€– Model Context Protocol (MCP) Integration

Go Quality Gate can act as an MCP server, providing standard AI coding agents (like Claude Desktop, Cursor, or Cline) with the ability to interact with your codebase's quality tools natively.

Connecting to an Agent

To use go-quality-gate with Cursor or Claude, simply configure the MCP server to run via standard I/O (stdio). For Cursor, create or update .mcp.json in your workspace:

{
  "mcpServers": {
    "go-quality-gate": {
      "command": "./quality-gate",
      "args": ["mcp"]
    }
  }
}

The server exposes the following MCP Tools to your AI:

  1. run_quality_checks: Executes linters and formatting checks, returning a parsed diagnostic for the AI.
  2. run_auto_fix: Allows the AI to automatically trigger the formatting fixes configured in quality.yml.

πŸ› οΈ Development

Prerequisites

  • Go 1.18+
  • Git
  • Package managers for your project languages (pip, npm, etc.)

Local Setup

# Clone the repository
git clone <repo>
cd go-quality-gate

# Install dependencies
go mod tidy

# Build
go build -o quality-gate ./cmd/quality-gate

# Run tests
go test ./...

# Test locally
./quality-gate --init
./quality-gate --install

Architecture

cmd/quality-gate/     # Main application
internal/
  domain/            # Entities and business rules
  service/           # Application logic
  infra/             # Infrastructure (git, shell, logger)
  repository/        # Persistence interfaces
  config/            # Configuration and parsing

🀝 Contributing

  1. Fork the project
  2. Create a branch: git checkout -b feature/new-feature
  3. Commit your changes: git commit -m 'feat: new feature'
  4. Push to the branch: git push origin feature/new-feature
  5. Open a Pull Request

See TODO.md for detailed roadmap and available tasks.

πŸ“„ License

This project is under the MIT license. See the LICENSE file for more details.


Version: v1.1.x
Status: Active development
Complete documentation: TODO.md

About

Language-agnostic code quality control tool with Git hooks A code quality control tool built in Go, distributed as a single binary with no external runtime dependencies. Provides enhanced visual feedback with spinners, execution timing, and structured JSON output.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages