Skip to content

Instantly share code, notes, and snippets.

@Chemaclass
Created April 2, 2025 16:01
Show Gist options
  • Save Chemaclass/5b2728feca724a65e449866623720be9 to your computer and use it in GitHub Desktop.
Save Chemaclass/5b2728feca724a65e449866623720be9 to your computer and use it in GitHub Desktop.
A bash script to render a graph with the number of releases per day
#!/usr/bin/env bash
###################################################################################
# usage example: bash local/release_chart.sh TypedDevs/bashunit --last 300
###################################################################################
set -euo pipefail
REPO=""
LIMIT_DAYS=0
main() {
parse_args "$@"
fetch_release_dates
filter_by_days
count_releases_per_day
render_chart
}
parse_args() {
if [[ $# -eq 0 ]]; then
echo "Usage: $0 <owner/repo> [--last X]"
exit 1
fi
REPO="$1"
shift
if [[ "${1:-}" == "--last" && -n "${2:-}" ]]; then
LIMIT_DAYS="$2"
fi
}
fetch_release_dates() {
echo "Fetching data from GitHub for '$REPO'..."
repo_name=$(gh api "/repos/$REPO" --jq '.full_name')
all_dates=$(
gh api -H "Accept: application/vnd.github+json" \
"/repos/$REPO/releases" \
--paginate \
| jq -r '.[].published_at' \
| cut -d'T' -f1 \
| sort
)
}
filter_by_days() {
if [[ "$LIMIT_DAYS" -gt 0 ]]; then
if date --version >/dev/null 2>&1; then
cutoff_date=$(date -d "$LIMIT_DAYS days ago" +%F)
else
cutoff_date=$(date -v-"$LIMIT_DAYS"d +%F)
fi
release_dates=$(echo "$all_dates" | awk -v cutoff="$cutoff_date" '$0 >= cutoff')
else
release_dates="$all_dates"
fi
}
count_releases_per_day() {
counts=$(echo "$release_dates" | uniq -c | sort -k2)
dates=()
values=()
max_count=0
while read -r count date; do
dates+=("$date")
values+=("$count")
(( count > max_count )) && max_count=$count
done <<< "$counts"
if [[ "${#dates[@]}" -eq 0 ]]; then
echo "No releases found for '$repo_name' in the last $LIMIT_DAYS days."
exit 0
fi
}
render_chart() {
echo ""
echo "πŸ“¦ Repo: $repo_name"
[[ "$LIMIT_DAYS" -gt 0 ]] && echo "πŸ“… Last $LIMIT_DAYS days" || echo "πŸ“… All release history"
find_peak_day
echo "πŸ† Peak day: ${dates[$peak_index]} (${values[$peak_index]} releases)"
echo ""
render_vertical_bars
render_x_axis
}
find_peak_day() {
peak_index=0
for i in "${!values[@]}"; do
if (( values[i] > values[peak_index] )); then
peak_index=$i
fi
done
}
render_vertical_bars() {
for (( level=max_count; level>=1; level-- )); do
line=""
for count in "${values[@]}"; do
if (( count >= level )); then
line+=" β–ˆ "
else
line+=" "
fi
done
echo "$line"
done
}
render_x_axis() {
printf '%s\n' "$(printf '───'%.0s "${dates[@]}")"
for date in "${dates[@]}"; do
printf " %s" "${date:5:2}" # MM
done
echo ""
for date in "${dates[@]}"; do
printf " %s" "${date:8:2}" # DD
done
echo ""
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment