#!/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"