From 49da96eb51ab8454a947f12722f94468bd869294 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 23:25:31 +0000 Subject: [PATCH 1/4] Initial plan From 26ba02985b029c7ec4bb57490fbd37b044374462 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 23:31:11 +0000 Subject: [PATCH 2/4] fix(ci): enforce strict conventional commits validation Co-authored-by: cziter15 <5003708+cziter15@users.noreply.github.com> --- .github/workflows/validate-commits.yml | 24 ++++++++++++++++++++--- CONTRIBUTING.md | 27 +++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/.github/workflows/validate-commits.yml b/.github/workflows/validate-commits.yml index 7b0edbe..d5946dd 100644 --- a/.github/workflows/validate-commits.yml +++ b/.github/workflows/validate-commits.yml @@ -20,8 +20,12 @@ jobs: # Conventional commits regex pattern # Matches: type[(scope)][!]: description - # Where type is one of: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert - PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?: .{1,}' + # Where: + # - type: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert (lowercase) + # - scope: optional, lowercase alphanumeric with hyphens/underscores/slashes + # - !: optional breaking change indicator + # - description: must start with lowercase, at least 3 characters total + PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9_/-]+\))?!?: [a-z].{2,}$' if [[ ! "$PR_TITLE" =~ $PATTERN ]]; then echo "================================================" @@ -34,12 +38,26 @@ jobs: echo "" echo "Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert" echo "" + echo "Requirements:" + echo " • Type must be lowercase" + echo " • Scope (optional) must be lowercase, alphanumeric with -/_" + echo " • Must have exactly ONE space after the colon" + echo " • Description must start with lowercase letter" + echo " • Description must be at least 3 characters" + echo "" echo "Examples:" echo " ✅ feat: add WiFi reconnection logic" echo " ✅ fix(mqtt): handle reconnect crash" - echo " ✅ docs: update README with setup steps" + echo " ✅ docs: update readme with setup steps" echo " ✅ feat!: remove deprecated API" echo "" + echo "Common mistakes:" + echo " ❌ feat: a (description too short)" + echo " ❌ feat: double space (multiple spaces)" + echo " ❌ Feat: capitalized type" + echo " ❌ feat: Add (capitalized description)" + echo " ❌ feat(Bad Scope): invalid scope" + echo "" echo "Please see CONTRIBUTING.md for more details." exit 1 else diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d04fb85..26afc24 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,15 +48,36 @@ feat: update WiFi connection API BREAKING CHANGE: WiFi.connect() now requires explicit credentials parameter ``` +## Requirements + +The PR title validation enforces these rules: + +- **Type**: Must be lowercase (e.g., `feat`, not `Feat`) +- **Scope**: Optional, must be lowercase alphanumeric with hyphens, underscores, or slashes (e.g., `wifi`, `mqtt`, `esp32-s3`, `wifi/manager`) +- **Separator**: Must have exactly ONE space after the colon (`: `) +- **Description**: Must start with a lowercase letter and be at least 3 characters long +- Individual commits within the PR can use any format + +## Common Mistakes + +Avoid these common errors: + +- ❌ `Feat: add feature` - Type must be lowercase +- ❌ `feat: Add feature` - Description must start with lowercase +- ❌ `feat:add feature` - Missing space after colon +- ❌ `feat: add feature` - Multiple spaces after colon +- ❌ `feat: a` - Description too short (minimum 3 characters) +- ❌ `feat(Bad Scope): add` - Scope must be lowercase +- ❌ `feat(scope with spaces): add` - Scope can't contain spaces +- ✅ `feat: add feature` - Correct format + ## Tips - Keep the PR title under 72 characters -- Use lowercase for type and description - Don't end the PR title with a period - Use the imperative mood ("add feature" not "added feature") -- Be concise and specific +- Be concise but meaningful (avoid very short descriptions) - Reference issues when possible (e.g., `fixes #123`) -- Individual commits within the PR can use any format ## Before pull requests From b72e0074390cda58f137dea976680aee6720399a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 23:33:18 +0000 Subject: [PATCH 3/4] test(ci): add comprehensive PR title validation tests Co-authored-by: cziter15 <5003708+cziter15@users.noreply.github.com> --- .github/workflows/test-pr-title-validation.sh | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100755 .github/workflows/test-pr-title-validation.sh diff --git a/.github/workflows/test-pr-title-validation.sh b/.github/workflows/test-pr-title-validation.sh new file mode 100755 index 0000000..47851a7 --- /dev/null +++ b/.github/workflows/test-pr-title-validation.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# Test script for PR title validation +# This script validates that the PR title validation regex works correctly +# Usage: ./test-pr-title-validation.sh + +set -eo pipefail + +# Use the same pattern as in validate-commits.yml +PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9_/-]+\))?!?: [a-z].{2,}$' + +PASS_COUNT=0 +FAIL_COUNT=0 +ERROR_COUNT=0 + +test_title() { + local title="$1" + local should_pass="$2" + local description="$3" + + if [[ "$title" =~ $PATTERN ]]; then + result="PASS" + else + result="FAIL" + fi + + if [ "$should_pass" = "$result" ]; then + PASS_COUNT=$((PASS_COUNT + 1)) + printf " ✅ %-6s: %s\n" "$result" "$title" + else + ERROR_COUNT=$((ERROR_COUNT + 1)) + printf " 🔴 %-6s: %s (expected: %s) - %s\n" "$result" "$title" "$should_pass" "$description" + fi +} + +echo "==========================================" +echo "PR Title Validation Test Suite" +echo "==========================================" +echo "" +echo "Pattern: $PATTERN" +echo "" + +echo "Valid PR titles (should PASS):" +test_title "feat: add wifi support" "PASS" "Basic feature" +test_title "fix: resolve connection issue" "PASS" "Basic fix" +test_title "docs: update readme" "PASS" "Basic docs" +test_title "feat(wifi): add reconnection" "PASS" "Feature with scope" +test_title "fix(mqtt): handle crash" "PASS" "Fix with scope" +test_title "feat!: breaking change" "PASS" "Breaking change without scope" +test_title "feat(api)!: remove endpoint" "PASS" "Breaking change with scope" +test_title "fix(wifi/manager): resolve issue" "PASS" "Scope with slash" +test_title "feat(esp32-s3): add support" "PASS" "Scope with hyphen" +test_title "chore: bump version to 1.0.46" "PASS" "Version bump" +test_title "refactor: simplify config loader" "PASS" "Refactoring" +test_title "perf: reduce memory usage" "PASS" "Performance improvement" +test_title "test: add unit tests" "PASS" "Tests" +test_title "build: update dependencies" "PASS" "Build changes" +test_title "ci: update workflow" "PASS" "CI changes" +test_title "style: format code" "PASS" "Style changes" +test_title "revert: previous commit" "PASS" "Revert" + +echo "" +echo "Invalid PR titles (should FAIL):" +test_title "Feat: add feature" "FAIL" "Capitalized type" +test_title "FEAT: add feature" "FAIL" "Uppercase type" +test_title "feat :add feature" "FAIL" "Space before colon" +test_title "feat:add feature" "FAIL" "No space after colon" +test_title "feat(scope):add feature" "FAIL" "No space after colon with scope" +test_title "feat: " "FAIL" "Empty description" +test_title "feat:" "FAIL" "No description" +test_title "Add feature" "FAIL" "No type" +test_title "add feature" "FAIL" "Invalid type" +test_title "feat: a" "FAIL" "Single character description" +test_title "feat: ab" "FAIL" "Two character description" +test_title "feat: double space" "FAIL" "Multiple spaces after colon" +test_title "feat(any scope with spaces): desc" "FAIL" "Scope with spaces" +test_title "feat(CAPS): description" "FAIL" "Capitalized scope" +test_title "feat: Add feature" "FAIL" "Capitalized description" +test_title "feat: ADD FEATURE" "FAIL" "Uppercase description" +test_title "feat(scope!): description" "FAIL" "Exclamation in scope" +test_title "feat(scope@version): desc" "FAIL" "Special char in scope" + +echo "" +echo "==========================================" +echo "Test Results" +echo "==========================================" +echo "Correct validations: $PASS_COUNT" +echo "Incorrect validations: $ERROR_COUNT" +echo "" + +if [ $ERROR_COUNT -eq 0 ]; then + echo "✅ All tests passed!" + exit 0 +else + echo "❌ Some tests failed!" + exit 1 +fi From e6d1737c444ca4c1e65be695a0c9ee0b8d731012 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 23:34:50 +0000 Subject: [PATCH 4/4] docs: add PR validation fix summary Co-authored-by: cziter15 <5003708+cziter15@users.noreply.github.com> --- PR_VALIDATION_FIX_SUMMARY.md | 106 +++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 PR_VALIDATION_FIX_SUMMARY.md diff --git a/PR_VALIDATION_FIX_SUMMARY.md b/PR_VALIDATION_FIX_SUMMARY.md new file mode 100644 index 0000000..ec0c658 --- /dev/null +++ b/PR_VALIDATION_FIX_SUMMARY.md @@ -0,0 +1,106 @@ +# PR Title Validation Fix Summary + +## Problem Statement + +The PR title validation workflow was not properly enforcing Conventional Commits specification, allowing non-compliant PR titles to pass validation. + +## Bugs Identified + +### 1. Single-character descriptions accepted +- ❌ Before: `feat: a` → **PASSED** (should fail) +- ✅ After: `feat: a` → **FAILED** (correctly) + +### 2. Multiple spaces after colon accepted +- ❌ Before: `feat: description` → **PASSED** (should fail) +- ✅ After: `feat: description` → **FAILED** (correctly) + +### 3. Scopes with spaces/special chars accepted +- ❌ Before: `feat(bad scope): desc` → **PASSED** (should fail) +- ✅ After: `feat(bad scope): desc` → **FAILED** (correctly) + +### 4. Uppercase descriptions accepted +- ❌ Before: `feat: Add feature` → **PASSED** (should fail) +- ✅ After: `feat: Add feature` → **FAILED** (correctly) + +### 5. Uppercase scopes accepted +- ❌ Before: `feat(CAPS): desc` → **PASSED** (should fail) +- ✅ After: `feat(CAPS): desc` → **FAILED** (correctly) + +## Changes Made + +### 1. Updated Regex Pattern + +**Before:** +```regex +^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?: .{1,} +``` + +**Issues with old pattern:** +- `\(.+\)` - Allows any characters in scope (spaces, special chars, uppercase) +- ` .{1,}` - Allows multiple spaces and single-char descriptions + +**After:** +```regex +^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9_/-]+\))?!?: [a-z].{2,}$ +``` + +**Improvements:** +- `\([a-z0-9_/-]+\)` - Scope limited to lowercase alphanumeric with hyphens, underscores, slashes +- `: ` - Exactly one space required after colon +- `[a-z].{2,}` - Description must start with lowercase letter and be at least 3 chars total +- `$` - Anchors at end to prevent trailing content + +### 2. Enhanced Error Messages + +Added detailed requirements and common mistakes to the validation error output: + +``` +Requirements: + • Type must be lowercase + • Scope (optional) must be lowercase, alphanumeric with -/_ + • Must have exactly ONE space after the colon + • Description must start with lowercase letter + • Description must be at least 3 characters + +Common mistakes: + ❌ feat: a (description too short) + ❌ feat: double space (multiple spaces) + ❌ Feat: capitalized type + ❌ feat: Add (capitalized description) + ❌ feat(Bad Scope): invalid scope +``` + +### 3. Updated CONTRIBUTING.md + +- Added explicit "Requirements" section +- Added "Common Mistakes" section with examples +- Clarified that description must be meaningful (3+ chars) +- Documented scope character restrictions + +### 4. Added Comprehensive Test Suite + +Created `test-pr-title-validation.sh` with 35 test cases covering: +- 17 valid PR title formats +- 18 invalid PR title formats +- All edge cases that were previously bugs + +## Validation Results + +All 35 test cases pass: +- ✅ 17 valid titles correctly accepted +- ✅ 18 invalid titles correctly rejected +- ✅ 0 incorrect validations + +## Impact + +This fix ensures that: +1. All PR titles strictly follow Conventional Commits specification +2. Release notes will have consistent, high-quality commit messages +3. Automated tooling can reliably parse commit types and scopes +4. Contributors get clear, actionable error messages when validation fails + +## Files Modified + +1. `.github/workflows/validate-commits.yml` - Updated regex and error messages +2. `CONTRIBUTING.md` - Added requirements and common mistakes sections +3. `.github/workflows/test-pr-title-validation.sh` - New test suite (35 tests)