[GitHub Actions] How to check branch name with GitHub Actions

2024-09-09 hit count image

Let's see how to check the branch name when creating a PR using GitHub Actions.

Outline

When developing a project using Git, you will use a branch strategy as shown in the following link.

At this time, sometimes you need to manage whether you are creating branches according to the branch strategy.

In this blog post, I will learn how to check the branch name when creating a PR using GitHub Actions.

GitHub Actions

To create GitHub Actions that check the branch name, create the .github/workflows/check-branch-name.yml file and modify it as follows.

name: Check Branch Name

on:
  pull_request:

jobs:
  check-branch-name:
    runs-on: ubuntu-latest
    timeout-minutes: 1
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4
      - name: Extract branch and service name
        id: extract_branch_and_service_name
        run : |
          FULL_BRANCH_NAME=$

          BRANCH_NAME=""
          SERVICE_NAME=""

          if [[ $FULL_BRANCH_NAME == "main" || $FULL_BRANCH_NAME == "develop" ]]; then
            BRANCH_NAME="$FULL_BRANCH_NAME"
            SERVICE_NAME="$FULL_BRANCH_NAME"
          else
            # Split the branch name by "/"
            IFS='/' read -ra BRANCH_PARTS <<< "$FULL_BRANCH_NAME"

            # Check if the length of the array is greater than 1
            if [ "${#BRANCH_PARTS[@]}" -gt 1 ]; then
              # Assign the second part as the service name
              BRANCH_NAME=${BRANCH_PARTS[0]}
              SERVICE_NAME=${BRANCH_PARTS[1]}
            else
              # If the length is 1, raise an error
              echo "[Error] Branch name does not contain a valid service name."
              echo "Please check the branch name and try again."
              echo "You can change the branch name by running the following command:"
              echo "git branch -m <new-branch-name>"
              exit 1
            fi
          fi

          echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
          echo "SERVICE_NAME=$SERVICE_NAME" >> $GITHUB_ENV
          echo "FULL_BRANCH_NAME=$FULL_BRANCH_NAME" >> $GITHUB_ENV
      - name: Check Branch Name
        run: |
          BRANCH_NAMES=("dependabot" "hotfix" "release" "review" "feature" "fix" "sub-feature")
          SERVICE_NAMES=("npm_and_yarn" "github_actions" "SERVICE_1" "SERVICE_2" "template" "components" "config" "common")

          if [[ $BRANCH_NAME == "main" || $BRANCH_NAME == "develop" ]]; then
            echo "Branch name is valid."
          elif printf '%s\n' "${BRANCH_NAMES[@]}" | grep -qx "${BRANCH_NAME}" && printf '%s\n' "${SERVICE_NAMES[@]}" | grep -qx "${SERVICE_NAME}"; then
            echo "Branch name is valid."
          else
            echo "[Error] Branch name must contain valid branch names and service names."
            echo "- Current branch: $BRANCH_NAME"
            echo "- Branch names: main develop ${BRANCH_NAMES[@]}"
            echo "- Service names: ${SERVICE_NAMES[@]}"
            exit 1
          fi

Let’s take a closer look at this GitHub Actions.

In my case, I manage the project with a monorepo.

So I use the following branch names.

feature/:SERVICE_NAME/:BRANCH_NAME
release/:SERVICE_NAME/:BRANCH_NAME
fix/:SERVICE_NAME/:BRANCH_NAME
...

I need to check whether the branch name is started with dependabot, hotfix, release, review, feature, fix, sub-feature, etc., and I need to extract the SERVICE_NAME and check if it is using the predefined name.

So I extracted the service name and branch name in advance and stored them in environment variables as follows.

...
      - name: Extract branch and service name
        id: extract_branch_and_service_name
        run : |
          FULL_BRANCH_NAME=$

          BRANCH_NAME=""
          SERVICE_NAME=""

          if [[ $FULL_BRANCH_NAME == "main" || $FULL_BRANCH_NAME == "develop" ]]; then
            BRANCH_NAME="$FULL_BRANCH_NAME"
            SERVICE_NAME="$FULL_BRANCH_NAME"
          else
            # Split the branch name by "/"
            IFS='/' read -ra BRANCH_PARTS <<< "$FULL_BRANCH_NAME"

            # Check if the length of the array is greater than 1
            if [ "${#BRANCH_PARTS[@]}" -gt 1 ]; then
              # Assign the second part as the service name
              BRANCH_NAME=${BRANCH_PARTS[0]}
              SERVICE_NAME=${BRANCH_PARTS[1]}
            else
              # If the length is 1, raise an error
              echo "[Error] Branch name does not contain a valid service name."
              echo "Please check the branch name and try again."
              echo "You can change the branch name by running the following command:"
              echo "git branch -m <new-branch-name>"
              exit 1
            fi
          fi

          echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
          echo "SERVICE_NAME=$SERVICE_NAME" >> $GITHUB_ENV
          echo "FULL_BRANCH_NAME=$FULL_BRANCH_NAME" >> $GITHUB_ENV
