Automating tasks in software development has always been a priority for efficient software teams. The faster and more accurately we can execute repetitive tasks, the more time we have for value-added activities. In this post I am going to discuss a bash script that allows developers to automate the creation of pull requests in AWS CodeCommit.

The script

#!/usr/bin/env bash
 
set -e
 
REPO=`git config --get remote.origin.url`
REPONAME=`basename "$REPO"`
 
CURRENT_BRANCH="$(git symbolic-ref HEAD 2>/dev/null)"
CURRENT_BRANCH=${BRANCH##refs/heads/}
 
echo "I want to merge my branch into:"
DEST=$(gum choose "develop" "master")
echo $DEST
 
sources=`git for-each-ref --format='%(refname:short)' refs/heads/ | grep -v $DEST | grep -v master | grep -v main`
 
echo "This is the branch I want to merge:"
SOURCE=$(gum choose ${sources})
echo $SOURCE
 
TITLE=$(gum input --placeholder "Give me a title for this PR")
echo TITLE=$TITLE
 
gum confirm "Create PR '$TITLE' ($SOURCE -> $DEST)?" || exit 1
 
echo "Creating PR..."
PULL_REQUEST_ID=`aws codecommit create-pull-request --title "$TITLE" --targets repositoryName=$REPONAME,sourceReference=$SOURCE,destinationReference=$DEST | jq -r '.pullRequest.pullRequestId'`
PULL_REQUEST_URL="https://eu-west-1.console.aws.amazon.com/codesuite/codecommit/repositories/$REPONAME/pull-requests/$PULL_REQUEST_ID/changes?region=eu-west-1"
printf "🔗 Pull request url:\n$PULL_REQUEST_URL\n"
echo $PULL_REQUEST_URL | pbcopy && printf "(copied to clipboard)\n"
 

How does it look like?

Script execution

Prerequisites for the script

Before diving into the code, there are some prerequisites that you need to install:

  1. gum: gum is an open-source utility that supercharges shell scripting by offering highly configurable, ready-to-use utilities. It’s particularly useful for creating dotfile aliases and interactive prompts within scripts. You can obtain gum from its official GitHub repository at https://github.com/charmbracelet/gum.

  2. aws cli v2: The AWS Command Line Interface (CLI) version 2 is a unified tool to manage and interact with AWS services from the command line. The script leverages the aws cli to interact with AWS CodeCommit for pull request operations. Ensure you have version 2 installed, as it introduces many enhancements over its predecessor. Alongside installation, remember to configure it with the necessary AWS credentials and default region. Visit the official AWS documentation for installation and configuration steps.

  3. jq: A lightweight and versatile command-line JSON processor, jq is indispensable for scripts that deal with JSON-formatted data. It provides the ability to parse, filter, transform, and output JSON data with ease. Whether you’re extracting specific data elements from a JSON payload or beautifying JSON outputs, jq serves as the go-to tool. Installing jq is straightforward, and it’s supported on a variety of platforms. It not only simplifies complex tasks but also ensures data is handled efficiently and accurately in shell scripts. Detailed installation guides and its myriad functionalities can be found on its official documentation.

Breaking down the script

Let’s start by analyzing the script bit by bit.

Shebang and set command

#!/usr/bin/env bash
set -e
  • The #!/usr/bin/env bash shebang tells the system to execute the script with bash.
  • set -e ensures that the script will exit immediately if any command returns a non-zero status.

Fetching repository information

REPO=`git config --get remote.origin.url`
REPONAME=`basename "$REPO"`

Here, the script fetches the remote URL of the repository using git config and extracts the repository name using basename shell function.

Ask for target branch

DEST=$(gum choose "develop" "main")

The user is prompted to select a destination branch for the pull request. gum choose allows a selection between “develop” and “main” (or “master” if you’re using the classic naming convention).

Ask for source branch

sources=`git for-each-ref --format='%(refname:short)' refs/heads/ | grep -v $DEST | grep -v master | grep -v main`
SOURCE=$(gum choose ${sources})

A list of source branches is generated, excluding certain branches like the destination, master, and main. The user then chooses one as the source for the PR.

Pull request title

TITLE=$(gum input --placeholder "Give me a title for this PR")

The user is prompted to input a title for the pull request.

Confirming the pull request creation

gum confirm "Create PR '$TITLE' ($SOURCE -> $DEST)?" || exit 1

A confirmation prompt is presented. If the user denies, the script exits.

Creating the pull request

PULL_REQUEST_ID=`aws codecommit create-pull-request --title "$TITLE" --targets repositoryName=$REPONAME,sourceReference=$SOURCE,destinationReference=$DEST | jq -r '.pullRequest.pullRequestId'`
PULL_REQUEST_URL="https://eu-west-1.console.aws.amazon.com/codesuite/codecommit/repositories/$REPONAME/pull-requests/$PULL_REQUEST_ID/changes?region=eu-west-1"

The aws codecommit create-pull-request command is used to create a PR in AWS CodeCommit. The script uses jq to parse the response and extract the URL of the newly created PR.

Printing and copying the PR URL

printf "🔗 Pull request url:\n$PULL_REQUEST_URL\n"
echo $PULL_REQUEST_URL | pbcopy && printf "(copied to clipboard)\n"

The pull request URL is printed out and copied to the clipboard using the pbcopy command (macOS-specific), ready to be shared with the reviewer.

Conclusion

This bash script is a handy tool for teams that frequently work with AWS CodeCommit. It simplifies the PR creation process, making it faster and less prone to manual errors. However, if you’re planning to use this in a production environment, you might want to add error handling and support for different operating systems (e.g., clipboard operations differ across OS).