How to run commitlint in GitHub workflow on every commit of a push

5.9k views Asked by At

I have a Github repository, installed commitlint and husky locally and would like to setup a workflow running commitlint on every commit of a push when validating pull requests. On the main branch older commits are not following the conventional commit rules.

I created a separate branch, based on this comment

https://github.com/conventional-changelog/commitlint/issues/586#issuecomment-657226800

I started with this workflow

name: Run commitlint on pull request

on: pull_request

jobs:
  run-commitlint-on-pull-request:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: 14.x

      - name: Install dependencies
        run: npm install

      - name: Validate all commits from PR
        run: npx commitlint --from HEAD~${{ github.event.pull_request.commits }} --to HEAD --verbose

I made two more commits following the conventional commit rules and started a pull request

  • I expected the workflow wouldn't run because I doesn't exist on the main branch yet.
    • Actually it runs
  • I exptected the workflow to check PR commits only
    • The workflow fails because it starts validating EVERY commit in the main branch. And since I know older commits don't follow the rules, this will never pass.

The first solution coming to my mind would be to rebase everything and rename each commit to follow the rules but this would require a huge effort.

I'm not sure if I have to improve this line here

npx commitlint --from HEAD~${{ github.event.pull_request.commits }} --to HEAD --verbose

to check commits from the PR only (unfortunately I don't know what needs to get fixed there).

Do you have any ideas or is rebasing and renaming the only solution?

3

There are 3 answers

3
Matt On BEST ANSWER

Solution

The straight-forward solution is to use the --to and --from arguments of commitlint with the SHA-1 values instead of the branch names or relative references. On the one hand, this reliably solves the problem of unknown revisions or paths in the working tree. On the other hand, only commits in scope of the PR will be checked. As a sidenote: GitHub uses the same references (SHA-1) for the ad-hoc merge that is being checked-out.

We need the base-SHA as well as the head-SHA. In a GitHub action those values are available in the pull-request object of the event in the github-context.

Therefore, you can use the following line which is tested and works as expected:

npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose

Demo

Here is a POC repository on GitHub with 3 test cases (pull-requests).

Complete workflow

name: Run Commitlint on PR

on:
  pull_request:

jobs:

  run-commitlint-on-pr:
    runs-on: ubuntu-latest

    steps:

      - uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: 14.x

      - name: Install dependencies
        run: npm install

      - name: Validate all commits from PR
        run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose
11
Constantin Konstantinidis On

git rev-list is considered because the commit of the pull request (PR) seems invalid. No loop should be required.

This issue hints to checkout the PR branch which seems simpler than fetching the PR commits. From the question, testing on default branch does not seem required.

- uses: actions/checkout@v2
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.base.sha }}

The lint instruction would be:

npx commitlint --from ${{ github.event.pull_request.base.sha }} --verbose

Documentation of pull-request payload does not offer the list of commits right away.

1
Julian Espinel On

I used the following github action: https://github.com/wagoid/commitlint-github-action

From the README of the linked repository:

Create a github workflow in the .github folder, e.g. .github/workflows/commitlint.yml:

name: Lint Commit Messages
on: [pull_request]

jobs:
  commitlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - uses: wagoid/commitlint-github-action@v5