...

The branch name and service name that I extracted in advance are compared with the predefined values to check if the branch name and service name are valid.

...
      - name: Check Branch Name
        run: |
          BRANCH_NAMES=("dependabot" "hotfix" "release" "review" "feature" "fix" "sub-feature")
          SERVICE_NAMES=("npm_and_yarn" "github_actions" "SERVICE_1" "SERVICE_2" "template" "components" "config" "common")

          if [[ $BRANCH_NAME == "main" || $BRANCH_NAME == "develop" ]]; then
            echo "Branch name is valid."
          elif printf '%s\n' "${BRANCH_NAMES[@]}" | grep -qx "${BRANCH_NAME}" && printf '%s\n' "${SERVICE_NAMES[@]}" | grep -qx "${SERVICE_NAME}"; then
            echo "Branch name is valid."
          else
            echo "[Error] Branch name must contain valid branch names and service names."
            echo "- Current branch: $BRANCH_NAME"
            echo "- Branch names: main develop ${BRANCH_NAMES[@]}"
            echo "- Service names: ${SERVICE_NAMES[@]}"
            exit 1
          fi
...

Change Branch Name

If you create a PR with a branch name that does not match the predefined rules using GitHub Actions, an error will occur. In this case, you can change the branch name as follows.

git checkout <current-branch-name>
git branch -m <new-branch-name>

Also, you can change the branch name as follows.

git branch -m <current-branch-name> <new-branch-name>

If you change the branch name like this, you can create a new PR and close the existing PR.

Git hooks

If you use the wrong branch name, you can check it with this GitHub Actions, but you cannot check it without creating a PR. Also, if you use the wrong branch name, you need to close the existing PR and create a new PR.

In this case, you can reduce unnecessary work by using Git hooks to check the branch name before creating a PR.

Create script to check branch name

To create a script that checks the branch name, create the scripts/check-branch-name.sh file and modify it as follows.

#!/usr/bin/env sh

pattern='^(dependabot|hotfix|release|review|feature|fix|sub-feature)/(npm_and_yarn|github_actions|SERVICE_1|SERVICE_2|template|components|config|common)/.*'
errorMessage='Invalid branch name. Please follow the correct naming convention.'

if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  echo "Error: Not inside Git working tree."
  exit 1
fi

branches=$(git branch | grep '^\*' | sed 's/^\* //')

if echo "$branches" | grep -Eq "$pattern"; then
  printf "\033[32mPassed\nBranch Name: %s\nPattern: %s\033[0m\n" "$branches" "$pattern"
else
  printf "\033[31mResult: failed\nError Msg: %s\nBranch Name: %s\nPattern: %s\033[0m\n" "$errorMessage" "$branches" "$pattern"
  echo "$errorMessage"
  exit 1
fi

Configure Husky

To set up Git hooks using Husky, modify the .husky/pre-commit file as follows.

# Run validation branch name
. "$(dirname -- "$0")/scripts/validateBranchName.sh"

# Run lint-staged
yarn lint-staged

And then, you need to move the check-branch-name.sh file you created earlier to .husky/scripts/validateBranchName.sh.

Configure Lefthook

To set up Git hooks using Lefthook, modify the .lefthook.yml file as follows.

pre-push:
  scripts:
    "validateBranchName.sh":
      runner: bash

And then, you need to move the check-branch-name.sh file you created earlier to .lefthook/pre-commit/validateBranchName.sh.

Completed

Done! We’ve seen how to check the branch name when creating a PR using GitHub Actions. We also learned how to check the branch name using Git hooks before creating a PR.

If the branch name plays an important role in the project like me, try checking the branch name using GitHub Actions and Git Hooks.

Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!

App promotion

You can use the applications that are created by this blog writer Deku.
Deku created the applications with Flutter.

If you have interested, please try to download them for free.

Posts