diff --git a/.github/workflows/docs-required-check.yml b/.github/workflows/docs-required-check.yml new file mode 100644 index 00000000..80b0caad --- /dev/null +++ b/.github/workflows/docs-required-check.yml @@ -0,0 +1,48 @@ +name: PR Title & Docs Check + +on: + pull_request: + types: [opened, synchronize, reopened, edited] + +jobs: + pr-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Validate Conventional Commits title + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + if echo "$PR_TITLE" | grep -qE '^(feat|fix|chore|docs|style|refactor|perf|test|build|ci|revert)(\(.+\))?!?: .+'; then + echo "✅ PR title follows Conventional Commits format." + else + echo "::error::PR title must follow Conventional Commits format: (): " + exit 1 + fi + + - name: Check docs update for fix/feat PRs + env: + PR_TITLE: ${{ github.event.pull_request.title }} + PR_BODY: ${{ github.event.pull_request.body }} + run: | + # Escape hatch: skip docs check if PR body contains "skip-docs-check" + if echo "$PR_BODY" | grep -qi 'skip-docs-check'; then + echo "⏭️ skip-docs-check found in PR body, skipping docs check." + exit 0 + fi + + if echo "$PR_TITLE" | grep -qE '^(fix|feat)(\(.+\))?!?: '; then + echo "This is a fix/feat PR, checking docs/ changes..." + DOCS_CHANGED=$(git diff --name-only ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} -- docs/ | wc -l) + if [ "$DOCS_CHANGED" -eq 0 ]; then + echo "::error::fix/feat PRs must include at least one docs/ update. Add skip-docs-check to the PR body to bypass." + exit 1 + else + echo "✅ docs/ has $DOCS_CHANGED file(s) changed." + fi + else + echo "⏭️ Not a fix/feat PR, skipping docs check." + fi