Skip to content

Commit

Permalink
Create a GitHub Release when publishing a new buildpack version (#1663)
Browse files Browse the repository at this point in the history
Previously when a new buildpack version was published only a Git tag
was created. Now a GitHub release will be too, which contains the
release's changelog entry extracted from `CHANGELOG.md`.

This change makes it possible for people to subscribe to just the
repository release event notifications, rather than needing to
subscribe to all pull requests events and manually spot release
PRs being opened/merged.

The GitHub CLI is used to create the release, which also creates the
Git tag - meaning the manual Git revision/tag/push steps are no longer
required.

In addition, some environment/release validation checks have been
added, which:
- Improve the onboarding UX if required tools aren't installed.
- Prevent accidentally running the publish step before having
  triggered/merged the prepare release PR workflow.
- Prevent version mismatch issues if the buildpack were ever
  rolled back on the registry.

See:
https://cli.github.com/manual/gh_release_view
https://cli.github.com/manual/gh_release_create
https://github.com/heroku/libcnb.rs/blob/ba5e8231b88f6f72533e8a9ba01d9745b3f40301/.github/workflows/release.yml#L52-L60

GUS-W-16959313.
  • Loading branch information
edmorley authored Oct 14, 2024
1 parent a2cf258 commit 737bba1
Showing 1 changed file with 52 additions and 15 deletions.
67 changes: 52 additions & 15 deletions etc/publish.sh
Original file line number Diff line number Diff line change
@@ -1,28 +1,65 @@
#!/usr/bin/env bash
# shellcheck disable=SC2250 # TODO: Use braces around variable references even when not strictly required.

set -euo pipefail
shopt -s inherit_errexit

BP_NAME=${1:-"heroku/python"}
buildpack_registry_name="heroku/python"

curVersion=$(heroku buildpacks:versions "$BP_NAME" | awk 'FNR == 3 { print $1 }')
newVersion="v$((curVersion + 1))"
function abort() {
echo
echo "Error: ${1}" >&2
exit 1
}

read -r -p "Deploy as version: $newVersion [y/n]? " choice
case "$choice" in
y | Y) echo "" ;;
echo "Checking environment..."

if ! command -v gh >/dev/null; then
abort "Install the GitHub CLI first: https://cli.github.com"
fi

if ! heroku buildpacks:publish --help >/dev/null; then
abort "Install the Buildpack Registry plugin first: https://github.com/heroku/plugin-buildpack-registry"
fi

# Explicitly check the CLI is logged in, since the Buildpack Registry plugin doesn't handle re-authing
# expired logins properly, which can otherwise lead to the release aborting partway through.
if ! heroku whoami >/dev/null; then
abort "Log into the Heroku CLI first: heroku login"
fi

echo "Checking buildpack versions in sync..."
current_github_release_version=$(gh release view --json tagName --jq '.tagName' | tr --delete 'v')
current_registry_version="$(heroku buildpacks:versions "${buildpack_registry_name}" | awk 'FNR == 3 { print $1 }')"

if [[ "${current_github_release_version}" != "${current_registry_version}" ]]; then
abort "The current GitHub release version (v${current_github_release_version}) does not match the registry version (v${current_registry_version}), likely due to a registry rollback. Fix this first!"
fi

new_version="$((current_github_release_version + 1))"
new_git_tag="v${new_version}"

echo "Extracting changelog entry for this release..."
git fetch origin
# Using `git show` to avoid having to disrupt the current branch/working directory.
changelog_entry="$(git show origin/main:CHANGELOG.md | awk "/^## \[v${new_version}\]/{flag=1; next} /^## /{flag=0} flag")"

if [[ -n "${changelog_entry}" ]]; then
echo -e "${changelog_entry}\n"
else
abort "Unable to find changelog entry for v${new_version}. Has the prepare release PR been triggered/merged?"
fi

read -r -p "Deploy as ${new_git_tag} [y/n]? " choice
case "${choice}" in
y | Y) ;;
n | N) exit 0 ;;
*) exit 1 ;;
esac

git fetch origin
originMain=$(git rev-parse origin/main)
echo "Tagging commit $originMain with $newVersion... "
git tag "$newVersion" "${originMain:?}"
git push origin "refs/tags/${newVersion}"
echo -e "\nCreating GitHub release..."
gh release create "${new_git_tag}" --title "${new_git_tag}" --notes "${changelog_entry}"

echo -e "\nPublishing to the buildpack registry..."
heroku buildpacks:publish "$BP_NAME" "$newVersion"
echo -e "\nPublishing to the Heroku Buildpack Registry..."
heroku buildpacks:publish "${buildpack_registry_name}" "${new_git_tag}"
echo
heroku buildpacks:versions "${BP_NAME}" | head -n 3
heroku buildpacks:versions "${buildpack_registry_name}" | head -n 3

0 comments on commit 737bba1

Please sign in to comment.