ci: add conventional commit and PR base checks #5
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Lint PR | |
| on: | |
| pull_request: | |
| types: | |
| - opened | |
| - edited | |
| - synchronize | |
| - reopened | |
| - labeled | |
| - unlabeled | |
| jobs: | |
| validate-pr-title: | |
| name: Validate PR title (Conventional Commits) | |
| runs-on: ubuntu-latest | |
| if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-conventional-commit-check') }} | |
| steps: | |
| - name: Check Conventional Commits format | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| run: | | |
| # Conventional Commits: <type>(<optional-scope>)(!): <subject> | |
| # Allowed types match the project's release-please changelog sections. | |
| PATTERN='^(feat|fix|docs|style|refactor|test|chore|ci|build|perf|revert)(\([^)]+\))?!?: .+' | |
| if printf '%s' "$PR_TITLE" | grep -qE "$PATTERN"; then | |
| echo "PR title is a valid Conventional Commit: $PR_TITLE" | |
| exit 0 | |
| fi | |
| { | |
| echo "::error title=Invalid PR title::PR title must follow Conventional Commits format." | |
| echo " Got: $PR_TITLE" | |
| echo " Expected: <type>(<optional-scope>)(!): <subject>" | |
| echo " Types: feat, fix, docs, style, refactor, test, chore, ci, build, perf, revert" | |
| echo "" | |
| echo " Examples:" | |
| echo " feat: add new endpoint" | |
| echo " fix(client): handle empty response" | |
| echo " chore!: drop python 3.11 support" | |
| echo "" | |
| echo " Add the 'skip-conventional-commit-check' label to bypass this check." | |
| } >&2 | |
| exit 1 | |
| validate-pr-base: | |
| name: Validate PR base branch | |
| runs-on: ubuntu-latest | |
| if: github.event.pull_request.base.ref == 'main' | |
| permissions: | |
| pull-requests: read | |
| steps: | |
| - name: Check base branch | |
| env: | |
| PR_AUTHOR: ${{ github.event.pull_request.user.login }} | |
| HAS_LABEL: ${{ contains(github.event.pull_request.labels.*.name, 'target-main') }} | |
| run: | | |
| # Exempt automated PRs (Stainless codegen, release-please, dependabot, etc.) | |
| case "$PR_AUTHOR" in | |
| stainless-app|stainless-app\[bot\]|release-please\[bot\]|github-actions\[bot\]|dependabot\[bot\]) | |
| echo "PR is from automation ($PR_AUTHOR); allowing PR targeting main." | |
| exit 0 | |
| ;; | |
| esac | |
| if [ "$HAS_LABEL" = "true" ]; then | |
| echo "Found 'target-main' label; allowing PR targeting main." | |
| exit 0 | |
| fi | |
| echo "::error title=PR should target 'next'::PRs should target the 'next' branch by default. The 'main' branch is reserved for release-please and Stainless automation. If this PR is an intentional hotfix or automation exception, add the 'target-main' label to bypass this check, or re-target the PR base to 'next'." | |
| exit 1 |