From c034dae9151358a91317cce6485a48bd528c9b9f Mon Sep 17 00:00:00 2001 From: hahirwar-cd Date: Wed, 11 Mar 2026 00:19:13 +0530 Subject: [PATCH 1/7] fix(ci): update PR validation workflow to use types, subjectPattern and validateSingleCommit inputs --- .github/workflows/pr-checks.yml | 31 ++++++++++++++++++++++++++++--- .github/workflows/pr_checks.yml | 31 ------------------------------- 2 files changed, 28 insertions(+), 34 deletions(-) delete mode 100644 .github/workflows/pr_checks.yml diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 86993e30..c882e03e 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -25,7 +25,7 @@ on: subjectPattern: required: false type: string - default: '^[A-Z].+$' + default: '^[A-Za-z].+$' validateSingleCommit: required: false type: boolean @@ -46,13 +46,27 @@ jobs: echo "PR Title: $TITLE" - PATTERN="^(feat|fix|docs|style|refactor|test|chore|build|ci|perf|revert)(\([a-zA-Z0-9_-]+\))?: .+" + TYPES=$(echo "${{ inputs.types }}" | tr '\n' '|' | sed 's/|$//') + + if [ "${{ inputs.requireScope }}" = "true" ]; then + PATTERN="^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))(\([a-zA-Z0-9_-]+\)): ${{ inputs.subjectPattern }}" + else + PATTERN="^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))(\([a-zA-Z0-9_-]+\))?: ${{ inputs.subjectPattern }}" + fi if [[ ! "$TITLE" =~ $PATTERN ]]; then echo "::error::PR title does not follow Conventional Commits format." echo "Valid examples:" echo " feat: Add login API" + echo " Feat: Add login API" echo " fix(auth): Resolve token issue" + echo " Fix(auth): Resolve token issue" + echo " docs: Update README" + echo " Docs(readme): Update README formatting" + echo " chore: Update dependencies" + echo " Chore(ci): Update CI pipeline" + echo " refactor(core): Simplify authentication logic" + echo " Refactor(core): Simplify authentication logic" exit 1 fi @@ -79,8 +93,19 @@ jobs: with: fetch-depth: 0 + - name: ๐Ÿ”ข Validate single commit + if: ${{ inputs.validateSingleCommit }} + run: | + COUNT=$(git rev-list --count origin/${{ github.base_ref }}..HEAD) + echo "Commit count in PR: $COUNT" + + if [ "$COUNT" -ne 1 ]; then + echo "::error::This PR must contain exactly one commit." + exit 1 + fi + - name: ๐Ÿงพ Commitlint Validation (Inline Config) uses: wagoid/commitlint-github-action@v6 with: configFile: commitlint.config.cjs -... +... \ No newline at end of file diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml deleted file mode 100644 index 91e1435e..00000000 --- a/.github/workflows/pr_checks.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: '๐Ÿ” PR Validation (compat alias)' -on: - workflow_call: - inputs: - types: - required: false - type: string - requireScope: - required: false - type: boolean - subjectPattern: - required: false - type: string - validateSingleCommit: - required: false - type: boolean - checkLabels: - required: false - type: boolean - -jobs: - delegate: - uses: ./.github/workflows/pr-checks.yml - with: - types: ${{ inputs.types }} - requireScope: ${{ inputs.requireScope }} - subjectPattern: ${{ inputs.subjectPattern }} - validateSingleCommit: ${{ inputs.validateSingleCommit }} - checkLabels: ${{ inputs.checkLabels }} - secrets: inherit From 635fa97449554d7d70a502e1e8f2f07c7a8f829c Mon Sep 17 00:00:00 2001 From: hahirwar-cd Date: Wed, 11 Mar 2026 00:36:04 +0530 Subject: [PATCH 2/7] feat: improve PR validation with specific error messages --- .github/workflows/pr-checks.yml | 45 ++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index c882e03e..ead47783 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -25,7 +25,7 @@ on: subjectPattern: required: false type: string - default: '^[A-Za-z].+$' + default: '[A-Za-z].+' validateSingleCommit: required: false type: boolean @@ -43,30 +43,39 @@ jobs: - name: Validate PR title format run: | TITLE="${{ github.event.pull_request.title }}" - echo "PR Title: $TITLE" TYPES=$(echo "${{ inputs.types }}" | tr '\n' '|' | sed 's/|$//') - if [ "${{ inputs.requireScope }}" = "true" ]; then - PATTERN="^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))(\([a-zA-Z0-9_-]+\)): ${{ inputs.subjectPattern }}" - else - PATTERN="^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))(\([a-zA-Z0-9_-]+\))?: ${{ inputs.subjectPattern }}" + # Check valid type + TYPE_REGEX="^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))" + + if [[ ! "$TITLE" =~ $TYPE_REGEX ]]; then + echo "::error::Invalid PR type." + echo "Allowed types:" + echo "${{ inputs.types }}" + exit 1 fi - if [[ ! "$TITLE" =~ $PATTERN ]]; then - echo "::error::PR title does not follow Conventional Commits format." - echo "Valid examples:" + # Check scope requirement + if [[ "${{ inputs.requireScope }}" == "true" ]]; then + if [[ ! "$TITLE" =~ ^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))\([a-zA-Z0-9_-]+\): ]]; then + echo "::error::PR title must include a scope because requireScope=true." + echo "Example:" + echo " feat(auth): Add login API" + exit 1 + fi + fi + + # Extract subject + SUBJECT=$(echo "$TITLE" | sed 's/^.*: //') + + # Validate subject pattern + if [[ ! "$SUBJECT" =~ ${{ inputs.subjectPattern }} ]]; then + echo "::error::PR subject does not match required pattern." + echo "Subject must match regex: ${{ inputs.subjectPattern }}" + echo "Example:" echo " feat: Add login API" - echo " Feat: Add login API" - echo " fix(auth): Resolve token issue" - echo " Fix(auth): Resolve token issue" - echo " docs: Update README" - echo " Docs(readme): Update README formatting" - echo " chore: Update dependencies" - echo " Chore(ci): Update CI pipeline" - echo " refactor(core): Simplify authentication logic" - echo " Refactor(core): Simplify authentication logic" exit 1 fi From a018b18e4ac0ffb53d0a7acddf4b0ae188655e7b Mon Sep 17 00:00:00 2001 From: hahirwar-cd Date: Wed, 11 Mar 2026 00:54:28 +0530 Subject: [PATCH 3/7] feat: allow user to pass their own commitlintConfig --- .github/workflows/pr-checks.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index ead47783..b8793136 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -34,6 +34,11 @@ on: required: false type: boolean default: true + commitlintConfig: + description: "Path to commitlint configuration file" + required: false + type: string + default: "commitlint.config.cjs" jobs: validate-title: @@ -60,7 +65,8 @@ jobs: # Check scope requirement if [[ "${{ inputs.requireScope }}" == "true" ]]; then if [[ ! "$TITLE" =~ ^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))\([a-zA-Z0-9_-]+\): ]]; then - echo "::error::PR title must include a scope because requireScope=true." + echo "::error::PR title must include a scope because requireScope is set to true." + echo "type(scope): Your Message" echo "Example:" echo " feat(auth): Add login API" exit 1 @@ -113,8 +119,8 @@ jobs: exit 1 fi - - name: ๐Ÿงพ Commitlint Validation (Inline Config) + - name: "๐Ÿงพ Commitlint Validation - type(scope): subject" uses: wagoid/commitlint-github-action@v6 with: - configFile: commitlint.config.cjs + configFile: ${{ inputs.commitlintConfig }} ... \ No newline at end of file From 8a69d41daee75fbf7a33ebe0ea52d3ef01306c49 Mon Sep 17 00:00:00 2001 From: hahirwar-cd Date: Wed, 11 Mar 2026 01:08:07 +0530 Subject: [PATCH 4/7] fix: update checks for PR Title --- .github/workflows/pr-checks.yml | 53 +++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index b8793136..eee1acbd 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -1,5 +1,6 @@ --- name: '๐Ÿ” PR Validation' + on: workflow_call: inputs: @@ -18,22 +19,27 @@ on: perf build revert + requireScope: required: false type: boolean default: false + subjectPattern: required: false type: string default: '[A-Za-z].+' + validateSingleCommit: required: false type: boolean default: false + checkLabels: required: false type: boolean default: true + commitlintConfig: description: "Path to commitlint configuration file" required: false @@ -44,6 +50,7 @@ jobs: validate-title: name: ๐Ÿ“ Validate PR title runs-on: ubuntu-latest + steps: - name: Validate PR title format run: | @@ -52,39 +59,39 @@ jobs: TYPES=$(echo "${{ inputs.types }}" | tr '\n' '|' | sed 's/|$//') - # Check valid type - TYPE_REGEX="^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))" + # Allow capitalized types as well + TYPES_REGEX="${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g')" + + # Full regex for conventional commits + FULL_REGEX="^(${TYPES_REGEX})(\([a-zA-Z0-9_-]+\))?:\s+${{ inputs.subjectPattern }}$" - if [[ ! "$TITLE" =~ $TYPE_REGEX ]]; then - echo "::error::Invalid PR type." + if [[ ! "$TITLE" =~ $FULL_REGEX ]]; then + echo "::error::PR title does not follow Conventional Commit format." + echo "" + echo "Required format:" + echo " type(scope): subject" + echo " type: subject" + echo "" + echo "Examples:" + echo " feat: Add login API" + echo " fix(auth): Resolve token issue" + echo " docs(readme): Update README" + echo "" echo "Allowed types:" echo "${{ inputs.types }}" exit 1 fi - # Check scope requirement + # Enforce scope if required if [[ "${{ inputs.requireScope }}" == "true" ]]; then - if [[ ! "$TITLE" =~ ^(${TYPES}|$(echo ${TYPES} | sed 's/\([^|]*\)/\u\1|\l\1/g'))\([a-zA-Z0-9_-]+\): ]]; then - echo "::error::PR title must include a scope because requireScope is set to true." - echo "type(scope): Your Message" + if [[ ! "$TITLE" =~ ^(${TYPES_REGEX})\([a-zA-Z0-9_-]+\): ]]; then + echo "::error::PR title must include a scope because requireScope=true" echo "Example:" echo " feat(auth): Add login API" exit 1 fi fi - # Extract subject - SUBJECT=$(echo "$TITLE" | sed 's/^.*: //') - - # Validate subject pattern - if [[ ! "$SUBJECT" =~ ${{ inputs.subjectPattern }} ]]; then - echo "::error::PR subject does not match required pattern." - echo "Subject must match regex: ${{ inputs.subjectPattern }}" - echo "Example:" - echo " feat: Add login API" - exit 1 - fi - echo "PR title validation passed." - name: ๐Ÿท๏ธ Check PR labels @@ -102,6 +109,7 @@ jobs: validate-commits: name: ๐Ÿงพ Validate Commit Messages runs-on: ubuntu-latest + steps: - name: ๐Ÿ“ฆ Checkout Repository uses: actions/checkout@v6 @@ -119,8 +127,7 @@ jobs: exit 1 fi - - name: "๐Ÿงพ Commitlint Validation - type(scope): subject" + - name: ๐Ÿงพ Commitlint Validation uses: wagoid/commitlint-github-action@v6 with: - configFile: ${{ inputs.commitlintConfig }} -... \ No newline at end of file + configFile: ${{ inputs.commitlintConfig }} \ No newline at end of file From 745eadd14c8bc049ee4972cf35bfd1d3404434ec Mon Sep 17 00:00:00 2001 From: hahirwar-cd Date: Wed, 11 Mar 2026 01:13:52 +0530 Subject: [PATCH 5/7] fix: yaml-lint --- .github/workflows/pr-checks.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index eee1acbd..a1fae02d 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -130,4 +130,5 @@ jobs: - name: ๐Ÿงพ Commitlint Validation uses: wagoid/commitlint-github-action@v6 with: - configFile: ${{ inputs.commitlintConfig }} \ No newline at end of file + configFile: ${{ inputs.commitlintConfig }} +... \ No newline at end of file From 3556e68c855b23eeb63cd569014625536923395d Mon Sep 17 00:00:00 2001 From: hahirwar-cd Date: Wed, 11 Mar 2026 20:41:01 +0530 Subject: [PATCH 6/7] ci: add caller workflow for PR validation --- .github/workflows/pr_checks.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/workflows/pr_checks.yml diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml new file mode 100644 index 00000000..2d10bc9d --- /dev/null +++ b/.github/workflows/pr_checks.yml @@ -0,0 +1,11 @@ +--- +name: ๐Ÿ” PR Validation + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + +jobs: + pr-validation: + uses: clouddrove/github-shared-workflows/.github/workflows/pr-checks.yml@master +... \ No newline at end of file From 37954d949b78381746784507d690d1439f62a14f Mon Sep 17 00:00:00 2001 From: hahirwar-cd Date: Wed, 11 Mar 2026 21:19:17 +0530 Subject: [PATCH 7/7] revert: keep pr_checks.yml as is, add new caller workflow for PR validation --- .github/workflows/caller-pr-checks.yml | 11 +++++++++ .github/workflows/pr_checks.yml | 33 +++++++++++++++++++++----- 2 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/caller-pr-checks.yml diff --git a/.github/workflows/caller-pr-checks.yml b/.github/workflows/caller-pr-checks.yml new file mode 100644 index 00000000..1d04e685 --- /dev/null +++ b/.github/workflows/caller-pr-checks.yml @@ -0,0 +1,11 @@ +--- +name: ๐Ÿ” PR Validation + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + +jobs: + pr-validation: + uses: ./.github/workflows/pr-checks.yml +... \ No newline at end of file diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml index 2d10bc9d..a660fec3 100644 --- a/.github/workflows/pr_checks.yml +++ b/.github/workflows/pr_checks.yml @@ -1,11 +1,32 @@ --- -name: ๐Ÿ” PR Validation - +name: '๐Ÿ” PR Validation (compat alias)' on: - pull_request: - types: [opened, edited, synchronize, reopened] + workflow_call: + inputs: + types: + required: false + type: string + requireScope: + required: false + type: boolean + subjectPattern: + required: false + type: string + validateSingleCommit: + required: false + type: boolean + checkLabels: + required: false + type: boolean jobs: - pr-validation: - uses: clouddrove/github-shared-workflows/.github/workflows/pr-checks.yml@master + delegate: + uses: ./.github/workflows/pr-checks.yml + with: + types: ${{ inputs.types }} + requireScope: ${{ inputs.requireScope }} + subjectPattern: ${{ inputs.subjectPattern }} + validateSingleCommit: ${{ inputs.validateSingleCommit }} + checkLabels: ${{ inputs.checkLabels }} + secrets: inherit ... \ No newline at end of file