How to Use a Bash Script to Count Your Heroku Releases
· 6 min readOur Creative Director asked me if I could estimate the number of production releases we have pushed so we could bost about it on our website. I quickly figured out a strategy that would work using just the heroku apps
and heroku releases
commands, but realized I would need to draft a script to iterate and parse the outputs. I also knew it would be best to do this in bash to make use of those heroku-cli commands.
Iām ashamed to say my bash is not strong, so I turned to ChatGPT 3.5 for help. Hereās a trimmed version of the exchange with ChatGPT.
Me: Please write a bash script that helps me count how total production releases to Heroku. Procedure:
- Calls
heroku apps -A
to list my Heroku apps- Finds all apps whose names contain the substring āprodā
- For each app in #2, calls
heroku releases -a {app_name}
- Sums all the latest version numbers to get a total number of production releases
ChatGPT was pretty close on the first try. The overall structure of the script was correct, but it was not correctly parsing the latest release from the output of the heroku releases
command. This was the command it drafted:
releases=$(heroku releases -a "$app" | grep -E '^[0-9]+' | head -n 1 | awk '{print $1}')
This is very close, but it wonāt yield any matches, because the regex used for grep
is matching digits 0-9, but the release numbers are prefixed with a v
, e.g. v55
. The correct regex is therefore: '^v[0-9]+'
. The variable name releases
is also not entirely accurate and may indicate a āmisunderstandingā of the goal. Weād like this line to give us just the latest release number. That said, the command is using head -n 1
to get the latest release. So I decided to give ChatGPT an example of the output to see if it could correct the error.
Me: This is close. There is just an issue parsing the latest release number from the result of the
heroku releases
command. Here is an example result:v88 Deploy b5e486a4 [email protected] 2023/12/15 03:33:29 -0500 (~ 12h ago) v87 Set REDIS_URL config vars [email protected] 2023/12/15 03:11:25 -0500 (~ 12h ago) v86 Deploy eb10b67c [email protected] 2023/12/15 02:48:50 -0500 (~ 13h ago) v85 Deploy 2ced23ee [email protected] 2023/12/15 00:41:51 -0500 (~ 15h ago) v84 Deploy 1f24c745 [email protected] 2023/12/13 02:29:13 -0500 v83 Deploy 58c7705c [email protected] 2023/12/13 02:08:38 -0500 v82 Deploy 8b80ec50 [email protected] 2023/12/12 21:19:02 -0500 v81 Deploy bb148408 [email protected] 2023/12/12 19:51:02 -0500 v80 Set USE_REDIS config vars [email protected] 2023/12/12 18:47:41 -0500 v79 Set REDIS_URL config vars [email protected] 2023/12/12 18:47:33 -0500 v78 Set REDIS_URL config vars [email protected] 2023/12/12 18:44:43 -0500 v77 Set REDIS_URL config vars [email protected] 2023/12/12 18:36:27 -0500 v76 Update NEW_RELIC by newrelic [email protected] 2023/12/12 10:44:14 -0500 v75 Set AWS_S3_SECURE_URLS config vars [email protected] 2023/12/10 17:29:48 -0500 v74 Set AWS_S3_CUSTOM_DOMAIN config vars [email protected] 2023/12/10 17:29:32 -0500
So in this case, we want to parse out the number 88 and add that to
total_releases
. Can you regenerate the script with that in mind?
ChatGPT then regenerated the script and changed the line. This time the regex is correct, but we have a regression. For some reason, ChatGPT removed the head -n 1
step. So this will give us a list of the release numbers of all releases in the output. I think it may have done this because I gave it a list of outputs above, instead of a single line.
latest_version=$(heroku releases -a "$app" | grep -E '^v[0-9]+' | awk '{print $1}' | sed 's/v//')
One more nudge from me set this right:
Me: Not quite. Instead of one
latest_version
this is giving me a list of all the versions. Try again?
And ChatGPT corrected the line. Now the variable name latest_version
is good and we are getting a single release number to add to total_releases
. Nice!
latest_version=$(heroku releases -a "$app" | grep -E '^v[0-9]+' | sort -rV | head -n 1 | awk '{print $1}' | sed 's/v//')
The Final Script
Here is the final script mainly authored by ChatGPT that will get a list of all production Heroku apps you have access to and sum up their latest release versions to give you a total number of all-time production deployments.
In our case, the number of total production releases is over 2000! And that doesnāt even include apps on AWS or those we have shut down and transferred away to clients. So Iād guess out team has probably pushed to prod almost 5000 times over the past five years. A vanity metric, perhaps, but itās still cool to think about.
#!/bin/bash
# Step 1: List Heroku apps
apps=$(heroku apps -A)
# Step 2: Find apps with names containing 'prod'
prod_apps=$(echo "$apps" | grep 'prod' | awk '{print $1}')
# Step 3 and 4: Iterate over prod apps and get total releases
total_releases=0
for app in $prod_apps; do
latest_version=$(heroku releases -a "$app" | grep -E '^v[0-9]+' | sort -rV | head -n 1 | awk '{print $1}' | sed 's/v//')
if [ -n "$latest_version" ]; then
total_releases=$((total_releases + latest_version))
echo "App $app has version v$latest_version as the latest production release."
else
echo "No production releases found for app $app."
fi
done
echo "Total production releases: $total_releases"