diff --git a/release b/release index e982487..f8fc9d8 100644 --- a/release +++ b/release @@ -5,12 +5,41 @@ set -eu VERSION_FORMAT="^v[0-9]+\.[0-9]+\.[0-9]+$" +exit_with_message() { + echo "$1" >&2 + exit 1 +} + +# Run only from default branch. +default_branch=$(git remote show origin | sed -n '/HEAD branch/s/.*: //p') +current_branch=$(git rev-parse --abbrev-ref HEAD) +if [ "$current_branch" != "$default_branch" ]; then + exit_with_message "Not on $default_branch branch. Switch to $default_branch before running this script." +fi + # Check for a clean working directory. if [ -n "$(git status --porcelain)" ]; then - echo "Your working directory is dirty. Commit or stash your changes before running this script." - exit 1 + exit_with_message "Your working directory is dirty. Commit or stash your changes before running this script." fi +# Ensure the local repository is up-to-date. +echo "Updating local repository…" +git fetch origin +git_status=$(git status -uno) +if echo "$git_status" | grep -q "Your branch is behind"; then + exit_with_message "Your local branch is behind the remote. Pull the latest changes before running this script." +elif echo "$git_status" | grep -q "Your branch is ahead"; then + echo "Your local branch is ahead of the remote. Checking if local changes can be pushed…" + if git push --dry-run &> /dev/null; then + echo "Local changes can be pushed without conflicts. Proceeding with the release." + else + exit_with_message "Unable to push local changes. Resolve any conflicts before running this script." + fi +elif ! echo "$git_status" | grep -q "Your branch is up to date"; then + exit_with_message "Unable to determine if branch is up to date. Check your git status manually." +fi +echo "Local repository is ready for release." + # Check if a version tag is provided. if [ "$#" -eq 1 ]; then VERSION_TAG=$1 @@ -24,24 +53,20 @@ else echo "Proceeding with version $suggested_version." VERSION_TAG=$suggested_version else - echo "Release preparation cancelled." - exit 1 + exit_with_message "Release preparation cancelled." fi fi # Verify that the version tag matches the expected format. if ! [[ $VERSION_TAG =~ $VERSION_FORMAT ]]; then - echo "Version tag $VERSION_TAG does not match the expected format ${VERSION_FORMAT}." - exit 1 + exit_with_message "Version tag $VERSION_TAG does not match the expected format ${VERSION_FORMAT}." fi echo "Preparing release ${VERSION_TAG}…" echo -poetry --quiet version "${VERSION_TAG#v}" # Update CHANGELOG. git cliff --tag "$VERSION_TAG" -o CHANGELOG.md -sed -i.bak -e 's/ @\([a-zA-Z0-9]\([-a-zA-Z0-9]*[a-zA-Z0-9]\)\?\)/ [@\1](https:\/\/github.com\/\1)/g' CHANGELOG.md && rm CHANGELOG.md.bak sed -E 's/@([a-zA-Z0-9_-]+)/[@\1](https:\/\/github.com\/\1)/g' CHANGELOG.md > CHANGELOG.tmp && mv CHANGELOG.tmp CHANGELOG.md # Add all changes and commit.