Last active
May 24, 2024 04:20
-
-
Save motss/d9d6c58ca7b064982dcdbb5e663f047f to your computer and use it in GitHub Desktop.
How to get a list of merged PRs after the last release tag then format for changelog using Github CLI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Ensure a reelase tag is provided | |
if [ -z "$1" ]; then | |
printf "Please provide a release tag!\n" | |
exit 1 | |
fi | |
RELEASES=$(gh release list --limit 1) | |
# Ensure there is at least one release tag in the repository | |
if [ -z "$RELEASES" ]; then | |
printf "No release found!\n" | |
exit 1 | |
fi | |
# Get the timestamp of the last release tag | |
# By default, Github CLI or gh list all release tags in descending order | |
# Apply limit=1 to get the last release tag | |
TIMESTAMP=$( | |
gh release list \ | |
--limit 1 \ | |
--json tagName,publishedAt \ | |
--jq ".[0].publishedAt | fromdateiso8601" | |
) | |
PRS=$(gh pr list --state merged --limit 1) | |
# Ensure there is at least one merged PR in the repository | |
if [ -z "$PRS" ]; then | |
printf "No merged PRs found!\n" | |
exit 1 | |
fi | |
# To format the merged PRs for changelog, we only need: | |
# 1. PR number - via .number | |
# 1. PR title - via .title | |
# 1. PR author - via .author.login | |
# 1. PR merged at - via .mergedAt | |
# 1. PR merge commit - via .mergeCommit.oid | |
# 1. PR URL - via .url | |
# | |
# Github CLI does not support filter so limit=999 is used here to get a huge number of PRs as a stopgap solution. | |
# 999 is a large enough number but feel free to tweak this to suit you the best. Larger value means Github CLI | |
# has to fetch more data which might slow things down. | |
# | |
# Then, use jq expressions to filter the list of merged PRs that has timestamp > timestamp of last release tag. | |
# | |
# Finally format them for changelog with linkable author and PR. | |
# | |
# Note that this assumes no merged PRs has the same timestamp as the last release tag. | |
MERGED_PRS=$( | |
gh pr list \ | |
--state merged \ | |
--json author,number,mergeCommit,mergedAt,url,title \ | |
--limit 999 \ | |
--jq ".[] | \ | |
select (.mergedAt | fromdateiso8601 > $TIMESTAMP) | \ | |
\"- [\`\(.mergeCommit.oid[0:7])\`](\(.url | split(\"/pull/\")[0])/commit/\(.mergeCommit.oid)) \(.title) by [@\(.author.login)](https://github.com/\(.author.login)) ([#\(.number)](\(.url)))\"" | |
) | |
# Get the last release tag and the repository URL | |
OLD_RELEASE_TAG=$(gh release list --limit 1 --json tagName --jq ".[] | .tagName") | |
# Define your own release tag format | |
NEW_RELEASE_TAG="$1" | |
# Get the repository URL | |
REPO_URL=$(gh repo view --json url --jq ".url") | |
# Define the header of the changelog | |
HEADER="## What's changed" | |
# Define the footer of the changelog | |
FOOTER="Full changelog: $REPO_URL/compare/$OLD_RELEASE_TAG...$NEW_RELEASE_TAG" | |
# Define the changelog | |
CHANGELOG="$HEADER\n\n$MERGED_PRS\n\n$FOOTER\n" | |
# Print the changelog for the release | |
printf "%s" "$CHANGELOG" | |
# Define the new release tag | |
# todo: use semver instead | |
$TAG="$(date '+%Y-%m-%d')-$(git rev-parse --short HEAD)" | |
gh release create $TAG --notes "$CHANGELOG" --title "$TAG" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment