|
| 1 | +# Checks all commits in a PR follow the repo rules: |
| 2 | +# |
| 3 | +# 1. conventional commit messages |
| 4 | +# 2. used `git commit --signoff` |
| 5 | +# 3. no extra merge commits |
| 6 | +name: Commits |
| 7 | + |
| 8 | +on: |
| 9 | + workflow_dispatch: |
| 10 | + # Perform these checks on PRs into *any* branch. |
| 11 | + # |
| 12 | + # Motivation: |
| 13 | + # Commits which are not --signoff but merged into other branches |
| 14 | + # will likely make their way into PRs for master. At which |
| 15 | + # point it will be difficult to get the original author to --signoff. |
| 16 | + pull_request: |
| 17 | + |
| 18 | +jobs: |
| 19 | + commit-checks: |
| 20 | + runs-on: ubuntu-latest |
| 21 | + steps: |
| 22 | + - uses: actions/checkout@v2 |
| 23 | + with: |
| 24 | + fetch-depth: 0 |
| 25 | + |
| 26 | + - name: Set commit range variables |
| 27 | + # Finding the commit range is not as trivial as it may seem. |
| 28 | + # |
| 29 | + # At this stage git's HEAD does not refer to the latest commit in the PR, |
| 30 | + # but rather to the merge commit inserted by the PR. So instead we have |
| 31 | + # to get 'HEAD' from the PR event. |
| 32 | + # |
| 33 | + # One cannot use the number of commits (github.event.pull_request.commits) |
| 34 | + # to find the start commit i.e. HEAD~N does not work, this breaks if there |
| 35 | + # are merge commits. |
| 36 | + run: | |
| 37 | + echo "PR_HEAD=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV |
| 38 | + echo "PR_BASE=${{ github.event.pull_request.base.sha }}" >> $GITHUB_ENV |
| 39 | +
|
| 40 | + - name: Install conventional-commit linter |
| 41 | + run: | |
| 42 | + # Intall the linter and the conventional commits config |
| 43 | + npm install @commitlint/config-conventional @commitlint/cli |
| 44 | +
|
| 45 | + # Extend the conventional commits config with the `--signoff` |
| 46 | + # requirement. |
| 47 | + echo "module.exports = { |
| 48 | + extends: ['@commitlint/config-conventional'], |
| 49 | + rules: { |
| 50 | + 'signed-off-by': [2, 'always', 'Signed-off-by:'], |
| 51 | + } |
| 52 | + }" > commitlint.config.js |
| 53 | +
|
| 54 | + - name: Conventional commit check |
| 55 | + run: | |
| 56 | + npx commitlint --from $PR_BASE --to $PR_HEAD |
| 57 | +
|
| 58 | + - name: No merge commits |
| 59 | + run: | |
| 60 | + # This will list any merge commits in the PR commit path |
| 61 | + MERGE=$(git log --merges --ancestry-path $PR_BASE..$PR_HEAD) |
| 62 | +
|
| 63 | + # The merge list should be empty |
| 64 | + [[ ! -z "$MERGE" ]] && { |
| 65 | + echo "PR contains merge commits:"; |
| 66 | + echo $MERGE; |
| 67 | + exit 1; |
| 68 | + } |
| 69 | + exit 0; |
0 commit comments