From d6fbe757218254ec764a4bfa573303b1292f861c Mon Sep 17 00:00:00 2001 From: Nicolas Date: Thu, 21 May 2026 19:13:43 +0000 Subject: [PATCH] ci: add PR title linting against Conventional Commits (#988) Lint PR titles Reviewed-on: https://gitea.com/gitea/runner/pulls/988 Reviewed-by: Lunny Xiao --- .gitea/workflows/pull-pr-title.yml | 27 +++++++++++++++++++++++++++ Makefile | 4 ++++ tools/lint-pr-title.ts | 19 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 .gitea/workflows/pull-pr-title.yml create mode 100644 tools/lint-pr-title.ts diff --git a/.gitea/workflows/pull-pr-title.yml b/.gitea/workflows/pull-pr-title.yml new file mode 100644 index 00000000..9ae1d9a9 --- /dev/null +++ b/.gitea/workflows/pull-pr-title.yml @@ -0,0 +1,27 @@ +name: pr-title + +on: + pull_request: + types: + - opened + - edited + - reopened + - synchronize + - ready_for_review + +permissions: + contents: read + +jobs: + lint-pr-title: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v4 + with: + node-version: 24 + - run: make lint-pr-title + env: + PR_TITLE: ${{ github.event.pull_request.title }} diff --git a/Makefile b/Makefile index caaeb70c..693685e1 100644 --- a/Makefile +++ b/Makefile @@ -118,6 +118,10 @@ lint-go: ## lint go files lint-go-fix: ## lint go files and fix issues $(GO) run $(GOLANGCI_LINT_PACKAGE) run --fix +.PHONY: lint-pr-title +lint-pr-title: ## lint PR title against Conventional Commits (set PR_TITLE=...) + @node ./tools/lint-pr-title.ts + .PHONY: security-check security-check: deps-tools GOEXPERIMENT= $(GO) run $(GOVULNCHECK_PACKAGE) -show color ./... || true diff --git a/tools/lint-pr-title.ts b/tools/lint-pr-title.ts new file mode 100644 index 00000000..a63defe9 --- /dev/null +++ b/tools/lint-pr-title.ts @@ -0,0 +1,19 @@ +#!/usr/bin/env node +import {env, exit} from 'node:process'; + +const allowedTypes = 'build, chore, ci, docs, enhance, feat, fix, perf, refactor, revert, style, test'; +const title = env.PR_TITLE; + +if (!title) { + console.error('Missing PR_TITLE'); + exit(1); +} + +const validTitlePattern = new RegExp(`^(${allowedTypes.replaceAll(', ', '|')})(\\([\\w.-]+\\))?(!)?: .+$`); + +if (!validTitlePattern.test(title)) { + console.error(`Invalid PR title: ${title}`); + console.error('Expected format: type(scope): subject'); + console.error(`Allowed types: ${allowedTypes}`); + exit(1); +}