# Conventional Commits Validator
[](https://github.com/andrey-fomin/ccval/actions/workflows/ci.yml)
[](https://github.com/andrey-fomin/ccval/releases)
[](https://hub.docker.com/r/andreyfomin/ccval)
Validate commit messages using the Conventional Commits format with YAML configuration.
## Installation
### crates.io
```bash
cargo install ccval
```
### GitHub Releases
Download prebuilt binaries from [GitHub Releases](https://github.com/andrey-fomin/ccval/releases) for Linux, macOS, and Windows.
### macOS
On macOS, you may see a warning: "Apple could not verify 'ccval' is free of malware."
To bypass Gatekeeper, run:
```bash
xattr -d com.apple.quarantine /path/to/ccval
```
Alternatively, right-click the binary > Open > Open when prompted.
### Docker
Images are available on Docker Hub: `andreyfomin/ccval`
| `:latest` | Alpine | Yes | ~11 MB |
| `:distroless` | Distroless | No | ~1 MB |
Use the `:distroless` variant for smaller images when only using stdin or file mode.
**Validate stdin:**
```bash
printf 'feat: new feature\n' | docker run --rm -i andreyfomin/ccval --stdin
```
**Validate git commits (Alpine image only):**
```bash
docker run --rm -v $(pwd):/repo -w /repo andreyfomin/ccval --trust-repo
```
### GitHub Action
Use as a GitHub Action in your workflows:
```yaml
on: pull_request
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: andrey-fomin/ccval@v0
```
The action automatically:
- Validates all commits in a PR (uses `--no-merges`)
- Validates the last commit on push events
- Discovers `conventional-commits.yaml` or `.github/conventional-commits.yaml`
**With custom config:**
```yaml
- uses: andrey-fomin/ccval@v0
with:
config: '.github/ccval.yaml'
```
**Override git arguments:**
```yaml
- uses: andrey-fomin/ccval@v0
with:
git-args: 'origin/main..HEAD --no-merges'
```
## Usage
```
Usage: ccval [-c <path>] [-r <path>] [-T] [-- <git-log-args>...]
ccval [-c <path>] --stdin
ccval [-c <path>] -f <path>
ccval -h
Validates commit messages from stdin, a file, or Git.
Modes:
(default) Validate commit(s) from git log
Use -- <git-log-args>... to pass arguments to git log
Default: -1 (last commit)
--stdin Read commit message from stdin
-f, --file <path> Read commit message from a file
-h, --help Show this help message
Options:
-c, --config <path> Use a custom config file path
-r, --repository <path>
Path to Git repository working tree
Cannot be used with --stdin or --file
-T, --trust-repo Trust the repository despite ownership mismatch
Useful when running in containers or accessing
repositories owned by other users
Requires git mode (cannot use with --stdin or --file)
Examples:
ccval # validate last commit
ccval -- origin/main..HEAD # validate commits on branch
ccval -r /path/to/repo # validate last commit in specific repo
ccval -T # validate last commit, trusting repo
ccval -r /repo -T # validate in container
printf 'feat: msg\n' | ccval --stdin
ccval --file .git/COMMIT_EDITMSG
ccval -c config.yaml --stdin
```
### Exit Codes
| 0 | Success |
| 1 | Validation failed |
| 2 | Parse error |
| 3 | Config error |
| 4 | CLI usage error |
| 5 | I/O error |
| 6 | Git error |
## Examples
```bash
ccval # validate last commit
ccval -- origin/main..HEAD # validate commits on branch
ccval -r /path/to/repo # validate last commit in specific repo
ccval -r . -c config.yaml # use custom config
printf 'feat: msg\n' | ccval --stdin
ccval --file .git/COMMIT_EDITMSG
ccval -c config.yaml --stdin
```
## Configuration
Create `conventional-commits.yaml` in your working directory:
```yaml
preset: strict
scope:
required: true
values:
- api
- core
- ui
type:
values:
- feat
- fix
- docs
- refactor
```
### Presets
- `default` - formatting rules for description spacing
- `strict` - `default` plus header length limits and common type restrictions
### Available Fields
```yaml
preset: default
message: <RULES>
header: <RULES>
type: <RULES>
scope: <RULES>
description: <RULES>
body: <RULES>
footer-token: <RULES>
footer-value: <RULES>
footers:
Closes: <RULES>
```
### Validation Rules
| `max-length` | Maximum total length (including newlines) |
| `max-line-length` | Maximum line length (excluding newlines) |
| `required` | Field must be present |
| `forbidden` | Field must not be present |
| `regexes` | List of regexes (all must match) |
| `values` | List of allowed values |
## Building from Source
```bash
cargo build --release
```
The binary will be at `./target/release/ccval`.