# .github/workflows/pr-commit-check.yml # This GitHub Action workflow checks if a pull request has more than one commit. # If it does, it fails the check and instructs the user to squash their commits. name: 'PR Commit Check' # This workflow runs on pull request events. # It's configured to run on any pull request that is opened or synchronized (new commits pushed). on: pull_request: types: [opened, synchronize] # Defines the jobs that will run as part of the workflow. jobs: check-commit-count: # The type of runner that the job will run on. 'ubuntu-latest' is a good default. runs-on: ubuntu-latest # The steps that will be executed as part of the job. steps: # Step 1: Check out the code # This action checks out your repository under $GITHUB_WORKSPACE, so your workflow can access it. - name: Checkout Code uses: actions/checkout@v4 with: # We need to fetch all commits to accurately count them. # '0' means fetch all history for all branches and tags. fetch-depth: 0 # Step 2: Count the commits in the pull request # This step runs a script to get the number of commits in the PR. - name: Count Commits id: count_commits # We use `git rev-list --count` to count the commits. # ${{ github.event.pull_request.base.sha }} is the commit SHA of the base branch. # ${{ github.event.pull_request.head.sha }} is the commit SHA of the head branch (the PR branch). # The '..' syntax gives us the list of commits in the head branch that are not in the base branch. # The output of the command (the count) is stored in a step output variable named 'count'. run: | count=$(git rev-list --count ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}) echo "commit_count=$count" >> $GITHUB_OUTPUT # Step 3: Check if the commit count is greater than 1 # This step uses the output from the previous step to decide whether to pass or fail. - name: Check Commit Count # This step only runs if the 'commit_count' output from the 'count_commits' step is greater than 1. if: steps.count_commits.outputs.commit_count > 1 # If the condition is met, the workflow will exit with a failure status. run: | echo "This pull request has ${{ steps.count_commits.outputs.commit_count }} commits." echo "Please squash them into a single commit before merging." echo "You can use git rebase -i HEAD~N" echo "...where N is the number of commits you want to squash together. The PR check conveniently tells you this number! For example, if the check says you have 3 commits, you would run: git rebase -i HEAD~3." echo "Because you have rewritten the commit history, you must use the --force flag to update the pull request: git push --force" exit 1 # Step 4: Success message # This step runs if the commit count is not greater than 1 (i.e., it's 1). - name: Success if: steps.count_commits.outputs.commit_count <= 1 run: | echo "This pull request has a single commit. Great job!"