diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000..7b273d6 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,59 @@ +name: Lint Commit Messages + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Fetch base branch + run: | + git fetch origin ${{ github.event.pull_request.base.ref }} + + - name: Validate commit messages + run: | + # Get all commits in this PR + commits=$(git log --format=%H origin/${{ github.event.pull_request.base.ref }}..HEAD) + + echo "Checking commit messages for conventional commit format..." + echo "" + + failed=0 + for commit in $commits; do + msg=$(git log --format=%s -n 1 $commit) + + # Check if message matches conventional commit format + # Format: type(optional-scope): description + # Types: feat, fix, docs, chore, refactor, test, ci, perf, style, revert + if echo "$msg" | grep -qE '^(feat|fix|docs|chore|refactor|test|ci|perf|style|revert)(\(.+\))?: .+'; then + echo "✅ $msg" + else + echo "❌ $msg" + echo " ^ Does not match conventional commit format" + failed=1 + fi + done + + echo "" + if [ $failed -eq 1 ]; then + echo "❌ One or more commits do not follow conventional commit format." + echo "" + echo "Expected format: type(optional-scope): description" + echo "Valid types: feat, fix, docs, chore, refactor, test, ci, perf, style, revert" + echo "" + echo "Examples:" + echo " feat: add support for subdirectory images" + echo " fix: resolve websocket connection timeout" + echo " docs: update installation instructions" + echo " chore(deps): update axum to 0.7" + exit 1 + fi + + echo "✅ All commits follow conventional commit format" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..526508e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,69 @@ +# Contributing to mdserve + +Thank you for your interest in contributing to mdserve! + +## Commit Message Format + +We follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. All commit messages must follow this format: + +``` +type(optional-scope): description + +[optional body] + +[optional footer(s)] +``` + +### Type + +Must be one of the following: + +- **feat**: A new feature +- **fix**: A bug fix +- **docs**: Documentation only changes +- **style**: Changes that do not affect the meaning of the code (white-space, formatting, etc) +- **refactor**: A code change that neither fixes a bug nor adds a feature +- **perf**: A code change that improves performance +- **test**: Adding missing tests or correcting existing tests +- **chore**: Changes to the build process or auxiliary tools and libraries +- **ci**: Changes to CI configuration files and scripts +- **revert**: Reverts a previous commit + +### Scope + +Optional. Can be anything specifying the place of the commit change (e.g., `deps`, `cli`, `server`). + +### Examples + +``` +feat: add support for subdirectory images +fix: resolve websocket connection timeout +docs: update installation instructions +chore(deps): update axum to 0.7 +ci: add commitlint workflow +``` + +### Subject + +- Use imperative, present tense: "add" not "added" nor "adds" +- Don't capitalize the first letter +- No period (.) at the end +- Maximum 72 characters + +## Pull Request Process + +1. Fork the repository and create your branch from `main` +2. Follow the commit message format above for all commits +3. Update documentation if needed +4. Ensure CI passes (tests, clippy, formatting, commit messages) +5. Submit your pull request + +## Code Style + +- Run `cargo fmt` before committing +- Run `cargo clippy` and fix any warnings +- Follow existing code conventions + +## Questions? + +Feel free to open an issue for any questions about contributing. diff --git a/README.md b/README.md index 8b0b05e..74c5609 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,8 @@ that push mdserve toward being a documentation platform or a configurable server are out of scope. We use [conventional commits](https://www.conventionalcommits.org/) (`feat:`, -`fix:`, `chore:`, etc.). PRs that don't follow this style will not be merged. +`fix:`, `chore:`, etc.). All commits are automatically validated against this +format in CI. See [CONTRIBUTING.md](CONTRIBUTING.md) for details. ## License